UNPKG

2.96 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.wrap = exports.setWasmExports = exports.awaitPromise = void 0;
4const asserts_js_1 = require("../deps/deno.land/std@0.134.0/testing/asserts.js");
5/**
6 * @typedef {object} WasmExports
7 * @property {WebAssembly.Memory} memory
8 * @property {function} asyncify_get_state
9 * @property {function} asyncify_start_unwind
10 * @property {function} asyncify_stop_unwind
11 * @property {function} asyncify_start_rewind
12 * @property {function} asyncify_stop_rewind
13 */
14/**
15 * @type {WasmExports}
16 */
17let wasm;
18/**
19 * @param {WasmExports} wasmExports
20 */
21function setWasmExports(wasmExports) {
22 wasm = wasmExports;
23}
24exports.setWasmExports = setWasmExports;
25/**
26 * @type {Int32Array}
27 */
28let cachedInt32Memory = null;
29/**
30 * @returns {Int32Array}
31 */
32function getInt32Memory() {
33 if (cachedInt32Memory === null ||
34 cachedInt32Memory.buffer !== wasm.memory.buffer) {
35 cachedInt32Memory = new Int32Array(wasm.memory.buffer);
36 }
37 return cachedInt32Memory;
38}
39// https://github.com/WebAssembly/binaryen/blob/fb9de9d391a7272548dcc41cd8229076189d7398/src/passes/Asyncify.cpp#L99
40const State = {
41 NONE: 0,
42 UNWINDING: 1,
43 REWINDING: 2,
44};
45function assertNoneState() {
46 (0, asserts_js_1.assertEquals)(wasm.asyncify_get_state(), State.NONE);
47}
48/**
49 * Maps `HTMLRewriter`s (their `asyncifyStackPtr`s) to `Promise`s.
50 * `asyncifyStackPtr` acts as unique reference to `HTMLRewriter`.
51 * Each rewriter MUST have AT MOST ONE pending promise at any time.
52 * @type {Map<number, Promise>}
53 */
54const promises = new Map();
55/**
56 * @param {number} stackPtr
57 * @param {Promise} promise
58 */
59function awaitPromise(stackPtr, promise) {
60 if (wasm.asyncify_get_state() === State.REWINDING) {
61 wasm.asyncify_stop_rewind();
62 return;
63 }
64 assertNoneState();
65 // https://github.com/WebAssembly/binaryen/blob/fb9de9d391a7272548dcc41cd8229076189d7398/src/passes/Asyncify.cpp#L106
66 (0, asserts_js_1.assertEquals)(stackPtr % 4, 0);
67 getInt32Memory().set([stackPtr + 8, stackPtr + 1024], stackPtr / 4);
68 wasm.asyncify_start_unwind(stackPtr);
69 (0, asserts_js_1.assert)(!promises.has(stackPtr));
70 promises.set(stackPtr, promise);
71}
72exports.awaitPromise = awaitPromise;
73/**
74 * @param {HTMLRewriter} rewriter
75 * @param {Function} fn
76 * @param args
77 */
78async function wrap(rewriter, fn, ...args) {
79 const stackPtr = rewriter.asyncifyStackPtr;
80 assertNoneState();
81 let result = fn(...args);
82 while (wasm.asyncify_get_state() === State.UNWINDING) {
83 wasm.asyncify_stop_unwind();
84 assertNoneState();
85 (0, asserts_js_1.assert)(promises.has(stackPtr));
86 await promises.get(stackPtr);
87 promises.delete(stackPtr);
88 assertNoneState();
89 wasm.asyncify_start_rewind(stackPtr);
90 result = fn();
91 }
92 assertNoneState();
93 return result;
94}
95exports.wrap = wrap;
96//# sourceMappingURL=asyncify.js.map
\No newline at end of file