Skip to content

Commit

Permalink
Finish implementing synchronous instantiation.
Browse files Browse the repository at this point in the history
This was tested with bytecodealliance/jco#413.
  • Loading branch information
whitequark committed May 11, 2024
1 parent c8bec54 commit 2f7fead
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 26 deletions.
55 changes: 31 additions & 24 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ export class Application {
}

// The `printLine` option is deprecated and not documented but still accepted for compatibility.
run(args, files = {}, options = {}) {
run(args = null, files = {}, options = {}) {
if (this.resourceData === null) {
if (options.synchronously)
throw new Error("Cannot run application synchronously unless resources are preloaded first");
throw new Error("Cannot run application synchronously unless resources are " +
"prefetched first; use `await run()` to do so");

return this.resources().then(fetchResources).then((resourceData) => {
this.resourceData = resourceData;
Expand All @@ -62,6 +63,7 @@ export class Application {
if (args === null)
return; // prefetch resources, but do not actually run

// meow. :3
const environment = new Environment();
environment.args = [this.argv0].concat(args);
environment.root = directoryFromTree(files);
Expand All @@ -72,30 +74,35 @@ export class Application {
environment.stdout = options.stdout === undefined ? lineBufferedConsole : options.stdout;
environment.stderr = options.stderr === undefined ? lineBufferedConsole : options.stderr;

const wasmCommand = this.instantiate(
(filename) => this.resourceData.modules[filename],
{ runtime: environment.exports },
(module, imports) => options.synchronously
? new WebAssembly.Instance(module, imports)
: WebAssembly.instantiate(module, imports));
let error = null;
try {
wasmCommand.run.run();
} catch (e) {
if (!(e instanceof Exit))
throw e;
if (e instanceof Exit && e.code !== 0)
error = e;
}
const runCommand = (wasmCommand) => {
let error = null;
try {
wasmCommand.run.run();
} catch (e) {
if (!(e instanceof Exit))
throw e;
if (e instanceof Exit && e.code !== 0)
error = e;
}

for (const dirName of Object.keys(this.resourceData.filesystem))
delete environment.root.files[dirName];
files = directoryIntoTree(environment.root, { decodeASCII: options.decodeASCII ?? true });
if (error !== null) {
error.files = files;
throw error;
} else {
return files;
}
};

for (const dirName of Object.keys(this.resourceData.filesystem))
delete environment.root.files[dirName];
files = directoryIntoTree(environment.root, { decodeASCII: options.decodeASCII ?? true });
if (error !== null) {
error.files = files;
throw error;
const getCoreModule = (filename) => this.resourceData.modules[filename];
const imports = { runtime: environment.exports };
if (options.synchronously) {
const instantiateCore = (module, imports) => new WebAssembly.Instance(module, imports);
return runCommand(this.instantiate(getCoreModule, imports, instantiateCore));
} else {
return files;
return this.instantiate(getCoreModule, imports).then(runCommand);
}
}
}
3 changes: 2 additions & 1 deletion test/yowasp_runtime_test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ await yowaspRuntimeTest.run([], {}, {
if (!(lines.length === 1 || lines[0] === 'some text'))
throw 'test 8 failed';

if ((yowaspRuntimeTest.run(['share/foo.txt', 'foo.txt'], {synchronously: true}))['foo.txt'] !== 'contents of foo')
// if used standalone, `await yowaspRuntimeTest.run();` must be invoked first
if ((yowaspRuntimeTest.run(['share/foo.txt', 'foo.txt'], {}, {synchronously: true}))['foo.txt'] !== 'contents of foo')
throw 'test 9 failed';
2 changes: 1 addition & 1 deletion test/yowasp_runtime_test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"scripts": {
"pack": "yowasp-pack-resources gen/resources.js gen share",
"transpile": "jco new ../copy.wasm --wasi-command --output copy.wasm && jco transpile copy.wasm --instantiation sync --no-typescript --no-namespaced-exports --map 'wasi:io/*=runtime#io' --map 'wasi:cli/*=runtime#cli' --map 'wasi:clocks/*=runtime#*' --map 'wasi:filesystem/*=runtime#fs' --out-dir gen/",
"transpile": "jco new ../copy.wasm --wasi-command --output copy.wasm && jco transpile copy.wasm --instantiation async --no-typescript --no-namespaced-exports --map 'wasi:io/*=runtime#io' --map 'wasi:cli/*=runtime#cli' --map 'wasi:clocks/*=runtime#*' --map 'wasi:filesystem/*=runtime#fs' --out-dir gen/",
"build": "./build.sh",
"test": "node ./index.js"
}
Expand Down

0 comments on commit 2f7fead

Please sign in to comment.