diff options
Diffstat (limited to 'targets/wasm_exec.js')
-rw-r--r-- | targets/wasm_exec.js | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/targets/wasm_exec.js b/targets/wasm_exec.js index c430cc2b2..d6270adbf 100644 --- a/targets/wasm_exec.js +++ b/targets/wasm_exec.js @@ -132,6 +132,7 @@ const decoder = new TextDecoder("utf-8"); let reinterpretBuf = new DataView(new ArrayBuffer(8)); var logLine = []; + const wasmExit = {}; // thrown to exit via proc_exit (not an error) global.Go = class { constructor() { @@ -270,14 +271,11 @@ fd_close: () => 0, // dummy fd_fdstat_get: () => 0, // dummy fd_seek: () => 0, // dummy - "proc_exit": (code) => { - if (global.process) { - // Node.js - process.exit(code); - } else { - // Can't exit in a browser. - throw 'trying to exit with code ' + code; - } + proc_exit: (code) => { + this.exited = true; + this.exitCode = code; + this._resolveExitPromise(); + throw wasmExit; }, random_get: (bufPtr, bufLen) => { crypto.getRandomValues(loadSlice(bufPtr, bufLen)); @@ -293,7 +291,14 @@ // func sleepTicks(timeout float64) "runtime.sleepTicks": (timeout) => { // Do not sleep, only reactivate scheduler after the given timeout. - setTimeout(this._inst.exports.go_scheduler, timeout); + setTimeout(() => { + if (this.exited) return; + try { + this._inst.exports.go_scheduler(); + } catch (e) { + if (e !== wasmExit) throw e; + } + }, timeout); }, // func finalizeRef(v ref) @@ -465,12 +470,23 @@ this._ids = new Map(); // mapping from JS values to reference ids this._idPool = []; // unused ids that have been garbage collected this.exited = false; // whether the Go program has exited + this.exitCode = 0; if (this._inst.exports._start) { - this._inst.exports._start(); + let exitPromise = new Promise((resolve, reject) => { + this._resolveExitPromise = resolve; + }); + + // Run program, but catch the wasmExit exception that's thrown + // to return back here. + try { + this._inst.exports._start(); + } catch (e) { + if (e !== wasmExit) throw e; + } - // TODO: wait until the program exists. - await new Promise(() => {}); + await exitPromise; + return this.exitCode; } else { this._inst.exports._initialize(); } @@ -480,7 +496,11 @@ if (this.exited) { throw new Error("Go program has already exited"); } - this._inst.exports.resume(); + try { + this._inst.exports.resume(); + } catch (e) { + if (e !== wasmExit) throw e; + } if (this.exited) { this._resolveExitPromise(); } |