"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.compile = void 0; const util_1 = require("util"); const degenerator_1 = require("./degenerator"); function compile(qjs, code, returnName, options = {}) { const compiled = (0, degenerator_1.degenerator)(code, options.names ?? []); const vm = qjs.newContext(); // Add functions to global if (options.sandbox) { for (const [name, value] of Object.entries(options.sandbox)) { if (typeof value !== 'function') { throw new Error(`Expected a "function" for sandbox property \`${name}\`, but got "${typeof value}"`); } const fnHandle = vm.newFunction(name, (...args) => { const result = value(...args.map((arg) => quickJSHandleToHost(vm, arg))); vm.runtime.executePendingJobs(); return hostToQuickJSHandle(vm, result); }); fnHandle.consume((handle) => vm.setProp(vm.global, name, handle)); } } const fnResult = vm.evalCode(`${compiled};${returnName}`, options.filename); const fn = vm.unwrapResult(fnResult); const t = vm.typeof(fn); if (t !== 'function') { throw new Error(`Expected a "function" named \`${returnName}\` to be defined, but got "${t}"`); } const r = async function (...args) { let promiseHandle; let resolvedHandle; try { const result = vm.callFunction(fn, vm.undefined, ...args.map((arg) => hostToQuickJSHandle(vm, arg))); promiseHandle = vm.unwrapResult(result); const resolvedResultP = vm.resolvePromise(promiseHandle); vm.runtime.executePendingJobs(); const resolvedResult = await resolvedResultP; resolvedHandle = vm.unwrapResult(resolvedResult); return quickJSHandleToHost(vm, resolvedHandle); } catch (err) { if (err && typeof err === 'object' && 'cause' in err && err.cause) { if (typeof err.cause === 'object' && 'stack' in err.cause && 'name' in err.cause && 'message' in err.cause && typeof err.cause.stack === 'string' && typeof err.cause.name === 'string' && typeof err.cause.message === 'string') { // QuickJS Error `stack` does not include the name + // message, so patch those in to behave more like V8 err.cause.stack = `${err.cause.name}: ${err.cause.message}\n${err.cause.stack}`; } throw err.cause; } throw err; } finally { promiseHandle?.dispose(); resolvedHandle?.dispose(); } }; Object.defineProperty(r, 'toString', { value: () => compiled, enumerable: false, }); return r; } exports.compile = compile; function quickJSHandleToHost(vm, val) { return vm.dump(val); } function hostToQuickJSHandle(vm, val) { if (typeof val === 'undefined') { return vm.undefined; } else if (val === null) { return vm.null; } else if (typeof val === 'string') { return vm.newString(val); } else if (typeof val === 'number') { return vm.newNumber(val); } else if (typeof val === 'bigint') { return vm.newBigInt(val); } else if (typeof val === 'boolean') { return val ? vm.true : vm.false; } else if (util_1.types.isPromise(val)) { const promise = vm.newPromise(); promise.settled.then(vm.runtime.executePendingJobs); val.then((r) => { promise.resolve(hostToQuickJSHandle(vm, r)); }, (err) => { promise.reject(hostToQuickJSHandle(vm, err)); }); return promise.handle; } else if (util_1.types.isNativeError(val)) { return vm.newError(val); } throw new Error(`Unsupported value: ${val}`); } //# sourceMappingURL=compile.js.map