UNPKG

@worker-tools/html-rewriter

Version:

WASM-based implementation of Cloudflare's HTML Rewriter for use in Deno, browsers, etc.

96 lines 2.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrap = exports.setWasmExports = exports.awaitPromise = void 0; const asserts_js_1 = require("../deps/deno.land/std@0.134.0/testing/asserts.js"); /** * @typedef {object} WasmExports * @property {WebAssembly.Memory} memory * @property {function} asyncify_get_state * @property {function} asyncify_start_unwind * @property {function} asyncify_stop_unwind * @property {function} asyncify_start_rewind * @property {function} asyncify_stop_rewind */ /** * @type {WasmExports} */ let wasm; /** * @param {WasmExports} wasmExports */ function setWasmExports(wasmExports) { wasm = wasmExports; } exports.setWasmExports = setWasmExports; /** * @type {Int32Array} */ let cachedInt32Memory = null; /** * @returns {Int32Array} */ function getInt32Memory() { if (cachedInt32Memory === null || cachedInt32Memory.buffer !== wasm.memory.buffer) { cachedInt32Memory = new Int32Array(wasm.memory.buffer); } return cachedInt32Memory; } // https://github.com/WebAssembly/binaryen/blob/fb9de9d391a7272548dcc41cd8229076189d7398/src/passes/Asyncify.cpp#L99 const State = { NONE: 0, UNWINDING: 1, REWINDING: 2, }; function assertNoneState() { (0, asserts_js_1.assertEquals)(wasm.asyncify_get_state(), State.NONE); } /** * Maps `HTMLRewriter`s (their `asyncifyStackPtr`s) to `Promise`s. * `asyncifyStackPtr` acts as unique reference to `HTMLRewriter`. * Each rewriter MUST have AT MOST ONE pending promise at any time. * @type {Map<number, Promise>} */ const promises = new Map(); /** * @param {number} stackPtr * @param {Promise} promise */ function awaitPromise(stackPtr, promise) { if (wasm.asyncify_get_state() === State.REWINDING) { wasm.asyncify_stop_rewind(); return; } assertNoneState(); // https://github.com/WebAssembly/binaryen/blob/fb9de9d391a7272548dcc41cd8229076189d7398/src/passes/Asyncify.cpp#L106 (0, asserts_js_1.assertEquals)(stackPtr % 4, 0); getInt32Memory().set([stackPtr + 8, stackPtr + 1024], stackPtr / 4); wasm.asyncify_start_unwind(stackPtr); (0, asserts_js_1.assert)(!promises.has(stackPtr)); promises.set(stackPtr, promise); } exports.awaitPromise = awaitPromise; /** * @param {HTMLRewriter} rewriter * @param {Function} fn * @param args */ async function wrap(rewriter, fn, ...args) { const stackPtr = rewriter.asyncifyStackPtr; assertNoneState(); let result = fn(...args); while (wasm.asyncify_get_state() === State.UNWINDING) { wasm.asyncify_stop_unwind(); assertNoneState(); (0, asserts_js_1.assert)(promises.has(stackPtr)); await promises.get(stackPtr); promises.delete(stackPtr); assertNoneState(); wasm.asyncify_start_rewind(stackPtr); result = fn(); } assertNoneState(); return result; } exports.wrap = wrap; //# sourceMappingURL=asyncify.js.map