From 263403fa16066adeebd9cb822122e259c8e925ce Mon Sep 17 00:00:00 2001 From: Stipe Varnica Date: Mon, 24 Jun 2024 13:07:34 +0200 Subject: [PATCH] Final prototype, added README.md --- .vscode/settings.json | 51 ++ C++/cmd.txt | 2 +- C++/test.cpp | 26 +- C++/test.js | 1878 +++++++++++++++++++++++++++++++++-------- C++/test.wasm | Bin 991 -> 30865 bytes README.md | 11 + index.html | 123 +-- index.js | 17 +- 8 files changed, 1626 insertions(+), 482 deletions(-) create mode 100644 .vscode/settings.json mode change 100644 => 100755 C++/test.wasm create mode 100644 README.md diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9d58277 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,51 @@ +{ + "liveServer.settings.port": 5501, + "files.associations": { + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/C++/cmd.txt b/C++/cmd.txt index d126731..0b62af5 100644 --- a/C++/cmd.txt +++ b/C++/cmd.txt @@ -1 +1 @@ -emcc -o test.js test.cpp -s NO_EXIT_RUNTIME=1 -s "EXPORTED_RUNTIME_METHODS=['ccall']" +emcc -lembind -o test.js test.cpp -s NO_EXIT_RUNTIME=1 -s "EXPORTED_RUNTIME_METHODS=['ccall']" diff --git a/C++/test.cpp b/C++/test.cpp index 0e96ae2..f516ef5 100644 --- a/C++/test.cpp +++ b/C++/test.cpp @@ -1,18 +1,20 @@ #include -#include +#include +#include +using namespace emscripten; -extern "C" { - EMSCRIPTEN_KEEPALIVE - int myFunction(int number) { - return number * number; - } +std::string myFunction(std::string word) +{ + std::string test = " testing"; + return word + test; +}; - EMSCRIPTEN_KEEPALIVE - int add(int a, int b) { - return a + b; - } -} +EMSCRIPTEN_BINDINGS(my_module) +{ + function("myFunction", &myFunction); +}; -int main() { +int main() +{ return 0; } \ No newline at end of file diff --git a/C++/test.js b/C++/test.js index e45668a..a3f9c3e 100644 --- a/C++/test.js +++ b/C++/test.js @@ -2,7 +2,7 @@ // 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(Module) { ..generated code.. } +// 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). @@ -14,6 +14,29 @@ // 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). + +// Attempt to auto-detect the environment +var ENVIRONMENT_IS_WEB = typeof window == 'object'; +var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function'; +// N.b. Electron.js environment is simultaneously a NODE-environment, but +// also a web environment. +var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string'; +var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; + +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)'); +} + +if (ENVIRONMENT_IS_NODE) { + // `require()` is no-op in an ESM module, use `createRequire()` to construct + // the require()` function. This is only necessary for multi-environment + // builds, `-sENVIRONMENT=node` emits a static import declaration instead. + // TODO: Swap all `require()`'s with `import()`'s? + +} + // --pre-jses are emitted after the Module integration code, so that they can // refer to Module (if they choose; they can also define Module) @@ -31,21 +54,6 @@ var quit_ = (status, toThrow) => { throw toThrow; }; -// Determine the runtime environment we are in. You can customize this by -// setting the ENVIRONMENT setting at compile time (see settings.js). - -// Attempt to auto-detect the environment -var ENVIRONMENT_IS_WEB = typeof window == 'object'; -var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function'; -// N.b. Electron.js environment is simultaneously a NODE-environment, but -// also a web environment. -var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string'; -var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; - -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)'); -} - // `/` should be present at the end if `scriptDirectory` is not empty var scriptDirectory = ''; function locateFile(path) { @@ -71,10 +79,6 @@ if (ENVIRONMENT_IS_NODE) { throw new Error('This emscripten-generated code requires node v16.0.0 (detected v' + nodeVersion + ')'); } - // `require()` is no-op in an ESM module, use `createRequire()` to construct - // the require()` function. This is only necessary for multi-environment - // builds, `-sENVIRONMENT=node` emits a static import declaration instead. - // TODO: Swap all `require()`'s with `import()`'s? // These modules will usually be used on Node.js. Load them eagerly to avoid // the complexity of lazy-loading. var fs = require('fs'); @@ -139,70 +143,6 @@ 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?)'); - if (typeof read != 'undefined') { - read_ = read; - } - - readBinary = (f) => { - if (typeof readbuffer == 'function') { - return new Uint8Array(readbuffer(f)); - } - let data = read(f, 'binary'); - assert(typeof data == 'object'); - return data; - }; - - readAsync = (f, onload, onerror) => { - setTimeout(() => onload(readBinary(f))); - }; - - if (typeof clearTimeout == 'undefined') { - globalThis.clearTimeout = (id) => {}; - } - - if (typeof setTimeout == 'undefined') { - // spidermonkey lacks setTimeout but we use it above in readAsync. - globalThis.setTimeout = (f) => (typeof f == 'function') ? f() : abort(); - } - - if (typeof scriptArgs != 'undefined') { - arguments_ = scriptArgs; - } else if (typeof arguments != 'undefined') { - arguments_ = arguments; - } - - if (typeof quit == 'function') { - quit_ = (status, toThrow) => { - // Unlike node which has process.exitCode, d8 has no such mechanism. So we - // have no way to set the exit code and then let the program exit with - // that code when it naturally stops running (say, when all setTimeouts - // have completed). For that reason, we must call `quit` - the only way to - // set the exit code - but quit also halts immediately. To increase - // consistency with node (and the web) we schedule the actual quit call - // using a setTimeout to give the current stack and any exception handlers - // a chance to run. This enables features such as addOnPostRun (which - // expected to be able to run code after main returns). - setTimeout(() => { - if (!(toThrow instanceof ExitStatus)) { - let toLog = toThrow; - if (toThrow && typeof toThrow == 'object' && toThrow.stack) { - toLog = [toThrow, toThrow.stack]; - } - err(`exiting due to exception: ${toLog}`); - } - quit(status); - }); - throw toThrow; - }; - } - - if (typeof print != 'undefined') { - // Prefer to use print/printErr where they exist, as they usually work better. - if (typeof console == 'undefined') console = /** @type{!Console} */({}); - console.log = /** @type{!function(this:Console, ...*): undefined} */ (print); - console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr != 'undefined' ? printErr : print); - } - } else // Note that this includes Node.js workers when relevant (pthreads is enabled). @@ -228,8 +168,6 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { 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?)'); - // Differentiate the Web Worker from the Node Worker case, as reading must - // be done differently. { // include: web_or_worker_shell_read.js read_ = (url) => { @@ -370,13 +308,6 @@ function assert(condition, text) { // We used to include malloc/free by default in the past. Show a helpful error in // builds with assertions. -function _malloc() { - abort('malloc() called but not included in the build - add `_malloc` to EXPORTED_FUNCTIONS'); -} -function _free() { - // Show a helpful error since we used to include free by default in the past. - abort('free() called but not included in the build - add `_free` to EXPORTED_FUNCTIONS'); -} // Memory management @@ -697,11 +628,13 @@ var isDataURI = (filename) => filename.startsWith(dataURIPrefix); */ var isFileURI = (filename) => filename.startsWith('file://'); // end include: URIUtils.js -function createExportWrapper(name) { +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); }; } @@ -804,14 +737,18 @@ function instantiateAsync(binary, binaryFile, imports, callback) { return instantiateArrayBuffer(binaryFile, imports, callback); } -// Create the wasm instance. -// Receives the wasm imports, returns the exports. -function createWasm() { +function getWasmImports() { // prepare imports - var info = { + 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 @@ -826,6 +763,10 @@ function createWasm() { 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'); @@ -856,7 +797,6 @@ function createWasm() { // Also pthreads and wasm workers initialize the wasm instance through this // path. if (Module['instantiateWasm']) { - try { return Module['instantiateWasm'](info, receiveInstance); } catch(e) { @@ -907,7 +847,7 @@ function isExportedByForceFilesystem(name) { } function missingGlobal(sym, msg) { - if (typeof globalThis !== 'undefined') { + if (typeof globalThis != 'undefined') { Object.defineProperty(globalThis, sym, { configurable: true, get() { @@ -922,7 +862,7 @@ 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)) { + if (typeof globalThis != 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) { Object.defineProperty(globalThis, sym, { configurable: true, get() { @@ -1040,6 +980,10 @@ function dbg(...args) { } } + var stackRestore = (val) => __emscripten_stack_restore(val); + + var stackSave = () => _emscripten_stack_get_current(); + var warnOnce = (text) => { warnOnce.shown ||= {}; if (!warnOnce.shown[text]) { @@ -1049,144 +993,6 @@ function dbg(...args) { } }; - - var runtimeKeepaliveCounter = 0; - var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0; - var _proc_exit = (code) => { - EXITSTATUS = code; - if (!keepRuntimeAlive()) { - Module['onExit']?.(code); - ABORT = true; - } - quit_(code, new ExitStatus(code)); - }; - - /** @param {boolean|number=} implicit */ - var exitJS = (status, implicit) => { - EXITSTATUS = status; - - checkUnflushedContent(); - - // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down - if (keepRuntimeAlive() && !implicit) { - var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`; - err(msg); - } - - _proc_exit(status); - }; - - var handleException = (e) => { - // Certain exception types we do not treat as errors since they are used for - // internal control flow. - // 1. ExitStatus, which is thrown by exit() - // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others - // that wish to return to JS event loop. - if (e instanceof ExitStatus || e == 'unwind') { - return EXITSTATUS; - } - checkStackCookie(); - if (e instanceof WebAssembly.RuntimeError) { - if (_emscripten_stack_get_current() <= 0) { - err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)'); - } - } - quit_(1, e); - }; - - 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); - }; - - 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 <= 0x7F) { - len++; - } else if (c <= 0x7FF) { - len += 2; - } else if (c >= 0xD800 && c <= 0xDFFF) { - len += 4; ++i; - } else { - len += 3; - } - } - return len; - }; - - var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { - 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 >= 0xD800 && u <= 0xDFFF) { - var u1 = str.charCodeAt(++i); - u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); - } - if (u <= 0x7F) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u; - } else if (u <= 0x7FF) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 0xC0 | (u >> 6); - heap[outIdx++] = 0x80 | (u & 63); - } else if (u <= 0xFFFF) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 0xE0 | (u >> 12); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } else { - if (outIdx + 3 >= endIdx) break; - if (u > 0x10FFFF) 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++] = 0xF0 | (u >> 18); - heap[outIdx++] = 0x80 | ((u >> 12) & 63); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } - } - // Null-terminate the pointer to the buffer. - heap[outIdx] = 0; - return outIdx - startIdx; - }; - 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 stringToUTF8OnStack = (str) => { - var size = lengthBytesUTF8(str) + 1; - var ret = stackAlloc(size); - stringToUTF8(str, ret, size); - return ret; - }; - - - - var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined; /** @@ -1260,90 +1066,1393 @@ function dbg(...args) { assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`); return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; }; + var ___assert_fail = (condition, filename, line, func) => { + abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']); + }; + + class ExceptionInfo { + // excPtr - Thrown object pointer to wrap. Metadata pointer is calculated from it. + constructor(excPtr) { + this.excPtr = excPtr; + this.ptr = excPtr - 24; + } - /** - * @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; - } - }; + set_type(type) { + HEAPU32[(((this.ptr)+(4))>>2)] = type; + } - function convertReturnValue(ret) { - if (returnType === 'string') { - - return UTF8ToString(ret); - } - if (returnType === 'boolean') return Boolean(ret); - return ret; + get_type() { + return HEAPU32[(((this.ptr)+(4))>>2)]; } - 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]; - } - } + set_destructor(destructor) { + HEAPU32[(((this.ptr)+(8))>>2)] = destructor; + } + + get_destructor() { + return HEAPU32[(((this.ptr)+(8))>>2)]; } - var ret = func(...cArgs); - function onDone(ret) { - if (stack !== 0) stackRestore(stack); - return convertReturnValue(ret); + + set_caught(caught) { + caught = caught ? 1 : 0; + HEAP8[(this.ptr)+(12)] = caught; } - ret = onDone(ret); - return ret; - }; -function checkIncomingModuleAPI() { - ignoredModuleProp('fetchSettings'); -} -var wasmImports = { + get_caught() { + return HEAP8[(this.ptr)+(12)] != 0; + } -}; -var wasmExports = createWasm(); -var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors'); -var _myFunction = Module['_myFunction'] = createExportWrapper('myFunction'); -var _add = Module['_add'] = createExportWrapper('add'); -var _main = Module['_main'] = createExportWrapper('main'); -var _fflush = createExportWrapper('fflush'); -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 stackSave = createExportWrapper('stackSave'); -var stackRestore = createExportWrapper('stackRestore'); -var stackAlloc = createExportWrapper('stackAlloc'); -var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])(); + set_rethrown(rethrown) { + rethrown = rethrown ? 1 : 0; + HEAP8[(this.ptr)+(13)] = rethrown; + } + + get_rethrown() { + return HEAP8[(this.ptr)+(13)] != 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)] = adjustedPtr; + } + + get_adjusted_ptr() { + return HEAPU32[(((this.ptr)+(16))>>2)]; + } + + // 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)]; + } + var adjusted = this.get_adjusted_ptr(); + if (adjusted !== 0) return adjusted; + return this.excPtr; + } + } + + var exceptionLast = 0; + + var uncaughtExceptionCount = 0; + var ___cxa_throw = (ptr, type, destructor) => { + var info = new ExceptionInfo(ptr); + // Initialize ExceptionInfo content after it was allocated in __cxa_allocate_exception. + info.init(type, destructor); + exceptionLast = ptr; + uncaughtExceptionCount++; + assert(false, 'Exception thrown, but exception catching is not enabled. Compile with -sNO_DISABLE_EXCEPTION_CATCHING or -sEXCEPTION_CATCHING_ALLOWED=[..] to catch.'); + }; + + var __embind_register_bigint = (primitiveType, name, size, minRange, maxRange) => {}; + + var embind_init_charCodes = () => { + var codes = new Array(256); + for (var i = 0; i < 256; ++i) { + codes[i] = String.fromCharCode(i); + } + embind_charCodes = codes; + }; + var embind_charCodes; + var readLatin1String = (ptr) => { + var ret = ""; + var c = ptr; + while (HEAPU8[c]) { + ret += embind_charCodes[HEAPU8[c++]]; + } + return ret; + }; + + var awaitingDependencies = { + }; + + var registeredTypes = { + }; + + var typeDependencies = { + }; + + var BindingError; + var throwBindingError = (message) => { throw new BindingError(message); }; + + + + + var InternalError; + var throwInternalError = (message) => { throw new InternalError(message); }; + var whenDependentTypesAreResolved = (myTypes, dependentTypes, getTypeConverters) => { + myTypes.forEach(function(type) { + typeDependencies[type] = dependentTypes; + }); + + function onComplete(typeConverters) { + var myTypeConverters = getTypeConverters(typeConverters); + if (myTypeConverters.length !== myTypes.length) { + throwInternalError('Mismatched type converter count'); + } + for (var i = 0; i < myTypes.length; ++i) { + registerType(myTypes[i], myTypeConverters[i]); + } + } + + var typeConverters = new Array(dependentTypes.length); + var unregisteredTypes = []; + var registered = 0; + dependentTypes.forEach((dt, i) => { + if (registeredTypes.hasOwnProperty(dt)) { + typeConverters[i] = registeredTypes[dt]; + } else { + unregisteredTypes.push(dt); + if (!awaitingDependencies.hasOwnProperty(dt)) { + awaitingDependencies[dt] = []; + } + awaitingDependencies[dt].push(() => { + typeConverters[i] = registeredTypes[dt]; + ++registered; + if (registered === unregisteredTypes.length) { + onComplete(typeConverters); + } + }); + } + }); + if (0 === unregisteredTypes.length) { + onComplete(typeConverters); + } + }; + /** @param {Object=} options */ + function sharedRegisterType(rawType, registeredInstance, options = {}) { + var name = registeredInstance.name; + if (!rawType) { + throwBindingError(`type "${name}" must have a positive integer typeid pointer`); + } + if (registeredTypes.hasOwnProperty(rawType)) { + if (options.ignoreDuplicateRegistrations) { + return; + } else { + throwBindingError(`Cannot register type '${name}' twice`); + } + } + + registeredTypes[rawType] = registeredInstance; + delete typeDependencies[rawType]; + + if (awaitingDependencies.hasOwnProperty(rawType)) { + var callbacks = awaitingDependencies[rawType]; + delete awaitingDependencies[rawType]; + callbacks.forEach((cb) => cb()); + } + } + /** @param {Object=} options */ + function registerType(rawType, registeredInstance, options = {}) { + if (!('argPackAdvance' in registeredInstance)) { + throw new TypeError('registerType registeredInstance requires argPackAdvance'); + } + return sharedRegisterType(rawType, registeredInstance, options); + } + + var GenericWireTypeSize = 8; + /** @suppress {globalThis} */ + var __embind_register_bool = (rawType, name, trueValue, falseValue) => { + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': function(wt) { + // ambiguous emscripten ABI: sometimes return values are + // true or false, and sometimes integers (0 or 1) + return !!wt; + }, + 'toWireType': function(destructors, o) { + return o ? trueValue : falseValue; + }, + 'argPackAdvance': GenericWireTypeSize, + 'readValueFromPointer': function(pointer) { + return this['fromWireType'](HEAPU8[pointer]); + }, + destructorFunction: null, // This type does not need a destructor + }); + }; + + + var emval_freelist = []; + + var emval_handles = []; + var __emval_decref = (handle) => { + if (handle > 9 && 0 === --emval_handles[handle + 1]) { + assert(emval_handles[handle] !== undefined, `Decref for unallocated handle.`); + emval_handles[handle] = undefined; + emval_freelist.push(handle); + } + }; + + + + + + var count_emval_handles = () => { + return emval_handles.length / 2 - 5 - emval_freelist.length; + }; + + var init_emval = () => { + // reserve 0 and some special values. These never get de-allocated. + emval_handles.push( + 0, 1, + undefined, 1, + null, 1, + true, 1, + false, 1, + ); + assert(emval_handles.length === 5 * 2); + Module['count_emval_handles'] = count_emval_handles; + }; + var Emval = { + toValue:(handle) => { + if (!handle) { + throwBindingError('Cannot use deleted val. handle = ' + handle); + } + // handle 2 is supposed to be `undefined`. + assert(handle === 2 || emval_handles[handle] !== undefined && handle % 2 === 0, `invalid handle: ${handle}`); + return emval_handles[handle]; + }, + toHandle:(value) => { + switch (value) { + case undefined: return 2; + case null: return 4; + case true: return 6; + case false: return 8; + default:{ + const handle = emval_freelist.pop() || emval_handles.length; + emval_handles[handle] = value; + emval_handles[handle + 1] = 1; + return handle; + } + } + }, + }; + + /** @suppress {globalThis} */ + function readPointer(pointer) { + return this['fromWireType'](HEAPU32[((pointer)>>2)]); + } + + var EmValType = { + name: 'emscripten::val', + 'fromWireType': (handle) => { + var rv = Emval.toValue(handle); + __emval_decref(handle); + return rv; + }, + 'toWireType': (destructors, value) => Emval.toHandle(value), + 'argPackAdvance': GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction: null, // This type does not need a destructor + + // TODO: do we need a deleteObject here? write a test where + // emval is passed into JS via an interface + }; + var __embind_register_emval = (rawType) => registerType(rawType, EmValType); + + var embindRepr = (v) => { + if (v === null) { + return 'null'; + } + var t = typeof v; + if (t === 'object' || t === 'array' || t === 'function') { + return v.toString(); + } else { + return '' + v; + } + }; + + var floatReadValueFromPointer = (name, width) => { + switch (width) { + case 4: return function(pointer) { + return this['fromWireType'](HEAPF32[((pointer)>>2)]); + }; + case 8: return function(pointer) { + return this['fromWireType'](HEAPF64[((pointer)>>3)]); + }; + default: + throw new TypeError(`invalid float width (${width}): ${name}`); + } + }; + + + var __embind_register_float = (rawType, name, size) => { + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': (value) => value, + 'toWireType': (destructors, value) => { + if (typeof value != "number" && typeof value != "boolean") { + throw new TypeError(`Cannot convert ${embindRepr(value)} to ${this.name}`); + } + // The VM will perform JS to Wasm value conversion, according to the spec: + // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue + return value; + }, + 'argPackAdvance': GenericWireTypeSize, + 'readValueFromPointer': floatReadValueFromPointer(name, size), + destructorFunction: null, // This type does not need a destructor + }); + }; + + var createNamedFunction = (name, body) => Object.defineProperty(body, 'name', { + value: name + }); + + var runDestructors = (destructors) => { + while (destructors.length) { + var ptr = destructors.pop(); + var del = destructors.pop(); + del(ptr); + } + }; + + + function usesDestructorStack(argTypes) { + // Skip return value at index 0 - it's not deleted here. + for (var i = 1; i < argTypes.length; ++i) { + // The type does not define a destructor function - must use dynamic stack + if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { + return true; + } + } + return false; + } + + function newFunc(constructor, argumentList) { + if (!(constructor instanceof Function)) { + throw new TypeError(`new_ called with constructor type ${typeof(constructor)} which is not a function`); + } + /* + * Previously, the following line was just: + * function dummy() {}; + * Unfortunately, Chrome was preserving 'dummy' as the object's name, even + * though at creation, the 'dummy' has the correct constructor name. Thus, + * objects created with IMVU.new would show up in the debugger as 'dummy', + * which isn't very helpful. Using IMVU.createNamedFunction addresses the + * issue. Doubly-unfortunately, there's no way to write a test for this + * behavior. -NRD 2013.02.22 + */ + var dummy = createNamedFunction(constructor.name || 'unknownFunctionName', function(){}); + dummy.prototype = constructor.prototype; + var obj = new dummy; + + var r = constructor.apply(obj, argumentList); + return (r instanceof Object) ? r : obj; + } + + function createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync) { + var needsDestructorStack = usesDestructorStack(argTypes); + var argCount = argTypes.length; + var argsList = ""; + var argsListWired = ""; + for (var i = 0; i < argCount - 2; ++i) { + argsList += (i!==0?", ":"")+"arg"+i; + argsListWired += (i!==0?", ":"")+"arg"+i+"Wired"; + } + + var invokerFnBody = ` + return function (${argsList}) { + if (arguments.length !== ${argCount - 2}) { + throwBindingError('function ' + humanName + ' called with ' + arguments.length + ' arguments, expected ${argCount - 2}'); + }`; + + if (needsDestructorStack) { + invokerFnBody += "var destructors = [];\n"; + } + + var dtorStack = needsDestructorStack ? "destructors" : "null"; + var args1 = ["humanName", "throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"]; + + if (isClassMethodFunc) { + invokerFnBody += "var thisWired = classParam['toWireType']("+dtorStack+", this);\n"; + } + + for (var i = 0; i < argCount - 2; ++i) { + invokerFnBody += "var arg"+i+"Wired = argType"+i+"['toWireType']("+dtorStack+", arg"+i+");\n"; + args1.push("argType"+i); + } + + if (isClassMethodFunc) { + argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired; + } + + invokerFnBody += + (returns || isAsync ? "var rv = ":"") + "invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n"; + + var returnVal = returns ? "rv" : ""; + + if (needsDestructorStack) { + invokerFnBody += "runDestructors(destructors);\n"; + } else { + for (var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method. + var paramName = (i === 1 ? "thisWired" : ("arg"+(i - 2)+"Wired")); + if (argTypes[i].destructorFunction !== null) { + invokerFnBody += `${paramName}_dtor(${paramName});\n`; + args1.push(`${paramName}_dtor`); + } + } + } + + if (returns) { + invokerFnBody += "var ret = retType['fromWireType'](rv);\n" + + "return ret;\n"; + } else { + } + + invokerFnBody += "}\n"; + + invokerFnBody = `if (arguments.length !== ${args1.length}){ throw new Error(humanName + "Expected ${args1.length} closure arguments " + arguments.length + " given."); }\n${invokerFnBody}`; + return [args1, invokerFnBody]; + } + function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc, /** boolean= */ isAsync) { + // humanName: a human-readable string name for the function to be generated. + // argTypes: An array that contains the embind type objects for all types in the function signature. + // argTypes[0] is the type object for the function return value. + // argTypes[1] is the type object for function this object/class type, or null if not crafting an invoker for a class method. + // argTypes[2...] are the actual function parameters. + // classType: The embind type object for the class to be bound, or null if this is not a method of a class. + // cppInvokerFunc: JS Function object to the C++-side function that interops into C++ code. + // cppTargetFunc: Function pointer (an integer to FUNCTION_TABLE) to the target C++ function the cppInvokerFunc will end up calling. + // isAsync: Optional. If true, returns an async function. Async bindings are only supported with JSPI. + var argCount = argTypes.length; + + if (argCount < 2) { + throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!"); + } + + assert(!isAsync, 'Async bindings are only supported with JSPI.'); + + var isClassMethodFunc = (argTypes[1] !== null && classType !== null); + + // Free functions with signature "void function()" do not need an invoker that marshalls between wire types. + // TODO: This omits argument count check - enable only at -O3 or similar. + // if (ENABLE_UNSAFE_OPTS && argCount == 2 && argTypes[0].name == "void" && !isClassMethodFunc) { + // return FUNCTION_TABLE[fn]; + // } + + // Determine if we need to use a dynamic stack to store the destructors for the function parameters. + // TODO: Remove this completely once all function invokers are being dynamically generated. + var needsDestructorStack = usesDestructorStack(argTypes); + + var returns = (argTypes[0].name !== "void"); + + // Builld the arguments that will be passed into the closure around the invoker + // function. + var closureArgs = [humanName, throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; + for (var i = 0; i < argCount - 2; ++i) { + closureArgs.push(argTypes[i+2]); + } + if (!needsDestructorStack) { + for (var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method. + if (argTypes[i].destructorFunction !== null) { + closureArgs.push(argTypes[i].destructorFunction); + } + } + } + + let [args, invokerFnBody] = createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync); + args.push(invokerFnBody); + var invokerFn = newFunc(Function, args)(...closureArgs); + return createNamedFunction(humanName, invokerFn); + } + + var ensureOverloadTable = (proto, methodName, humanName) => { + if (undefined === proto[methodName].overloadTable) { + var prevFunc = proto[methodName]; + // Inject an overload resolver function that routes to the appropriate overload based on the number of arguments. + proto[methodName] = function(...args) { + // TODO This check can be removed in -O3 level "unsafe" optimizations. + if (!proto[methodName].overloadTable.hasOwnProperty(args.length)) { + throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`); + } + return proto[methodName].overloadTable[args.length].apply(this, args); + }; + // Move the previous function into the overload table. + proto[methodName].overloadTable = []; + proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; + } + }; + + /** @param {number=} numArguments */ + var exposePublicSymbol = (name, value, numArguments) => { + if (Module.hasOwnProperty(name)) { + if (undefined === numArguments || (undefined !== Module[name].overloadTable && undefined !== Module[name].overloadTable[numArguments])) { + throwBindingError(`Cannot register public name '${name}' twice`); + } + + // We are exposing a function with the same name as an existing function. Create an overload table and a function selector + // that routes between the two. + ensureOverloadTable(Module, name, name); + if (Module.hasOwnProperty(numArguments)) { + throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`); + } + // Add the new function into the overload table. + Module[name].overloadTable[numArguments] = value; + } + else { + Module[name] = value; + if (undefined !== numArguments) { + Module[name].numArguments = numArguments; + } + } + }; + + var heap32VectorToArray = (count, firstElement) => { + var array = []; + for (var i = 0; i < count; i++) { + // TODO(https://github.com/emscripten-core/emscripten/issues/17310): + // Find a way to hoist the `>> 2` or `>> 3` out of this loop. + array.push(HEAPU32[(((firstElement)+(i * 4))>>2)]); + } + return array; + }; + + + /** @param {number=} numArguments */ + var replacePublicSymbol = (name, value, numArguments) => { + if (!Module.hasOwnProperty(name)) { + throwInternalError('Replacing nonexistent public symbol'); + } + // If there's an overload table for this symbol, replace the symbol in the overload table instead. + if (undefined !== Module[name].overloadTable && undefined !== numArguments) { + Module[name].overloadTable[numArguments] = value; + } + else { + Module[name] = value; + Module[name].argCount = numArguments; + } + }; + + + + var dynCallLegacy = (sig, ptr, args) => { + sig = sig.replace(/p/g, 'i') + assert(('dynCall_' + sig) in Module, `bad function pointer type - dynCall function not found for sig '${sig}'`); + if (args?.length) { + // j (64-bit integer) must be passed in as two numbers [low 32, high 32]. + assert(args.length === sig.substring(1).replace(/j/g, '--').length); + } else { + assert(sig.length == 1); + } + var f = Module['dynCall_' + sig]; + return f(ptr, ...args); + }; + + var wasmTableMirror = []; + + 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 dynCall = (sig, ptr, args = []) => { + // Without WASM_BIGINT support we cannot directly call function with i64 as + // part of their signature, so we rely on the dynCall functions generated by + // wasm-emscripten-finalize + if (sig.includes('j')) { + return dynCallLegacy(sig, ptr, args); + } + assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`); + var rtn = getWasmTableEntry(ptr)(...args); + return rtn; + }; + var getDynCaller = (sig, ptr) => { + assert(sig.includes('j') || sig.includes('p'), 'getDynCaller should only be called with i64 sigs') + return (...args) => dynCall(sig, ptr, args); + }; + + + var embind__requireFunction = (signature, rawFunction) => { + signature = readLatin1String(signature); + + function makeDynCaller() { + if (signature.includes('j')) { + return getDynCaller(signature, rawFunction); + } + return getWasmTableEntry(rawFunction); + } + + var fp = makeDynCaller(); + if (typeof fp != "function") { + throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`); + } + return fp; + }; + + + + var extendError = (baseErrorType, errorName) => { + var errorClass = createNamedFunction(errorName, function(message) { + this.name = errorName; + this.message = message; + + var stack = (new Error(message)).stack; + if (stack !== undefined) { + this.stack = this.toString() + '\n' + + stack.replace(/^Error(:[^\n]*)?\n/, ''); + } + }); + errorClass.prototype = Object.create(baseErrorType.prototype); + errorClass.prototype.constructor = errorClass; + errorClass.prototype.toString = function() { + if (this.message === undefined) { + return this.name; + } else { + return `${this.name}: ${this.message}`; + } + }; + + return errorClass; + }; + var UnboundTypeError; + + + + var getTypeName = (type) => { + var ptr = ___getTypeName(type); + var rv = readLatin1String(ptr); + _free(ptr); + return rv; + }; + var throwUnboundTypeError = (message, types) => { + var unboundTypes = []; + var seen = {}; + function visit(type) { + if (seen[type]) { + return; + } + if (registeredTypes[type]) { + return; + } + if (typeDependencies[type]) { + typeDependencies[type].forEach(visit); + return; + } + unboundTypes.push(type); + seen[type] = true; + } + types.forEach(visit); + + throw new UnboundTypeError(`${message}: ` + unboundTypes.map(getTypeName).join([', '])); + }; + + + var getFunctionName = (signature) => { + signature = signature.trim(); + const argsIndex = signature.indexOf("("); + if (argsIndex !== -1) { + assert(signature[signature.length - 1] == ")", "Parentheses for argument names should match."); + return signature.substr(0, argsIndex); + } else { + return signature; + } + }; + var __embind_register_function = (name, argCount, rawArgTypesAddr, signature, rawInvoker, fn, isAsync) => { + var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + name = readLatin1String(name); + name = getFunctionName(name); + + rawInvoker = embind__requireFunction(signature, rawInvoker); + + exposePublicSymbol(name, function() { + throwUnboundTypeError(`Cannot call ${name} due to unbound types`, argTypes); + }, argCount - 1); + + whenDependentTypesAreResolved([], argTypes, (argTypes) => { + var invokerArgsArray = [argTypes[0] /* return value */, null /* no class 'this'*/].concat(argTypes.slice(1) /* actual params */); + replacePublicSymbol(name, craftInvokerFunction(name, invokerArgsArray, null /* no class 'this'*/, rawInvoker, fn, isAsync), argCount - 1); + return []; + }); + }; + + + var integerReadValueFromPointer = (name, width, signed) => { + // integers are quite common, so generate very specialized functions + switch (width) { + case 1: return signed ? + (pointer) => HEAP8[pointer] : + (pointer) => HEAPU8[pointer]; + case 2: return signed ? + (pointer) => HEAP16[((pointer)>>1)] : + (pointer) => HEAPU16[((pointer)>>1)] + case 4: return signed ? + (pointer) => HEAP32[((pointer)>>2)] : + (pointer) => HEAPU32[((pointer)>>2)] + default: + throw new TypeError(`invalid integer width (${width}): ${name}`); + } + }; + + + /** @suppress {globalThis} */ + var __embind_register_integer = (primitiveType, name, size, minRange, maxRange) => { + name = readLatin1String(name); + // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come + // out as 'i32 -1'. Always treat those as max u32. + if (maxRange === -1) { + maxRange = 4294967295; + } + + var fromWireType = (value) => value; + + if (minRange === 0) { + var bitshift = 32 - 8*size; + fromWireType = (value) => (value << bitshift) >>> bitshift; + } + + var isUnsignedType = (name.includes('unsigned')); + var checkAssertions = (value, toTypeName) => { + if (typeof value != "number" && typeof value != "boolean") { + throw new TypeError(`Cannot convert "${embindRepr(value)}" to ${toTypeName}`); + } + if (value < minRange || value > maxRange) { + throw new TypeError(`Passing a number "${embindRepr(value)}" from JS side to C/C++ side to an argument of type "${name}", which is outside the valid range [${minRange}, ${maxRange}]!`); + } + } + var toWireType; + if (isUnsignedType) { + toWireType = function(destructors, value) { + checkAssertions(value, this.name); + return value >>> 0; + } + } else { + toWireType = function(destructors, value) { + checkAssertions(value, this.name); + // The VM will perform JS to Wasm value conversion, according to the spec: + // https://www.w3.org/TR/wasm-js-api-1/#towebassemblyvalue + return value; + } + } + registerType(primitiveType, { + name, + 'fromWireType': fromWireType, + 'toWireType': toWireType, + 'argPackAdvance': GenericWireTypeSize, + 'readValueFromPointer': integerReadValueFromPointer(name, size, minRange !== 0), + destructorFunction: null, // This type does not need a destructor + }); + }; + + + var __embind_register_memory_view = (rawType, dataTypeIndex, name) => { + var typeMapping = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + ]; + + var TA = typeMapping[dataTypeIndex]; + + function decodeMemoryView(handle) { + var size = HEAPU32[((handle)>>2)]; + var data = HEAPU32[(((handle)+(4))>>2)]; + return new TA(HEAP8.buffer, data, size); + } + + name = readLatin1String(name); + registerType(rawType, { + name, + 'fromWireType': decodeMemoryView, + 'argPackAdvance': GenericWireTypeSize, + 'readValueFromPointer': decodeMemoryView, + }, { + ignoreDuplicateRegistrations: true, + }); + }; + + + + + + var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => { + 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 >= 0xD800 && u <= 0xDFFF) { + var u1 = str.charCodeAt(++i); + u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); + } + if (u <= 0x7F) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 0xC0 | (u >> 6); + heap[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 0xE0 | (u >> 12); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + if (u > 0x10FFFF) 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++] = 0xF0 | (u >> 18); + heap[outIdx++] = 0x80 | ((u >> 12) & 63); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; + }; + 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 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 <= 0x7F) { + len++; + } else if (c <= 0x7FF) { + len += 2; + } else if (c >= 0xD800 && c <= 0xDFFF) { + len += 4; ++i; + } else { + len += 3; + } + } + return len; + }; + + + + var __embind_register_std_string = (rawType, name) => { + name = readLatin1String(name); + var stdStringIsUTF8 + //process only std::string bindings with UTF8 support, in contrast to e.g. std::basic_string + = (name === "std::string"); + + registerType(rawType, { + name, + // For some method names we use string keys here since they are part of + // the public/external API and/or used by the runtime-generated code. + 'fromWireType'(value) { + var length = HEAPU32[((value)>>2)]; + var payload = value + 4; + + var str; + if (stdStringIsUTF8) { + var decodeStartPtr = payload; + // Looping here to support possible embedded '0' bytes + for (var i = 0; i <= length; ++i) { + var currentBytePtr = payload + i; + if (i == length || HEAPU8[currentBytePtr] == 0) { + var maxRead = currentBytePtr - decodeStartPtr; + var stringSegment = UTF8ToString(decodeStartPtr, maxRead); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + 1; + } + } + } else { + var a = new Array(length); + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(HEAPU8[payload + i]); + } + str = a.join(''); + } + + _free(value); + + return str; + }, + 'toWireType'(destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + + var length; + var valueIsOfTypeString = (typeof value == 'string'); + + if (!(valueIsOfTypeString || value instanceof Uint8Array || value instanceof Uint8ClampedArray || value instanceof Int8Array)) { + throwBindingError('Cannot pass non-string to std::string'); + } + if (stdStringIsUTF8 && valueIsOfTypeString) { + length = lengthBytesUTF8(value); + } else { + length = value.length; + } + + // assumes POINTER_SIZE alignment + var base = _malloc(4 + length + 1); + var ptr = base + 4; + HEAPU32[((base)>>2)] = length; + if (stdStringIsUTF8 && valueIsOfTypeString) { + stringToUTF8(value, ptr, length + 1); + } else { + if (valueIsOfTypeString) { + for (var i = 0; i < length; ++i) { + var charCode = value.charCodeAt(i); + if (charCode > 255) { + _free(ptr); + throwBindingError('String has UTF-16 code units that do not fit in 8 bits'); + } + HEAPU8[ptr + i] = charCode; + } + } else { + for (var i = 0; i < length; ++i) { + HEAPU8[ptr + i] = value[i]; + } + } + } + + if (destructors !== null) { + destructors.push(_free, base); + } + return base; + }, + 'argPackAdvance': GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction(ptr) { + _free(ptr); + }, + }); + }; + + + + + var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined;; + var UTF16ToString = (ptr, maxBytesToRead) => { + assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!'); + var endPtr = ptr; + // 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. + var idx = endPtr >> 1; + var maxIdx = idx + maxBytesToRead / 2; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; + endPtr = idx << 1; + + if (endPtr - ptr > 32 && UTF16Decoder) + return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); + + // Fallback: decode without UTF16Decoder + var str = ''; + + // If maxBytesToRead is not passed explicitly, it will be undefined, and the + // for-loop's condition will always evaluate to true. The loop is then + // terminated on the first null char. + for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { + var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; + if (codeUnit == 0) break; + // fromCharCode constructs a character from a UTF-16 code unit, so we can + // pass the UTF16 string right through. + str += String.fromCharCode(codeUnit); + } + + return str; + }; + + var stringToUTF16 = (str, outPtr, maxBytesToWrite) => { + assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!'); + assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 0x7FFFFFFF; + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; // Null terminator. + var startPtr = outPtr; + var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + HEAP16[((outPtr)>>1)] = codeUnit; + outPtr += 2; + } + // Null-terminate the pointer to the HEAP. + HEAP16[((outPtr)>>1)] = 0; + return outPtr - startPtr; + }; + + var lengthBytesUTF16 = (str) => { + return str.length*2; + }; + + var UTF32ToString = (ptr, maxBytesToRead) => { + assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); + var i = 0; + + var str = ''; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(i >= maxBytesToRead / 4)) { + var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; + if (utf32 == 0) break; + ++i; + // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + if (utf32 >= 0x10000) { + var ch = utf32 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } else { + str += String.fromCharCode(utf32); + } + } + return str; + }; + + var stringToUTF32 = (str, outPtr, maxBytesToWrite) => { + assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); + assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + maxBytesToWrite ??= 0x7FFFFFFF; + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + 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! We must decode the string to UTF-32 to the heap. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { + var trailSurrogate = str.charCodeAt(++i); + codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); + } + HEAP32[((outPtr)>>2)] = codeUnit; + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + // Null-terminate the pointer to the HEAP. + HEAP32[((outPtr)>>2)] = 0; + return outPtr - startPtr; + }; + + var lengthBytesUTF32 = (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! We must decode the string to UTF-32 to the heap. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate. + len += 4; + } + + return len; + }; + var __embind_register_std_wstring = (rawType, charSize, name) => { + name = readLatin1String(name); + var decodeString, encodeString, readCharAt, lengthBytesUTF; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + readCharAt = (pointer) => HEAPU16[((pointer)>>1)]; + } else if (charSize === 4) { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + readCharAt = (pointer) => HEAPU32[((pointer)>>2)]; + } + registerType(rawType, { + name, + 'fromWireType': (value) => { + // Code mostly taken from _embind_register_std_string fromWireType + var length = HEAPU32[((value)>>2)]; + var str; + + var decodeStartPtr = value + 4; + // Looping here to support possible embedded '0' bytes + for (var i = 0; i <= length; ++i) { + var currentBytePtr = value + 4 + i * charSize; + if (i == length || readCharAt(currentBytePtr) == 0) { + var maxReadBytes = currentBytePtr - decodeStartPtr; + var stringSegment = decodeString(decodeStartPtr, maxReadBytes); + if (str === undefined) { + str = stringSegment; + } else { + str += String.fromCharCode(0); + str += stringSegment; + } + decodeStartPtr = currentBytePtr + charSize; + } + } + + _free(value); + + return str; + }, + 'toWireType': (destructors, value) => { + if (!(typeof value == 'string')) { + throwBindingError(`Cannot pass non-string to C++ string type ${name}`); + } + + // assumes POINTER_SIZE alignment + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + HEAPU32[((ptr)>>2)] = length / charSize; + + encodeString(value, ptr + 4, length + charSize); + + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + 'argPackAdvance': GenericWireTypeSize, + 'readValueFromPointer': readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); + }; + + + var __embind_register_void = (rawType, name) => { + name = readLatin1String(name); + registerType(rawType, { + isVoid: true, // void return values can be optimized out sometimes + name, + 'argPackAdvance': 0, + 'fromWireType': () => undefined, + // TODO: assert if anything else is given? + 'toWireType': (destructors, o) => undefined, + }); + }; + + var __emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num); + + var _abort = () => { + abort('native code called abort()'); + }; + + var getHeapMax = () => + HEAPU8.length; + + var abortOnCannotGrowMemory = (requestedSize) => { + abort(`Cannot enlarge memory arrays to size ${requestedSize} bytes (OOM). Either (1) compile with -sINITIAL_MEMORY=X with X higher than the current value ${HEAP8.length}, (2) compile with -sALLOW_MEMORY_GROWTH which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -sABORTING_MALLOC=0`); + }; + var _emscripten_resize_heap = (requestedSize) => { + var oldSize = HEAPU8.length; + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; + abortOnCannotGrowMemory(requestedSize); + }; + + var SYSCALLS = { + varargs:undefined, + getStr(ptr) { + var ret = UTF8ToString(ptr); + return ret; + }, + }; + var _fd_close = (fd) => { + abort('fd_close called without SYSCALLS_REQUIRE_FILESYSTEM'); + }; + + 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 + 0x200000) >>> 0 < 0x400001 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN; + }; + function _fd_seek(fd,offset_low, offset_high,whence,newOffset) { + var offset = convertI32PairToI53Checked(offset_low, offset_high); + + + 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); + }; + + + var _fd_write = (fd, iov, iovcnt, pnum) => { + // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0 + var num = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov)>>2)]; + var len = HEAPU32[(((iov)+(4))>>2)]; + iov += 8; + for (var j = 0; j < len; j++) { + printChar(fd, HEAPU8[ptr+j]); + } + num += len; + } + HEAPU32[((pnum)>>2)] = num; + return 0; + }; + + + var runtimeKeepaliveCounter = 0; + var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0; + var _proc_exit = (code) => { + EXITSTATUS = code; + if (!keepRuntimeAlive()) { + Module['onExit']?.(code); + ABORT = true; + } + quit_(code, new ExitStatus(code)); + }; + + /** @param {boolean|number=} implicit */ + var exitJS = (status, implicit) => { + EXITSTATUS = status; + + checkUnflushedContent(); + + // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down + if (keepRuntimeAlive() && !implicit) { + var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`; + err(msg); + } + + _proc_exit(status); + }; + + var handleException = (e) => { + // Certain exception types we do not treat as errors since they are used for + // internal control flow. + // 1. ExitStatus, which is thrown by exit() + // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others + // that wish to return to JS event loop. + if (e instanceof ExitStatus || e == 'unwind') { + return EXITSTATUS; + } + checkStackCookie(); + if (e instanceof WebAssembly.RuntimeError) { + if (_emscripten_stack_get_current() <= 0) { + err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)'); + } + } + quit_(1, e); + }; +embind_init_charCodes(); +BindingError = Module['BindingError'] = class BindingError extends Error { constructor(message) { super(message); this.name = 'BindingError'; }}; +InternalError = Module['InternalError'] = class InternalError extends Error { constructor(message) { super(message); this.name = 'InternalError'; }}; +init_emval();; +UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');; +function checkIncomingModuleAPI() { + ignoredModuleProp('fetchSettings'); +} +var wasmImports = { + /** @export */ + __assert_fail: ___assert_fail, + /** @export */ + __cxa_throw: ___cxa_throw, + /** @export */ + _embind_register_bigint: __embind_register_bigint, + /** @export */ + _embind_register_bool: __embind_register_bool, + /** @export */ + _embind_register_emval: __embind_register_emval, + /** @export */ + _embind_register_float: __embind_register_float, + /** @export */ + _embind_register_function: __embind_register_function, + /** @export */ + _embind_register_integer: __embind_register_integer, + /** @export */ + _embind_register_memory_view: __embind_register_memory_view, + /** @export */ + _embind_register_std_string: __embind_register_std_string, + /** @export */ + _embind_register_std_wstring: __embind_register_std_wstring, + /** @export */ + _embind_register_void: __embind_register_void, + /** @export */ + _emscripten_memcpy_js: __emscripten_memcpy_js, + /** @export */ + abort: _abort, + /** @export */ + emscripten_resize_heap: _emscripten_resize_heap, + /** @export */ + fd_close: _fd_close, + /** @export */ + fd_seek: _fd_seek, + /** @export */ + fd_write: _fd_write +}; +var wasmExports = createWasm(); +var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0); +var ___getTypeName = createExportWrapper('__getTypeName', 1); +var _malloc = createExportWrapper('malloc', 1); +var _main = Module['_main'] = createExportWrapper('main', 2); +var _fflush = createExportWrapper('fflush', 1); +var _free = createExportWrapper('free', 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_is_pointer_type = createExportWrapper('__cxa_is_pointer_type', 1); +var dynCall_jiji = Module['dynCall_jiji'] = createExportWrapper('dynCall_jiji', 5); // include: postamble.js // === Auto-generated postamble setup entry stuff === -Module['ccall'] = ccall; var missingLibrarySymbols = [ 'writeI53ToI64', 'writeI53ToI64Clamped', @@ -1353,11 +2462,11 @@ var missingLibrarySymbols = [ 'readI53FromI64', 'readI53FromU64', 'convertI32PairToI53', - 'convertI32PairToI53Checked', 'convertU32PairToI53', + 'stackAlloc', + 'getTempRet0', + 'setTempRet0', 'zeroMemory', - 'getHeapMax', - 'abortOnCannotGrowMemory', 'growMemory', 'isLeapYear', 'ydayFromDate', @@ -1371,17 +2480,12 @@ var missingLibrarySymbols = [ 'writeSockaddr', 'initRandomFill', 'randomFill', - 'getCallstack', 'emscriptenLog', - 'convertPCtoSourceLocation', 'readEmAsmArgs', 'jstoi_q', 'getExecutableName', 'listenOnce', 'autoResumeAudioContext', - 'dynCallLegacy', - 'getDynCaller', - 'dynCall', 'runtimeKeepalivePush', 'runtimeKeepalivePop', 'callUserCallback', @@ -1396,6 +2500,8 @@ var missingLibrarySymbols = [ 'STACK_ALIGN', 'POINTER_SIZE', 'ASSERTIONS', + 'getCFunc', + 'ccall', 'cwrap', 'uleb128Encode', 'sigToWasmTypes', @@ -1415,13 +2521,9 @@ var missingLibrarySymbols = [ 'intArrayToString', 'AsciiToString', 'stringToAscii', - 'UTF16ToString', - 'stringToUTF16', - 'lengthBytesUTF16', - 'UTF32ToString', - 'stringToUTF32', - 'lengthBytesUTF32', 'stringToNewUTF8', + 'stringToUTF8OnStack', + 'writeArrayToMemory', 'registerKeyEventCallback', 'maybeCStringToJsString', 'findEventTarget', @@ -1464,10 +2566,10 @@ var missingLibrarySymbols = [ 'setCanvasElementSize', 'getCanvasElementSize', 'jsStackTrace', - 'stackTrace', + 'getCallstack', + 'convertPCtoSourceLocation', 'getEnvStrings', 'checkWasiClock', - 'flush_NO_FILESYSTEM', 'wasiRightsToMuslOFlags', 'wasiOFlagsToMuslOFlags', 'createDyncallWrapper', @@ -1479,7 +2581,6 @@ var missingLibrarySymbols = [ 'makePromise', 'idsToPromises', 'makePromiseCallback', - 'ExceptionInfo', 'findMatchingCatch', 'Browser_asyncPrepareDataCounter', 'setMainLoop', @@ -1519,6 +2620,47 @@ var missingLibrarySymbols = [ 'writeAsciiToMemory', 'setErrNo', 'demangle', + 'stackTrace', + 'getFunctionArgsName', + 'requireRegisteredType', + 'createJsInvokerSignature', + 'init_embind', + 'getBasestPointer', + 'registerInheritedInstance', + 'unregisterInheritedInstance', + 'getInheritedInstance', + 'getInheritedInstanceCount', + 'getLiveInheritedInstances', + 'enumReadValueFromPointer', + 'genericPointerToWireType', + 'constNoSmartPtrRawPointerToWireType', + 'nonConstNoSmartPtrRawPointerToWireType', + 'init_RegisteredPointer', + 'RegisteredPointer', + 'RegisteredPointer_fromWireType', + 'runDestructor', + 'releaseClassHandle', + 'detachFinalizer', + 'attachFinalizer', + 'makeClassHandle', + 'init_ClassHandle', + 'ClassHandle', + 'throwInstanceAlreadyDeleted', + 'flushPendingDeletes', + 'setDelayFunction', + 'RegisteredClass', + 'shallowCopyInternalPointer', + 'downcastPointer', + 'upcastPointer', + 'validateThis', + 'char_0', + 'char_9', + 'makeLegalFunctionName', + 'getStringOrSymbol', + 'emval_get_global', + 'emval_returnValue', + 'emval_lookupTypes', + 'emval_addMethodCaller', ]; missingLibrarySymbols.forEach(missingLibrarySymbol) @@ -1543,15 +2685,15 @@ var unexportedSymbols = [ 'abort', 'wasmMemory', 'wasmExports', - 'stackAlloc', - 'stackSave', - 'stackRestore', - 'getTempRet0', - 'setTempRet0', 'writeStackCookie', 'checkStackCookie', + 'convertI32PairToI53Checked', + 'stackSave', + 'stackRestore', 'ptrToString', 'exitJS', + 'getHeapMax', + 'abortOnCannotGrowMemory', 'ENV', 'MONTH_DAYS_REGULAR', 'MONTH_DAYS_LEAP', @@ -1564,14 +2706,15 @@ var unexportedSymbols = [ 'Sockets', 'timers', 'warnOnce', - 'UNWIND_CACHE', 'readEmAsmArgsArray', 'jstoi_s', + 'dynCallLegacy', + 'getDynCaller', + 'dynCall', 'handleException', 'keepRuntimeAlive', 'wasmTable', 'noExitRuntime', - 'getCFunc', 'freeTableIndexes', 'functionsInTableMap', 'setValue', @@ -1585,18 +2728,25 @@ var unexportedSymbols = [ 'stringToUTF8', 'lengthBytesUTF8', 'UTF16Decoder', - 'stringToUTF8OnStack', - 'writeArrayToMemory', + 'UTF16ToString', + 'stringToUTF16', + 'lengthBytesUTF16', + 'UTF32ToString', + 'stringToUTF32', + 'lengthBytesUTF32', 'JSEvents', 'specialHTMLTargets', 'findCanvasEventTarget', 'currentFullscreenStrategy', 'restoreOldWindowedStyle', + 'UNWIND_CACHE', 'ExitStatus', + 'flush_NO_FILESYSTEM', 'promiseMap', 'uncaughtExceptionCount', 'exceptionLast', 'exceptionCaught', + 'ExceptionInfo', 'Browser', 'getPreloadedImageData__data', 'wget', @@ -1621,6 +2771,58 @@ var unexportedSymbols = [ 'SDL_gfx', 'allocateUTF8', 'allocateUTF8OnStack', + 'InternalError', + 'BindingError', + 'throwInternalError', + 'throwBindingError', + 'registeredTypes', + 'awaitingDependencies', + 'typeDependencies', + 'tupleRegistrations', + 'structRegistrations', + 'sharedRegisterType', + 'whenDependentTypesAreResolved', + 'embind_charCodes', + 'embind_init_charCodes', + 'readLatin1String', + 'getTypeName', + 'getFunctionName', + 'heap32VectorToArray', + 'usesDestructorStack', + 'createJsInvoker', + 'UnboundTypeError', + 'PureVirtualError', + 'GenericWireTypeSize', + 'EmValType', + 'throwUnboundTypeError', + 'ensureOverloadTable', + 'exposePublicSymbol', + 'replacePublicSymbol', + 'extendError', + 'createNamedFunction', + 'embindRepr', + 'registeredInstances', + 'registeredPointers', + 'registerType', + 'integerReadValueFromPointer', + 'floatReadValueFromPointer', + 'readPointer', + 'runDestructors', + 'newFunc', + 'craftInvokerFunction', + 'embind__requireFunction', + 'finalizationRegistry', + 'detachFinalizer_deps', + 'deletionQueue', + 'delayFunction', + 'emval_freelist', + 'emval_handles', + 'emval_symbols', + 'init_emval', + 'count_emval_handles', + 'Emval', + 'emval_methodCallers', + 'reflectConstruct', ]; unexportedSymbols.forEach(unexportedRuntimeSymbol); @@ -1734,7 +2936,7 @@ function checkUnflushedContent() { has = true; } try { // it doesn't matter if it fails - _fflush(0); + flush_NO_FILESYSTEM(); } catch(e) {} out = oldOut; err = oldErr; diff --git a/C++/test.wasm b/C++/test.wasm old mode 100644 new mode 100755 index 165ea898a7a75bdad94b8cb18d585dff884b5656..c1fe616f160b8f1a851237736d4fd088b9af3727 GIT binary patch literal 30865 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 E0|BvrRR910 diff --git a/README.md b/README.md new file mode 100644 index 0000000..03785b0 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Prototype + +Link for compiling code with Embind → https://emscripten.org/docs/porting connecting_cpp_and_javascript/embind.html +Command for compiling code with Embind: +``` +emcc -lembind -o test.js test.cpp -s NO_EXIT_RUNTIME=1 -s "EXPORTED_RUNTIME_METHODS=['ccall']" +``` +- EMSCRIPTEN_BINDINGS macro is used to bind the C++ function to make it callable from JavaScript +- Emscripten compiles the C++ code to WebAssembly, generating a .wasm file and JavaScript glue code that loads the WebAssembly module and sets up the bindings +- When the HTML page is loaded, test.js is executed, loading the WebAssembly module , Emscripten's Module object is created, exposing the C++ functions (like myFunction) to JavaScript +- Example of using Module: var result = Module.myFunction(input) \ No newline at end of file diff --git a/index.html b/index.html index 19e7615..cb4d6e1 100644 --- a/index.html +++ b/index.html @@ -10,27 +10,21 @@ href="node_modules/bootstrap/dist/css/bootstrap.min.css" /> -
-

Square calculator

- +

Test

+
@@ -42,115 +36,6 @@
- -
-
-
-
-

Sum calculator

- - - -
-
-
-
-

Output

-
-
-
-
-
-
-

Checkbox Container

-
-
-
-
- - -
-
- - -
-
- - -
-
-
-
-
-
- - -
-
- - -
-
- - -
-
-
-
-
+ diff --git a/index.js b/index.js index 3e2f94e..6894f4c 100644 --- a/index.js +++ b/index.js @@ -1,16 +1,9 @@ function calculateResult() { - var numberInput = parseInt(document.getElementById("numberInput").value); - var result = Module.ccall("myFunction", "number", ["number"], [numberInput]); - document.getElementById("output").innerText = "Result: " + result; + var input = document.getElementById("numberInput").value; + var result = Module.myFunction(input) + document.getElementById("output").innerText = result; } -// document -// .getElementById("calculateBtn") -// .addEventListener("click", calculateResult); -function calculate() { - var a = parseInt(document.getElementById("input1").value); - var b = parseInt(document.getElementById("input2").value); - var result = Module.ccall("add", "number", ["number", "number"], [a, b]); - document.getElementById("result").innerText = "Result: " + result; -} + +