From 74bcd6e4f686836ed3c3e4e4a7b1f75e05f798b6 Mon Sep 17 00:00:00 2001 From: Amit Steiner Date: Tue, 31 Dec 2024 13:42:58 +0200 Subject: [PATCH 1/4] improve endianness validation strategy --- cpp/bloom_filter.js | 2463 +++++++++++++++++++++++++++++++++++++ cpp/bloom_filter.wasm | Bin 0 -> 169893 bytes cpp/bloom_filter.wasm.map | 1 + test2.ts | 12 +- 4 files changed, 2470 insertions(+), 6 deletions(-) create mode 100644 cpp/bloom_filter.js create mode 100755 cpp/bloom_filter.wasm create mode 100644 cpp/bloom_filter.wasm.map diff --git a/cpp/bloom_filter.js b/cpp/bloom_filter.js new file mode 100644 index 0000000..43f02ef --- /dev/null +++ b/cpp/bloom_filter.js @@ -0,0 +1,2463 @@ +// include: shell.js +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(moduleArg) => Promise +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +var Module = typeof Module != "undefined" ? Module : {}; + +// Determine the runtime environment we are in. You can customize this by +// setting the ENVIRONMENT setting at compile time (see settings.js). +var ENVIRONMENT_IS_WEB = true; + +var ENVIRONMENT_IS_WORKER = false; + +var ENVIRONMENT_IS_NODE = false; + +var ENVIRONMENT_IS_SHELL = false; + +if (Module["ENVIRONMENT"]) { + throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)"); +} + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) +// Sometimes an existing Module object exists with properties +// meant to overwrite the default module functionality. Here +// we collect those properties and reapply _after_ we configure +// the current environment's defaults to avoid having to be so +// defensive during initialization. +var moduleOverrides = Object.assign({}, Module); + +var arguments_ = []; + +var thisProgram = "./this.program"; + +var quit_ = (status, toThrow) => { + throw toThrow; +}; + +// `/` should be present at the end if `scriptDirectory` is not empty +var scriptDirectory = ""; + +function locateFile(path) { + if (Module["locateFile"]) { + return Module["locateFile"](path, scriptDirectory); + } + return scriptDirectory + path; +} + +// Hooks that are implemented differently in different runtime environments. +var readAsync, readBinary; + +if (ENVIRONMENT_IS_SHELL) { + if ((typeof process == "object" && typeof require === "function") || typeof window == "object" || typeof importScripts == "function") throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)"); +} else // Note that this includes Node.js workers when relevant (pthreads is enabled). +// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and +// ENVIRONMENT_IS_NODE. +if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + if (ENVIRONMENT_IS_WORKER) { + // Check worker, not web, since window could be polyfilled + scriptDirectory = self.location.href; + } else if (typeof document != "undefined" && document.currentScript) { + // web + scriptDirectory = document.currentScript.src; + } + // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them. + // otherwise, slice off the final part of the url to find the script directory. + // if scriptDirectory does not contain a slash, lastIndexOf will return -1, + // and scriptDirectory will correctly be replaced with an empty string. + // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #), + // they are removed because they could contain a slash. + if (scriptDirectory.startsWith("blob:")) { + scriptDirectory = ""; + } else { + scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1); + } + if (!(typeof window == "object" || typeof importScripts == "function")) throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)"); + { + // include: web_or_worker_shell_read.js + readAsync = url => { + assert(!isFileURI(url), "readAsync does not work with file:// URLs"); + return fetch(url, { + credentials: "same-origin" + }).then(response => { + if (response.ok) { + return response.arrayBuffer(); + } + return Promise.reject(new Error(response.status + " : " + response.url)); + }); + }; + } +} else // end include: web_or_worker_shell_read.js +{ + throw new Error("environment detection error"); +} + +var out = Module["print"] || console.log.bind(console); + +var err = Module["printErr"] || console.error.bind(console); + +// Merge back in the overrides +Object.assign(Module, moduleOverrides); + +// Free the object hierarchy contained in the overrides, this lets the GC +// reclaim data used. +moduleOverrides = null; + +checkIncomingModuleAPI(); + +// Emit code to handle expected values on the Module object. This applies Module.x +// to the proper local x. This has two benefits: first, we only emit it if it is +// expected to arrive, and second, by using a local everywhere else that can be +// minified. +if (Module["arguments"]) arguments_ = Module["arguments"]; + +legacyModuleProp("arguments", "arguments_"); + +if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; + +legacyModuleProp("thisProgram", "thisProgram"); + +if (Module["quit"]) quit_ = Module["quit"]; + +legacyModuleProp("quit", "quit_"); + +// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message +// Assertions on removed incoming Module JS APIs. +assert(typeof Module["memoryInitializerPrefixURL"] == "undefined", "Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["pthreadMainPrefixURL"] == "undefined", "Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["cdInitializerPrefixURL"] == "undefined", "Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["filePackagePrefixURL"] == "undefined", "Module.filePackagePrefixURL option was removed, use Module.locateFile instead"); + +assert(typeof Module["read"] == "undefined", "Module.read option was removed"); + +assert(typeof Module["readAsync"] == "undefined", "Module.readAsync option was removed (modify readAsync in JS)"); + +assert(typeof Module["readBinary"] == "undefined", "Module.readBinary option was removed (modify readBinary in JS)"); + +assert(typeof Module["setWindowTitle"] == "undefined", "Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)"); + +assert(typeof Module["TOTAL_MEMORY"] == "undefined", "Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY"); + +legacyModuleProp("asm", "wasmExports"); + +legacyModuleProp("readAsync", "readAsync"); + +legacyModuleProp("readBinary", "readBinary"); + +legacyModuleProp("setWindowTitle", "setWindowTitle"); + +var IDBFS = "IDBFS is no longer included by default; build with -lidbfs.js"; + +var PROXYFS = "PROXYFS is no longer included by default; build with -lproxyfs.js"; + +var WORKERFS = "WORKERFS is no longer included by default; build with -lworkerfs.js"; + +var FETCHFS = "FETCHFS is no longer included by default; build with -lfetchfs.js"; + +var ICASEFS = "ICASEFS is no longer included by default; build with -licasefs.js"; + +var JSFILEFS = "JSFILEFS is no longer included by default; build with -ljsfilefs.js"; + +var OPFS = "OPFS is no longer included by default; build with -lopfs.js"; + +var NODEFS = "NODEFS is no longer included by default; build with -lnodefs.js"; + +assert(!ENVIRONMENT_IS_WORKER, "worker environment detected but not enabled at build time. Add `worker` to `-sENVIRONMENT` to enable."); + +assert(!ENVIRONMENT_IS_NODE, "node environment detected but not enabled at build time. Add `node` to `-sENVIRONMENT` to enable."); + +assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable."); + +// end include: shell.js +// include: preamble.js +// === Preamble library stuff === +// Documentation for the public APIs defined in this file must be updated in: +// site/source/docs/api_reference/preamble.js.rst +// A prebuilt local version of the documentation is available at: +// site/build/text/docs/api_reference/preamble.js.txt +// You can also build docs locally as HTML or other formats in site/ +// An online HTML version (which may be of a different version of Emscripten) +// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html +var wasmBinary; + +if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"]; + +legacyModuleProp("wasmBinary", "wasmBinary"); + +if (typeof WebAssembly != "object") { + err("no native wasm support detected"); +} + +// Wasm globals +var wasmMemory; + +//======================================== +// Runtime essentials +//======================================== +// whether we are quitting the application. no code should run after this. +// set in exit() and abort() +var ABORT = false; + +// set by exit() and abort(). Passed to 'onExit' handler. +// NOTE: This is also used as the process return code code in shell environments +// but only when noExitRuntime is false. +var EXITSTATUS; + +// In STRICT mode, we only define assert() when ASSERTIONS is set. i.e. we +// don't define it at all in release modes. This matches the behaviour of +// MINIMAL_RUNTIME. +// TODO(sbc): Make this the default even without STRICT enabled. +/** @type {function(*, string=)} */ function assert(condition, text) { + if (!condition) { + abort("Assertion failed" + (text ? ": " + text : "")); + } +} + +// We used to include malloc/free by default in the past. Show a helpful error in +// builds with assertions. +// Memory management +var HEAP, /** @type {!Int8Array} */ HEAP8, /** @type {!Uint8Array} */ HEAPU8, /** @type {!Int16Array} */ HEAP16, /** @type {!Uint16Array} */ HEAPU16, /** @type {!Int32Array} */ HEAP32, /** @type {!Uint32Array} */ HEAPU32, /** @type {!Float32Array} */ HEAPF32, /** @type {!Float64Array} */ HEAPF64; + +// include: runtime_shared.js +function updateMemoryViews() { + var b = wasmMemory.buffer; + Module["HEAP8"] = HEAP8 = new Int8Array(b); + Module["HEAP16"] = HEAP16 = new Int16Array(b); + Module["HEAPU8"] = HEAPU8 = new Uint8Array(b); + Module["HEAPU16"] = HEAPU16 = new Uint16Array(b); + Module["HEAP32"] = HEAP32 = new Int32Array(b); + Module["HEAPU32"] = HEAPU32 = new Uint32Array(b); + Module["HEAPF32"] = HEAPF32 = new Float32Array(b); + Module["HEAPF64"] = HEAPF64 = new Float64Array(b); +} + +// end include: runtime_shared.js +assert(!Module["STACK_SIZE"], "STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time"); + +assert(typeof Int32Array != "undefined" && typeof Float64Array !== "undefined" && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined, "JS engine does not provide full typed array support"); + +// If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY +assert(!Module["wasmMemory"], "Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally"); + +assert(!Module["INITIAL_MEMORY"], "Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically"); + +// include: runtime_stack_check.js +// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. +function writeStackCookie() { + var max = _emscripten_stack_get_end(); + assert((max & 3) == 0); + // If the stack ends at address zero we write our cookies 4 bytes into the + // stack. This prevents interference with SAFE_HEAP and ASAN which also + // monitor writes to address zero. + if (max == 0) { + max += 4; + } + // The stack grow downwards towards _emscripten_stack_get_end. + // We write cookies to the final two words in the stack and detect if they are + // ever overwritten. + HEAPU32[((max) >>> 2) >>> 0] = 34821223; + HEAPU32[(((max) + (4)) >>> 2) >>> 0] = 2310721022; + // Also test the global address 0 for integrity. + HEAPU32[((0) >>> 2) >>> 0] = 1668509029; +} + +function checkStackCookie() { + if (ABORT) return; + var max = _emscripten_stack_get_end(); + // See writeStackCookie(). + if (max == 0) { + max += 4; + } + var cookie1 = HEAPU32[((max) >>> 2) >>> 0]; + var cookie2 = HEAPU32[(((max) + (4)) >>> 2) >>> 0]; + if (cookie1 != 34821223 || cookie2 != 2310721022) { + abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`); + } + // Also test the global address 0 for integrity. + if (HEAPU32[((0) >>> 2) >>> 0] != 1668509029) /* 'emsc' */ { + abort("Runtime error: The application has corrupted its heap memory area (address zero)!"); + } +} + +// end include: runtime_stack_check.js +// include: runtime_assertions.js +// Endianness check +(function() { + var h16 = new Int16Array(1); + var h8 = new Int8Array(h16.buffer); + h16[0] = 25459; + if (h8[0] !== 115 || h8[1] !== 99) throw "Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)"; +})(); + +// end include: runtime_assertions.js +var __ATPRERUN__ = []; + +// functions called before the runtime is initialized +var __ATINIT__ = []; + +// functions called during startup +var __ATEXIT__ = []; + +// functions called during shutdown +var __ATPOSTRUN__ = []; + +// functions called after the main() is called +var runtimeInitialized = false; + +function preRun() { + if (Module["preRun"]) { + if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ]; + while (Module["preRun"].length) { + addOnPreRun(Module["preRun"].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); +} + +function initRuntime() { + assert(!runtimeInitialized); + runtimeInitialized = true; + checkStackCookie(); + setStackLimits(); + callRuntimeCallbacks(__ATINIT__); +} + +function postRun() { + checkStackCookie(); + if (Module["postRun"]) { + if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ]; + while (Module["postRun"].length) { + addOnPostRun(Module["postRun"].shift()); + } + } + callRuntimeCallbacks(__ATPOSTRUN__); +} + +function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); +} + +function addOnInit(cb) { + __ATINIT__.unshift(cb); +} + +function addOnExit(cb) {} + +function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); +} + +// include: runtime_math.js +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc +assert(Math.imul, "This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +assert(Math.fround, "This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +assert(Math.clz32, "This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +assert(Math.trunc, "This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill"); + +// end include: runtime_math.js +// A counter of dependencies for calling run(). If we need to +// do asynchronous work before running, increment this and +// decrement it. Incrementing must happen in a place like +// Module.preRun (used by emcc to add file preloading). +// Note that you can add dependencies in preRun, even though +// it happens right before run - run will be postponed until +// the dependencies are met. +var runDependencies = 0; + +var runDependencyWatcher = null; + +var dependenciesFulfilled = null; + +// overridden to take different actions when all run dependencies are fulfilled +var runDependencyTracking = {}; + +function getUniqueRunDependency(id) { + var orig = id; + while (1) { + if (!runDependencyTracking[id]) return id; + id = orig + Math.random(); + } +} + +function addRunDependency(id) { + runDependencies++; + Module["monitorRunDependencies"]?.(runDependencies); + if (id) { + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if (runDependencyWatcher === null && typeof setInterval != "undefined") { + // Check for missing dependencies every few seconds + runDependencyWatcher = setInterval(() => { + if (ABORT) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + return; + } + var shown = false; + for (var dep in runDependencyTracking) { + if (!shown) { + shown = true; + err("still waiting on run dependencies:"); + } + err(`dependency: ${dep}`); + } + if (shown) { + err("(end of list)"); + } + }, 1e4); + } + } else { + err("warning: run dependency added without ID"); + } +} + +function removeRunDependency(id) { + runDependencies--; + Module["monitorRunDependencies"]?.(runDependencies); + if (id) { + assert(runDependencyTracking[id]); + delete runDependencyTracking[id]; + } else { + err("warning: run dependency removed without ID"); + } + if (runDependencies == 0) { + if (runDependencyWatcher !== null) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + } + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); + } + } +} + +/** @param {string|number=} what */ function abort(what) { + Module["onAbort"]?.(what); + what = "Aborted(" + what + ")"; + // TODO(sbc): Should we remove printing and leave it up to whoever + // catches the exception? + err(what); + ABORT = true; + EXITSTATUS = 1; + // Use a wasm runtime error, because a JS error might be seen as a foreign + // exception, which means we'd run destructors on it. We need the error to + // simply make the program stop. + // FIXME This approach does not work in Wasm EH because it currently does not assume + // all RuntimeErrors are from traps; it decides whether a RuntimeError is from + // a trap or not based on a hidden field within the object. So at the moment + // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that + // allows this in the wasm spec. + // Suppress closure compiler warning here. Closure compiler's builtin extern + // definition for WebAssembly.RuntimeError claims it takes no arguments even + // though it can. + // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed. + /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what); + // Throw the error whether or not MODULARIZE is set because abort is used + // in code paths apart from instantiation where an exception is expected + // to be thrown when abort is called. + throw e; +} + +// include: memoryprofiler.js +// end include: memoryprofiler.js +// show errors on likely calls to FS when it was not included +var FS = { + error() { + abort("Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -sFORCE_FILESYSTEM"); + }, + init() { + FS.error(); + }, + createDataFile() { + FS.error(); + }, + createPreloadedFile() { + FS.error(); + }, + createLazyFile() { + FS.error(); + }, + open() { + FS.error(); + }, + mkdev() { + FS.error(); + }, + registerDevice() { + FS.error(); + }, + analyzePath() { + FS.error(); + }, + ErrnoError() { + FS.error(); + } +}; + +Module["FS_createDataFile"] = FS.createDataFile; + +Module["FS_createPreloadedFile"] = FS.createPreloadedFile; + +// include: URIUtils.js +// Prefix of data URIs emitted by SINGLE_FILE and related options. +var dataURIPrefix = "data:application/octet-stream;base64,"; + +/** + * Indicates whether filename is a base64 data URI. + * @noinline + */ var isDataURI = filename => filename.startsWith(dataURIPrefix); + +/** + * Indicates whether filename is delivered via file protocol (as opposed to http/https) + * @noinline + */ var isFileURI = filename => filename.startsWith("file://"); + +// end include: URIUtils.js +function createExportWrapper(name, nargs) { + return (...args) => { + assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`); + var f = wasmExports[name]; + assert(f, `exported native function \`${name}\` not found`); + // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled. + assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`); + return f(...args); + }; +} + +// include: runtime_exceptions.js +// Base Emscripten EH error class +class EmscriptenEH extends Error {} + +class EmscriptenSjLj extends EmscriptenEH {} + +class CppException extends EmscriptenEH { + constructor(excPtr) { + super(excPtr); + this.excPtr = excPtr; + const excInfo = getExceptionMessage(excPtr); + this.name = excInfo[0]; + this.message = excInfo[1]; + } +} + +// end include: runtime_exceptions.js +function findWasmBinary() { + var f = "bloom_filter.wasm"; + if (!isDataURI(f)) { + return locateFile(f); + } + return f; +} + +var wasmBinaryFile; + +function getBinarySync(file) { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + if (readBinary) { + return readBinary(file); + } + throw "both async and sync fetching of the wasm failed"; +} + +function getBinaryPromise(binaryFile) { + // If we don't have the binary yet, load it asynchronously using readAsync. + if (!wasmBinary) { + // Fetch the binary using readAsync + return readAsync(binaryFile).then(response => new Uint8Array(/** @type{!ArrayBuffer} */ (response)), // Fall back to getBinarySync if readAsync fails + () => getBinarySync(binaryFile)); + } + // Otherwise, getBinarySync should be able to get it synchronously + return Promise.resolve().then(() => getBinarySync(binaryFile)); +} + +function instantiateArrayBuffer(binaryFile, imports, receiver) { + return getBinaryPromise(binaryFile).then(binary => WebAssembly.instantiate(binary, imports)).then(receiver, reason => { + err(`failed to asynchronously prepare wasm: ${reason}`); + // Warn on some common problems. + if (isFileURI(wasmBinaryFile)) { + err(`warning: Loading from a file URI (${wasmBinaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`); + } + abort(reason); + }); +} + +function instantiateAsync(binary, binaryFile, imports, callback) { + if (!binary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(binaryFile) && typeof fetch == "function") { + return fetch(binaryFile, { + credentials: "same-origin" + }).then(response => { + // Suppress closure warning here since the upstream definition for + // instantiateStreaming only allows Promise rather than + // an actual Response. + // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed. + /** @suppress {checkTypes} */ var result = WebAssembly.instantiateStreaming(response, imports); + return result.then(callback, function(reason) { + // We expect the most common failure cause to be a bad MIME type for the binary, + // in which case falling back to ArrayBuffer instantiation should work. + err(`wasm streaming compile failed: ${reason}`); + err("falling back to ArrayBuffer instantiation"); + return instantiateArrayBuffer(binaryFile, imports, callback); + }); + }); + } + return instantiateArrayBuffer(binaryFile, imports, callback); +} + +function getWasmImports() { + // prepare imports + return { + "env": wasmImports, + "wasi_snapshot_preview1": wasmImports + }; +} + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. +function createWasm() { + var info = getWasmImports(); + // Load the wasm module and create an instance of using native support in the JS engine. + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) { + wasmExports = instance.exports; + wasmExports = applySignatureConversions(wasmExports); + wasmMemory = wasmExports["memory"]; + assert(wasmMemory, "memory not found in wasm exports"); + updateMemoryViews(); + wasmTable = wasmExports["__indirect_function_table"]; + assert(wasmTable, "table not found in wasm exports"); + addOnInit(wasmExports["__wasm_call_ctors"]); + removeRunDependency("wasm-instantiate"); + return wasmExports; + } + // wait for the pthread pool (if any) + addRunDependency("wasm-instantiate"); + // Prefer streaming instantiation if available. + // Async compilation can be confusing when an error on the page overwrites Module + // (for example, if the order of elements is wrong, and the one defining Module is + // later), so we save Module and check it later. + var trueModule = Module; + function receiveInstantiationResult(result) { + // 'result' is a ResultObject object which has both the module and instance. + // receiveInstance() will swap in the exports (to Module.asm) so they can be called + assert(Module === trueModule, "the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?"); + trueModule = null; + // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line. + // When the regression is fixed, can restore the above PTHREADS-enabled path. + receiveInstance(result["instance"]); + } + // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback + // to manually instantiate the Wasm module themselves. This allows pages to + // run the instantiation parallel to any other async startup actions they are + // performing. + // Also pthreads and wasm workers initialize the wasm instance through this + // path. + if (Module["instantiateWasm"]) { + try { + return Module["instantiateWasm"](info, receiveInstance); + } catch (e) { + err(`Module.instantiateWasm callback failed with error: ${e}`); + return false; + } + } + if (!wasmBinaryFile) wasmBinaryFile = findWasmBinary(); + instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult); + return {}; +} + +// Globals used by JS i64 conversions (see makeSetValue) +var tempDouble; + +var tempI64; + +// include: runtime_debug.js +function legacyModuleProp(prop, newName, incoming = true) { + if (!Object.getOwnPropertyDescriptor(Module, prop)) { + Object.defineProperty(Module, prop, { + configurable: true, + get() { + let extra = incoming ? " (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)" : ""; + abort(`\`Module.${prop}\` has been replaced by \`${newName}\`` + extra); + } + }); + } +} + +function ignoredModuleProp(prop) { + if (Object.getOwnPropertyDescriptor(Module, prop)) { + abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`); + } +} + +// forcing the filesystem exports a few things by default +function isExportedByForceFilesystem(name) { + return name === "FS_createPath" || name === "FS_createDataFile" || name === "FS_createPreloadedFile" || name === "FS_unlink" || name === "addRunDependency" || // The old FS has some functionality that WasmFS lacks. + name === "FS_createLazyFile" || name === "FS_createDevice" || name === "removeRunDependency"; +} + +function missingGlobal(sym, msg) { + if (typeof globalThis != "undefined") { + Object.defineProperty(globalThis, sym, { + configurable: true, + get() { + warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`); + return undefined; + } + }); + } +} + +missingGlobal("buffer", "Please use HEAP8.buffer or wasmMemory.buffer"); + +missingGlobal("asm", "Please use wasmExports instead"); + +function missingLibrarySymbol(sym) { + if (typeof globalThis != "undefined" && !Object.getOwnPropertyDescriptor(globalThis, sym)) { + Object.defineProperty(globalThis, sym, { + configurable: true, + get() { + // Can't `abort()` here because it would break code that does runtime + // checks. e.g. `if (typeof SDL === 'undefined')`. + var msg = `\`${sym}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`; + // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in + // library.js, which means $name for a JS name with no prefix, or name + // for a JS name like _name. + var librarySymbol = sym; + if (!librarySymbol.startsWith("_")) { + librarySymbol = "$" + sym; + } + msg += ` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`; + if (isExportedByForceFilesystem(sym)) { + msg += ". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"; + } + warnOnce(msg); + return undefined; + } + }); + } + // Any symbol that is not included from the JS library is also (by definition) + // not exported on the Module object. + unexportedRuntimeSymbol(sym); +} + +function unexportedRuntimeSymbol(sym) { + if (!Object.getOwnPropertyDescriptor(Module, sym)) { + Object.defineProperty(Module, sym, { + configurable: true, + get() { + var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`; + if (isExportedByForceFilesystem(sym)) { + msg += ". Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you"; + } + abort(msg); + } + }); + } +} + +// Used by XXXXX_DEBUG settings to output debug messages. +function dbg(...args) { + // TODO(sbc): Make this configurable somehow. Its not always convenient for + // logging to show up as warnings. + console.warn(...args); +} + +// end include: runtime_debug.js +// === Body === +// end include: preamble.js +/** @constructor */ function ExitStatus(status) { + this.name = "ExitStatus"; + this.message = `Program terminated with exit(${status})`; + this.status = status; +} + +var callRuntimeCallbacks = callbacks => { + while (callbacks.length > 0) { + // Pass the module as the first argument. + callbacks.shift()(Module); + } +}; + +/** + * @param {number} ptr + * @param {string} type + */ function getValue(ptr, type = "i8") { + if (type.endsWith("*")) type = "*"; + switch (type) { + case "i1": + return HEAP8[ptr >>> 0]; + + case "i8": + return HEAP8[ptr >>> 0]; + + case "i16": + return HEAP16[((ptr) >>> 1) >>> 0]; + + case "i32": + return HEAP32[((ptr) >>> 2) >>> 0]; + + case "i64": + abort("to do getValue(i64) use WASM_BIGINT"); + + case "float": + return HEAPF32[((ptr) >>> 2) >>> 0]; + + case "double": + return HEAPF64[((ptr) >>> 3) >>> 0]; + + case "*": + return HEAPU32[((ptr) >>> 2) >>> 0]; + + default: + abort(`invalid type for getValue: ${type}`); + } +} + +var noExitRuntime = Module["noExitRuntime"] || true; + +var ptrToString = ptr => { + assert(typeof ptr === "number"); + return "0x" + ptr.toString(16).padStart(8, "0"); +}; + +var setStackLimits = () => { + var stackLow = _emscripten_stack_get_base(); + var stackHigh = _emscripten_stack_get_end(); + ___set_stack_limits(stackLow, stackHigh); +}; + +/** + * @param {number} ptr + * @param {number} value + * @param {string} type + */ function setValue(ptr, value, type = "i8") { + if (type.endsWith("*")) type = "*"; + switch (type) { + case "i1": + HEAP8[ptr >>> 0] = value; + break; + + case "i8": + HEAP8[ptr >>> 0] = value; + break; + + case "i16": + HEAP16[((ptr) >>> 1) >>> 0] = value; + break; + + case "i32": + HEAP32[((ptr) >>> 2) >>> 0] = value; + break; + + case "i64": + abort("to do setValue(i64) use WASM_BIGINT"); + + case "float": + HEAPF32[((ptr) >>> 2) >>> 0] = value; + break; + + case "double": + HEAPF64[((ptr) >>> 3) >>> 0] = value; + break; + + case "*": + HEAPU32[((ptr) >>> 2) >>> 0] = value; + break; + + default: + abort(`invalid type for setValue: ${type}`); + } +} + +var stackRestore = val => __emscripten_stack_restore(val); + +var stackSave = () => _emscripten_stack_get_current(); + +var warnOnce = text => { + warnOnce.shown ||= {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + err(text); + } +}; + +var convertI32PairToI53Checked = (lo, hi) => { + assert(lo == (lo >>> 0) || lo == (lo | 0)); + // lo should either be a i32 or a u32 + assert(hi === (hi | 0)); + // hi should be a i32 + return ((hi + 2097152) >>> 0 < 4194305 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN; +}; + +var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder : undefined; + +/** + * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given + * array that contains uint8 values, returns a copy of that string as a + * Javascript String object. + * heapOrArray is either a regular array, or a JavaScript typed array view. + * @param {number} idx + * @param {number=} maxBytesToRead + * @return {string} + */ var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => { + idx >>>= 0; + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on + // null terminator by itself. Also, use the length info to avoid running tiny + // strings through TextDecoder, since .subarray() allocates garbage. + // (As a tiny code save trick, compare endPtr against endIdx using a negation, + // so that undefined means Infinity) + while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); + } + var str = ""; + // If building with TextDecoder, we have already computed the string length + // above, so test loop end condition against that + while (idx < endPtr) { + // For UTF8 byte structure, see: + // http://en.wikipedia.org/wiki/UTF-8#Description + // https://www.ietf.org/rfc/rfc2279.txt + // https://tools.ietf.org/html/rfc3629 + var u0 = heapOrArray[idx++]; + if (!(u0 & 128)) { + str += String.fromCharCode(u0); + continue; + } + var u1 = heapOrArray[idx++] & 63; + if ((u0 & 224) == 192) { + str += String.fromCharCode(((u0 & 31) << 6) | u1); + continue; + } + var u2 = heapOrArray[idx++] & 63; + if ((u0 & 240) == 224) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + if ((u0 & 248) != 240) warnOnce("Invalid UTF-8 leading byte " + ptrToString(u0) + " encountered when deserializing a UTF-8 string in wasm memory to a JS string!"); + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63); + } + if (u0 < 65536) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 65536; + str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023)); + } + } + return str; +}; + +/** + * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the + * emscripten HEAP, returns a copy of that string as a Javascript String object. + * + * @param {number} ptr + * @param {number=} maxBytesToRead - An optional length that specifies the + * maximum number of bytes to read. You can omit this parameter to scan the + * string until the first 0 byte. If maxBytesToRead is passed, and the string + * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the + * string will cut short at that byte index (i.e. maxBytesToRead will not + * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing + * frequent uses of UTF8ToString() with and without maxBytesToRead may throw + * JS JIT optimizations off, so it is worth to consider consistently using one + * @return {string} + */ var UTF8ToString = (ptr, maxBytesToRead) => { + assert(typeof ptr == "number", `UTF8ToString expects a number (got ${typeof ptr})`); + ptr >>>= 0; + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; +}; + +function ___assert_fail(condition, filename, line, func) { + condition >>>= 0; + filename >>>= 0; + func >>>= 0; + abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]); +} + +var exceptionCaught = []; + +var uncaughtExceptionCount = 0; + +function ___cxa_begin_catch(ptr) { + ptr >>>= 0; + var info = new ExceptionInfo(ptr); + if (!info.get_caught()) { + info.set_caught(true); + uncaughtExceptionCount--; + } + info.set_rethrown(false); + exceptionCaught.push(info); + ___cxa_increment_exception_refcount(info.excPtr); + return info.get_exception_ptr(); +} + +var exceptionLast = 0; + +var ___cxa_end_catch = () => { + // Clear state flag. + _setThrew(0, 0); + assert(exceptionCaught.length > 0); + // Call destructor if one is registered then clear it. + var info = exceptionCaught.pop(); + ___cxa_decrement_exception_refcount(info.excPtr); + exceptionLast = 0; +}; + +// XXX in decRef? +class ExceptionInfo { + // excPtr - Thrown object pointer to wrap. Metadata pointer is calculated from it. + constructor(excPtr) { + this.excPtr = excPtr; + this.ptr = excPtr - 24; + } + set_type(type) { + HEAPU32[(((this.ptr) + (4)) >>> 2) >>> 0] = type; + } + get_type() { + return HEAPU32[(((this.ptr) + (4)) >>> 2) >>> 0]; + } + set_destructor(destructor) { + HEAPU32[(((this.ptr) + (8)) >>> 2) >>> 0] = destructor; + } + get_destructor() { + return HEAPU32[(((this.ptr) + (8)) >>> 2) >>> 0]; + } + set_caught(caught) { + caught = caught ? 1 : 0; + HEAP8[(this.ptr) + (12) >>> 0] = caught; + } + get_caught() { + return HEAP8[(this.ptr) + (12) >>> 0] != 0; + } + set_rethrown(rethrown) { + rethrown = rethrown ? 1 : 0; + HEAP8[(this.ptr) + (13) >>> 0] = rethrown; + } + get_rethrown() { + return HEAP8[(this.ptr) + (13) >>> 0] != 0; + } + // Initialize native structure fields. Should be called once after allocated. + init(type, destructor) { + this.set_adjusted_ptr(0); + this.set_type(type); + this.set_destructor(destructor); + } + set_adjusted_ptr(adjustedPtr) { + HEAPU32[(((this.ptr) + (16)) >>> 2) >>> 0] = adjustedPtr; + } + get_adjusted_ptr() { + return HEAPU32[(((this.ptr) + (16)) >>> 2) >>> 0]; + } + // Get pointer which is expected to be received by catch clause in C++ code. It may be adjusted + // when the pointer is casted to some of the exception object base classes (e.g. when virtual + // inheritance is used). When a pointer is thrown this method should return the thrown pointer + // itself. + get_exception_ptr() { + // Work around a fastcomp bug, this code is still included for some reason in a build without + // exceptions support. + var isPointer = ___cxa_is_pointer_type(this.get_type()); + if (isPointer) { + return HEAPU32[((this.excPtr) >>> 2) >>> 0]; + } + var adjusted = this.get_adjusted_ptr(); + if (adjusted !== 0) return adjusted; + return this.excPtr; + } +} + +function ___resumeException(ptr) { + ptr >>>= 0; + if (!exceptionLast) { + exceptionLast = new CppException(ptr); + } + throw exceptionLast; +} + +var setTempRet0 = val => __emscripten_tempret_set(val); + +var findMatchingCatch = args => { + var thrown = exceptionLast?.excPtr; + if (!thrown) { + // just pass through the null ptr + setTempRet0(0); + return 0; + } + var info = new ExceptionInfo(thrown); + info.set_adjusted_ptr(thrown); + var thrownType = info.get_type(); + if (!thrownType) { + // just pass through the thrown ptr + setTempRet0(0); + return thrown; + } + // can_catch receives a **, add indirection + // The different catch blocks are denoted by different types. + // Due to inheritance, those types may not precisely match the + // type of the thrown object. Find one which matches, and + // return the type of the catch block which should be called. + for (var caughtType of args) { + if (caughtType === 0 || caughtType === thrownType) { + // Catch all clause matched or exactly the same type is caught + break; + } + var adjusted_ptr_addr = info.ptr + 16; + if (___cxa_can_catch(caughtType, thrownType, adjusted_ptr_addr)) { + setTempRet0(caughtType); + return thrown; + } + } + setTempRet0(thrownType); + return thrown; +}; + +function ___cxa_find_matching_catch_2() { + return findMatchingCatch([]); +} + +function ___cxa_find_matching_catch_3(arg0) { + arg0 >>>= 0; + return findMatchingCatch([ arg0 ]); +} + +function ___cxa_throw(ptr, type, destructor) { + ptr >>>= 0; + type >>>= 0; + destructor >>>= 0; + var info = new ExceptionInfo(ptr); + // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception. + info.init(type, destructor); + exceptionLast = new CppException(ptr); + uncaughtExceptionCount++; + throw exceptionLast; +} + +function ___handle_stack_overflow(requested) { + requested >>>= 0; + var base = _emscripten_stack_get_base(); + var end = _emscripten_stack_get_end(); + abort(`stack overflow (Attempt to set SP to ${ptrToString(requested)}` + `, with stack limits [${ptrToString(end)} - ${ptrToString(base)}` + "]). If you require more stack space build with -sSTACK_SIZE="); +} + +var __abort_js = () => { + abort("native code called abort()"); +}; + +var nowIsMonotonic = 1; + +var __emscripten_get_now_is_monotonic = () => nowIsMonotonic; + +function __emscripten_memcpy_js(dest, src, num) { + dest >>>= 0; + src >>>= 0; + num >>>= 0; + return HEAPU8.copyWithin(dest >>> 0, src >>> 0, src + num >>> 0); +} + +var _emscripten_date_now = () => Date.now(); + +var _emscripten_get_now; + +// Modern environment where performance.now() is supported: +// N.B. a shorter form "_emscripten_get_now = performance.now;" is +// unfortunately not allowed even in current browsers (e.g. FF Nightly 75). +_emscripten_get_now = () => performance.now(); + +var reallyNegative = x => x < 0 || (x === 0 && (1 / x) === -Infinity); + +var convertI32PairToI53 = (lo, hi) => { + // This function should not be getting called with too large unsigned numbers + // in high part (if hi >= 0x7FFFFFFFF, one should have been calling + // convertU32PairToI53()) + assert(hi === (hi | 0)); + return (lo >>> 0) + hi * 4294967296; +}; + +var convertU32PairToI53 = (lo, hi) => (lo >>> 0) + (hi >>> 0) * 4294967296; + +var reSign = (value, bits) => { + if (value <= 0) { + return value; + } + var half = bits <= 32 ? Math.abs(1 << (bits - 1)) : // abs is needed if bits == 32 + Math.pow(2, bits - 1); + // for huge values, we can hit the precision limit and always get true here. + // so don't do that but, in general there is no perfect solution here. With + // 64-bit ints, we get rounding and errors + // TODO: In i64 mode 1, resign the two parts separately and safely + if (value >= half && (bits <= 32 || value > half)) { + // Cannot bitshift half, as it may be at the limit of the bits JS uses in + // bitshifts + value = -2 * half + value; + } + return value; +}; + +var unSign = (value, bits) => { + if (value >= 0) { + return value; + } + // Need some trickery, since if bits == 32, we are right at the limit of the + // bits JS uses in bitshifts + return bits <= 32 ? 2 * Math.abs(1 << (bits - 1)) + value : Math.pow(2, bits) + value; +}; + +var strLen = ptr => { + var end = ptr; + while (HEAPU8[end >>> 0]) ++end; + return end - ptr; +}; + +var lengthBytesUTF8 = str => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code + // unit, not a Unicode code point of the character! So decode + // UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var c = str.charCodeAt(i); + // possibly a lead surrogate + if (c <= 127) { + len++; + } else if (c <= 2047) { + len += 2; + } else if (c >= 55296 && c <= 57343) { + len += 4; + ++i; + } else { + len += 3; + } + } + return len; +}; + +var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + outIdx >>>= 0; + assert(typeof str === "string", `stringToUTF8Array expects a string (got ${typeof str})`); + // Parameter maxBytesToWrite is not optional. Negative values, 0, null, + // undefined and false each don't write out any bytes. + if (!(maxBytesToWrite > 0)) return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code + // unit, not a Unicode code point of the character! So decode + // UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description + // and https://www.ietf.org/rfc/rfc2279.txt + // and https://tools.ietf.org/html/rfc3629 + var u = str.charCodeAt(i); + // possibly a lead surrogate + if (u >= 55296 && u <= 57343) { + var u1 = str.charCodeAt(++i); + u = 65536 + ((u & 1023) << 10) | (u1 & 1023); + } + if (u <= 127) { + if (outIdx >= endIdx) break; + heap[outIdx++ >>> 0] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++ >>> 0] = 192 | (u >> 6); + heap[outIdx++ >>> 0] = 128 | (u & 63); + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++ >>> 0] = 224 | (u >> 12); + heap[outIdx++ >>> 0] = 128 | ((u >> 6) & 63); + heap[outIdx++ >>> 0] = 128 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + if (u > 1114111) warnOnce("Invalid Unicode code point " + ptrToString(u) + " encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF)."); + heap[outIdx++ >>> 0] = 240 | (u >> 18); + heap[outIdx++ >>> 0] = 128 | ((u >> 12) & 63); + heap[outIdx++ >>> 0] = 128 | ((u >> 6) & 63); + heap[outIdx++ >>> 0] = 128 | (u & 63); + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx >>> 0] = 0; + return outIdx - startIdx; +}; + +/** @type {function(string, boolean=, number=)} */ function intArrayFromString(stringy, dontAddNull, length) { + var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); + if (dontAddNull) u8array.length = numBytesWritten; + return u8array; +} + +var formatString = (format, varargs) => { + assert((varargs & 3) === 0); + var textIndex = format; + var argIndex = varargs; + // This must be called before reading a double or i64 vararg. It will bump the pointer properly. + // It also does an assert on i32 values, so it's nice to call it before all varargs calls. + function prepVararg(ptr, type) { + if (type === "double" || type === "i64") { + // move so the load is aligned + if (ptr & 7) { + assert((ptr & 7) === 4); + ptr += 4; + } + } else { + assert((ptr & 3) === 0); + } + return ptr; + } + function getNextArg(type) { + // NOTE: Explicitly ignoring type safety. Otherwise this fails: + // int x = 4; printf("%c\n", (char)x); + var ret; + argIndex = prepVararg(argIndex, type); + if (type === "double") { + ret = HEAPF64[((argIndex) >>> 3) >>> 0]; + argIndex += 8; + } else if (type == "i64") { + ret = [ HEAP32[((argIndex) >>> 2) >>> 0], HEAP32[(((argIndex) + (4)) >>> 2) >>> 0] ]; + argIndex += 8; + } else { + assert((argIndex & 3) === 0); + type = "i32"; + // varargs are always i32, i64, or double + ret = HEAP32[((argIndex) >>> 2) >>> 0]; + argIndex += 4; + } + return ret; + } + var ret = []; + var curr, next, currArg; + while (1) { + var startTextIndex = textIndex; + curr = HEAP8[textIndex >>> 0]; + if (curr === 0) break; + next = HEAP8[textIndex + 1 >>> 0]; + if (curr == 37) { + // Handle flags. + var flagAlwaysSigned = false; + var flagLeftAlign = false; + var flagAlternative = false; + var flagZeroPad = false; + var flagPadSign = false; + flagsLoop: while (1) { + switch (next) { + case 43: + flagAlwaysSigned = true; + break; + + case 45: + flagLeftAlign = true; + break; + + case 35: + flagAlternative = true; + break; + + case 48: + if (flagZeroPad) { + break flagsLoop; + } else { + flagZeroPad = true; + break; + } + + case 32: + flagPadSign = true; + break; + + default: + break flagsLoop; + } + textIndex++; + next = HEAP8[textIndex + 1 >>> 0]; + } + // Handle width. + var width = 0; + if (next == 42) { + width = getNextArg("i32"); + textIndex++; + next = HEAP8[textIndex + 1 >>> 0]; + } else { + while (next >= 48 && next <= 57) { + width = width * 10 + (next - 48); + textIndex++; + next = HEAP8[textIndex + 1 >>> 0]; + } + } + // Handle precision. + var precisionSet = false, precision = -1; + if (next == 46) { + precision = 0; + precisionSet = true; + textIndex++; + next = HEAP8[textIndex + 1 >>> 0]; + if (next == 42) { + precision = getNextArg("i32"); + textIndex++; + } else { + while (1) { + var precisionChr = HEAP8[textIndex + 1 >>> 0]; + if (precisionChr < 48 || precisionChr > 57) break; + precision = precision * 10 + (precisionChr - 48); + textIndex++; + } + } + next = HEAP8[textIndex + 1 >>> 0]; + } + if (precision < 0) { + precision = 6; + // Standard default. + precisionSet = false; + } + // Handle integer sizes. WARNING: These assume a 32-bit architecture! + var argSize; + switch (String.fromCharCode(next)) { + case "h": + var nextNext = HEAP8[textIndex + 2 >>> 0]; + if (nextNext == 104) { + textIndex++; + argSize = 1; + } else // char (actually i32 in varargs) + { + argSize = 2; + } + // short (actually i32 in varargs) + break; + + case "l": + var nextNext = HEAP8[textIndex + 2 >>> 0]; + if (nextNext == 108) { + textIndex++; + argSize = 8; + } else // long long + { + argSize = 4; + } + // long + break; + + case "L": + // long long + case "q": + // int64_t + case "j": + // intmax_t + argSize = 8; + break; + + case "z": + // size_t + case "t": + // ptrdiff_t + case "I": + // signed ptrdiff_t or unsigned size_t + argSize = 4; + break; + + default: + argSize = null; + } + if (argSize) textIndex++; + next = HEAP8[textIndex + 1 >>> 0]; + // Handle type specifier. + switch (String.fromCharCode(next)) { + case "d": + case "i": + case "u": + case "o": + case "x": + case "X": + case "p": + { + // Integer. + var signed = next == 100 || next == 105; + argSize = argSize || 4; + currArg = getNextArg("i" + (argSize * 8)); + var argText; + // Flatten i64-1 [low, high] into a (slightly rounded) double + if (argSize == 8) { + currArg = next == 117 ? convertU32PairToI53(currArg[0], currArg[1]) : convertI32PairToI53(currArg[0], currArg[1]); + } + // Truncate to requested size. + if (argSize <= 4) { + var limit = Math.pow(256, argSize) - 1; + currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8); + } + // Format the number. + var currAbsArg = Math.abs(currArg); + var prefix = ""; + if (next == 100 || next == 105) { + argText = reSign(currArg, 8 * argSize).toString(10); + } else if (next == 117) { + argText = unSign(currArg, 8 * argSize).toString(10); + currArg = Math.abs(currArg); + } else if (next == 111) { + argText = (flagAlternative ? "0" : "") + currAbsArg.toString(8); + } else if (next == 120 || next == 88) { + prefix = (flagAlternative && currArg != 0) ? "0x" : ""; + if (currArg < 0) { + // Represent negative numbers in hex as 2's complement. + currArg = -currArg; + argText = (currAbsArg - 1).toString(16); + var buffer = []; + for (var i = 0; i < argText.length; i++) { + buffer.push((15 - parseInt(argText[i], 16)).toString(16)); + } + argText = buffer.join(""); + while (argText.length < argSize * 2) argText = "f" + argText; + } else { + argText = currAbsArg.toString(16); + } + if (next == 88) { + prefix = prefix.toUpperCase(); + argText = argText.toUpperCase(); + } + } else if (next == 112) { + if (currAbsArg === 0) { + argText = "(nil)"; + } else { + prefix = "0x"; + argText = currAbsArg.toString(16); + } + } + if (precisionSet) { + while (argText.length < precision) { + argText = "0" + argText; + } + } + // Add sign if needed + if (currArg >= 0) { + if (flagAlwaysSigned) { + prefix = "+" + prefix; + } else if (flagPadSign) { + prefix = " " + prefix; + } + } + // Move sign to prefix so we zero-pad after the sign + if (argText.charAt(0) == "-") { + prefix = "-" + prefix; + argText = argText.substr(1); + } + // Add padding. + while (prefix.length + argText.length < width) { + if (flagLeftAlign) { + argText += " "; + } else { + if (flagZeroPad) { + argText = "0" + argText; + } else { + prefix = " " + prefix; + } + } + } + // Insert the result into the buffer. + argText = prefix + argText; + argText.split("").forEach(function(chr) { + ret.push(chr.charCodeAt(0)); + }); + break; + } + + case "f": + case "F": + case "e": + case "E": + case "g": + case "G": + { + // Float. + currArg = getNextArg("double"); + var argText; + if (isNaN(currArg)) { + argText = "nan"; + flagZeroPad = false; + } else if (!isFinite(currArg)) { + argText = (currArg < 0 ? "-" : "") + "inf"; + flagZeroPad = false; + } else { + var isGeneral = false; + var effectivePrecision = Math.min(precision, 20); + // Convert g/G to f/F or e/E, as per: + // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html + if (next == 103 || next == 71) { + isGeneral = true; + precision = precision || 1; + var exponent = parseInt(currArg.toExponential(effectivePrecision).split("e")[1], 10); + if (precision > exponent && exponent >= -4) { + next = ((next == 103) ? "f" : "F").charCodeAt(0); + precision -= exponent + 1; + } else { + next = ((next == 103) ? "e" : "E").charCodeAt(0); + precision--; + } + effectivePrecision = Math.min(precision, 20); + } + if (next == 101 || next == 69) { + argText = currArg.toExponential(effectivePrecision); + // Make sure the exponent has at least 2 digits. + if (/[eE][-+]\d$/.test(argText)) { + argText = argText.slice(0, -1) + "0" + argText.slice(-1); + } + } else if (next == 102 || next == 70) { + argText = currArg.toFixed(effectivePrecision); + if (currArg === 0 && reallyNegative(currArg)) { + argText = "-" + argText; + } + } + var parts = argText.split("e"); + if (isGeneral && !flagAlternative) { + // Discard trailing zeros and periods. + while (parts[0].length > 1 && parts[0].includes(".") && (parts[0].slice(-1) == "0" || parts[0].slice(-1) == ".")) { + parts[0] = parts[0].slice(0, -1); + } + } else { + // Make sure we have a period in alternative mode. + if (flagAlternative && argText.indexOf(".") == -1) parts[0] += "."; + // Zero pad until required precision. + while (precision > effectivePrecision++) parts[0] += "0"; + } + argText = parts[0] + (parts.length > 1 ? "e" + parts[1] : ""); + // Capitalize 'E' if needed. + if (next == 69) argText = argText.toUpperCase(); + // Add sign. + if (currArg >= 0) { + if (flagAlwaysSigned) { + argText = "+" + argText; + } else if (flagPadSign) { + argText = " " + argText; + } + } + } + // Add padding. + while (argText.length < width) { + if (flagLeftAlign) { + argText += " "; + } else { + if (flagZeroPad && (argText[0] == "-" || argText[0] == "+")) { + argText = argText[0] + "0" + argText.slice(1); + } else { + argText = (flagZeroPad ? "0" : " ") + argText; + } + } + } + // Adjust case. + if (next < 97) argText = argText.toUpperCase(); + // Insert the result into the buffer. + argText.split("").forEach(function(chr) { + ret.push(chr.charCodeAt(0)); + }); + break; + } + + case "s": + { + // String. + var arg = getNextArg("i8*"); + var argLength = arg ? strLen(arg) : "(null)".length; + if (precisionSet) argLength = Math.min(argLength, precision); + if (!flagLeftAlign) { + while (argLength < width--) { + ret.push(32); + } + } + if (arg) { + for (var i = 0; i < argLength; i++) { + ret.push(HEAPU8[arg++ >>> 0]); + } + } else { + ret = ret.concat(intArrayFromString("(null)".substr(0, argLength), true)); + } + if (flagLeftAlign) { + while (argLength < width--) { + ret.push(32); + } + } + break; + } + + case "c": + { + // Character. + if (flagLeftAlign) ret.push(getNextArg("i8")); + while (--width > 0) { + ret.push(32); + } + if (!flagLeftAlign) ret.push(getNextArg("i8")); + break; + } + + case "n": + { + // Write the length written so far to the next parameter. + var ptr = getNextArg("i32*"); + HEAP32[((ptr) >>> 2) >>> 0] = ret.length; + break; + } + + case "%": + { + // Literal percent sign. + ret.push(curr); + break; + } + + default: + { + // Unknown specifiers remain untouched. + for (var i = startTextIndex; i < textIndex + 2; i++) { + ret.push(HEAP8[i >>> 0]); + } + } + } + textIndex += 2; + } else // TODO: Support a/A (hex float) and m (last error) specifiers. + // TODO: Support %1${specifier} for arg selection. + { + ret.push(curr); + textIndex += 1; + } + } + return ret; +}; + +function jsStackTrace() { + return (new Error).stack.toString(); +} + +/** @param {number=} flags */ function getCallstack(flags) { + var callstack = jsStackTrace(); + // Find the symbols in the callstack that corresponds to the functions that + // report callstack information, and remove everything up to these from the + // output. + var iThisFunc = callstack.lastIndexOf("_emscripten_log"); + var iThisFunc2 = callstack.lastIndexOf("_emscripten_get_callstack"); + var iNextLine = callstack.indexOf("\n", Math.max(iThisFunc, iThisFunc2)) + 1; + callstack = callstack.slice(iNextLine); + // If user requested to see the original source stack, but no source map + // information is available, just fall back to showing the JS stack. + if (flags & 8 && typeof emscripten_source_map == "undefined") { + warnOnce('Source map information is not available, emscripten_log with EM_LOG_C_STACK will be ignored. Build with "--pre-js $EMSCRIPTEN/src/emscripten-source-map.min.js" linker flag to add source map loading to code.'); + flags ^= 8; + flags |= 16; + } + // Process all lines: + var lines = callstack.split("\n"); + callstack = ""; + // New FF30 with column info: extract components of form: + // ' Object._main@http://server.com:4324:12' + var newFirefoxRe = new RegExp("\\s*(.*?)@(.*?):([0-9]+):([0-9]+)"); + // Old FF without column info: extract components of form: + // ' Object._main@http://server.com:4324' + var firefoxRe = new RegExp("\\s*(.*?)@(.*):(.*)(:(.*))?"); + // Extract components of form: + // ' at Object._main (http://server.com/file.html:4324:12)' + var chromeRe = new RegExp("\\s*at (.*?) \\((.*):(.*):(.*)\\)"); + for (var l in lines) { + var line = lines[l]; + var symbolName = ""; + var file = ""; + var lineno = 0; + var column = 0; + var parts = chromeRe.exec(line); + if (parts && parts.length == 5) { + symbolName = parts[1]; + file = parts[2]; + lineno = parts[3]; + column = parts[4]; + } else { + parts = newFirefoxRe.exec(line); + if (!parts) parts = firefoxRe.exec(line); + if (parts && parts.length >= 4) { + symbolName = parts[1]; + file = parts[2]; + lineno = parts[3]; + // Old Firefox doesn't carry column information, but in new FF30, it + // is present. See https://bugzilla.mozilla.org/show_bug.cgi?id=762556 + column = parts[4] | 0; + } else { + // Was not able to extract this line for demangling/sourcemapping + // purposes. Output it as-is. + callstack += line + "\n"; + continue; + } + } + var haveSourceMap = false; + if (flags & 8) { + var orig = emscripten_source_map.originalPositionFor({ + line: lineno, + column: column + }); + haveSourceMap = orig?.source; + if (haveSourceMap) { + if (flags & 64) { + orig.source = orig.source.substring(orig.source.replace(/\\/g, "/").lastIndexOf("/") + 1); + } + callstack += ` at ${symbolName} (${orig.source}:${orig.line}:${orig.column})\n`; + } + } + if ((flags & 16) || !haveSourceMap) { + if (flags & 64) { + file = file.substring(file.replace(/\\/g, "/").lastIndexOf("/") + 1); + } + callstack += (haveSourceMap ? (` = ${symbolName}`) : (` at ${symbolName}`)) + ` (${file}:${lineno}:${column})\n`; + } + } + // Trim extra whitespace at the end of the output. + callstack = callstack.replace(/\s+$/, ""); + return callstack; +} + +var emscriptenLog = (flags, str) => { + if (flags & 24) { + str = str.replace(/\s+$/, ""); + // Ensure the message and the callstack are joined cleanly with exactly one newline. + str += (str.length > 0 ? "\n" : "") + getCallstack(flags); + } + if (flags & 1) { + if (flags & 4) { + console.error(str); + } else if (flags & 2) { + console.warn(str); + } else if (flags & 512) { + console.info(str); + } else if (flags & 256) { + console.debug(str); + } else { + console.log(str); + } + } else if (flags & 6) { + err(str); + } else { + out(str); + } +}; + +function _emscripten_log(flags, format, varargs) { + format >>>= 0; + varargs >>>= 0; + var result = formatString(format, varargs); + var str = UTF8ArrayToString(result, 0); + emscriptenLog(flags, str); +} + +var getHeapMax = () => // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate +// full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side +// for any code that deals with heap sizes, which would require special +// casing all heap size related code to treat 0 specially. +4294901760; + +var growMemory = size => { + var b = wasmMemory.buffer; + var pages = (size - b.byteLength + 65535) / 65536; + try { + // round size grow request up to wasm page size (fixed 64KB per spec) + wasmMemory.grow(pages); + // .grow() takes a delta compared to the previous size + updateMemoryViews(); + return 1; + } /*success*/ catch (e) { + err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`); + } +}; + +// implicit 0 return to save code size (caller will cast "undefined" into 0 +// anyhow) +function _emscripten_resize_heap(requestedSize) { + requestedSize >>>= 0; + var oldSize = HEAPU8.length; + // With multithreaded builds, races can happen (another thread might increase the size + // in between), so return a failure, and let the caller retry. + assert(requestedSize > oldSize); + // Memory resize rules: + // 1. Always increase heap size to at least the requested size, rounded up + // to next page multiple. + // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap + // geometrically: increase the heap size according to + // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most + // overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB). + // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap + // linearly: increase the heap size by at least + // MEMORY_GROWTH_LINEAR_STEP bytes. + // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by + // MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest + // 4. If we were unable to allocate as much memory, it may be due to + // over-eager decision to excessively reserve due to (3) above. + // Hence if an allocation fails, cut down on the amount of excess + // growth, in an attempt to succeed to perform a smaller allocation. + // A limit is set for how much we can grow. We should not exceed that + // (the wasm binary specifies it, so if we tried, we'd fail anyhow). + var maxHeapSize = getHeapMax(); + if (requestedSize > maxHeapSize) { + err(`Cannot enlarge memory, requested ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`); + return false; + } + var alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple; + // Loop through potential heap size increases. If we attempt a too eager + // reservation that fails, cut down on the attempted size and reserve a + // smaller bump instead. (max 3 times, chosen somewhat arbitrarily) + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + .2 / cutDown); + // ensure geometric growth + // but limit overreserving (default to capping at +96MB overgrowth at most) + overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); + var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); + var replacement = growMemory(newSize); + if (replacement) { + return true; + } + } + err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`); + return false; +} + +var SYSCALLS = { + varargs: undefined, + getStr(ptr) { + var ret = UTF8ToString(ptr); + return ret; + } +}; + +var _fd_close = fd => { + abort("fd_close called without SYSCALLS_REQUIRE_FILESYSTEM"); +}; + +function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + newOffset >>>= 0; + return 70; +} + +var printCharBuffers = [ null, [], [] ]; + +var printChar = (stream, curr) => { + var buffer = printCharBuffers[stream]; + assert(buffer); + if (curr === 0 || curr === 10) { + (stream === 1 ? out : err)(UTF8ArrayToString(buffer, 0)); + buffer.length = 0; + } else { + buffer.push(curr); + } +}; + +var flush_NO_FILESYSTEM = () => { + // flush anything remaining in the buffers during shutdown + _fflush(0); + if (printCharBuffers[1].length) printChar(1, 10); + if (printCharBuffers[2].length) printChar(2, 10); +}; + +function _fd_write(fd, iov, iovcnt, pnum) { + iov >>>= 0; + iovcnt >>>= 0; + pnum >>>= 0; + // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0 + var num = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov) >>> 2) >>> 0]; + var len = HEAPU32[(((iov) + (4)) >>> 2) >>> 0]; + iov += 8; + for (var j = 0; j < len; j++) { + printChar(fd, HEAPU8[ptr + j >>> 0]); + } + num += len; + } + HEAPU32[((pnum) >>> 2) >>> 0] = num; + return 0; +} + +function _llvm_eh_typeid_for(type) { + type >>>= 0; + return type; +} + +var wasmTableMirror = []; + +/** @type {WebAssembly.Table} */ var wasmTable; + +var getWasmTableEntry = funcPtr => { + var func = wasmTableMirror[funcPtr]; + if (!func) { + if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1; + wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr); + } + assert(wasmTable.get(funcPtr) == func, "JavaScript-side Wasm function table mirror is out of date!"); + return func; +}; + +var getCFunc = ident => { + var func = Module["_" + ident]; + // closure exported function + assert(func, "Cannot call unknown function " + ident + ", make sure it is exported"); + return func; +}; + +var writeArrayToMemory = (array, buffer) => { + assert(array.length >= 0, "writeArrayToMemory array must have a length (should be an array or typed array)"); + HEAP8.set(array, buffer >>> 0); +}; + +var stringToUTF8 = (str, outPtr, maxBytesToWrite) => { + assert(typeof maxBytesToWrite == "number", "stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!"); + return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); +}; + +var stackAlloc = sz => __emscripten_stack_alloc(sz); + +var stringToUTF8OnStack = str => { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8(str, ret, size); + return ret; +}; + +/** + * @param {string|null=} returnType + * @param {Array=} argTypes + * @param {Arguments|Array=} args + * @param {Object=} opts + */ var ccall = (ident, returnType, argTypes, args, opts) => { + // For fast lookup of conversion functions + var toC = { + "string": str => { + var ret = 0; + if (str !== null && str !== undefined && str !== 0) { + // null string + // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0' + ret = stringToUTF8OnStack(str); + } + return ret; + }, + "array": arr => { + var ret = stackAlloc(arr.length); + writeArrayToMemory(arr, ret); + return ret; + } + }; + function convertReturnValue(ret) { + if (returnType === "string") { + return UTF8ToString(ret); + } + if (returnType === "boolean") return Boolean(ret); + return ret; + } + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + assert(returnType !== "array", 'Return type should not be "array".'); + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func(...cArgs); + function onDone(ret) { + if (stack !== 0) stackRestore(stack); + return convertReturnValue(ret); + } + ret = onDone(ret); + return ret; +}; + +/** + * @param {string=} returnType + * @param {Array=} argTypes + * @param {Object=} opts + */ var cwrap = (ident, returnType, argTypes, opts) => (...args) => ccall(ident, returnType, argTypes, args, opts); + +var incrementExceptionRefcount = ptr => ___cxa_increment_exception_refcount(ptr); + +Module["incrementExceptionRefcount"] = incrementExceptionRefcount; + +var decrementExceptionRefcount = ptr => ___cxa_decrement_exception_refcount(ptr); + +Module["decrementExceptionRefcount"] = decrementExceptionRefcount; + +var getExceptionMessageCommon = ptr => { + var sp = stackSave(); + var type_addr_addr = stackAlloc(4); + var message_addr_addr = stackAlloc(4); + ___get_exception_message(ptr, type_addr_addr, message_addr_addr); + var type_addr = HEAPU32[((type_addr_addr) >>> 2) >>> 0]; + var message_addr = HEAPU32[((message_addr_addr) >>> 2) >>> 0]; + var type = UTF8ToString(type_addr); + _free(type_addr); + var message; + if (message_addr) { + message = UTF8ToString(message_addr); + _free(message_addr); + } + stackRestore(sp); + return [ type, message ]; +}; + +var getExceptionMessage = ptr => getExceptionMessageCommon(ptr); + +Module["getExceptionMessage"] = getExceptionMessage; + +function checkIncomingModuleAPI() { + ignoredModuleProp("fetchSettings"); +} + +var wasmImports = { + /** @export */ __assert_fail: ___assert_fail, + /** @export */ __cxa_begin_catch: ___cxa_begin_catch, + /** @export */ __cxa_end_catch: ___cxa_end_catch, + /** @export */ __cxa_find_matching_catch_2: ___cxa_find_matching_catch_2, + /** @export */ __cxa_find_matching_catch_3: ___cxa_find_matching_catch_3, + /** @export */ __cxa_throw: ___cxa_throw, + /** @export */ __handle_stack_overflow: ___handle_stack_overflow, + /** @export */ __resumeException: ___resumeException, + /** @export */ _abort_js: __abort_js, + /** @export */ _emscripten_get_now_is_monotonic: __emscripten_get_now_is_monotonic, + /** @export */ _emscripten_memcpy_js: __emscripten_memcpy_js, + /** @export */ emscripten_date_now: _emscripten_date_now, + /** @export */ emscripten_get_now: _emscripten_get_now, + /** @export */ emscripten_log: _emscripten_log, + /** @export */ emscripten_resize_heap: _emscripten_resize_heap, + /** @export */ fd_close: _fd_close, + /** @export */ fd_seek: _fd_seek, + /** @export */ fd_write: _fd_write, + /** @export */ invoke_ii: invoke_ii, + /** @export */ invoke_iii: invoke_iii, + /** @export */ invoke_iiidi: invoke_iiidi, + /** @export */ invoke_iiii: invoke_iiii, + /** @export */ invoke_j: invoke_j, + /** @export */ invoke_v: invoke_v, + /** @export */ invoke_vi: invoke_vi, + /** @export */ invoke_vii: invoke_vii, + /** @export */ invoke_viii: invoke_viii, + /** @export */ invoke_viiii: invoke_viiii, + /** @export */ llvm_eh_typeid_for: _llvm_eh_typeid_for +}; + +var wasmExports = createWasm(); + +var ___wasm_call_ctors = createExportWrapper("__wasm_call_ctors", 0); + +var _malloc = Module["_malloc"] = createExportWrapper("malloc", 1); + +var _free = Module["_free"] = createExportWrapper("free", 1); + +var ___cxa_free_exception = createExportWrapper("__cxa_free_exception", 1); + +var _createBloomFilter = Module["_createBloomFilter"] = createExportWrapper("createBloomFilter", 3); + +var _createBloomFilterFromData = Module["_createBloomFilterFromData"] = createExportWrapper("createBloomFilterFromData", 1); + +var _addToFilter = Module["_addToFilter"] = createExportWrapper("addToFilter", 2); + +var _checkInFilter = Module["_checkInFilter"] = createExportWrapper("checkInFilter", 2); + +var _deleteBloomFilter = Module["_deleteBloomFilter"] = createExportWrapper("deleteBloomFilter", 1); + +var _getBloomFilterPointer = Module["_getBloomFilterPointer"] = createExportWrapper("getBloomFilterPointer", 1); + +var _getBloomFilterSize = Module["_getBloomFilterSize"] = createExportWrapper("getBloomFilterSize", 1); + +var _getBloomFilterNumberOfHashes = Module["_getBloomFilterNumberOfHashes"] = createExportWrapper("getBloomFilterNumberOfHashes", 1); + +var _fflush = createExportWrapper("fflush", 1); + +var _strerror = createExportWrapper("strerror", 1); + +var _setThrew = createExportWrapper("setThrew", 2); + +var __emscripten_tempret_set = createExportWrapper("_emscripten_tempret_set", 1); + +var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports["emscripten_stack_init"])(); + +var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports["emscripten_stack_get_free"])(); + +var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports["emscripten_stack_get_base"])(); + +var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports["emscripten_stack_get_end"])(); + +var __emscripten_stack_restore = a0 => (__emscripten_stack_restore = wasmExports["_emscripten_stack_restore"])(a0); + +var __emscripten_stack_alloc = a0 => (__emscripten_stack_alloc = wasmExports["_emscripten_stack_alloc"])(a0); + +var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports["emscripten_stack_get_current"])(); + +var ___cxa_increment_exception_refcount = createExportWrapper("__cxa_increment_exception_refcount", 1); + +var ___cxa_decrement_exception_refcount = createExportWrapper("__cxa_decrement_exception_refcount", 1); + +var ___get_exception_message = createExportWrapper("__get_exception_message", 3); + +var ___cxa_can_catch = createExportWrapper("__cxa_can_catch", 3); + +var ___cxa_is_pointer_type = createExportWrapper("__cxa_is_pointer_type", 1); + +var ___set_stack_limits = Module["___set_stack_limits"] = createExportWrapper("__set_stack_limits", 2); + +var dynCall_j = Module["dynCall_j"] = createExportWrapper("dynCall_j", 1); + +var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji", 5); + +function invoke_iii(index, a1, a2) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_iiidi(index, a1, a2, a3, a4) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3, a4); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_viii(index, a1, a2, a3) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_ii(index, a1) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_v(index) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_viiii(index, a1, a2, a3, a4) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_vi(index, a1) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_iiii(index, a1, a2, a3) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_vii(index, a1, a2) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +function invoke_j(index) { + var sp = stackSave(); + try { + return dynCall_j(index); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } +} + +// Argument name here must shadow the `wasmExports` global so +// that it is recognised by metadce and minify-import-export-names +// passes. +function applySignatureConversions(wasmExports) { + // First, make a copy of the incoming exports object + wasmExports = Object.assign({}, wasmExports); + var makeWrapper_pp = f => a0 => f(a0) >>> 0; + var makeWrapper_p_ = f => a0 => f(a0) >>> 0; + var makeWrapper_p = f => () => f() >>> 0; + wasmExports["malloc"] = makeWrapper_pp(wasmExports["malloc"]); + wasmExports["strerror"] = makeWrapper_p_(wasmExports["strerror"]); + wasmExports["emscripten_stack_get_base"] = makeWrapper_p(wasmExports["emscripten_stack_get_base"]); + wasmExports["emscripten_stack_get_end"] = makeWrapper_p(wasmExports["emscripten_stack_get_end"]); + wasmExports["_emscripten_stack_alloc"] = makeWrapper_pp(wasmExports["_emscripten_stack_alloc"]); + wasmExports["emscripten_stack_get_current"] = makeWrapper_p(wasmExports["emscripten_stack_get_current"]); + return wasmExports; +} + +// include: postamble.js +// === Auto-generated postamble setup entry stuff === +Module["ccall"] = ccall; + +Module["cwrap"] = cwrap; + +Module["UTF8ToString"] = UTF8ToString; + +var missingLibrarySymbols = [ "writeI53ToI64", "writeI53ToI64Clamped", "writeI53ToI64Signaling", "writeI53ToU64Clamped", "writeI53ToU64Signaling", "readI53FromI64", "readI53FromU64", "getTempRet0", "zeroMemory", "exitJS", "isLeapYear", "ydayFromDate", "arraySum", "addDays", "strError", "inetPton4", "inetNtop4", "inetPton6", "inetNtop6", "readSockaddr", "writeSockaddr", "initRandomFill", "randomFill", "readEmAsmArgs", "jstoi_q", "getExecutableName", "listenOnce", "autoResumeAudioContext", "dynCallLegacy", "getDynCaller", "dynCall", "handleException", "keepRuntimeAlive", "runtimeKeepalivePush", "runtimeKeepalivePop", "callUserCallback", "maybeExit", "asmjsMangle", "asyncLoad", "alignMemory", "mmapAlloc", "HandleAllocator", "getNativeTypeSize", "STACK_SIZE", "STACK_ALIGN", "POINTER_SIZE", "ASSERTIONS", "uleb128Encode", "sigToWasmTypes", "generateFuncType", "convertJsFunctionToWasm", "getEmptyTableSlot", "updateTableMap", "getFunctionAddress", "addFunction", "removeFunction", "intArrayToString", "AsciiToString", "stringToAscii", "UTF16ToString", "stringToUTF16", "lengthBytesUTF16", "UTF32ToString", "stringToUTF32", "lengthBytesUTF32", "stringToNewUTF8", "registerKeyEventCallback", "maybeCStringToJsString", "findEventTarget", "getBoundingClientRect", "fillMouseEventData", "registerMouseEventCallback", "registerWheelEventCallback", "registerUiEventCallback", "registerFocusEventCallback", "fillDeviceOrientationEventData", "registerDeviceOrientationEventCallback", "fillDeviceMotionEventData", "registerDeviceMotionEventCallback", "screenOrientation", "fillOrientationChangeEventData", "registerOrientationChangeEventCallback", "fillFullscreenChangeEventData", "registerFullscreenChangeEventCallback", "JSEvents_requestFullscreen", "JSEvents_resizeCanvasForFullscreen", "registerRestoreOldStyle", "hideEverythingExceptGivenElement", "restoreHiddenElements", "setLetterbox", "softFullscreenResizeWebGLRenderTarget", "doRequestFullscreen", "fillPointerlockChangeEventData", "registerPointerlockChangeEventCallback", "registerPointerlockErrorEventCallback", "requestPointerLock", "fillVisibilityChangeEventData", "registerVisibilityChangeEventCallback", "registerTouchEventCallback", "fillGamepadEventData", "registerGamepadEventCallback", "registerBeforeUnloadEventCallback", "fillBatteryEventData", "battery", "registerBatteryEventCallback", "setCanvasElementSize", "getCanvasElementSize", "convertPCtoSourceLocation", "getEnvStrings", "checkWasiClock", "wasiRightsToMuslOFlags", "wasiOFlagsToMuslOFlags", "createDyncallWrapper", "safeSetTimeout", "setImmediateWrapped", "clearImmediateWrapped", "polyfillSetImmediate", "getPromise", "makePromise", "idsToPromises", "makePromiseCallback", "Browser_asyncPrepareDataCounter", "setMainLoop", "getSocketFromFD", "getSocketAddress", "FS_createPreloadedFile", "FS_modeStringToFlags", "FS_getMode", "FS_stdin_getChar", "FS_unlink", "FS_createDataFile", "FS_mkdirTree", "_setNetworkCallback", "heapObjectForWebGLType", "toTypedArrayIndex", "webgl_enable_ANGLE_instanced_arrays", "webgl_enable_OES_vertex_array_object", "webgl_enable_WEBGL_draw_buffers", "webgl_enable_WEBGL_multi_draw", "emscriptenWebGLGet", "computeUnpackAlignedImageSize", "colorChannelsInGlTextureFormat", "emscriptenWebGLGetTexPixelData", "emscriptenWebGLGetUniform", "webglGetUniformLocation", "webglPrepareUniformLocationsBeforeFirstUse", "webglGetLeftBracePos", "emscriptenWebGLGetVertexAttrib", "__glGetActiveAttribOrUniform", "writeGLArray", "registerWebGlEventCallback", "runAndAbortIfError", "ALLOC_NORMAL", "ALLOC_STACK", "allocate", "writeStringToMemory", "writeAsciiToMemory", "setErrNo", "demangle", "stackTrace" ]; + +missingLibrarySymbols.forEach(missingLibrarySymbol); + +var unexportedSymbols = [ "run", "addOnPreRun", "addOnInit", "addOnPreMain", "addOnExit", "addOnPostRun", "addRunDependency", "removeRunDependency", "out", "err", "callMain", "abort", "wasmMemory", "wasmExports", "writeStackCookie", "checkStackCookie", "convertI32PairToI53", "convertI32PairToI53Checked", "convertU32PairToI53", "stackSave", "stackRestore", "stackAlloc", "setTempRet0", "ptrToString", "getHeapMax", "growMemory", "ENV", "setStackLimits", "MONTH_DAYS_REGULAR", "MONTH_DAYS_LEAP", "MONTH_DAYS_REGULAR_CUMULATIVE", "MONTH_DAYS_LEAP_CUMULATIVE", "ERRNO_CODES", "DNS", "Protocols", "Sockets", "timers", "warnOnce", "emscriptenLog", "readEmAsmArgsArray", "jstoi_s", "wasmTable", "noExitRuntime", "getCFunc", "freeTableIndexes", "functionsInTableMap", "reallyNegative", "unSign", "strLen", "reSign", "formatString", "setValue", "getValue", "PATH", "PATH_FS", "UTF8Decoder", "UTF8ArrayToString", "stringToUTF8Array", "stringToUTF8", "lengthBytesUTF8", "intArrayFromString", "UTF16Decoder", "stringToUTF8OnStack", "writeArrayToMemory", "JSEvents", "specialHTMLTargets", "findCanvasEventTarget", "currentFullscreenStrategy", "restoreOldWindowedStyle", "jsStackTrace", "getCallstack", "UNWIND_CACHE", "ExitStatus", "flush_NO_FILESYSTEM", "promiseMap", "uncaughtExceptionCount", "exceptionLast", "exceptionCaught", "ExceptionInfo", "findMatchingCatch", "getExceptionMessageCommon", "incrementExceptionRefcount", "decrementExceptionRefcount", "getExceptionMessage", "Browser", "getPreloadedImageData__data", "wget", "SYSCALLS", "preloadPlugins", "FS_stdin_getChar_buffer", "FS_createPath", "FS_createDevice", "FS_readFile", "FS", "FS_createLazyFile", "MEMFS", "TTY", "PIPEFS", "SOCKFS", "tempFixedLengthArray", "miniTempWebGLFloatBuffers", "miniTempWebGLIntBuffers", "GL", "AL", "GLUT", "EGL", "GLEW", "IDBStore", "SDL", "SDL_gfx", "allocateUTF8", "allocateUTF8OnStack", "print", "printErr" ]; + +unexportedSymbols.forEach(unexportedRuntimeSymbol); + +var calledRun; + +dependenciesFulfilled = function runCaller() { + // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) + if (!calledRun) run(); + if (!calledRun) dependenciesFulfilled = runCaller; +}; + +// try this again later, after new deps are fulfilled +function stackCheckInit() { + // This is normally called automatically during __wasm_call_ctors but need to + // get these values before even running any of the ctors so we call it redundantly + // here. + _emscripten_stack_init(); + // TODO(sbc): Move writeStackCookie to native to to avoid this. + writeStackCookie(); +} + +function run() { + if (runDependencies > 0) { + return; + } + stackCheckInit(); + preRun(); + // a preRun added a dependency, run will be called later + if (runDependencies > 0) { + return; + } + function doRun() { + // run may have just been called through dependencies being fulfilled just in this very frame, + // or while the async setStatus time below was happening + if (calledRun) return; + calledRun = true; + Module["calledRun"] = true; + if (ABORT) return; + initRuntime(); + Module["onRuntimeInitialized"]?.(); + assert(!Module["_main"], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]'); + postRun(); + } + if (Module["setStatus"]) { + Module["setStatus"]("Running..."); + setTimeout(function() { + setTimeout(function() { + Module["setStatus"](""); + }, 1); + doRun(); + }, 1); + } else { + doRun(); + } + checkStackCookie(); +} + +function checkUnflushedContent() { + // Compiler settings do not allow exiting the runtime, so flushing + // the streams is not possible. but in ASSERTIONS mode we check + // if there was something to flush, and if so tell the user they + // should request that the runtime be exitable. + // Normally we would not even include flush() at all, but in ASSERTIONS + // builds we do so just for this check, and here we see if there is any + // content to flush, that is, we check if there would have been + // something a non-ASSERTIONS build would have not seen. + // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0 + // mode (which has its own special function for this; otherwise, all + // the code is inside libc) + var oldOut = out; + var oldErr = err; + var has = false; + out = err = x => { + has = true; + }; + try { + // it doesn't matter if it fails + flush_NO_FILESYSTEM(); + } catch (e) {} + out = oldOut; + err = oldErr; + if (has) { + warnOnce("stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the Emscripten FAQ), or make sure to emit a newline when you printf etc."); + warnOnce("(this may also be due to not including full filesystem support - try building with -sFORCE_FILESYSTEM)"); + } +} + +if (Module["preInit"]) { + if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ]; + while (Module["preInit"].length > 0) { + Module["preInit"].pop()(); + } +} + +run(); diff --git a/cpp/bloom_filter.wasm b/cpp/bloom_filter.wasm new file mode 100755 index 0000000000000000000000000000000000000000..93451ae132fc306f80b9ab3ff928c83c2b5844a6 GIT binary patch literal 169893 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 { } const REPO_FILE_PATH = - '/Users/ofri/Documents/ovvio/goatdb-test/test/notes.jsonl'; + '/Users/ofri/Documents/ovvio/goatdb-test/test/notes1M.jsonl'; const DB_PATH = '/Users/ofri/Documents/ovvio/goatdb-test/'; @@ -154,7 +154,7 @@ export async function testsMain(): Promise { .numberOfCommits() .toLocaleString()}\n# Keys = ${repo.storage .numberOfKeys() - .toLocaleString()}`, + .toLocaleString()}` ); if (repo.numberOfCommits() === 0) { @@ -166,7 +166,7 @@ export async function testsMain(): Promise { console.log( `Populating repo ended. Took ${populatingTime / 1000} sec, avg ${ populatingTime / ITEM_COUNT - }ms/item`, + }ms/item` ); } else { // const editCount = await editDB(db, 0.5); @@ -193,7 +193,7 @@ export async function testsMain(): Promise { console.log( `Reading ${keys.length.toLocaleString()} items took ${ readTime / 1000 - } sec. Avg ${readTime / keys.length} ms / key`, + } sec. Avg ${readTime / keys.length} ms / key` ); // debugger; @@ -247,7 +247,7 @@ export async function testsMain(): Promise { console.log( `Query finished in ${ (performance.now() - queryStart) / queryIter - } ms.\n# Results = ${prevCount}`, + } ms.\n# Results = ${prevCount}` ); // Deno.exit(); From 9afc17ad2e8b46f07b08fb686af1e6d2107fe387 Mon Sep 17 00:00:00 2001 From: Amit Steiner Date: Tue, 31 Dec 2024 15:02:48 +0200 Subject: [PATCH 2/4] improve endianness validation strategy --- cpp/BloomFilter.cpp | 22 ++++++++++------------ cpp/BloomFilter.hpp | 12 ++---------- cpp/bloom_filter.ts | 33 +++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/cpp/BloomFilter.cpp b/cpp/BloomFilter.cpp index f8ab9a9..1af485e 100644 --- a/cpp/BloomFilter.cpp +++ b/cpp/BloomFilter.cpp @@ -16,6 +16,14 @@ #include "BloomFilter.hpp" #include "MurmurHash3.h" +// Endianness check at compile time +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#error "Big endian systems are not supported for compilation" +#elif defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) +#error "Big endian systems are not supported for compilation" +#endif + static std::mt19937 _gGen{static_cast( std::chrono::system_clock::now().time_since_epoch().count())}; static std::uniform_int_distribution<> _gDis(0, std::numeric_limits::max()); @@ -66,28 +74,18 @@ BloomFilter::~BloomFilter() const char *BloomFilter::getInternalPointer() const { -#if IS_BIG_ENDIAN - throw std::runtime_error("Big endian systems are not supported"); -#endif return reinterpret_cast(internal); } char *BloomFilter::getMutableInternalPointer() { -#if IS_BIG_ENDIAN - throw std::runtime_error("Big endian systems are not supported"); -#endif return reinterpret_cast(internal); } -// Zero-copy constructor BloomFilter::BloomFilter(const char *buff) { -#if IS_BIG_ENDIAN - throw std::runtime_error("Big endian systems are not supported"); -#endif - internal = - const_cast(reinterpret_cast(buff)); + internal = const_cast( + reinterpret_cast(buff)); } auto BloomFilter::hashString(const std::string &value, uint32_t seed) -> uint32_t diff --git a/cpp/BloomFilter.hpp b/cpp/BloomFilter.hpp index cad5e1d..3d65a99 100644 --- a/cpp/BloomFilter.hpp +++ b/cpp/BloomFilter.hpp @@ -5,19 +5,11 @@ #include #include -// TODO: check these preprocessor directives.. #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define IS_BIG_ENDIAN 1 -#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define IS_BIG_ENDIAN 0 +#error "Big endian systems are not supported for compilation" #elif defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || \ defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) -#define IS_BIG_ENDIAN 1 -#elif defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__THUMBEL__) || \ - defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) -#define IS_BIG_ENDIAN 0 -#else -#error "Unable to determine endianness, manual configuration required" +#error "Big endian systems are not supported for compilation" #endif class FalsePositiveRate diff --git a/cpp/bloom_filter.ts b/cpp/bloom_filter.ts index 353f510..284ea0e 100644 --- a/cpp/bloom_filter.ts +++ b/cpp/bloom_filter.ts @@ -7,12 +7,12 @@ interface BloomFilterModule extends EmscriptenModule { ident: string, returnType: string, argTypes: string[], - args: (number | string | boolean)[], + args: (number | string | boolean)[] ) => R; cwrap: ( ident: string, returnType: string, - argTypes: string[], + argTypes: string[] ) => (...args: A) => R; _malloc: (size: number) => number; _free: (ptr: number) => void; @@ -21,6 +21,12 @@ interface BloomFilterModule extends EmscriptenModule { UTF8ToString: (ptr: number) => string; } +function checkEndianness(): boolean { + const buffer = new ArrayBuffer(2); + new DataView(buffer).setInt16(0, 256, true); + return new Int16Array(buffer)[0] === 256; +} + declare global { let Module: BloomFilterModule; } @@ -28,6 +34,9 @@ declare global { let moduleLoadPromise: Promise; function initializeModule(): Promise { + if (!checkEndianness()) { + throw new Error('This application requires a little-endian system'); + } if (!moduleLoadPromise) { moduleLoadPromise = (async () => { const wasmUrl = @@ -35,14 +44,14 @@ function initializeModule(): Promise { ? new URL('/__system_assets/bloom_filter.wasm', self.location.href) : new URL( '../assets/__system_assets/bloom_filter.wasm', - import.meta.url, + import.meta.url ); const jsUrl = self.Deno === undefined ? new URL('/__system_assets/bloom_filter.js', self.location.href) : new URL( '../assets/__system_assets/bloom_filter.js', - import.meta.url, + import.meta.url ); const wasmResponse = await fetch(wasmUrl); @@ -75,7 +84,7 @@ export class BloomFilter { private static create_bloom_filter: ( size: number, fpr: number, - _ptr: number, + _ptr: number ) => number; private static add_to_filter: (ptr: number, str: string) => void; private static check_in_filter: (ptr: number, str: string) => number; @@ -90,6 +99,10 @@ export class BloomFilter { private static get_bloom_filter_number_of_hashes: (data: number) => number; static async initNativeFunctions(): Promise { + if (!checkEndianness()) { + throw new Error('This application requires a little-endian system'); + } + if (!this.create_bloom_filter) { await initializeModule(); this.create_bloom_filter = Module.cwrap('createBloomFilter', 'number', [ @@ -100,7 +113,7 @@ export class BloomFilter { this.create_bloom_filter_from_data = Module.cwrap( 'createBloomFilterFromData', 'number', - ['number'], + ['number'] ); this.add_to_filter = Module.cwrap('addToFilter', 'void', [ 'number', @@ -116,17 +129,17 @@ export class BloomFilter { this.get_bloom_filter_pointer = Module.cwrap( 'getBloomFilterPointer', 'number', - ['number'], + ['number'] ); this.get_bloom_filter_size = Module.cwrap( 'getBloomFilterSize', 'number', - ['number'], + ['number'] ); this.get_bloom_filter_number_of_hashes = Module.cwrap( 'getBloomFilterNumberOfHashes', 'number', - ['number'], + ['number'] ); this._malloc = Module._malloc; this._free = Module._free; @@ -199,7 +212,7 @@ export class BloomFilter { if (filterPtr === 0) { throw new Error( - `Failed to create BloomFilter from data with pointer ${ptr}`, + `Failed to create BloomFilter from data with pointer ${ptr}` ); } From c91682baa4c6b8db655770f61b2e19e4161db16d Mon Sep 17 00:00:00 2001 From: Amit Steiner Date: Wed, 1 Jan 2025 15:42:56 +0200 Subject: [PATCH 3/4] changed error wording --- cpp/BloomFilter.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cpp/BloomFilter.cpp b/cpp/BloomFilter.cpp index 1af485e..86f3edb 100644 --- a/cpp/BloomFilter.cpp +++ b/cpp/BloomFilter.cpp @@ -16,14 +16,6 @@ #include "BloomFilter.hpp" #include "MurmurHash3.h" -// Endianness check at compile time -#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#error "Big endian systems are not supported for compilation" -#elif defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || \ - defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) -#error "Big endian systems are not supported for compilation" -#endif - static std::mt19937 _gGen{static_cast( std::chrono::system_clock::now().time_since_epoch().count())}; static std::uniform_int_distribution<> _gDis(0, std::numeric_limits::max()); From cf5dd6b38f4be0c4e6ad2b566557115eeae211c2 Mon Sep 17 00:00:00 2001 From: Amit Steiner Date: Wed, 1 Jan 2025 15:44:40 +0200 Subject: [PATCH 4/4] changed error wording --- cpp/BloomFilter.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/BloomFilter.hpp b/cpp/BloomFilter.hpp index 3d65a99..3640269 100644 --- a/cpp/BloomFilter.hpp +++ b/cpp/BloomFilter.hpp @@ -6,10 +6,10 @@ #include #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#error "Big endian systems are not supported for compilation" +#error "TODO: Big Endian support" #elif defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || \ defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) -#error "Big endian systems are not supported for compilation" +#error "TODO: Big Endian support" #endif class FalsePositiveRate