diff --git a/cmd/workers-assets-gen/assets/wasm_exec_tinygo.js b/cmd/workers-assets-gen/assets/wasm_exec_tinygo.js index cd1699c..1afa3e9 100644 --- a/cmd/workers-assets-gen/assets/wasm_exec_tinygo.js +++ b/cmd/workers-assets-gen/assets/wasm_exec_tinygo.js @@ -32,7 +32,7 @@ /* if (!global.fs && global.require) { - global.fs = require("fs"); + global.fs = require("node:fs"); } */ @@ -106,7 +106,7 @@ /* if (!global.crypto) { - const nodeCrypto = require("crypto"); + const nodeCrypto = require("node:crypto"); global.crypto = { getRandomValues(b) { nodeCrypto.randomFillSync(b); @@ -126,11 +126,11 @@ /* if (!global.TextEncoder) { - global.TextEncoder = require("util").TextEncoder; + global.TextEncoder = require("node:util").TextEncoder; } if (!global.TextDecoder) { - global.TextDecoder = require("util").TextDecoder; + global.TextDecoder = require("node:util").TextDecoder; } */ @@ -140,6 +140,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() { @@ -278,14 +279,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)); @@ -301,7 +299,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) @@ -481,23 +486,25 @@ 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; - const mem = new DataView(this._inst.exports.memory.buffer) - - while (true) { - const callbackPromise = new Promise((resolve) => { - this._resolveCallbackPromise = () => { - if (this.exited) { - throw new Error("bad callback: Go program has already exited"); - } - setTimeout(resolve, 0); // make sure it is asynchronous - }; + if (this._inst.exports._start) { + let exitPromise = new Promise((resolve, reject) => { + this._resolveExitPromise = resolve; }); - this._inst.exports._start(); - if (this.exited) { - break; + + // 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; } - await callbackPromise; + + await exitPromise; + return this.exitCode; + } else { + this._inst.exports._initialize(); } } @@ -505,7 +512,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(); }