"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuickJSAsyncWASMModule = void 0; const errors_1 = require("./errors"); const lifetime_1 = require("./lifetime"); const module_1 = require("./module"); const runtime_asyncify_1 = require("./runtime-asyncify"); /** * Asyncified version of [[QuickJSWASMModule]]. * * Due to limitations of Emscripten's ASYNCIFY process, only a single async * function call can happen at a time across the entire WebAssembly module. * * That means that all runtimes, contexts, functions, etc created inside this * WebAssembly are limited to a single concurrent async action. * **Multiple concurrent async actions is an error.** * * To allow for multiple concurrent async actions, you must create multiple WebAssembly * modules. */ class QuickJSAsyncWASMModule extends module_1.QuickJSWASMModule { /** @private */ constructor(module, ffi) { super(module, ffi); this.ffi = ffi; this.module = module; } /** * Create a new async runtime inside this WebAssembly module. All runtimes inside a * module are limited to a single async call at a time. For multiple * concurrent async actions, create multiple WebAssembly modules. */ newRuntime(options = {}) { const rt = new lifetime_1.Lifetime(this.ffi.QTS_NewRuntime(), undefined, (rt_ptr) => { this.callbacks.deleteRuntime(rt_ptr); this.ffi.QTS_FreeRuntime(rt_ptr); }); const runtime = new runtime_asyncify_1.QuickJSAsyncRuntime({ module: this.module, ffi: this.ffi, rt, callbacks: this.callbacks, }); (0, module_1.applyBaseRuntimeOptions)(runtime, options); if (options.moduleLoader) { runtime.setModuleLoader(options.moduleLoader); } return runtime; } /** * A simplified API to create a new [[QuickJSRuntime]] and a * [[QuickJSContext]] inside that runtime at the same time. The runtime will * be disposed when the context is disposed. */ newContext(options = {}) { const runtime = this.newRuntime(); const lifetimes = options.ownedLifetimes ? options.ownedLifetimes.concat([runtime]) : [runtime]; const context = runtime.newContext({ ...options, ownedLifetimes: lifetimes }); runtime.context = context; return context; } /** Synchronous evalCode is not supported. */ evalCode() { throw new errors_1.QuickJSNotImplemented("QuickJSWASMModuleAsyncify.evalCode: use evalCodeAsync instead"); } /** * One-off evaluate code without needing to create a [[QuickJSRuntimeAsync]] or * [[QuickJSContextSync]] explicitly. * * This version allows for asynchronous Ecmascript module loading. * * Note that only a single async action can occur at a time inside the entire WebAssembly module. * **Multiple concurrent async actions is an error.** * * See the documentation for [[QuickJSWASMModule.evalCode]] for more details. */ evalCodeAsync(code, options) { // TODO: we should really figure out generator for the Promise monad... return lifetime_1.Scope.withScopeAsync(async (scope) => { const vm = scope.manage(this.newContext()); (0, module_1.applyModuleEvalRuntimeOptions)(vm.runtime, options); const result = await vm.evalCodeAsync(code, "eval.js"); if (options.memoryLimitBytes !== undefined) { // Remove memory limit so we can dump the result without exceeding it. vm.runtime.setMemoryLimit(-1); } if (result.error) { const error = vm.dump(scope.manage(result.error)); throw error; } const value = vm.dump(scope.manage(result.value)); return value; }); } } exports.QuickJSAsyncWASMModule = QuickJSAsyncWASMModule; //# sourceMappingURL=module-asyncify.js.map