(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.wasiThreads = {})); })(this, (function (exports) { var _WebAssembly = typeof WebAssembly !== 'undefined' ? WebAssembly : typeof WXWebAssembly !== 'undefined' ? WXWebAssembly : undefined; var ENVIRONMENT_IS_NODE = typeof process === 'object' && process !== null && typeof process.versions === 'object' && process.versions !== null && typeof process.versions.node === 'string'; function getPostMessage(options) { return typeof (options === null || options === void 0 ? void 0 : options.postMessage) === 'function' ? options.postMessage : typeof postMessage === 'function' ? postMessage : undefined; } function serizeErrorToBuffer(sab, code, error) { var i32array = new Int32Array(sab); Atomics.store(i32array, 0, code); if (code > 1 && error) { var name_1 = error.name; var message = error.message; var stack = error.stack; var nameBuffer = new TextEncoder().encode(name_1); var messageBuffer = new TextEncoder().encode(message); var stackBuffer = new TextEncoder().encode(stack); Atomics.store(i32array, 1, nameBuffer.length); Atomics.store(i32array, 2, messageBuffer.length); Atomics.store(i32array, 3, stackBuffer.length); var buffer = new Uint8Array(sab); buffer.set(nameBuffer, 16); buffer.set(messageBuffer, 16 + nameBuffer.length); buffer.set(stackBuffer, 16 + nameBuffer.length + messageBuffer.length); } } function deserizeErrorFromBuffer(sab) { var _a, _b; var i32array = new Int32Array(sab); var status = Atomics.load(i32array, 0); if (status <= 1) { return null; } var nameLength = Atomics.load(i32array, 1); var messageLength = Atomics.load(i32array, 2); var stackLength = Atomics.load(i32array, 3); var buffer = new Uint8Array(sab); var nameBuffer = buffer.slice(16, 16 + nameLength); var messageBuffer = buffer.slice(16 + nameLength, 16 + nameLength + messageLength); var stackBuffer = buffer.slice(16 + nameLength + messageLength, 16 + nameLength + messageLength + stackLength); var name = new TextDecoder().decode(nameBuffer); var message = new TextDecoder().decode(messageBuffer); var stack = new TextDecoder().decode(stackBuffer); var ErrorConstructor = (_a = globalThis[name]) !== null && _a !== void 0 ? _a : (name === 'RuntimeError' ? ((_b = _WebAssembly.RuntimeError) !== null && _b !== void 0 ? _b : Error) : Error); var error = new ErrorConstructor(message); Object.defineProperty(error, 'stack', { value: stack, writable: true, enumerable: false, configurable: true }); return error; } /** @public */ function isSharedArrayBuffer(value) { return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) || (Object.prototype.toString.call(value) === '[object SharedArrayBuffer]')); } /** @public */ function isTrapError(e) { try { return e instanceof _WebAssembly.RuntimeError; } catch (_) { return false; } } function createMessage(type, payload) { return { __emnapi__: { type: type, payload: payload } }; } var WASI_THREADS_MAX_TID = 0x1FFFFFFF; function checkSharedWasmMemory(wasmMemory) { if (wasmMemory) { if (!isSharedArrayBuffer(wasmMemory.buffer)) { throw new Error('Multithread features require shared wasm memory. ' + 'Try to compile with `-matomics -mbulk-memory` and use `--import-memory --shared-memory` during linking, ' + 'then create WebAssembly.Memory with `shared: true` option'); } } else { if (typeof SharedArrayBuffer === 'undefined') { throw new Error('Current environment does not support SharedArrayBuffer, threads are not available!'); } } } function getReuseWorker(value) { var _a; if (typeof value === 'boolean') { return value ? { size: 0, strict: false } : false; } if (typeof value === 'number') { if (!(value >= 0)) { throw new RangeError('reuseWorker: size must be a non-negative integer'); } return { size: value, strict: false }; } if (!value) { return false; } var size = (_a = Number(value.size)) !== null && _a !== void 0 ? _a : 0; var strict = Boolean(value.strict); if (!(size > 0) && strict) { throw new RangeError('reuseWorker: size must be set to positive integer if strict is set to true'); } return { size: size, strict: strict }; } var nextWorkerID = 0; /** @public */ var ThreadManager = /*#__PURE__*/ (function () { function ThreadManager(options) { var _a; this.unusedWorkers = []; this.runningWorkers = []; this.pthreads = Object.create(null); this.wasmModule = null; this.wasmMemory = null; this.messageEvents = new WeakMap(); if (!options) { throw new TypeError('ThreadManager(): options is not provided'); } if ('childThread' in options) { this._childThread = Boolean(options.childThread); } else { this._childThread = false; } if (this._childThread) { this._onCreateWorker = undefined; this._reuseWorker = false; this._beforeLoad = undefined; } else { this._onCreateWorker = options.onCreateWorker; this._reuseWorker = getReuseWorker(options.reuseWorker); this._beforeLoad = options.beforeLoad; } this.printErr = (_a = options.printErr) !== null && _a !== void 0 ? _a : console.error.bind(console); } Object.defineProperty(ThreadManager.prototype, "nextWorkerID", { get: function () { return nextWorkerID; }, enumerable: false, configurable: true }); ThreadManager.prototype.init = function () { if (!this._childThread) { this.initMainThread(); } }; ThreadManager.prototype.initMainThread = function () { this.preparePool(); }; ThreadManager.prototype.preparePool = function () { if (this._reuseWorker) { if (this._reuseWorker.size) { var pthreadPoolSize = this._reuseWorker.size; while (pthreadPoolSize--) { var worker = this.allocateUnusedWorker(); if (ENVIRONMENT_IS_NODE) { // https://github.com/nodejs/node/issues/53036 worker.once('message', function () { }); worker.unref(); } } } } }; ThreadManager.prototype.shouldPreloadWorkers = function () { return !this._childThread && this._reuseWorker && this._reuseWorker.size > 0; }; ThreadManager.prototype.loadWasmModuleToAllWorkers = function () { var _this_1 = this; var promises = Array(this.unusedWorkers.length); var _loop_1 = function (i) { var worker = this_1.unusedWorkers[i]; if (ENVIRONMENT_IS_NODE) worker.ref(); promises[i] = this_1.loadWasmModuleToWorker(worker).then(function (w) { if (ENVIRONMENT_IS_NODE) worker.unref(); return w; }, function (e) { if (ENVIRONMENT_IS_NODE) worker.unref(); throw e; }); }; var this_1 = this; for (var i = 0; i < this.unusedWorkers.length; ++i) { _loop_1(i); } return Promise.all(promises).catch(function (err) { _this_1.terminateAllThreads(); throw err; }); }; ThreadManager.prototype.preloadWorkers = function () { if (this.shouldPreloadWorkers()) { return this.loadWasmModuleToAllWorkers(); } return Promise.resolve([]); }; ThreadManager.prototype.setup = function (wasmModule, wasmMemory) { this.wasmModule = wasmModule; this.wasmMemory = wasmMemory; }; ThreadManager.prototype.markId = function (worker) { if (worker.__emnapi_tid) return worker.__emnapi_tid; var tid = nextWorkerID + 43; nextWorkerID = (nextWorkerID + 1) % (WASI_THREADS_MAX_TID - 42); this.pthreads[tid] = worker; worker.__emnapi_tid = tid; return tid; }; ThreadManager.prototype.returnWorkerToPool = function (worker) { var tid = worker.__emnapi_tid; if (tid !== undefined) { delete this.pthreads[tid]; } this.unusedWorkers.push(worker); this.runningWorkers.splice(this.runningWorkers.indexOf(worker), 1); delete worker.__emnapi_tid; if (ENVIRONMENT_IS_NODE) { worker.unref(); } }; ThreadManager.prototype.loadWasmModuleToWorker = function (worker, sab) { var _this_1 = this; if (worker.whenLoaded) return worker.whenLoaded; var err = this.printErr; var beforeLoad = this._beforeLoad; // eslint-disable-next-line @typescript-eslint/no-this-alias var _this = this; worker.whenLoaded = new Promise(function (resolve, reject) { var handleError = function (e) { var message = 'worker sent an error!'; if (worker.__emnapi_tid !== undefined) { message = 'worker (tid = ' + worker.__emnapi_tid + ') sent an error!'; } err(message + ' ' + e.message); if (e.message.indexOf('RuntimeError') !== -1 || e.message.indexOf('unreachable') !== -1) { try { _this.terminateAllThreads(); } catch (_) { } } reject(e); throw e; }; var handleMessage = function (data) { if (data.__emnapi__) { var type = data.__emnapi__.type; var payload = data.__emnapi__.payload; if (type === 'loaded') { worker.loaded = true; if (ENVIRONMENT_IS_NODE && !worker.__emnapi_tid) { worker.unref(); } resolve(worker); // if (payload.err) { // err('failed to load in child thread: ' + (payload.err.message || payload.err)) // } } else if (type === 'cleanup-thread') { if (payload.tid in _this_1.pthreads) { _this_1.cleanThread(worker, payload.tid); } } } }; worker.onmessage = function (e) { handleMessage(e.data); _this_1.fireMessageEvent(worker, e); }; worker.onerror = handleError; if (ENVIRONMENT_IS_NODE) { worker.on('message', function (data) { var _a, _b; (_b = (_a = worker).onmessage) === null || _b === void 0 ? void 0 : _b.call(_a, { data: data }); }); worker.on('error', function (e) { var _a, _b; (_b = (_a = worker).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, e); }); worker.on('detachedExit', function () { }); } if (typeof beforeLoad === 'function') { beforeLoad(worker); } try { worker.postMessage(createMessage('load', { wasmModule: _this_1.wasmModule, wasmMemory: _this_1.wasmMemory, sab: sab })); } catch (err) { checkSharedWasmMemory(_this_1.wasmMemory); throw err; } }); return worker.whenLoaded; }; ThreadManager.prototype.allocateUnusedWorker = function () { var _onCreateWorker = this._onCreateWorker; if (typeof _onCreateWorker !== 'function') { throw new TypeError('`options.onCreateWorker` is not provided'); } var worker = _onCreateWorker({ type: 'thread', name: 'emnapi-pthread' }); this.unusedWorkers.push(worker); return worker; }; ThreadManager.prototype.getNewWorker = function (sab) { if (this._reuseWorker) { if (this.unusedWorkers.length === 0) { if (this._reuseWorker.strict) { if (!ENVIRONMENT_IS_NODE) { var err = this.printErr; err('Tried to spawn a new thread, but the thread pool is exhausted.\n' + 'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.'); return; } } var worker_1 = this.allocateUnusedWorker(); // eslint-disable-next-line @typescript-eslint/no-floating-promises this.loadWasmModuleToWorker(worker_1, sab); } return this.unusedWorkers.pop(); } var worker = this.allocateUnusedWorker(); // eslint-disable-next-line @typescript-eslint/no-floating-promises this.loadWasmModuleToWorker(worker, sab); return this.unusedWorkers.pop(); }; ThreadManager.prototype.cleanThread = function (worker, tid, force) { if (!force && this._reuseWorker) { this.returnWorkerToPool(worker); } else { delete this.pthreads[tid]; var index = this.runningWorkers.indexOf(worker); if (index !== -1) { this.runningWorkers.splice(index, 1); } this.terminateWorker(worker); delete worker.__emnapi_tid; } }; ThreadManager.prototype.terminateWorker = function (worker) { var _this_1 = this; var _a; var tid = worker.__emnapi_tid; // eslint-disable-next-line @typescript-eslint/no-floating-promises worker.terminate(); (_a = this.messageEvents.get(worker)) === null || _a === void 0 ? void 0 : _a.clear(); this.messageEvents.delete(worker); worker.onmessage = function (e) { if (e.data.__emnapi__) { var err = _this_1.printErr; err('received "' + e.data.__emnapi__.type + '" command from terminated worker: ' + tid); } }; }; ThreadManager.prototype.terminateAllThreads = function () { for (var i = 0; i < this.runningWorkers.length; ++i) { this.terminateWorker(this.runningWorkers[i]); } for (var i = 0; i < this.unusedWorkers.length; ++i) { this.terminateWorker(this.unusedWorkers[i]); } this.unusedWorkers = []; this.runningWorkers = []; this.pthreads = Object.create(null); this.preparePool(); }; ThreadManager.prototype.addMessageEventListener = function (worker, onMessage) { var listeners = this.messageEvents.get(worker); if (!listeners) { listeners = new Set(); this.messageEvents.set(worker, listeners); } listeners.add(onMessage); return function () { listeners === null || listeners === void 0 ? void 0 : listeners.delete(onMessage); }; }; ThreadManager.prototype.fireMessageEvent = function (worker, e) { var listeners = this.messageEvents.get(worker); if (!listeners) return; var err = this.printErr; listeners.forEach(function (listener) { try { listener(e); } catch (e) { err(e.stack); } }); }; return ThreadManager; }()); var kIsProxy = Symbol('kIsProxy'); /** @public */ function createInstanceProxy(instance, memory) { if (instance[kIsProxy]) return instance; // https://github.com/nodejs/help/issues/4102 var originalExports = instance.exports; var createHandler = function (target) { var handlers = [ 'apply', 'construct', 'defineProperty', 'deleteProperty', 'get', 'getOwnPropertyDescriptor', 'getPrototypeOf', 'has', 'isExtensible', 'ownKeys', 'preventExtensions', 'set', 'setPrototypeOf' ]; var handler = {}; var _loop_1 = function (i) { var name_1 = handlers[i]; handler[name_1] = function () { var args = Array.prototype.slice.call(arguments, 1); args.unshift(target); return Reflect[name_1].apply(Reflect, args); }; }; for (var i = 0; i < handlers.length; i++) { _loop_1(i); } return handler; }; var handler = createHandler(originalExports); var _initialize = function () { }; var _start = function () { return 0; }; handler.get = function (_target, p, receiver) { var _a; if (p === 'memory') { return (_a = (typeof memory === 'function' ? memory() : memory)) !== null && _a !== void 0 ? _a : Reflect.get(originalExports, p, receiver); } if (p === '_initialize') { return p in originalExports ? _initialize : undefined; } if (p === '_start') { return p in originalExports ? _start : undefined; } return Reflect.get(originalExports, p, receiver); }; handler.has = function (_target, p) { if (p === 'memory') return true; return Reflect.has(originalExports, p); }; var exportsProxy = new Proxy(Object.create(null), handler); return new Proxy(instance, { get: function (target, p, receiver) { if (p === 'exports') { return exportsProxy; } if (p === kIsProxy) { return true; } return Reflect.get(target, p, receiver); } }); } var patchedWasiInstances = new WeakMap(); /** @public */ var WASIThreads = /*#__PURE__*/ (function () { function WASIThreads(options) { var _this_1 = this; if (!options) { throw new TypeError('WASIThreads(): options is not provided'); } if (!options.wasi) { throw new TypeError('WASIThreads(): options.wasi is not provided'); } patchedWasiInstances.set(this, new WeakSet()); var wasi = options.wasi; patchWasiInstance(this, wasi); this.wasi = wasi; if ('childThread' in options) { this.childThread = Boolean(options.childThread); } else { this.childThread = false; } this.PThread = undefined; if ('threadManager' in options) { if (typeof options.threadManager === 'function') { this.PThread = options.threadManager(); } else { this.PThread = options.threadManager; } } else { if (!this.childThread) { this.PThread = new ThreadManager(options); this.PThread.init(); } } var waitThreadStart = false; if ('waitThreadStart' in options) { waitThreadStart = typeof options.waitThreadStart === 'number' ? options.waitThreadStart : Boolean(options.waitThreadStart); } var postMessage = getPostMessage(options); if (this.childThread && typeof postMessage !== 'function') { throw new TypeError('options.postMessage is not a function'); } this.postMessage = postMessage; var wasm64 = Boolean(options.wasm64); var onMessage = function (e) { if (e.data.__emnapi__) { var type = e.data.__emnapi__.type; var payload = e.data.__emnapi__.payload; if (type === 'spawn-thread') { threadSpawn(payload.startArg, payload.errorOrTid); } else if (type === 'terminate-all-threads') { _this_1.terminateAllThreads(); } } }; var threadSpawn = function (startArg, errorOrTid) { var _a; var EAGAIN = 6; var isNewABI = errorOrTid !== undefined; try { checkSharedWasmMemory(_this_1.wasmMemory); } catch (err) { (_a = _this_1.PThread) === null || _a === void 0 ? void 0 : _a.printErr(err.stack); if (isNewABI) { var struct_1 = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2); Atomics.store(struct_1, 0, 1); Atomics.store(struct_1, 1, EAGAIN); Atomics.notify(struct_1, 1); return 1; } else { return -6; } } if (!isNewABI) { var malloc = _this_1.wasmInstance.exports.malloc; errorOrTid = wasm64 ? Number(malloc(BigInt(8))) : malloc(8); if (!errorOrTid) { return -48; /* ENOMEM */ } } var _free = _this_1.wasmInstance.exports.free; var free = wasm64 ? function (ptr) { _free(BigInt(ptr)); } : _free; var struct = new Int32Array(_this_1.wasmMemory.buffer, errorOrTid, 2); Atomics.store(struct, 0, 0); Atomics.store(struct, 1, 0); if (_this_1.childThread) { postMessage(createMessage('spawn-thread', { startArg: startArg, errorOrTid: errorOrTid })); Atomics.wait(struct, 1, 0); var isError = Atomics.load(struct, 0); var result = Atomics.load(struct, 1); if (isNewABI) { return isError; } free(errorOrTid); return isError ? -result : result; } var shouldWait = waitThreadStart || (waitThreadStart === 0); var sab; if (shouldWait) { sab = new Int32Array(new SharedArrayBuffer(16 + 8192)); Atomics.store(sab, 0, 0); } var worker; var tid; var PThread = _this_1.PThread; try { worker = PThread.getNewWorker(sab); if (!worker) { throw new Error('failed to get new worker'); } PThread.addMessageEventListener(worker, onMessage); tid = PThread.markId(worker); if (ENVIRONMENT_IS_NODE) { worker.ref(); } worker.postMessage(createMessage('start', { tid: tid, arg: startArg, sab: sab })); if (shouldWait) { if (typeof waitThreadStart === 'number') { var waitResult = Atomics.wait(sab, 0, 0, waitThreadStart); if (waitResult === 'timed-out') { try { PThread.cleanThread(worker, tid, true); } catch (_) { } throw new Error('Spawning thread timed out. Please check if the worker is created successfully and if message is handled properly in the worker.'); } } else { Atomics.wait(sab, 0, 0); } var r = Atomics.load(sab, 0); if (r > 1) { try { PThread.cleanThread(worker, tid, true); } catch (_) { } throw deserizeErrorFromBuffer(sab.buffer); } } } catch (e) { Atomics.store(struct, 0, 1); Atomics.store(struct, 1, EAGAIN); Atomics.notify(struct, 1); PThread === null || PThread === void 0 ? void 0 : PThread.printErr(e.stack); if (isNewABI) { return 1; } free(errorOrTid); return -6; } Atomics.store(struct, 0, 0); Atomics.store(struct, 1, tid); Atomics.notify(struct, 1); PThread.runningWorkers.push(worker); if (!shouldWait) { worker.whenLoaded.catch(function (err) { delete worker.whenLoaded; PThread.cleanThread(worker, tid, true); throw err; }); } if (isNewABI) { return 0; } free(errorOrTid); return tid; }; this.threadSpawn = threadSpawn; } WASIThreads.prototype.getImportObject = function () { return { wasi: { 'thread-spawn': this.threadSpawn } }; }; WASIThreads.prototype.setup = function (wasmInstance, wasmModule, wasmMemory) { wasmMemory !== null && wasmMemory !== void 0 ? wasmMemory : (wasmMemory = wasmInstance.exports.memory); this.wasmInstance = wasmInstance; this.wasmMemory = wasmMemory; if (this.PThread) { this.PThread.setup(wasmModule, wasmMemory); } }; WASIThreads.prototype.preloadWorkers = function () { if (this.PThread) { return this.PThread.preloadWorkers(); } return Promise.resolve([]); }; /** * It's ok to call this method to a WASI command module. * * in child thread, must call this method instead of {@link WASIThreads.start} even if it's a WASI command module * * @returns A proxied WebAssembly instance if in child thread, other wise the original instance */ WASIThreads.prototype.initialize = function (instance, module, memory) { var exports = instance.exports; memory !== null && memory !== void 0 ? memory : (memory = exports.memory); if (this.childThread) { instance = createInstanceProxy(instance, memory); } this.setup(instance, module, memory); var wasi = this.wasi; if (('_start' in exports) && (typeof exports._start === 'function')) { if (this.childThread) { wasi.start(instance); try { var kStarted = getWasiSymbol(wasi, 'kStarted'); wasi[kStarted] = false; } catch (_) { } } else { setupInstance(wasi, instance); } } else { wasi.initialize(instance); } return instance; }; /** * Equivalent to calling {@link WASIThreads.initialize} and then calling {@link WASIInstance.start} * ```js * this.initialize(instance, module, memory) * this.wasi.start(instance) * ``` */ WASIThreads.prototype.start = function (instance, module, memory) { var exports = instance.exports; memory !== null && memory !== void 0 ? memory : (memory = exports.memory); if (this.childThread) { instance = createInstanceProxy(instance, memory); } this.setup(instance, module, memory); var exitCode = this.wasi.start(instance); return { exitCode: exitCode, instance: instance }; }; WASIThreads.prototype.terminateAllThreads = function () { var _a; if (!this.childThread) { (_a = this.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads(); } else { this.postMessage(createMessage('terminate-all-threads', {})); } }; return WASIThreads; }()); function patchWasiInstance(wasiThreads, wasi) { var patched = patchedWasiInstances.get(wasiThreads); if (patched.has(wasi)) { return; } var _this = wasiThreads; var wasiImport = wasi.wasiImport; if (wasiImport) { var proc_exit_1 = wasiImport.proc_exit; wasiImport.proc_exit = function (code) { _this.terminateAllThreads(); return proc_exit_1.call(this, code); }; } var start = wasi.start; if (typeof start === 'function') { wasi.start = function (instance) { try { return start.call(this, instance); } catch (err) { if (isTrapError(err)) { _this.terminateAllThreads(); } throw err; } }; } patched.add(wasi); } function getWasiSymbol(wasi, description) { var symbols = Object.getOwnPropertySymbols(wasi); var selectDescription = function (description) { return function (s) { if (s.description) { return s.description === description; } return s.toString() === "Symbol(".concat(description, ")"); }; }; if (Array.isArray(description)) { return description.map(function (d) { return symbols.filter(selectDescription(d))[0]; }); } return symbols.filter(selectDescription(description))[0]; } function setupInstance(wasi, instance) { var _a = getWasiSymbol(wasi, ['kInstance', 'kSetMemory']), kInstance = _a[0], kSetMemory = _a[1]; wasi[kInstance] = instance; wasi[kSetMemory](instance.exports.memory); } /** @public */ var ThreadMessageHandler = /*#__PURE__*/ (function () { function ThreadMessageHandler(options) { var postMsg = getPostMessage(options); if (typeof postMsg !== 'function') { throw new TypeError('options.postMessage is not a function'); } this.postMessage = postMsg; this.onLoad = options === null || options === void 0 ? void 0 : options.onLoad; this.instance = undefined; // this.module = undefined this.messagesBeforeLoad = []; } /** @virtual */ ThreadMessageHandler.prototype.instantiate = function (data) { if (typeof this.onLoad === 'function') { return this.onLoad(data); } throw new Error('ThreadMessageHandler.prototype.instantiate is not implemented'); }; /** @virtual */ ThreadMessageHandler.prototype.handle = function (e) { var _this = this; var _a; if ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.__emnapi__) { var type = e.data.__emnapi__.type; var payload_1 = e.data.__emnapi__.payload; if (type === 'load') { this._load(payload_1); } else if (type === 'start') { this.handleAfterLoad(e, function () { _this._start(payload_1); }); } } }; ThreadMessageHandler.prototype._load = function (payload) { var _this = this; if (this.instance !== undefined) return; var source; try { source = this.instantiate(payload); } catch (err) { this._loaded(err, null, payload); return; } var then = source && 'then' in source ? source.then : undefined; if (typeof then === 'function') { // eslint-disable-next-line @typescript-eslint/no-floating-promises then.call(source, function (source) { _this._loaded(null, source, payload); }, function (err) { _this._loaded(err, null, payload); }); } else { this._loaded(null, source, payload); } }; ThreadMessageHandler.prototype._start = function (payload) { if (typeof this.instance.exports.wasi_thread_start !== 'function') { var err = new TypeError('wasi_thread_start is not exported'); notifyPthreadCreateResult(payload.sab, 2, err); throw err; } var postMessage = this.postMessage; var tid = payload.tid; var startArg = payload.arg; notifyPthreadCreateResult(payload.sab, 1); try { this.instance.exports.wasi_thread_start(tid, startArg); } catch (err) { if (isTrapError(err)) { postMessage(createMessage('terminate-all-threads', {})); } throw err; } postMessage(createMessage('cleanup-thread', { tid: tid })); }; ThreadMessageHandler.prototype._loaded = function (err, source, payload) { if (err) { notifyPthreadCreateResult(payload.sab, 2, err); throw err; } if (source == null) { var err_1 = new TypeError('onLoad should return an object'); notifyPthreadCreateResult(payload.sab, 2, err_1); throw err_1; } var instance = source.instance; if (!instance) { var err_2 = new TypeError('onLoad should return an object which includes "instance"'); notifyPthreadCreateResult(payload.sab, 2, err_2); throw err_2; } this.instance = instance; var postMessage = this.postMessage; postMessage(createMessage('loaded', {})); var messages = this.messagesBeforeLoad; this.messagesBeforeLoad = []; for (var i = 0; i < messages.length; i++) { var data = messages[i]; this.handle({ data: data }); } }; ThreadMessageHandler.prototype.handleAfterLoad = function (e, f) { if (this.instance !== undefined) { f.call(this, e); } else { this.messagesBeforeLoad.push(e.data); } }; return ThreadMessageHandler; }()); function notifyPthreadCreateResult(sab, result, error) { if (sab) { serizeErrorToBuffer(sab.buffer, result, error); Atomics.notify(sab, 0); } } exports.ThreadManager = ThreadManager; exports.ThreadMessageHandler = ThreadMessageHandler; exports.WASIThreads = WASIThreads; exports.createInstanceProxy = createInstanceProxy; exports.isSharedArrayBuffer = isSharedArrayBuffer; exports.isTrapError = isTrapError; }));