"use strict"; class Index { constructor(index, generation) { this.index = index; this.generation = generation; } toNum() { return Number((BigInt(this.generation) << BigInt(32)) | BigInt(this.index)); } static fromNum(n) { const i = Number(((BigInt(n) & BigInt(0xffffffff00000000)) >> BigInt(32)) & BigInt(0xffffffff)); const g = n & 0xffffffff; return new Index(g, i); } } class GenerationalArena { constructor() { this.items = []; this.generation = 0; this.free_list_head = undefined; this.length = 0; } insert(v) { // lets use the first free entry if we have one if (this.free_list_head !== undefined) { let i = this.free_list_head; this.free_list_head = this.items[i].nextFree; this.items[i] = { generation: this.generation, value: v, }; this.length += 1; return new Index(i, this.generation); } this.items.push({ generation: this.generation, value: v, }); const idx = new Index(this.items.length - 1, this.generation); this.length += 1; return idx; } contains(idx) { return this.get(idx) !== undefined; } get(i) { let e = this.items[i.index]; if (e && e.generation === i.generation) { return e.value; } return undefined; } remove(idx) { if (idx.index >= this.items.length) { return undefined; } let e = this.items[idx.index]; if (e.generation !== undefined && e.generation == idx.generation) { this.generation += 1; this.items[idx.index] = { nextFree: this.free_list_head, }; this.free_list_head = idx.index; this.length -= 1; return e.value; } return undefined; } *[Symbol.iterator]() { for (let i = 0; i < this.items.length; i++) { const x = this.items[i]; if (x.generation !== undefined) { yield { index: new Index(i, x.generation), value: x.value }; } } } indices() { return { items: this.items, [Symbol.iterator]: function* iter() { for (let i = 0; i < this.items.length; i++) { const x = this.items[i]; if (x.generation !== undefined) { yield new Index(i, x.generation); } } }, }; } values() { return { items: this.items, [Symbol.iterator]: function* iter() { for (let i = 0; i < this.items.length; i++) { const x = this.items[i]; if (x.generation !== undefined) { yield x.value; } } }, }; } } const JsWasm = { createEnvironment() { const arena = new GenerationalArena(); arena.insert(undefined); arena.insert(null); arena.insert(self); arena.insert(typeof document != "undefined" ? document : null); arena.insert(typeof document != "undefined" ? document.body : null); const context = { functions: [ function () { debugger; return 0; }, ], objects: arena, utf8dec: new TextDecoder("utf-8"), utf8enc: new TextEncoder(), utf16dec: new TextDecoder("utf-16"), toCallbackArg: function (arg) { if (typeof arg === "object") { return context.storeObject(arg); } return arg; }, createCallback: function (cb) { if (!this.module) { throw new Error("module not set"); } const fnHandleCallback = this.module.instance.exports.handle_callback; return function () { const arg = arguments; fnHandleCallback(cb, context.toCallbackArg(arg[0]), context.toCallbackArg(arg[1]), context.toCallbackArg(arg[2]), context.toCallbackArg(arg[3]), context.toCallbackArg(arg[4]), context.toCallbackArg(arg[5]), context.toCallbackArg(arg[6]), context.toCallbackArg(arg[7]), context.toCallbackArg(arg[8]), context.toCallbackArg(arg[9])); }; }, readUtf8FromMemory: function (start, len) { const text = this.utf8dec.decode(this.getMemory().subarray(start, start + len)); return text; }, createAllocation: function (size) { if (!this.module) { throw new Error("module not set"); } const allocationId = this.module.instance.exports.create_allocation(size); const allocationPtr = this.module.instance.exports.allocation_ptr(allocationId); return [allocationId, allocationPtr]; }, writeUtf8ToMemory: function (str) { const bytes = this.utf8enc.encode(str); const len = bytes.length; const [id, start] = this.createAllocation(len); this.getMemory().set(bytes, start); return id; }, readUtf16FromMemory: function (start, len) { const text = this.utf16dec.decode(this.getMemory().subarray(start, start + len)); return text; }, readUint8ArrayFromMemory(start) { if (!this.module) { throw new Error("module not set"); } const data32 = new Uint32Array(this.module.instance.exports.memory.buffer); const ptr = data32[start / 4]; const length = data32[ptr / 4]; let b = this.getMemory().slice(ptr + 4, ptr + 4 + length); return new Uint8Array(b); }, storeObject: function (obj) { const index = this.objects.insert(obj); return index.toNum(); }, getObject: function (handle) { return this.objects.get(Index.fromNum(handle)); }, releaseObject: function (handle) { this.objects.remove(Index.fromNum(handle)); }, getMemory: function () { if (!this.module) { throw new Error("module not set"); } return new Uint8Array(this.module.instance.exports.memory.buffer); }, }; return [{ abort() { throw new Error("WebAssembly module aborted"); }, js_release(obj) { context.releaseObject(obj); }, js_register_function(start, len, utfByteLen) { let functionBody; if (utfByteLen === 16) { functionBody = context.readUtf16FromMemory(start, len); } else { functionBody = context.readUtf8FromMemory(start, len); } let id = context.functions.length; context.functions.push(Function(`"use strict";return(${functionBody})`)()); return id; }, js_invoke_function(funcHandle, a, b, c, d, e, f, g, h, i, j) { return context.functions[funcHandle].call(context, a, b, c, d, e, f, g, h, i, j); }, }, context]; }, async loadAndRunWasm(wasmURL) { const [env, context] = JsWasm.createEnvironment(); const response = await fetch(wasmURL); const bytes = await response.arrayBuffer(); const module = await WebAssembly.instantiate(bytes, { env, }); context.module = module; module.instance.exports.main(); }, }; document.addEventListener("DOMContentLoaded", function () { const wasmScripts = document.querySelectorAll("script[type='application/wasm']"); for (let i = 0; i < wasmScripts.length; i++) { const src = wasmScripts[i].src; if (src) { JsWasm.loadAndRunWasm(src); } else { console.error("Script tag must have 'src' property."); } } }); if (window.WasmScriptComponents) { window.WasmScriptComponents["js-wasm"] = function (e) { return { ...e, ...JsWasm.createEnvironment(), }; }; }