diff --git a/CMakeLists.txt b/CMakeLists.txt index f51bbd5..5d7fbe4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ set( ${BELDEX_CORE_CPP_SRC}/serial_bridge_utils.cpp ${BELDEX_CORE_CPP_SRC}/tools__ret_vals.hpp ${BELDEX_CORE_CPP_SRC}/tools__ret_vals.cpp + ${BELDEX_CORE_CPP_SRC}/register_mn_data.hpp # ${BELDEX_LIBAPP_CPP_SRC}/SendFunds/Controllers/SendFundsFormSubmissionController.hpp ${BELDEX_LIBAPP_CPP_SRC}/SendFunds/Controllers/SendFundsFormSubmissionController.cpp @@ -100,6 +101,8 @@ set( ${BELDEX_SRC}/crypto/jh.c ${BELDEX_SRC}/crypto/skein.c ${BELDEX_SRC}/cryptonote_core/cryptonote_tx_utils.cpp + ${BELDEX_SRC}/cryptonote_core/master_node_list.cpp + ${BELDEX_SRC}/cryptonote_core/master_node_rules.cpp ${BELDEX_SRC}/common/base58.cpp ${BELDEX_SRC}/common/threadpool.cpp ${BELDEX_SRC}/common/aligned.c diff --git a/libapp_js/BeldexLibAppBridgeClass.js b/libapp_js/BeldexLibAppBridgeClass.js index 13af281..54ad35e 100644 --- a/libapp_js/BeldexLibAppBridgeClass.js +++ b/libapp_js/BeldexLibAppBridgeClass.js @@ -204,7 +204,9 @@ class BeldexLibAppBridgeClass extends MyMoneroCoreBridgeEssentialsClass self._cb_handlers__SendFundsFormSubmission = null // reset so we can enter process again }; const args = - { + { + registration_string: fn_args.registration_string, + isRegisterStr: fn_args.isRegister, fromWallet_didFailToInitialize: fn_args.fromWallet_didFailToInitialize, fromWallet_didFailToBoot: fn_args.fromWallet_didFailToBoot, fromWallet_needsImport: fn_args.fromWallet_needsImport, @@ -249,6 +251,7 @@ class BeldexLibAppBridgeClass extends MyMoneroCoreBridgeEssentialsClass args.resolvedPaymentID = fn_args.resolvedPaymentID; } const args_str = JSON.stringify(args, null, '') + // console.log('semd-funds args_str', args_str); const ret_string = this.Module.send_funds(args_str); const ret = JSON.parse(ret_string); if (typeof ret.err_msg !== 'undefined' && ret.err_msg) { // this is actually an exception diff --git a/libapp_js/BeldexLibAppCpp_WASM.js b/libapp_js/BeldexLibAppCpp_WASM.js index 991e769..4477877 100644 --- a/libapp_js/BeldexLibAppCpp_WASM.js +++ b/libapp_js/BeldexLibAppCpp_WASM.js @@ -3,7165 +3,6705 @@ var BeldexLibAppCpp = (() => { var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; return ( -function(BeldexLibAppCpp) { - BeldexLibAppCpp = BeldexLibAppCpp || {}; +function(moduleArg = {}) { +// Support for growable heap + pthreads, where the buffer may change, so JS views +// must be updated. +function GROWABLE_HEAP_I8() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAP8; +} +function GROWABLE_HEAP_U8() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPU8; +} +function GROWABLE_HEAP_I16() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAP16; +} +function GROWABLE_HEAP_U16() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPU16; +} +function GROWABLE_HEAP_I32() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAP32; +} +function GROWABLE_HEAP_U32() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPU32; +} +function GROWABLE_HEAP_F32() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPF32; +} +function GROWABLE_HEAP_F64() { + if (wasmMemory.buffer != HEAP8.buffer) { + updateMemoryViews(); + } + return HEAPF64; +} +var Module = moduleArg; -// 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.. } -// 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 BeldexLibAppCpp != 'undefined' ? BeldexLibAppCpp : {}; - -// See https://caniuse.com/mdn-javascript_builtins_object_assign - -// See https://caniuse.com/mdn-javascript_builtins_bigint64array - -// Set up the promise that indicates the Module is initialized var readyPromiseResolve, readyPromiseReject; -Module['ready'] = new Promise(function(resolve, reject) { - readyPromiseResolve = resolve; - readyPromiseReject = reject; -}); -["_main","___getTypeName","__embind_initialize_bindings","_fflush","___set_stack_limits","onRuntimeInitialized"].forEach((prop) => { - if (!Object.getOwnPropertyDescriptor(Module['ready'], prop)) { - Object.defineProperty(Module['ready'], prop, { - get: () => abort('You are getting ' + prop + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js'), - set: () => abort('You are setting ' + prop + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js'), - }); - } -}); -// --pre-jses are emitted after the Module integration code, so that they can -// refer to Module (if they choose; they can also define Module) +Module["ready"] = new Promise((resolve, reject) => { + readyPromiseResolve = resolve; + readyPromiseReject = reject; +}); +[ "_main", "__emscripten_thread_init", "__emscripten_thread_exit", "__emscripten_thread_crashed", "__emscripten_thread_mailbox_await", "__emscripten_tls_init", "_pthread_self", "checkMailbox", "__embind_initialize_bindings", "establishStackSpace", "invokeEntryPoint", "PThread", "getExceptionMessage", "___get_exception_message", "_free", "___indirect_function_table", "_fflush", "___start_em_asm", "___stop_em_asm", "___set_stack_limits", "onRuntimeInitialized" ].forEach(prop => { + if (!Object.getOwnPropertyDescriptor(Module["ready"], prop)) { + Object.defineProperty(Module["ready"], prop, { + get: () => abort("You are getting " + prop + " on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js"), + set: () => abort("You are setting " + prop + " on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js") + }); + } +}); -// 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 thisProgram = "./this.program"; + var quit_ = (status, toThrow) => { - throw 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). +var ENVIRONMENT_IS_WEB = typeof window == "object"; -// 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; +var ENVIRONMENT_IS_WORKER = typeof importScripts == "function"; -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)'); -} +var ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string"; -// `/` 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; -} +var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; -// Hooks that are implemented differently in different runtime environments. -var read_, - readAsync, - readBinary, - setWindowTitle; - -// Normally we don't log exceptions but instead let them bubble out the top -// level where the embedding environment (e.g. the browser) can handle -// them. -// However under v8 and node we sometimes exit the process direcly in which case -// its up to use us to log the exception before exiting. -// If we fix https://github.com/emscripten-core/emscripten/issues/15080 -// this may no longer be needed under node. -function logExceptionOnExit(e) { - if (e instanceof ExitStatus) return; - let toLog = e; - if (e && typeof e == 'object' && e.stack) { - toLog = [e, e.stack]; - } - err('exiting due to exception: ' + toLog); +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) { - if (typeof process == 'undefined' || !process.release || process.release.name !== 'node') 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 (ENVIRONMENT_IS_WORKER) { - scriptDirectory = require('path').dirname(scriptDirectory) + '/'; - } else { - scriptDirectory = __dirname + '/'; - } - -// include: node_shell_read.js +var ENVIRONMENT_IS_PTHREAD = Module["ENVIRONMENT_IS_PTHREAD"] || false; +var scriptDirectory = ""; -// These modules will usually be used on Node.js. Load them eagerly to avoid -// the complexity of lazy-loading. However, for now we must guard on require() -// actually existing: if the JS is put in a .mjs file (ES6 module) and run on -// node, then we'll detect node as the environment and get here, but require() -// does not exist (since ES6 modules should use |import|). If the code actually -// uses the node filesystem then it will crash, of course, but in the case of -// code that never uses it we don't want to crash here, so the guarding if lets -// such code work properly. See discussion in -// https://github.com/emscripten-core/emscripten/pull/17851 -var fs, nodePath; -if (typeof require === 'function') { - fs = require('fs'); - nodePath = require('path'); +function locateFile(path) { + if (Module["locateFile"]) { + return Module["locateFile"](path, scriptDirectory); + } + return scriptDirectory + path; } -read_ = (filename, binary) => { - filename = nodePath['normalize'](filename); - return fs.readFileSync(filename, binary ? undefined : 'utf8'); -}; +var read_, readAsync, readBinary; -readBinary = (filename) => { +if (ENVIRONMENT_IS_NODE) { + if (typeof process == "undefined" || !process.release || process.release.name !== "node") 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?)"); + var nodeVersion = process.versions.node; + var numericVersion = nodeVersion.split(".").slice(0, 3); + numericVersion = (numericVersion[0] * 1e4) + (numericVersion[1] * 100) + (numericVersion[2].split("-")[0] * 1); + var minVersion = 16e4; + if (numericVersion < 16e4) { + throw new Error("This emscripten-generated code requires node v16.0.0 (detected v" + nodeVersion + ")"); + } + var fs = require("fs"); + var nodePath = require("path"); + if (ENVIRONMENT_IS_WORKER) { + scriptDirectory = nodePath.dirname(scriptDirectory) + "/"; + } else { + scriptDirectory = __dirname + "/"; + } + read_ = (filename, binary) => { + filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename); + return fs.readFileSync(filename, binary ? undefined : "utf8"); + }; + readBinary = filename => { var ret = read_(filename, true); if (!ret.buffer) { - ret = new Uint8Array(ret); + ret = new Uint8Array(ret); } assert(ret.buffer); return ret; -}; - -readAsync = (filename, onload, onerror) => { - filename = nodePath['normalize'](filename); - fs.readFile(filename, function(err, data) { - if (err) onerror(err); - else onload(data.buffer); + }; + readAsync = (filename, onload, onerror, binary = true) => { + filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename); + fs.readFile(filename, binary ? undefined : "utf8", (err, data) => { + if (err) onerror(err); else onload(binary ? data.buffer : data); }); -}; - -// end include: node_shell_read.js - if (process['argv'].length > 1) { - thisProgram = process['argv'][1].replace(/\\/g, '/'); + }; + if (!Module["thisProgram"] && process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, "/"); + } + arguments_ = process.argv.slice(2); + quit_ = (status, toThrow) => { + process.exitCode = status; + throw toThrow; + }; + Module["inspect"] = () => "[Emscripten Module object]"; + let nodeWorkerThreads; + try { + nodeWorkerThreads = require("worker_threads"); + } catch (e) { + console.error('The "worker_threads" module is not supported in this node.js build - perhaps a newer version is needed?'); + throw e; + } + global.Worker = nodeWorkerThreads.Worker; +} else 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") { + 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) => { + 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") { + 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 if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + if (ENVIRONMENT_IS_WORKER) { + scriptDirectory = self.location.href; + } else if (typeof document != "undefined" && document.currentScript) { + scriptDirectory = document.currentScript.src; + } + if (_scriptDir) { + scriptDirectory = _scriptDir; + } + if (scriptDirectory.indexOf("blob:") !== 0) { + scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1); + } else { + scriptDirectory = ""; + } + 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?)"); + if (!ENVIRONMENT_IS_NODE) { + read_ = url => { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + xhr.send(null); + return xhr.responseText; + }; + if (ENVIRONMENT_IS_WORKER) { + readBinary = url => { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + xhr.responseType = "arraybuffer"; + xhr.send(null); + return new Uint8Array(/** @type{!ArrayBuffer} */ (xhr.response)); + }; } + readAsync = (url, onload, onerror) => { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, true); + xhr.responseType = "arraybuffer"; + xhr.onload = () => { + if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { + onload(xhr.response); + return; + } + onerror(); + }; + xhr.onerror = onerror; + xhr.send(null); + }; + } +} else { + throw new Error("environment detection error"); +} - arguments_ = process['argv'].slice(2); +if (ENVIRONMENT_IS_NODE) { + if (typeof performance == "undefined") { + global.performance = require("perf_hooks").performance; + } +} - // MODULARIZE will export the module in the proper place outside, we don't need to export here +var defaultPrint = console.log.bind(console); - process['on']('uncaughtException', function(ex) { - // suppress ExitStatus exceptions from showing an error - if (!(ex instanceof ExitStatus)) { - throw ex; - } - }); +var defaultPrintErr = console.error.bind(console); - quit_ = (status, toThrow) => { - if (keepRuntimeAlive()) { - process['exitCode'] = status; - throw toThrow; - } - logExceptionOnExit(toThrow); - process['exit'](status); - }; +if (ENVIRONMENT_IS_NODE) { + defaultPrint = (...args) => fs.writeSync(1, args.join(" ") + "\n"); + defaultPrintErr = (...args) => fs.writeSync(2, args.join(" ") + "\n"); +} - Module['inspect'] = function () { return '[Emscripten Module object]'; }; +var out = Module["print"] || defaultPrint; -} else -if (ENVIRONMENT_IS_SHELL) { +var err = Module["printErr"] || defaultPrintErr; - 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?)'); +Object.assign(Module, moduleOverrides); - if (typeof read != 'undefined') { - read_ = function shell_read(f) { - return read(f); - }; - } +moduleOverrides = null; - readBinary = function readBinary(f) { - let data; - if (typeof readbuffer == 'function') { - return new Uint8Array(readbuffer(f)); - } - data = read(f, 'binary'); - assert(typeof data == 'object'); - return data; - }; +checkIncomingModuleAPI(); - readAsync = function readAsync(f, onload, onerror) { - setTimeout(() => onload(readBinary(f)), 0); - }; +if (Module["arguments"]) arguments_ = Module["arguments"]; - if (typeof scriptArgs != 'undefined') { - arguments_ = scriptArgs; - } else if (typeof arguments != 'undefined') { - arguments_ = arguments; - } +legacyModuleProp("arguments", "arguments_"); - if (typeof quit == 'function') { - quit_ = (status, toThrow) => { - logExceptionOnExit(toThrow); - quit(status); - }; - } +if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; - 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). -// 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; - } - // When MODULARIZE, this JS may be executed later, after document.currentScript - // is gone, so we saved it, and we use it here instead of any other info. - if (_scriptDir) { - scriptDirectory = _scriptDir; - } - // 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.indexOf('blob:') !== 0) { - scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf('/')+1); - } else { - scriptDirectory = ''; - } +legacyModuleProp("thisProgram", "thisProgram"); - 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?)'); +if (Module["quit"]) quit_ = Module["quit"]; - // Differentiate the Web Worker from the Node Worker case, as reading must - // be done differently. - { -// include: web_or_worker_shell_read.js +legacyModuleProp("quit", "quit_"); +assert(typeof Module["memoryInitializerPrefixURL"] == "undefined", "Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead"); - read_ = (url) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.send(null); - return xhr.responseText; - } +assert(typeof Module["pthreadMainPrefixURL"] == "undefined", "Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead"); - if (ENVIRONMENT_IS_WORKER) { - readBinary = (url) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.responseType = 'arraybuffer'; - xhr.send(null); - return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); - }; - } +assert(typeof Module["cdInitializerPrefixURL"] == "undefined", "Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead"); - readAsync = (url, onload, onerror) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'arraybuffer'; - xhr.onload = () => { - if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 - onload(xhr.response); - return; - } - onerror(); - }; - xhr.onerror = onerror; - xhr.send(null); - } +assert(typeof Module["filePackagePrefixURL"] == "undefined", "Module.filePackagePrefixURL option was removed, use Module.locateFile instead"); -// end include: web_or_worker_shell_read.js - } +assert(typeof Module["read"] == "undefined", "Module.read option was removed (modify read_ in JS)"); - setWindowTitle = (title) => document.title = title; -} else -{ - throw new Error('environment detection error'); -} +assert(typeof Module["readAsync"] == "undefined", "Module.readAsync option was removed (modify readAsync in JS)"); -var out = Module['print'] || console.log.bind(console); -var err = Module['printErr'] || console.warn.bind(console); +assert(typeof Module["readBinary"] == "undefined", "Module.readBinary option was removed (modify readBinary in JS)"); -// Merge back in the overrides -Object.assign(Module, moduleOverrides); -// Free the object hierarchy contained in the overrides, this lets the GC -// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array. -moduleOverrides = null; -checkIncomingModuleAPI(); +assert(typeof Module["setWindowTitle"] == "undefined", "Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)"); -// 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 (modify read_ in JS)'); -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 setWindowTitle in JS)'); -assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY'); -legacyModuleProp('read', 'read_'); -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 NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; +assert(typeof Module["TOTAL_MEMORY"] == "undefined", "Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY"); -assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable."); +legacyModuleProp("asm", "wasmExports"); +legacyModuleProp("read", "read_"); +legacyModuleProp("readAsync", "readAsync"); +legacyModuleProp("readBinary", "readBinary"); -var STACK_ALIGN = 16; -var POINTER_SIZE = 4; +legacyModuleProp("setWindowTitle", "setWindowTitle"); -function getNativeTypeSize(type) { - switch (type) { - case 'i1': case 'i8': case 'u8': return 1; - case 'i16': case 'u16': return 2; - case 'i32': case 'u32': return 4; - case 'i64': case 'u64': return 8; - case 'float': return 4; - case 'double': return 8; - default: { - if (type[type.length - 1] === '*') { - return POINTER_SIZE; - } - if (type[0] === 'i') { - const bits = Number(type.substr(1)); - assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type); - return bits / 8; - } - return 0; - } - } -} +var IDBFS = "IDBFS is no longer included by default; build with -lidbfs.js"; -// include: runtime_debug.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"; -function legacyModuleProp(prop, newName) { - if (!Object.getOwnPropertyDescriptor(Module, prop)) { - Object.defineProperty(Module, prop, { - configurable: true, - get: function() { - abort('Module.' + prop + ' has been replaced with plain ' + newName + ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)'); - } - }); - } -} +var FETCHFS = "FETCHFS is no longer included by default; build with -lfetchfs.js"; -function ignoredModuleProp(prop) { - if (Object.getOwnPropertyDescriptor(Module, prop)) { - abort('`Module.' + prop + '` was supplied but `' + prop + '` not included in INCOMING_MODULE_JS_API'); - } -} +var ICASEFS = "ICASEFS is no longer included by default; build with -licasefs.js"; -// 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'; -} +var JSFILEFS = "JSFILEFS is no longer included by default; build with -ljsfilefs.js"; -function missingLibrarySymbol(sym) { - if (typeof globalThis !== 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) { - Object.defineProperty(globalThis, sym, { - configurable: true, - get: function() { - // 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; - } - }); - } -} +var OPFS = "OPFS is no longer included by default; build with -lopfs.js"; -function unexportedRuntimeSymbol(sym) { - if (!Object.getOwnPropertyDescriptor(Module, sym)) { - Object.defineProperty(Module, sym, { - configurable: true, - get: function() { - var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)"; - if (isExportedByForceFilesystem(sym)) { - msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; - } - abort(msg); - } - }); - } -} +var NODEFS = "NODEFS is no longer included by default; build with -lnodefs.js"; -// end include: runtime_debug.js +assert(ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_NODE, "Pthreads do not work in this environment yet (need Web Workers, or an alternative to them)"); +assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable."); -// === Preamble library stuff === +var wasmBinary; -// 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 +if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"]; -var wasmBinary; -if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary'); -var noExitRuntime = Module['noExitRuntime'] || true;legacyModuleProp('noExitRuntime', 'noExitRuntime'); +legacyModuleProp("wasmBinary", "wasmBinary"); -if (typeof WebAssembly != 'object') { - abort('no native wasm support detected'); +if (typeof WebAssembly != "object") { + abort("no native wasm support detected"); } -// Wasm globals - var wasmMemory; -//======================================== -// Runtime essentials -//======================================== +var wasmModule; -// 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; -/** @type {function(*, string=)} */ -function assert(condition, text) { - if (!condition) { - abort('Assertion failed' + (text ? ': ' + text : '')); - } +/** @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. - -// include: runtime_strings.js - - -// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime. - -var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined; - -// Given a pointer 'ptr' 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} - */ -function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) { - 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 & 0x80)) { str += String.fromCharCode(u0); continue; } - var u1 = heapOrArray[idx++] & 63; - if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } - var u2 = heapOrArray[idx++] & 63; - if ((u0 & 0xF0) == 0xE0) { - u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; - } else { - if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' 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 < 0x10000) { - str += String.fromCharCode(u0); - } else { - var ch = u0 - 0x10000; - str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); - } - } - return str; +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; + +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); } -// 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. -// 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 -// style or the other. -/** - * @param {number} ptr - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ToString(ptr, maxBytesToRead) { - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; -} +assert(!Module["STACK_SIZE"], "STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time"); -// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', -// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element. -// outIdx: The starting offset in the array to begin the copying. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. -// This count should include the null terminator, -// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else. -// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes. - 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 0x' + u.toString(16) + ' 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; -} +assert(typeof Int32Array != "undefined" && typeof Float64Array !== "undefined" && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined, "JS engine does not provide full typed array support"); -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Returns the number of bytes written, EXCLUDING the null terminator. +var INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 16777216; -function 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); -} +legacyModuleProp("INITIAL_MEMORY", "INITIAL_MEMORY"); -// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte. -function 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; -} +assert(INITIAL_MEMORY >= 65536, "INITIAL_MEMORY should be larger than STACK_SIZE, was " + INITIAL_MEMORY + "! (STACK_SIZE=" + 65536 + ")"); -// end include: runtime_strings.js -// Memory management - -var HEAP, -/** @type {!ArrayBuffer} */ - buffer, -/** @type {!Int8Array} */ - HEAP8, -/** @type {!Uint8Array} */ - HEAPU8, -/** @type {!Int16Array} */ - HEAP16, -/** @type {!Uint16Array} */ - HEAPU16, -/** @type {!Int32Array} */ - HEAP32, -/** @type {!Uint32Array} */ - HEAPU32, -/** @type {!Float32Array} */ - HEAPF32, -/** @type {!Float64Array} */ - HEAPF64; - -function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module['HEAP8'] = HEAP8 = new Int8Array(buf); - Module['HEAP16'] = HEAP16 = new Int16Array(buf); - Module['HEAP32'] = HEAP32 = new Int32Array(buf); - Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf); - Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf); - Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf); - Module['HEAPF32'] = HEAPF32 = new Float32Array(buf); - Module['HEAPF64'] = HEAPF64 = new Float64Array(buf); +if (ENVIRONMENT_IS_PTHREAD) { + wasmMemory = Module["wasmMemory"]; +} else { + if (Module["wasmMemory"]) { + wasmMemory = Module["wasmMemory"]; + } else { + wasmMemory = new WebAssembly.Memory({ + "initial": INITIAL_MEMORY / 65536, + "maximum": 2147483648 / 65536, + "shared": true + }); + if (!(wasmMemory.buffer instanceof SharedArrayBuffer)) { + err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag"); + if (ENVIRONMENT_IS_NODE) { + err("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and/or recent version)"); + } + throw Error("bad memory"); + } + } } -var TOTAL_STACK = 5242880; -if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime') +updateMemoryViews(); -var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;legacyModuleProp('INITIAL_MEMORY', 'INITIAL_MEMORY'); +INITIAL_MEMORY = wasmMemory.buffer.byteLength; -assert(INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')'); +assert(INITIAL_MEMORY % 65536 === 0); -// check for full engine support (use string 'subarray' to avoid closure compiler confusion) -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. -assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally'); -assert(INITIAL_MEMORY == 16777216, 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically'); - -// include: runtime_init_table.js -// In regular non-RELOCATABLE mode the table is exported -// from the wasm module and this will be assigned once -// the exports are available. -var wasmTable; - -// end include: runtime_init_table.js -// 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); - // 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)] = 0x2135467; - HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE; - // Also test the global address 0 for integrity. - HEAPU32[0] = 0x63736d65; /* 'emsc' */ + var max = _emscripten_stack_get_end(); + assert((max & 3) == 0); + if (max == 0) { + max += 4; + } + GROWABLE_HEAP_U32()[((max) >> 2)] = 34821223; + checkInt32(34821223); + GROWABLE_HEAP_U32()[(((max) + (4)) >> 2)] = 2310721022; + checkInt32(2310721022); + GROWABLE_HEAP_U32()[((0) >> 2)] = 1668509029; + checkInt32(1668509029); } function checkStackCookie() { - if (ABORT) return; - var max = _emscripten_stack_get_end(); - var cookie1 = HEAPU32[((max)>>2)]; - var cookie2 = HEAPU32[(((max)+(4))>>2)]; - if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) { - abort('Stack overflow! Stack cookie has been overwritten at 0x' + max.toString(16) + ', expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' 0x' + cookie1.toString(16)); - } - // Also test the global address 0 for integrity. - if (HEAPU32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!'); + if (ABORT) return; + var max = _emscripten_stack_get_end(); + if (max == 0) { + max += 4; + } + var cookie1 = GROWABLE_HEAP_U32()[((max) >> 2)]; + var cookie2 = GROWABLE_HEAP_U32()[(((max) + (4)) >> 2)]; + 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)}`); + } + if (GROWABLE_HEAP_U32()[((0) >> 2)] != 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] = 0x6373; - if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)'; + 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 __ATMAIN__ = []; // functions called when main() is to be run -var __ATEXIT__ = []; // functions called during shutdown -var __ATPOSTRUN__ = []; // functions called after the main() is called +var __ATPRERUN__ = []; -var runtimeInitialized = false; +var __ATINIT__ = []; -function keepRuntimeAlive() { - return noExitRuntime; -} +var __ATMAIN__ = []; -function preRun() { +var __ATEXIT__ = []; - if (Module['preRun']) { - if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; - while (Module['preRun'].length) { - addOnPreRun(Module['preRun'].shift()); - } - } +var __ATPOSTRUN__ = []; + +var runtimeInitialized = false; - callRuntimeCallbacks(__ATPRERUN__); +function preRun() { + assert(!ENVIRONMENT_IS_PTHREAD); + 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(); - - ___set_stack_limits(_emscripten_stack_get_base(), _emscripten_stack_get_end()); - -if (!Module["noFSInit"] && !FS.init.initialized) - FS.init(); -FS.ignorePermissions = false; - -TTY.init(); - callRuntimeCallbacks(__ATINIT__); + assert(!runtimeInitialized); + runtimeInitialized = true; + if (ENVIRONMENT_IS_PTHREAD) return; + checkStackCookie(); + setStackLimits(); + if (!Module["noFSInit"] && !FS.init.initialized) FS.init(); + FS.ignorePermissions = false; + TTY.init(); + callRuntimeCallbacks(__ATINIT__); } function preMain() { - checkStackCookie(); - - callRuntimeCallbacks(__ATMAIN__); + checkStackCookie(); + if (ENVIRONMENT_IS_PTHREAD) return; + callRuntimeCallbacks(__ATMAIN__); } function postRun() { - checkStackCookie(); - - if (Module['postRun']) { - if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; - while (Module['postRun'].length) { - addOnPostRun(Module['postRun'].shift()); - } + checkStackCookie(); + if (ENVIRONMENT_IS_PTHREAD) return; + if (Module["postRun"]) { + if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ]; + while (Module["postRun"].length) { + addOnPostRun(Module["postRun"].shift()); } - - callRuntimeCallbacks(__ATPOSTRUN__); + } + callRuntimeCallbacks(__ATPOSTRUN__); } function addOnPreRun(cb) { - __ATPRERUN__.unshift(cb); + __ATPRERUN__.unshift(cb); } function addOnInit(cb) { - __ATINIT__.unshift(cb); + __ATINIT__.unshift(cb); } function addOnPreMain(cb) { - __ATMAIN__.unshift(cb); + __ATMAIN__.unshift(cb); } -function addOnExit(cb) { -} +function addOnExit(cb) {} function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb); + __ATPOSTRUN__.unshift(cb); } -// include: runtime_math.js +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"); -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul +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"); -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround +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"); -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 +var runDependencies = 0; -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc +var runDependencyWatcher = null; -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'); +var dependenciesFulfilled = null; -// 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(); - } + var orig = id; + while (1) { + if (!runDependencyTracking[id]) return id; + id = orig + Math.random(); + } } function addRunDependency(id) { - runDependencies++; - - if (Module['monitorRunDependencies']) { - 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(function() { - 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)'); - } - }, 10000); - } - } else { - err('warning: run dependency added without ID'); + runDependencies++; + if (Module["monitorRunDependencies"]) { + Module["monitorRunDependencies"](runDependencies); + } + if (id) { + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if (runDependencyWatcher === null && typeof setInterval != "undefined") { + 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--; - - if (Module['monitorRunDependencies']) { - Module['monitorRunDependencies'](runDependencies); - } - - if (id) { - assert(runDependencyTracking[id]); - delete runDependencyTracking[id]; - } else { - err('warning: run dependency removed without ID'); + runDependencies--; + if (Module["monitorRunDependencies"]) { + 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 (runDependencies == 0) { - if (runDependencyWatcher !== null) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null; - } - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback(); // can add another dependenciesFulfilled - } + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); } + } } -/** @param {string|number=} what */ -function abort(what) { - { - if (Module['onAbort']) { - Module['onAbort'](what); - } - } +/** @param {string|number=} what */ function abort(what) { + if (Module["onAbort"]) { + Module["onAbort"](what); + } + what = "Aborted(" + what + ")"; + err(what); + ABORT = true; + EXITSTATUS = 1; + /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what); + readyPromiseReject(e); + throw e; +} - what = 'Aborted(' + what + ')'; - // TODO(sbc): Should we remove printing and leave it up to whoever - // catches the exception? - err(what); +var dataURIPrefix = "data:application/octet-stream;base64,"; - 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 - // defintion 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); - - readyPromiseReject(e); - // 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; -} +/** + * Indicates whether filename is a base64 data URI. + * @noinline + */ var isDataURI = filename => filename.startsWith(dataURIPrefix); -// {{MEM_INITIALIZER}} +/** + * Indicates whether filename is delivered via file protocol (as opposed to http/https) + * @noinline + */ var isFileURI = filename => filename.startsWith("file://"); + +function createExportWrapper(name) { + return function() { + assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`); + var f = wasmExports[name]; + assert(f, `exported native function \`${name}\` not found`); + return f.apply(null, arguments); + }; +} -// include: memoryprofiler.js +class EmscriptenEH extends Error {} +class EmscriptenSjLj extends EmscriptenEH {} -// end include: memoryprofiler.js -// include: URIUtils.js +class CppException extends EmscriptenEH { + constructor(excPtr) { + super(excPtr); + this.excPtr = excPtr; + const excInfo = getExceptionMessage(excPtr); + this.name = excInfo[0]; + this.message = excInfo[1]; + } +} +var wasmBinaryFile; -// Prefix of data URIs emitted by SINGLE_FILE and related options. -var dataURIPrefix = 'data:application/octet-stream;base64,'; +wasmBinaryFile = "BeldexLibAppCpp_WASM.wasm"; -// Indicates whether filename is a base64 data URI. -function isDataURI(filename) { - // Prefix of data URIs emitted by SINGLE_FILE and related options. - return filename.startsWith(dataURIPrefix); +if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); } -// Indicates whether filename is delivered via file protocol (as opposed to http/https) -function isFileURI(filename) { - return filename.startsWith('file://'); +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"; } -// end include: URIUtils.js -/** @param {boolean=} fixedasm */ -function createExportWrapper(name, fixedasm) { - return function() { - var displayName = name; - var asm = fixedasm; - if (!fixedasm) { - asm = Module['asm']; - } - assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization'); - if (!asm[name]) { - assert(asm[name], 'exported native function `' + displayName + '` not found'); - } - return asm[name].apply(null, arguments); - }; +function getBinaryPromise(binaryFile) { + if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { + if (typeof fetch == "function" && !isFileURI(binaryFile)) { + return fetch(binaryFile, { + credentials: "same-origin" + }).then(response => { + if (!response["ok"]) { + throw "failed to load wasm binary file at '" + binaryFile + "'"; + } + return response["arrayBuffer"](); + }).catch(() => getBinarySync(binaryFile)); + } else if (readAsync) { + return new Promise((resolve, reject) => { + readAsync(binaryFile, response => resolve(new Uint8Array(/** @type{!ArrayBuffer} */ (response))), reject); + }); + } + } + return Promise.resolve().then(() => getBinarySync(binaryFile)); } -var wasmBinaryFile; - wasmBinaryFile = 'BeldexLibAppCpp_WASM.wasm'; - if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile); +function instantiateArrayBuffer(binaryFile, imports, receiver) { + return getBinaryPromise(binaryFile).then(binary => WebAssembly.instantiate(binary, imports)).then(instance => instance).then(receiver, reason => { + err(`failed to asynchronously prepare wasm: ${reason}`); + 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) && !isFileURI(binaryFile) && !ENVIRONMENT_IS_NODE && typeof fetch == "function") { + return fetch(binaryFile, { + credentials: "same-origin" + }).then(response => { + /** @suppress {checkTypes} */ var result = WebAssembly.instantiateStreaming(response, imports); + return result.then(callback, function(reason) { + err(`wasm streaming compile failed: ${reason}`); + err("falling back to ArrayBuffer instantiation"); + return instantiateArrayBuffer(binaryFile, imports, callback); + }); + }); + } + return instantiateArrayBuffer(binaryFile, imports, callback); +} -function getBinary(file) { +function createWasm() { + var info = { + "env": wasmImports, + "wasi_snapshot_preview1": wasmImports + }; + /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) { + wasmExports = instance.exports; + registerTLSInit(wasmExports["_emscripten_tls_init"]); + wasmTable = wasmExports["__indirect_function_table"]; + assert(wasmTable, "table not found in wasm exports"); + addOnInit(wasmExports["__wasm_call_ctors"]); + wasmModule = module; + removeRunDependency("wasm-instantiate"); + return wasmExports; + } + addRunDependency("wasm-instantiate"); + var trueModule = Module; + function receiveInstantiationResult(result) { + assert(Module === trueModule, "the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?"); + trueModule = null; + receiveInstance(result["instance"], result["module"]); + } + if (Module["instantiateWasm"]) { try { - if (file == wasmBinaryFile && wasmBinary) { - return new Uint8Array(wasmBinary); - } - if (readBinary) { - return readBinary(file); - } - throw "both async and sync fetching of the wasm failed"; - } - catch (err) { - abort(err); + return Module["instantiateWasm"](info, receiveInstance); + } catch (e) { + err(`Module.instantiateWasm callback failed with error: ${e}`); + readyPromiseReject(e); } + } + instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject); + return {}; } -function getBinaryPromise() { - // If we don't have the binary yet, try to to load it asynchronously. - // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url. - // See https://github.com/github/fetch/pull/92#issuecomment-140665932 - // Cordova or Electron apps are typically loaded from a file:// url. - // So use fetch if it is available and the url is not a file, otherwise fall back to XHR. - if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { - if (typeof fetch == 'function' - && !isFileURI(wasmBinaryFile) - ) { - return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { - if (!response['ok']) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; - } - return response['arrayBuffer'](); - }).catch(function () { - return getBinary(wasmBinaryFile); - }); - } - else { - if (readAsync) { - // fetch is not available or url is file => try XHR (readAsync uses XHR internally) - return new Promise(function(resolve, reject) { - readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject) - }); - } - } - } +var tempDouble; - // Otherwise, getBinary should be able to get it synchronously - return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); }); -} +var tempI64; -// Create the wasm instance. -// Receives the wasm imports, returns the exports. -function createWasm() { - // prepare imports - var info = { - 'env': asmLibraryArg, - 'wasi_snapshot_preview1': asmLibraryArg, - }; - // 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) { - var exports = instance.exports; - - Module['asm'] = exports; - - wasmMemory = Module['asm']['memory']; - assert(wasmMemory, "memory not found in wasm exports"); - // This assertion doesn't hold when emscripten is run in --post-link - // mode. - // TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode. - //assert(wasmMemory.buffer.byteLength === 16777216); - updateGlobalBufferAndViews(wasmMemory.buffer); - - wasmTable = Module['asm']['__indirect_function_table']; - assert(wasmTable, "table not found in wasm exports"); - - addOnInit(Module['asm']['__wasm_call_ctors']); - - removeRunDependency('wasm-instantiate'); - - } - // we can't run yet (except in a pthread, where we have a custom sync instantiator) - 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 USE_PTHREADS-enabled path. - receiveInstance(result['instance']); - } - - function instantiateArrayBuffer(receiver) { - return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info); - }).then(function (instance) { - return instance; - }).then(receiver, function(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 legacyModuleProp(prop, newName, incomming = true) { + if (!Object.getOwnPropertyDescriptor(Module, prop)) { + Object.defineProperty(Module, prop, { + configurable: true, + get() { + let extra = incomming ? " (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 instantiateAsync() { - if (!wasmBinary && - typeof WebAssembly.instantiateStreaming == 'function' && - !isDataURI(wasmBinaryFile) && - // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. - !isFileURI(wasmBinaryFile) && - // Avoid instantiateStreaming() on Node.js environment for now, as while - // Node.js v18.1.0 implements it, it does not have a full fetch() - // implementation yet. - // - // Reference: - // https://github.com/emscripten-core/emscripten/pull/16917 - !ENVIRONMENT_IS_NODE && - typeof fetch == 'function') { - return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(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, info); - - return result.then( - receiveInstantiationResult, - 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(receiveInstantiationResult); - }); - }); - } else { - return instantiateArrayBuffer(receiveInstantiationResult); - } - } +function ignoredModuleProp(prop) { + if (Object.getOwnPropertyDescriptor(Module, prop)) { + abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`); + } +} - // 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 { - var exports = Module['instantiateWasm'](info, receiveInstance); - return exports; - } catch(e) { - err('Module.instantiateWasm callback failed with error: ' + e); - // If instantiation fails, reject the module ready promise. - readyPromiseReject(e); - } - } +function isExportedByForceFilesystem(name) { + return name === "FS_createPath" || name === "FS_createDataFile" || name === "FS_createPreloadedFile" || name === "FS_unlink" || name === "addRunDependency" || name === "FS_createLazyFile" || name === "FS_createDevice" || name === "removeRunDependency"; +} - // If instantiation fails, reject the module ready promise. - instantiateAsync().catch(readyPromiseReject); - return {}; // no exports yet; we'll fill them in later +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; + } + }); + } } -// Globals used by JS i64 conversions (see makeSetValue) -var tempDouble; -var tempI64; +missingGlobal("buffer", "Please use HEAP8.buffer or wasmMemory.buffer"); -// === Body === +missingGlobal("asm", "Please use wasmExports instead"); -var ASM_CONSTS = { - 376220: ($0) => { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__error(JS__req_params); }, - 376401: ($0) => { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__success(JS__req_params); }, - 376584: ($0) => { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__status_update(JS__req_params); }, - 376773: () => { Module.fromCpp__SendFundsFormSubmission__willBeginSending({}); }, - 376840: () => { Module.fromCpp__SendFundsFormSubmission__canceled({}); }, - 376899: () => { Module.fromCpp__SendFundsFormSubmission__authenticate(); }, - 376960: ($0) => { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__get_unspent_outs(JS__req_params); }, - 377152: ($0) => { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__get_random_outs(JS__req_params); }, - 377343: ($0) => { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__submit_raw_tx(JS__req_params); } -}; +function missingLibrarySymbol(sym) { + if (typeof globalThis !== "undefined" && !Object.getOwnPropertyDescriptor(globalThis, sym)) { + Object.defineProperty(globalThis, sym, { + configurable: true, + get() { + 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`; + 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; + } + }); + } + 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); + } + }); + } +} +var MAX_UINT8 = (2 ** 8) - 1; +var MAX_UINT16 = (2 ** 16) - 1; +var MAX_UINT32 = (2 ** 32) - 1; +var MAX_UINT53 = (2 ** 53) - 1; - /** @constructor */ - function ExitStatus(status) { - this.name = 'ExitStatus'; - this.message = 'Program terminated with exit(' + status + ')'; - this.status = status; - } +var MAX_UINT64 = (2 ** 64) - 1; - function callRuntimeCallbacks(callbacks) { - while (callbacks.length > 0) { - // Pass the module as the first argument. - callbacks.shift()(Module); - } - } +var MIN_INT8 = -(2 ** (8 - 1)) + 1; - function withStackSave(f) { - var stack = stackSave(); - var ret = f(); - stackRestore(stack); - return ret; - } - function demangle(func) { - // If demangle has failed before, stop demangling any further function names - // This avoids an infinite recursion with malloc()->abort()->stackTrace()->demangle()->malloc()->... - demangle.recursionGuard = (demangle.recursionGuard|0)+1; - if (demangle.recursionGuard > 1) return func; - assert(___cxa_demangle); - return withStackSave(function() { - try { - var s = func; - if (s.startsWith('__Z')) - s = s.substr(1); - var len = lengthBytesUTF8(s)+1; - var buf = stackAlloc(len); - stringToUTF8(s, buf, len); - var status = stackAlloc(4); - var ret = ___cxa_demangle(buf, 0, 0, status); - if (HEAP32[((status)>>2)] === 0 && ret) { - return UTF8ToString(ret); - } - // otherwise, libcxxabi failed - } catch(e) { - } finally { - _free(ret); - if (demangle.recursionGuard < 2) --demangle.recursionGuard; - } - // failure when using libcxxabi, don't demangle - return func; - }); - } +var MIN_INT16 = -(2 ** (16 - 1)) + 1; - - /** - * @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)]; - case 'i32': return HEAP32[((ptr)>>2)]; - case 'i64': return HEAP32[((ptr)>>2)]; - case 'float': return HEAPF32[((ptr)>>2)]; - case 'double': return HEAPF64[((ptr)>>3)]; - case '*': return HEAPU32[((ptr)>>2)]; - default: abort('invalid type for getValue: ' + type); - } - return null; - } +var MIN_INT32 = -(2 ** (32 - 1)) + 1; - - /** - * @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)] = value; break; - case 'i32': HEAP32[((ptr)>>2)] = value; break; - case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break; - case 'float': HEAPF32[((ptr)>>2)] = value; break; - case 'double': HEAPF64[((ptr)>>3)] = value; break; - case '*': HEAPU32[((ptr)>>2)] = value; break; - default: abort('invalid type for setValue: ' + type); - } - } +var MIN_INT53 = -(2 ** (53 - 1)) + 1; - function jsStackTrace() { - var error = new Error(); - if (!error.stack) { - // IE10+ special cases: It does have callstack info, but it is only - // populated if an Error object is thrown, so try that as a special-case. - try { - throw new Error(); - } catch(e) { - error = e; - } - if (!error.stack) { - return '(no stack trace available)'; - } - } - return error.stack.toString(); - } - - function demangleAll(text) { - var regex = - /\b_Z[\w\d_]+/g; - return text.replace(regex, - function(x) { - var y = demangle(x); - return x === y ? x : (y + ' [' + x + ']'); - }); - } - function stackTrace() { - var js = jsStackTrace(); - if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); - return demangleAll(js); - } +var MIN_INT64 = -(2 ** (64 - 1)) + 1; - function warnOnce(text) { - if (!warnOnce.shown) warnOnce.shown = {}; - if (!warnOnce.shown[text]) { - warnOnce.shown[text] = 1; - if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text; - err(text); - } - } +function checkInt(value, bits, min, max) { + assert(Number.isInteger(Number(value)), `attempt to write non-integer (${value}) into integer heap`); + assert(value <= max, `value (${value}) too large to write as ${bits}-bit value`); + assert(value >= min, `value (${value}) too small to write as ${bits}-bit value`); +} - function ___assert_fail(condition, filename, line, func) { - abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']); - } +var checkInt1 = value => checkInt(value, 1, 1); - function ___cxa_allocate_exception(size) { - // Thrown object is prepended by exception metadata block - return _malloc(size + 24) + 24; - } +var checkInt8 = value => checkInt(value, 8, MIN_INT8, MAX_UINT8); - var exceptionCaught = []; - - function exception_addRef(info) { - info.add_ref(); - } - - var uncaughtExceptionCount = 0; - function ___cxa_begin_catch(ptr) { - var info = new ExceptionInfo(ptr); - if (!info.get_caught()) { - info.set_caught(true); - uncaughtExceptionCount--; - } - info.set_rethrown(false); - exceptionCaught.push(info); - exception_addRef(info); - return info.get_exception_ptr(); - } +var checkInt16 = value => checkInt(value, 16, MIN_INT16, MAX_UINT16); - function ___cxa_call_unexpected(exception) { - err('Unexpected exception thrown, this is not properly supported - aborting'); - ABORT = true; - throw exception; - } +var checkInt32 = value => checkInt(value, 32, MIN_INT32, MAX_UINT32); - var exceptionLast = 0; - - /** @constructor */ - function ExceptionInfo(excPtr) { - this.excPtr = excPtr; - this.ptr = excPtr - 24; - - this.set_type = function(type) { - HEAPU32[(((this.ptr)+(4))>>2)] = type; - }; - - this.get_type = function() { - return HEAPU32[(((this.ptr)+(4))>>2)]; - }; - - this.set_destructor = function(destructor) { - HEAPU32[(((this.ptr)+(8))>>2)] = destructor; - }; - - this.get_destructor = function() { - return HEAPU32[(((this.ptr)+(8))>>2)]; - }; - - this.set_refcount = function(refcount) { - HEAP32[((this.ptr)>>2)] = refcount; - }; - - this.set_caught = function (caught) { - caught = caught ? 1 : 0; - HEAP8[(((this.ptr)+(12))>>0)] = caught; - }; - - this.get_caught = function () { - return HEAP8[(((this.ptr)+(12))>>0)] != 0; - }; - - this.set_rethrown = function (rethrown) { - rethrown = rethrown ? 1 : 0; - HEAP8[(((this.ptr)+(13))>>0)] = rethrown; - }; - - this.get_rethrown = function () { - return HEAP8[(((this.ptr)+(13))>>0)] != 0; - }; - - // Initialize native structure fields. Should be called once after allocated. - this.init = function(type, destructor) { - this.set_adjusted_ptr(0); - this.set_type(type); - this.set_destructor(destructor); - this.set_refcount(0); - this.set_caught(false); - this.set_rethrown(false); - } - - this.add_ref = function() { - var value = HEAP32[((this.ptr)>>2)]; - HEAP32[((this.ptr)>>2)] = value + 1; - }; - - // Returns true if last reference released. - this.release_ref = function() { - var prev = HEAP32[((this.ptr)>>2)]; - HEAP32[((this.ptr)>>2)] = prev - 1; - assert(prev > 0); - return prev === 1; - }; - - this.set_adjusted_ptr = function(adjustedPtr) { - HEAPU32[(((this.ptr)+(16))>>2)] = adjustedPtr; - }; - - this.get_adjusted_ptr = function() { - 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. - this.get_exception_ptr = function() { - // 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; - }; - } - function ___cxa_free_exception(ptr) { - try { - return _free(new ExceptionInfo(ptr).ptr); - } catch(e) { - err('exception during __cxa_free_exception: ' + e); - } - } - - var wasmTableMirror = []; - function 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; - } - function exception_decRef(info) { - // A rethrown exception can reach refcount 0; it must not be discarded - // Its next handler will clear the rethrown flag and addRef it, prior to - // final decRef and destruction here - if (info.release_ref() && !info.get_rethrown()) { - var destructor = info.get_destructor(); - if (destructor) { - // In Wasm, destructors return 'this' as in ARM - getWasmTableEntry(destructor)(info.excPtr); - } - ___cxa_free_exception(info.excPtr); - } - } - function ___cxa_end_catch() { - // Clear state flag. - _setThrew(0); - assert(exceptionCaught.length > 0); - // Call destructor if one is registered then clear it. - var info = exceptionCaught.pop(); - - exception_decRef(info); - exceptionLast = 0; // XXX in decRef? - } +var checkInt53 = value => checkInt(value, 53, MIN_INT53, MAX_UINT53); - function ___resumeException(ptr) { - if (!exceptionLast) { exceptionLast = ptr; } - throw ptr; - } - function ___cxa_find_matching_catch_2() { - var thrown = exceptionLast; - 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 i = 0; i < arguments.length; i++) { - var caughtType = arguments[i]; - 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; - } +var checkInt64 = value => checkInt(value, 64, MIN_INT64, MAX_UINT64); - function ___cxa_find_matching_catch_3() { - var thrown = exceptionLast; - 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 i = 0; i < arguments.length; i++) { - var caughtType = arguments[i]; - 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 dbg(text) { + if (ENVIRONMENT_IS_NODE) { + fs.writeSync(2, Array.from(arguments).join(" ") + "\n"); + } else console.warn.apply(console, arguments); +} +var ASM_CONSTS = { + 374384: $0 => { + const JS__req_params_string = Module.UTF8ToString($0); + const JS__req_params = JSON.parse(JS__req_params_string); + Module.fromCpp__SendFundsFormSubmission__error(JS__req_params); + }, + 374565: $0 => { + const JS__req_params_string = Module.UTF8ToString($0); + const JS__req_params = JSON.parse(JS__req_params_string); + Module.fromCpp__SendFundsFormSubmission__success(JS__req_params); + }, + 374748: $0 => { + const JS__req_params_string = Module.UTF8ToString($0); + const JS__req_params = JSON.parse(JS__req_params_string); + Module.fromCpp__SendFundsFormSubmission__status_update(JS__req_params); + }, + 374937: () => { + Module.fromCpp__SendFundsFormSubmission__willBeginSending({}); + }, + 375004: () => { + Module.fromCpp__SendFundsFormSubmission__canceled({}); + }, + 375063: () => { + Module.fromCpp__SendFundsFormSubmission__authenticate(); + }, + 375124: $0 => { + const JS__req_params_string = Module.UTF8ToString($0); + const JS__req_params = JSON.parse(JS__req_params_string); + Module.fromCpp__SendFundsFormSubmission__get_unspent_outs(JS__req_params); + }, + 375316: $0 => { + const JS__req_params_string = Module.UTF8ToString($0); + const JS__req_params = JSON.parse(JS__req_params_string); + Module.fromCpp__SendFundsFormSubmission__get_random_outs(JS__req_params); + }, + 375507: $0 => { + const JS__req_params_string = Module.UTF8ToString($0); + const JS__req_params = JSON.parse(JS__req_params_string); + Module.fromCpp__SendFundsFormSubmission__submit_raw_tx(JS__req_params); + } +}; - function ___cxa_rethrow() { - var info = exceptionCaught.pop(); - if (!info) { - abort('no exception to throw'); - } - var ptr = info.excPtr; - if (!info.get_rethrown()) { - // Only pop if the corresponding push was through rethrow_primary_exception - exceptionCaught.push(info); - info.set_rethrown(true); - info.set_caught(false); - uncaughtExceptionCount++; - } - exceptionLast = ptr; - throw ptr; - } +/** @constructor */ function ExitStatus(status) { + this.name = "ExitStatus"; + this.message = `Program terminated with exit(${status})`; + this.status = status; +} - function ___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++; - throw ptr; - } +var terminateWorker = worker => { + worker.terminate(); + worker.onmessage = e => { + var cmd = e["data"]["cmd"]; + err(`received "${cmd}" command from terminated worker: ${worker.workerID}`); + }; +}; - function ___cxa_uncaught_exceptions() { - return uncaughtExceptionCount; - } +var killThread = pthread_ptr => { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! killThread() can only ever be called from main application thread!"); + assert(pthread_ptr, "Internal Error! Null pthread_ptr in killThread!"); + var worker = PThread.pthreads[pthread_ptr]; + delete PThread.pthreads[pthread_ptr]; + terminateWorker(worker); + __emscripten_thread_free_data(pthread_ptr); + PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker), 1); + worker.pthread_ptr = 0; +}; - function ___handle_stack_overflow(requested) { - requested = requested >>> 0; - abort('stack overflow (Attempt to set SP to 0x' + requested.toString(16) + - ', with stack limits [0x' + _emscripten_stack_get_end().toString(16) + - ' - 0x' + _emscripten_stack_get_base().toString(16) + '])'); - } +var cancelThread = pthread_ptr => { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! cancelThread() can only ever be called from main application thread!"); + assert(pthread_ptr, "Internal Error! Null pthread_ptr in cancelThread!"); + var worker = PThread.pthreads[pthread_ptr]; + worker.postMessage({ + "cmd": "cancel" + }); +}; +var cleanupThread = pthread_ptr => { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! cleanupThread() can only ever be called from main application thread!"); + assert(pthread_ptr, "Internal Error! Null pthread_ptr in cleanupThread!"); + var worker = PThread.pthreads[pthread_ptr]; + assert(worker); + PThread.returnWorkerToPool(worker); +}; - var PATH = {isAbs:(path) => path.charAt(0) === '/',splitPath:(filename) => { - var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; - return splitPathRe.exec(filename).slice(1); - },normalizeArray:(parts, allowAboveRoot) => { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up; up--) { - parts.unshift('..'); - } - } - return parts; - },normalize:(path) => { - var isAbsolute = PATH.isAbs(path), - trailingSlash = path.substr(-1) === '/'; - // Normalize the path - path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/'); - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - return (isAbsolute ? '/' : '') + path; - },dirname:(path) => { - var result = PATH.splitPath(path), - root = result[0], - dir = result[1]; - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - return root + dir; - },basename:(path) => { - // EMSCRIPTEN return '/'' for '/', not an empty string - if (path === '/') return '/'; - path = PATH.normalize(path); - path = path.replace(/\/$/, ""); - var lastSlash = path.lastIndexOf('/'); - if (lastSlash === -1) return path; - return path.substr(lastSlash+1); - },join:function() { - var paths = Array.prototype.slice.call(arguments); - return PATH.normalize(paths.join('/')); - },join2:(l, r) => { - return PATH.normalize(l + '/' + r); - }}; - - function getRandomDevice() { - if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') { - // for modern web browsers - var randomBuffer = new Uint8Array(1); - return () => { crypto.getRandomValues(randomBuffer); return randomBuffer[0]; }; - } else - if (ENVIRONMENT_IS_NODE) { - // for nodejs with or without crypto support included - try { - var crypto_module = require('crypto'); - // nodejs has crypto support - return () => crypto_module['randomBytes'](1)[0]; - } catch (e) { - // nodejs doesn't have crypto support - } - } - // we couldn't find a proper implementation, as Math.random() is not suitable for /dev/random, see emscripten-core/emscripten/pull/7096 - return () => abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); - } - - var PATH_FS = {resolve:function() { - var resolvedPath = '', - resolvedAbsolute = false; - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : FS.cwd(); - // Skip empty and invalid entries - if (typeof path != 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - return ''; // an invalid portion invalidates the whole thing - } - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = PATH.isAbs(path); - } - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/'); - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; - },relative:(from, to) => { - from = PATH_FS.resolve(from).substr(1); - to = PATH_FS.resolve(to).substr(1); - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - return outputParts.join('/'); - }}; - - /** @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 TTY = {ttys:[],init:function () { - // https://github.com/emscripten-core/emscripten/pull/1555 - // if (ENVIRONMENT_IS_NODE) { - // // currently, FS.init does not distinguish if process.stdin is a file or TTY - // // device, it always assumes it's a TTY device. because of this, we're forcing - // // process.stdin to UTF8 encoding to at least make stdin reading compatible - // // with text files until FS.init can be refactored. - // process['stdin']['setEncoding']('utf8'); - // } - },shutdown:function() { - // https://github.com/emscripten-core/emscripten/pull/1555 - // if (ENVIRONMENT_IS_NODE) { - // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)? - // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation - // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists? - // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle - // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call - // process['stdin']['pause'](); - // } - },register:function(dev, ops) { - TTY.ttys[dev] = { input: [], output: [], ops: ops }; - FS.registerDevice(dev, TTY.stream_ops); - },stream_ops:{open:function(stream) { - var tty = TTY.ttys[stream.node.rdev]; - if (!tty) { - throw new FS.ErrnoError(43); - } - stream.tty = tty; - stream.seekable = false; - },close:function(stream) { - // flush any pending line data - stream.tty.ops.fsync(stream.tty); - },fsync:function(stream) { - stream.tty.ops.fsync(stream.tty); - },read:function(stream, buffer, offset, length, pos /* ignored */) { - if (!stream.tty || !stream.tty.ops.get_char) { - throw new FS.ErrnoError(60); - } - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = stream.tty.ops.get_char(stream.tty); - } catch (e) { - throw new FS.ErrnoError(29); - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6); - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset+i] = result; - } - if (bytesRead) { - stream.node.timestamp = Date.now(); - } - return bytesRead; - },write:function(stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.put_char) { - throw new FS.ErrnoError(60); - } - try { - for (var i = 0; i < length; i++) { - stream.tty.ops.put_char(stream.tty, buffer[offset+i]); - } - } catch (e) { - throw new FS.ErrnoError(29); - } - if (length) { - stream.node.timestamp = Date.now(); - } - return i; - }},default_tty_ops:{get_char:function(tty) { - if (!tty.input.length) { - var result = null; - if (ENVIRONMENT_IS_NODE) { - // we will read data by chunks of BUFSIZE - var BUFSIZE = 256; - var buf = Buffer.alloc(BUFSIZE); - var bytesRead = 0; - - try { - bytesRead = fs.readSync(process.stdin.fd, buf, 0, BUFSIZE, -1); - } catch(e) { - // Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes, - // reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0. - if (e.toString().includes('EOF')) bytesRead = 0; - else throw e; - } - - if (bytesRead > 0) { - result = buf.slice(0, bytesRead).toString('utf-8'); - } else { - result = null; - } - } else - if (typeof window != 'undefined' && - typeof window.prompt == 'function') { - // Browser. - result = window.prompt('Input: '); // returns null on cancel - if (result !== null) { - result += '\n'; - } - } else if (typeof readline == 'function') { - // Command line. - result = readline(); - if (result !== null) { - result += '\n'; - } - } - if (!result) { - return null; - } - tty.input = intArrayFromString(result, true); - } - return tty.input.shift(); - },put_char:function(tty, val) { - if (val === null || val === 10) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } else { - if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle. - } - },fsync:function(tty) { - if (tty.output && tty.output.length > 0) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } - }},default_tty1_ops:{put_char:function(tty, val) { - if (val === null || val === 10) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } else { - if (val != 0) tty.output.push(val); - } - },fsync:function(tty) { - if (tty.output && tty.output.length > 0) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } - }}}; - - function zeroMemory(address, size) { - HEAPU8.fill(0, address, address + size); - return address; - } - - function alignMemory(size, alignment) { - assert(alignment, "alignment argument is required"); - return Math.ceil(size / alignment) * alignment; - } - function mmapAlloc(size) { - abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported'); - } - var MEMFS = {ops_table:null,mount:function(mount) { - return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0); - },createNode:function(parent, name, mode, dev) { - if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { - // no supported - throw new FS.ErrnoError(63); - } - if (!MEMFS.ops_table) { - MEMFS.ops_table = { - dir: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - lookup: MEMFS.node_ops.lookup, - mknod: MEMFS.node_ops.mknod, - rename: MEMFS.node_ops.rename, - unlink: MEMFS.node_ops.unlink, - rmdir: MEMFS.node_ops.rmdir, - readdir: MEMFS.node_ops.readdir, - symlink: MEMFS.node_ops.symlink - }, - stream: { - llseek: MEMFS.stream_ops.llseek - } - }, - file: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: { - llseek: MEMFS.stream_ops.llseek, - read: MEMFS.stream_ops.read, - write: MEMFS.stream_ops.write, - allocate: MEMFS.stream_ops.allocate, - mmap: MEMFS.stream_ops.mmap, - msync: MEMFS.stream_ops.msync - } - }, - link: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - readlink: MEMFS.node_ops.readlink - }, - stream: {} - }, - chrdev: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: FS.chrdev_stream_ops - } - }; - } - var node = FS.createNode(parent, name, mode, dev); - if (FS.isDir(node.mode)) { - node.node_ops = MEMFS.ops_table.dir.node; - node.stream_ops = MEMFS.ops_table.dir.stream; - node.contents = {}; - } else if (FS.isFile(node.mode)) { - node.node_ops = MEMFS.ops_table.file.node; - node.stream_ops = MEMFS.ops_table.file.stream; - node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity. - // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred - // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size - // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme. - node.contents = null; - } else if (FS.isLink(node.mode)) { - node.node_ops = MEMFS.ops_table.link.node; - node.stream_ops = MEMFS.ops_table.link.stream; - } else if (FS.isChrdev(node.mode)) { - node.node_ops = MEMFS.ops_table.chrdev.node; - node.stream_ops = MEMFS.ops_table.chrdev.stream; - } - node.timestamp = Date.now(); - // add the new node to the parent - if (parent) { - parent.contents[name] = node; - parent.timestamp = node.timestamp; - } - return node; - },getFileDataAsTypedArray:function(node) { - if (!node.contents) return new Uint8Array(0); - if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes. - return new Uint8Array(node.contents); - },expandFileStorage:function(node, newCapacity) { - var prevCapacity = node.contents ? node.contents.length : 0; - if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough. - // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity. - // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to - // avoid overshooting the allocation cap by a very large margin. - var CAPACITY_DOUBLING_MAX = 1024 * 1024; - newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0); - if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding. - var oldContents = node.contents; - node.contents = new Uint8Array(newCapacity); // Allocate new storage. - if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage. - },resizeFileStorage:function(node, newSize) { - if (node.usedBytes == newSize) return; - if (newSize == 0) { - node.contents = null; // Fully decommit when requesting a resize to zero. - node.usedBytes = 0; - } else { - var oldContents = node.contents; - node.contents = new Uint8Array(newSize); // Allocate new storage. - if (oldContents) { - node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage. - } - node.usedBytes = newSize; - } - },node_ops:{getattr:function(node) { - var attr = {}; - // device numbers reuse inode numbers. - attr.dev = FS.isChrdev(node.mode) ? node.id : 1; - attr.ino = node.id; - attr.mode = node.mode; - attr.nlink = 1; - attr.uid = 0; - attr.gid = 0; - attr.rdev = node.rdev; - if (FS.isDir(node.mode)) { - attr.size = 4096; - } else if (FS.isFile(node.mode)) { - attr.size = node.usedBytes; - } else if (FS.isLink(node.mode)) { - attr.size = node.link.length; - } else { - attr.size = 0; - } - attr.atime = new Date(node.timestamp); - attr.mtime = new Date(node.timestamp); - attr.ctime = new Date(node.timestamp); - // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize), - // but this is not required by the standard. - attr.blksize = 4096; - attr.blocks = Math.ceil(attr.size / attr.blksize); - return attr; - },setattr:function(node, attr) { - if (attr.mode !== undefined) { - node.mode = attr.mode; - } - if (attr.timestamp !== undefined) { - node.timestamp = attr.timestamp; - } - if (attr.size !== undefined) { - MEMFS.resizeFileStorage(node, attr.size); - } - },lookup:function(parent, name) { - throw FS.genericErrors[44]; - },mknod:function(parent, name, mode, dev) { - return MEMFS.createNode(parent, name, mode, dev); - },rename:function(old_node, new_dir, new_name) { - // if we're overwriting a directory at new_name, make sure it's empty. - if (FS.isDir(old_node.mode)) { - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name); - } catch (e) { - } - if (new_node) { - for (var i in new_node.contents) { - throw new FS.ErrnoError(55); - } - } - } - // do the internal rewiring - delete old_node.parent.contents[old_node.name]; - old_node.parent.timestamp = Date.now() - old_node.name = new_name; - new_dir.contents[new_name] = old_node; - new_dir.timestamp = old_node.parent.timestamp; - old_node.parent = new_dir; - },unlink:function(parent, name) { - delete parent.contents[name]; - parent.timestamp = Date.now(); - },rmdir:function(parent, name) { - var node = FS.lookupNode(parent, name); - for (var i in node.contents) { - throw new FS.ErrnoError(55); - } - delete parent.contents[name]; - parent.timestamp = Date.now(); - },readdir:function(node) { - var entries = ['.', '..']; - for (var key in node.contents) { - if (!node.contents.hasOwnProperty(key)) { - continue; - } - entries.push(key); - } - return entries; - },symlink:function(parent, newname, oldpath) { - var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0); - node.link = oldpath; - return node; - },readlink:function(node) { - if (!FS.isLink(node.mode)) { - throw new FS.ErrnoError(28); - } - return node.link; - }},stream_ops:{read:function(stream, buffer, offset, length, position) { - var contents = stream.node.contents; - if (position >= stream.node.usedBytes) return 0; - var size = Math.min(stream.node.usedBytes - position, length); - assert(size >= 0); - if (size > 8 && contents.subarray) { // non-trivial, and typed array - buffer.set(contents.subarray(position, position + size), offset); - } else { - for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i]; - } - return size; - },write:function(stream, buffer, offset, length, position, canOwn) { - // The data buffer should be a typed array view - assert(!(buffer instanceof ArrayBuffer)); - // If the buffer is located in main memory (HEAP), and if - // memory can grow, we can't hold on to references of the - // memory buffer, as they may get invalidated. That means we - // need to do copy its contents. - if (buffer.buffer === HEAP8.buffer) { - canOwn = false; - } - - if (!length) return 0; - var node = stream.node; - node.timestamp = Date.now(); - - if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array? - if (canOwn) { - assert(position === 0, 'canOwn must imply no weird position inside the file'); - node.contents = buffer.subarray(offset, offset + length); - node.usedBytes = length; - return length; - } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data. - node.contents = buffer.slice(offset, offset + length); - node.usedBytes = length; - return length; - } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file? - node.contents.set(buffer.subarray(offset, offset + length), position); - return length; - } - } - - // Appending to an existing file and we need to reallocate, or source data did not come as a typed array. - MEMFS.expandFileStorage(node, position+length); - if (node.contents.subarray && buffer.subarray) { - // Use typed array write which is available. - node.contents.set(buffer.subarray(offset, offset + length), position); - } else { - for (var i = 0; i < length; i++) { - node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not. - } - } - node.usedBytes = Math.max(node.usedBytes, position + length); - return length; - },llseek:function(stream, offset, whence) { - var position = offset; - if (whence === 1) { - position += stream.position; - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - position += stream.node.usedBytes; - } - } - if (position < 0) { - throw new FS.ErrnoError(28); - } - return position; - },allocate:function(stream, offset, length) { - MEMFS.expandFileStorage(stream.node, offset + length); - stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length); - },mmap:function(stream, length, position, prot, flags) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - var ptr; - var allocated; - var contents = stream.node.contents; - // Only make a new copy when MAP_PRIVATE is specified. - if (!(flags & 2) && contents.buffer === buffer) { - // We can't emulate MAP_SHARED when the file is not backed by the buffer - // we're mapping to (e.g. the HEAP buffer). - allocated = false; - ptr = contents.byteOffset; - } else { - // Try to avoid unnecessary slices. - if (position > 0 || position + length < contents.length) { - if (contents.subarray) { - contents = contents.subarray(position, position + length); - } else { - contents = Array.prototype.slice.call(contents, position, position + length); - } - } - allocated = true; - ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48); - } - HEAP8.set(contents, ptr); - } - return { ptr: ptr, allocated: allocated }; - },msync:function(stream, buffer, offset, length, mmapFlags) { - MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); - // should we check if bytesWritten and length are the same? - return 0; - }}}; - - /** @param {boolean=} noRunDep */ - function asyncLoad(url, onload, onerror, noRunDep) { - var dep = !noRunDep ? getUniqueRunDependency('al ' + url) : ''; - readAsync(url, (arrayBuffer) => { - assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).'); - onload(new Uint8Array(arrayBuffer)); - if (dep) removeRunDependency(dep); - }, (event) => { - if (onerror) { - onerror(); - } else { - throw 'Loading data file "' + url + '" failed.'; - } - }); - if (dep) addRunDependency(dep); - } - - var ERRNO_MESSAGES = {0:"Success",1:"Arg list too long",2:"Permission denied",3:"Address already in use",4:"Address not available",5:"Address family not supported by protocol family",6:"No more processes",7:"Socket already connected",8:"Bad file number",9:"Trying to read unreadable message",10:"Mount device busy",11:"Operation canceled",12:"No children",13:"Connection aborted",14:"Connection refused",15:"Connection reset by peer",16:"File locking deadlock error",17:"Destination address required",18:"Math arg out of domain of func",19:"Quota exceeded",20:"File exists",21:"Bad address",22:"File too large",23:"Host is unreachable",24:"Identifier removed",25:"Illegal byte sequence",26:"Connection already in progress",27:"Interrupted system call",28:"Invalid argument",29:"I/O error",30:"Socket is already connected",31:"Is a directory",32:"Too many symbolic links",33:"Too many open files",34:"Too many links",35:"Message too long",36:"Multihop attempted",37:"File or path name too long",38:"Network interface is not configured",39:"Connection reset by network",40:"Network is unreachable",41:"Too many open files in system",42:"No buffer space available",43:"No such device",44:"No such file or directory",45:"Exec format error",46:"No record locks available",47:"The link has been severed",48:"Not enough core",49:"No message of desired type",50:"Protocol not available",51:"No space left on device",52:"Function not implemented",53:"Socket is not connected",54:"Not a directory",55:"Directory not empty",56:"State not recoverable",57:"Socket operation on non-socket",59:"Not a typewriter",60:"No such device or address",61:"Value too large for defined data type",62:"Previous owner died",63:"Not super-user",64:"Broken pipe",65:"Protocol error",66:"Unknown protocol",67:"Protocol wrong type for socket",68:"Math result not representable",69:"Read only file system",70:"Illegal seek",71:"No such process",72:"Stale file handle",73:"Connection timed out",74:"Text file busy",75:"Cross-device link",100:"Device not a stream",101:"Bad font file fmt",102:"Invalid slot",103:"Invalid request code",104:"No anode",105:"Block device required",106:"Channel number out of range",107:"Level 3 halted",108:"Level 3 reset",109:"Link number out of range",110:"Protocol driver not attached",111:"No CSI structure available",112:"Level 2 halted",113:"Invalid exchange",114:"Invalid request descriptor",115:"Exchange full",116:"No data (for no delay io)",117:"Timer expired",118:"Out of streams resources",119:"Machine is not on the network",120:"Package not installed",121:"The object is remote",122:"Advertise error",123:"Srmount error",124:"Communication error on send",125:"Cross mount point (not really error)",126:"Given log. name not unique",127:"f.d. invalid for this operation",128:"Remote address changed",129:"Can access a needed shared lib",130:"Accessing a corrupted shared lib",131:".lib section in a.out corrupted",132:"Attempting to link in too many libs",133:"Attempting to exec a shared library",135:"Streams pipe error",136:"Too many users",137:"Socket type not supported",138:"Not supported",139:"Protocol family not supported",140:"Can't send after socket shutdown",141:"Too many references",142:"Host is down",148:"No medium (in tape drive)",156:"Level 2 not synchronized"}; - - var ERRNO_CODES = {}; - var FS = {root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path, opts = {}) => { - path = PATH_FS.resolve(FS.cwd(), path); - - if (!path) return { path: '', node: null }; - - var defaults = { - follow_mount: true, - recurse_count: 0 - }; - opts = Object.assign(defaults, opts) - - if (opts.recurse_count > 8) { // max recursive lookup of 8 - throw new FS.ErrnoError(32); - } - - // split the path - var parts = PATH.normalizeArray(path.split('/').filter((p) => !!p), false); - - // start at the root - var current = FS.root; - var current_path = '/'; - - for (var i = 0; i < parts.length; i++) { - var islast = (i === parts.length-1); - if (islast && opts.parent) { - // stop resolving - break; - } - - current = FS.lookupNode(current, parts[i]); - current_path = PATH.join2(current_path, parts[i]); - - // jump to the mount's root node if this is a mountpoint - if (FS.isMountpoint(current)) { - if (!islast || (islast && opts.follow_mount)) { - current = current.mounted.root; - } - } - - // by default, lookupPath will not follow a symlink if it is the final path component. - // setting opts.follow = true will override this behavior. - if (!islast || opts.follow) { - var count = 0; - while (FS.isLink(current.mode)) { - var link = FS.readlink(current_path); - current_path = PATH_FS.resolve(PATH.dirname(current_path), link); - - var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count + 1 }); - current = lookup.node; - - if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX). - throw new FS.ErrnoError(32); - } - } - } - } - - return { path: current_path, node: current }; - },getPath:(node) => { - var path; - while (true) { - if (FS.isRoot(node)) { - var mount = node.mount.mountpoint; - if (!path) return mount; - return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path; - } - path = path ? node.name + '/' + path : node.name; - node = node.parent; - } - },hashName:(parentid, name) => { - var hash = 0; - - for (var i = 0; i < name.length; i++) { - hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; - } - return ((parentid + hash) >>> 0) % FS.nameTable.length; - },hashAddNode:(node) => { - var hash = FS.hashName(node.parent.id, node.name); - node.name_next = FS.nameTable[hash]; - FS.nameTable[hash] = node; - },hashRemoveNode:(node) => { - var hash = FS.hashName(node.parent.id, node.name); - if (FS.nameTable[hash] === node) { - FS.nameTable[hash] = node.name_next; - } else { - var current = FS.nameTable[hash]; - while (current) { - if (current.name_next === node) { - current.name_next = node.name_next; - break; - } - current = current.name_next; - } - } - },lookupNode:(parent, name) => { - var errCode = FS.mayLookup(parent); - if (errCode) { - throw new FS.ErrnoError(errCode, parent); - } - var hash = FS.hashName(parent.id, name); - for (var node = FS.nameTable[hash]; node; node = node.name_next) { - var nodeName = node.name; - if (node.parent.id === parent.id && nodeName === name) { - return node; - } - } - // if we failed to find it in the cache, call into the VFS - return FS.lookup(parent, name); - },createNode:(parent, name, mode, rdev) => { - assert(typeof parent == 'object') - var node = new FS.FSNode(parent, name, mode, rdev); - - FS.hashAddNode(node); - - return node; - },destroyNode:(node) => { - FS.hashRemoveNode(node); - },isRoot:(node) => { - return node === node.parent; - },isMountpoint:(node) => { - return !!node.mounted; - },isFile:(mode) => { - return (mode & 61440) === 32768; - },isDir:(mode) => { - return (mode & 61440) === 16384; - },isLink:(mode) => { - return (mode & 61440) === 40960; - },isChrdev:(mode) => { - return (mode & 61440) === 8192; - },isBlkdev:(mode) => { - return (mode & 61440) === 24576; - },isFIFO:(mode) => { - return (mode & 61440) === 4096; - },isSocket:(mode) => { - return (mode & 49152) === 49152; - },flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:(str) => { - var flags = FS.flagModes[str]; - if (typeof flags == 'undefined') { - throw new Error('Unknown file open mode: ' + str); - } - return flags; - },flagsToPermissionString:(flag) => { - var perms = ['r', 'w', 'rw'][flag & 3]; - if ((flag & 512)) { - perms += 'w'; - } - return perms; - },nodePermissions:(node, perms) => { - if (FS.ignorePermissions) { - return 0; - } - // return 0 if any user, group or owner bits are set. - if (perms.includes('r') && !(node.mode & 292)) { - return 2; - } else if (perms.includes('w') && !(node.mode & 146)) { - return 2; - } else if (perms.includes('x') && !(node.mode & 73)) { - return 2; - } - return 0; - },mayLookup:(dir) => { - var errCode = FS.nodePermissions(dir, 'x'); - if (errCode) return errCode; - if (!dir.node_ops.lookup) return 2; - return 0; - },mayCreate:(dir, name) => { - try { - var node = FS.lookupNode(dir, name); - return 20; - } catch (e) { - } - return FS.nodePermissions(dir, 'wx'); - },mayDelete:(dir, name, isdir) => { - var node; - try { - node = FS.lookupNode(dir, name); - } catch (e) { - return e.errno; - } - var errCode = FS.nodePermissions(dir, 'wx'); - if (errCode) { - return errCode; - } - if (isdir) { - if (!FS.isDir(node.mode)) { - return 54; - } - if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { - return 10; - } - } else { - if (FS.isDir(node.mode)) { - return 31; - } - } - return 0; - },mayOpen:(node, flags) => { - if (!node) { - return 44; - } - if (FS.isLink(node.mode)) { - return 32; - } else if (FS.isDir(node.mode)) { - if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write - (flags & 512)) { // TODO: check for O_SEARCH? (== search for dir only) - return 31; - } - } - return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); - },MAX_OPEN_FDS:4096,nextfd:(fd_start = 0, fd_end = FS.MAX_OPEN_FDS) => { - for (var fd = fd_start; fd <= fd_end; fd++) { - if (!FS.streams[fd]) { - return fd; - } - } - throw new FS.ErrnoError(33); - },getStream:(fd) => FS.streams[fd],createStream:(stream, fd_start, fd_end) => { - if (!FS.FSStream) { - FS.FSStream = /** @constructor */ function() { - this.shared = { }; - }; - FS.FSStream.prototype = {}; - Object.defineProperties(FS.FSStream.prototype, { - object: { - /** @this {FS.FSStream} */ - get: function() { return this.node; }, - /** @this {FS.FSStream} */ - set: function(val) { this.node = val; } - }, - isRead: { - /** @this {FS.FSStream} */ - get: function() { return (this.flags & 2097155) !== 1; } - }, - isWrite: { - /** @this {FS.FSStream} */ - get: function() { return (this.flags & 2097155) !== 0; } - }, - isAppend: { - /** @this {FS.FSStream} */ - get: function() { return (this.flags & 1024); } - }, - flags: { - /** @this {FS.FSStream} */ - get: function() { return this.shared.flags; }, - /** @this {FS.FSStream} */ - set: function(val) { this.shared.flags = val; }, - }, - position : { - /** @this {FS.FSStream} */ - get: function() { return this.shared.position; }, - /** @this {FS.FSStream} */ - set: function(val) { this.shared.position = val; }, - }, - }); - } - // clone it, so we can return an instance of FSStream - stream = Object.assign(new FS.FSStream(), stream); - var fd = FS.nextfd(fd_start, fd_end); - stream.fd = fd; - FS.streams[fd] = stream; - return stream; - },closeStream:(fd) => { - FS.streams[fd] = null; - },chrdev_stream_ops:{open:(stream) => { - var device = FS.getDevice(stream.node.rdev); - // override node's stream ops with the device's - stream.stream_ops = device.stream_ops; - // forward the open call - if (stream.stream_ops.open) { - stream.stream_ops.open(stream); - } - },llseek:() => { - throw new FS.ErrnoError(70); - }},major:(dev) => ((dev) >> 8),minor:(dev) => ((dev) & 0xff),makedev:(ma, mi) => ((ma) << 8 | (mi)),registerDevice:(dev, ops) => { - FS.devices[dev] = { stream_ops: ops }; - },getDevice:(dev) => FS.devices[dev],getMounts:(mount) => { - var mounts = []; - var check = [mount]; - - while (check.length) { - var m = check.pop(); - - mounts.push(m); - - check.push.apply(check, m.mounts); - } - - return mounts; - },syncfs:(populate, callback) => { - if (typeof populate == 'function') { - callback = populate; - populate = false; - } - - FS.syncFSRequests++; - - if (FS.syncFSRequests > 1) { - err('warning: ' + FS.syncFSRequests + ' FS.syncfs operations in flight at once, probably just doing extra work'); - } - - var mounts = FS.getMounts(FS.root.mount); - var completed = 0; - - function doCallback(errCode) { - assert(FS.syncFSRequests > 0); - FS.syncFSRequests--; - return callback(errCode); - } - - function done(errCode) { - if (errCode) { - if (!done.errored) { - done.errored = true; - return doCallback(errCode); - } - return; - } - if (++completed >= mounts.length) { - doCallback(null); - } - }; - - // sync all mounts - mounts.forEach((mount) => { - if (!mount.type.syncfs) { - return done(null); - } - mount.type.syncfs(mount, populate, done); - }); - },mount:(type, opts, mountpoint) => { - if (typeof type == 'string') { - // The filesystem was not included, and instead we have an error - // message stored in the variable. - throw type; - } - var root = mountpoint === '/'; - var pseudo = !mountpoint; - var node; - - if (root && FS.root) { - throw new FS.ErrnoError(10); - } else if (!root && !pseudo) { - var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); - - mountpoint = lookup.path; // use the absolute path - node = lookup.node; - - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - - if (!FS.isDir(node.mode)) { - throw new FS.ErrnoError(54); - } - } - - var mount = { - type: type, - opts: opts, - mountpoint: mountpoint, - mounts: [] - }; - - // create a root node for the fs - var mountRoot = type.mount(mount); - mountRoot.mount = mount; - mount.root = mountRoot; - - if (root) { - FS.root = mountRoot; - } else if (node) { - // set as a mountpoint - node.mounted = mount; - - // add the new mount to the current mount's children - if (node.mount) { - node.mount.mounts.push(mount); - } - } - - return mountRoot; - },unmount:(mountpoint) => { - var lookup = FS.lookupPath(mountpoint, { follow_mount: false }); - - if (!FS.isMountpoint(lookup.node)) { - throw new FS.ErrnoError(28); - } - - // destroy the nodes for this mount, and all its child mounts - var node = lookup.node; - var mount = node.mounted; - var mounts = FS.getMounts(mount); - - Object.keys(FS.nameTable).forEach((hash) => { - var current = FS.nameTable[hash]; - - while (current) { - var next = current.name_next; - - if (mounts.includes(current.mount)) { - FS.destroyNode(current); - } - - current = next; - } - }); - - // no longer a mountpoint - node.mounted = null; - - // remove this mount from the child mounts - var idx = node.mount.mounts.indexOf(mount); - assert(idx !== -1); - node.mount.mounts.splice(idx, 1); - },lookup:(parent, name) => { - return parent.node_ops.lookup(parent, name); - },mknod:(path, mode, dev) => { - var lookup = FS.lookupPath(path, { parent: true }); - var parent = lookup.node; - var name = PATH.basename(path); - if (!name || name === '.' || name === '..') { - throw new FS.ErrnoError(28); - } - var errCode = FS.mayCreate(parent, name); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.mknod) { - throw new FS.ErrnoError(63); - } - return parent.node_ops.mknod(parent, name, mode, dev); - },create:(path, mode) => { - mode = mode !== undefined ? mode : 438 /* 0666 */; - mode &= 4095; - mode |= 32768; - return FS.mknod(path, mode, 0); - },mkdir:(path, mode) => { - mode = mode !== undefined ? mode : 511 /* 0777 */; - mode &= 511 | 512; - mode |= 16384; - return FS.mknod(path, mode, 0); - },mkdirTree:(path, mode) => { - var dirs = path.split('/'); - var d = ''; - for (var i = 0; i < dirs.length; ++i) { - if (!dirs[i]) continue; - d += '/' + dirs[i]; - try { - FS.mkdir(d, mode); - } catch(e) { - if (e.errno != 20) throw e; - } - } - },mkdev:(path, mode, dev) => { - if (typeof dev == 'undefined') { - dev = mode; - mode = 438 /* 0666 */; - } - mode |= 8192; - return FS.mknod(path, mode, dev); - },symlink:(oldpath, newpath) => { - if (!PATH_FS.resolve(oldpath)) { - throw new FS.ErrnoError(44); - } - var lookup = FS.lookupPath(newpath, { parent: true }); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44); - } - var newname = PATH.basename(newpath); - var errCode = FS.mayCreate(parent, newname); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.symlink) { - throw new FS.ErrnoError(63); - } - return parent.node_ops.symlink(parent, newname, oldpath); - },rename:(old_path, new_path) => { - var old_dirname = PATH.dirname(old_path); - var new_dirname = PATH.dirname(new_path); - var old_name = PATH.basename(old_path); - var new_name = PATH.basename(new_path); - // parents must exist - var lookup, old_dir, new_dir; - - // let the errors from non existant directories percolate up - lookup = FS.lookupPath(old_path, { parent: true }); - old_dir = lookup.node; - lookup = FS.lookupPath(new_path, { parent: true }); - new_dir = lookup.node; - - if (!old_dir || !new_dir) throw new FS.ErrnoError(44); - // need to be part of the same mount - if (old_dir.mount !== new_dir.mount) { - throw new FS.ErrnoError(75); - } - // source must exist - var old_node = FS.lookupNode(old_dir, old_name); - // old path should not be an ancestor of the new path - var relative = PATH_FS.relative(old_path, new_dirname); - if (relative.charAt(0) !== '.') { - throw new FS.ErrnoError(28); - } - // new path should not be an ancestor of the old path - relative = PATH_FS.relative(new_path, old_dirname); - if (relative.charAt(0) !== '.') { - throw new FS.ErrnoError(55); - } - // see if the new path already exists - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name); - } catch (e) { - // not fatal - } - // early out if nothing needs to change - if (old_node === new_node) { - return; - } - // we'll need to delete the old entry - var isdir = FS.isDir(old_node.mode); - var errCode = FS.mayDelete(old_dir, old_name, isdir); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - // need delete permissions if we'll be overwriting. - // need create permissions if new doesn't already exist. - errCode = new_node ? - FS.mayDelete(new_dir, new_name, isdir) : - FS.mayCreate(new_dir, new_name); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!old_dir.node_ops.rename) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { - throw new FS.ErrnoError(10); - } - // if we are going to change the parent, check write permissions - if (new_dir !== old_dir) { - errCode = FS.nodePermissions(old_dir, 'w'); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - } - // remove the node from the lookup hash - FS.hashRemoveNode(old_node); - // do the underlying fs rename - try { - old_dir.node_ops.rename(old_node, new_dir, new_name); - } catch (e) { - throw e; - } finally { - // add the node back to the hash (in case node_ops.rename - // changed its name) - FS.hashAddNode(old_node); - } - },rmdir:(path) => { - var lookup = FS.lookupPath(path, { parent: true }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, true); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.rmdir) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - parent.node_ops.rmdir(parent, name); - FS.destroyNode(node); - },readdir:(path) => { - var lookup = FS.lookupPath(path, { follow: true }); - var node = lookup.node; - if (!node.node_ops.readdir) { - throw new FS.ErrnoError(54); - } - return node.node_ops.readdir(node); - },unlink:(path) => { - var lookup = FS.lookupPath(path, { parent: true }); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44); - } - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, false); - if (errCode) { - // According to POSIX, we should map EISDIR to EPERM, but - // we instead do what Linux does (and we must, as we use - // the musl linux libc). - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.unlink) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - parent.node_ops.unlink(parent, name); - FS.destroyNode(node); - },readlink:(path) => { - var lookup = FS.lookupPath(path); - var link = lookup.node; - if (!link) { - throw new FS.ErrnoError(44); - } - if (!link.node_ops.readlink) { - throw new FS.ErrnoError(28); - } - return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link)); - },stat:(path, dontFollow) => { - var lookup = FS.lookupPath(path, { follow: !dontFollow }); - var node = lookup.node; - if (!node) { - throw new FS.ErrnoError(44); - } - if (!node.node_ops.getattr) { - throw new FS.ErrnoError(63); - } - return node.node_ops.getattr(node); - },lstat:(path) => { - return FS.stat(path, true); - },chmod:(path, mode, dontFollow) => { - var node; - if (typeof path == 'string') { - var lookup = FS.lookupPath(path, { follow: !dontFollow }); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - node.node_ops.setattr(node, { - mode: (mode & 4095) | (node.mode & ~4095), - timestamp: Date.now() - }); - },lchmod:(path, mode) => { - FS.chmod(path, mode, true); - },fchmod:(fd, mode) => { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8); - } - FS.chmod(stream.node, mode); - },chown:(path, uid, gid, dontFollow) => { - var node; - if (typeof path == 'string') { - var lookup = FS.lookupPath(path, { follow: !dontFollow }); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - node.node_ops.setattr(node, { - timestamp: Date.now() - // we ignore the uid / gid for now - }); - },lchown:(path, uid, gid) => { - FS.chown(path, uid, gid, true); - },fchown:(fd, uid, gid) => { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8); - } - FS.chown(stream.node, uid, gid); - },truncate:(path, len) => { - if (len < 0) { - throw new FS.ErrnoError(28); - } - var node; - if (typeof path == 'string') { - var lookup = FS.lookupPath(path, { follow: true }); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - if (FS.isDir(node.mode)) { - throw new FS.ErrnoError(31); - } - if (!FS.isFile(node.mode)) { - throw new FS.ErrnoError(28); - } - var errCode = FS.nodePermissions(node, 'w'); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - node.node_ops.setattr(node, { - size: len, - timestamp: Date.now() - }); - },ftruncate:(fd, len) => { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(28); - } - FS.truncate(stream.node, len); - },utime:(path, atime, mtime) => { - var lookup = FS.lookupPath(path, { follow: true }); - var node = lookup.node; - node.node_ops.setattr(node, { - timestamp: Math.max(atime, mtime) - }); - },open:(path, flags, mode) => { - if (path === "") { - throw new FS.ErrnoError(44); - } - flags = typeof flags == 'string' ? FS.modeStringToFlags(flags) : flags; - mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode; - if ((flags & 64)) { - mode = (mode & 4095) | 32768; - } else { - mode = 0; - } - var node; - if (typeof path == 'object') { - node = path; - } else { - path = PATH.normalize(path); - try { - var lookup = FS.lookupPath(path, { - follow: !(flags & 131072) - }); - node = lookup.node; - } catch (e) { - // ignore - } - } - // perhaps we need to create the node - var created = false; - if ((flags & 64)) { - if (node) { - // if O_CREAT and O_EXCL are set, error out if the node already exists - if ((flags & 128)) { - throw new FS.ErrnoError(20); - } - } else { - // node doesn't exist, try to create it - node = FS.mknod(path, mode, 0); - created = true; - } - } - if (!node) { - throw new FS.ErrnoError(44); - } - // can't truncate a device - if (FS.isChrdev(node.mode)) { - flags &= ~512; - } - // if asked only for a directory, then this must be one - if ((flags & 65536) && !FS.isDir(node.mode)) { - throw new FS.ErrnoError(54); - } - // check permissions, if this is not a file we just created now (it is ok to - // create and write to a file with read-only permissions; it is read-only - // for later use) - if (!created) { - var errCode = FS.mayOpen(node, flags); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - } - // do truncation if necessary - if ((flags & 512) && !created) { - FS.truncate(node, 0); - } - // we've already handled these, don't pass down to the underlying vfs - flags &= ~(128 | 512 | 131072); - - // register the stream with the filesystem - var stream = FS.createStream({ - node: node, - path: FS.getPath(node), // we want the absolute path to the node - flags: flags, - seekable: true, - position: 0, - stream_ops: node.stream_ops, - // used by the file family libc calls (fopen, fwrite, ferror, etc.) - ungotten: [], - error: false - }); - // call the new stream's open function - if (stream.stream_ops.open) { - stream.stream_ops.open(stream); - } - if (Module['logReadFiles'] && !(flags & 1)) { - if (!FS.readFiles) FS.readFiles = {}; - if (!(path in FS.readFiles)) { - FS.readFiles[path] = 1; - } - } - return stream; - },close:(stream) => { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (stream.getdents) stream.getdents = null; // free readdir state - try { - if (stream.stream_ops.close) { - stream.stream_ops.close(stream); - } - } catch (e) { - throw e; - } finally { - FS.closeStream(stream.fd); - } - stream.fd = null; - },isClosed:(stream) => { - return stream.fd === null; - },llseek:(stream, offset, whence) => { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (!stream.seekable || !stream.stream_ops.llseek) { - throw new FS.ErrnoError(70); - } - if (whence != 0 && whence != 1 && whence != 2) { - throw new FS.ErrnoError(28); - } - stream.position = stream.stream_ops.llseek(stream, offset, whence); - stream.ungotten = []; - return stream.position; - },read:(stream, buffer, offset, length, position) => { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28); - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(8); - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31); - } - if (!stream.stream_ops.read) { - throw new FS.ErrnoError(28); - } - var seeking = typeof position != 'undefined'; - if (!seeking) { - position = stream.position; - } else if (!stream.seekable) { - throw new FS.ErrnoError(70); - } - var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); - if (!seeking) stream.position += bytesRead; - return bytesRead; - },write:(stream, buffer, offset, length, position, canOwn) => { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28); - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8); - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31); - } - if (!stream.stream_ops.write) { - throw new FS.ErrnoError(28); - } - if (stream.seekable && stream.flags & 1024) { - // seek to the end before writing in append mode - FS.llseek(stream, 0, 2); - } - var seeking = typeof position != 'undefined'; - if (!seeking) { - position = stream.position; - } else if (!stream.seekable) { - throw new FS.ErrnoError(70); - } - var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); - if (!seeking) stream.position += bytesWritten; - return bytesWritten; - },allocate:(stream, offset, length) => { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (offset < 0 || length <= 0) { - throw new FS.ErrnoError(28); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8); - } - if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - if (!stream.stream_ops.allocate) { - throw new FS.ErrnoError(138); - } - stream.stream_ops.allocate(stream, offset, length); - },mmap:(stream, length, position, prot, flags) => { - // User requests writing to file (prot & PROT_WRITE != 0). - // Checking if we have permissions to write to the file unless - // MAP_PRIVATE flag is set. According to POSIX spec it is possible - // to write to file opened in read-only mode with MAP_PRIVATE flag, - // as all modifications will be visible only in the memory of - // the current process. - if ((prot & 2) !== 0 - && (flags & 2) === 0 - && (stream.flags & 2097155) !== 2) { - throw new FS.ErrnoError(2); - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(2); - } - if (!stream.stream_ops.mmap) { - throw new FS.ErrnoError(43); - } - return stream.stream_ops.mmap(stream, length, position, prot, flags); - },msync:(stream, buffer, offset, length, mmapFlags) => { - if (!stream.stream_ops.msync) { - return 0; - } - return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags); - },munmap:(stream) => 0,ioctl:(stream, cmd, arg) => { - if (!stream.stream_ops.ioctl) { - throw new FS.ErrnoError(59); - } - return stream.stream_ops.ioctl(stream, cmd, arg); - },readFile:(path, opts = {}) => { - opts.flags = opts.flags || 0; - opts.encoding = opts.encoding || 'binary'; - if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') { - throw new Error('Invalid encoding type "' + opts.encoding + '"'); - } - var ret; - var stream = FS.open(path, opts.flags); - var stat = FS.stat(path); - var length = stat.size; - var buf = new Uint8Array(length); - FS.read(stream, buf, 0, length, 0); - if (opts.encoding === 'utf8') { - ret = UTF8ArrayToString(buf, 0); - } else if (opts.encoding === 'binary') { - ret = buf; - } - FS.close(stream); - return ret; - },writeFile:(path, data, opts = {}) => { - opts.flags = opts.flags || 577; - var stream = FS.open(path, opts.flags, opts.mode); - if (typeof data == 'string') { - var buf = new Uint8Array(lengthBytesUTF8(data)+1); - var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); - FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn); - } else if (ArrayBuffer.isView(data)) { - FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn); - } else { - throw new Error('Unsupported data type'); - } - FS.close(stream); - },cwd:() => FS.currentPath,chdir:(path) => { - var lookup = FS.lookupPath(path, { follow: true }); - if (lookup.node === null) { - throw new FS.ErrnoError(44); - } - if (!FS.isDir(lookup.node.mode)) { - throw new FS.ErrnoError(54); - } - var errCode = FS.nodePermissions(lookup.node, 'x'); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - FS.currentPath = lookup.path; - },createDefaultDirectories:() => { - FS.mkdir('/tmp'); - FS.mkdir('/home'); - FS.mkdir('/home/web_user'); - },createDefaultDevices:() => { - // create /dev - FS.mkdir('/dev'); - // setup /dev/null - FS.registerDevice(FS.makedev(1, 3), { - read: () => 0, - write: (stream, buffer, offset, length, pos) => length, - }); - FS.mkdev('/dev/null', FS.makedev(1, 3)); - // setup /dev/tty and /dev/tty1 - // stderr needs to print output using err() rather than out() - // so we register a second tty just for it. - TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); - TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); - FS.mkdev('/dev/tty', FS.makedev(5, 0)); - FS.mkdev('/dev/tty1', FS.makedev(6, 0)); - // setup /dev/[u]random - var random_device = getRandomDevice(); - FS.createDevice('/dev', 'random', random_device); - FS.createDevice('/dev', 'urandom', random_device); - // we're not going to emulate the actual shm device, - // just create the tmp dirs that reside in it commonly - FS.mkdir('/dev/shm'); - FS.mkdir('/dev/shm/tmp'); - },createSpecialDirectories:() => { - // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the - // name of the stream for fd 6 (see test_unistd_ttyname) - FS.mkdir('/proc'); - var proc_self = FS.mkdir('/proc/self'); - FS.mkdir('/proc/self/fd'); - FS.mount({ - mount: () => { - var node = FS.createNode(proc_self, 'fd', 16384 | 511 /* 0777 */, 73); - node.node_ops = { - lookup: (parent, name) => { - var fd = +name; - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - var ret = { - parent: null, - mount: { mountpoint: 'fake' }, - node_ops: { readlink: () => stream.path }, - }; - ret.parent = ret; // make it look like a simple root node - return ret; - } - }; - return node; - } - }, {}, '/proc/self/fd'); - },createStandardStreams:() => { - // TODO deprecate the old functionality of a single - // input / output callback and that utilizes FS.createDevice - // and instead require a unique set of stream ops - - // by default, we symlink the standard streams to the - // default tty devices. however, if the standard streams - // have been overwritten we create a unique device for - // them instead. - if (Module['stdin']) { - FS.createDevice('/dev', 'stdin', Module['stdin']); - } else { - FS.symlink('/dev/tty', '/dev/stdin'); - } - if (Module['stdout']) { - FS.createDevice('/dev', 'stdout', null, Module['stdout']); - } else { - FS.symlink('/dev/tty', '/dev/stdout'); - } - if (Module['stderr']) { - FS.createDevice('/dev', 'stderr', null, Module['stderr']); - } else { - FS.symlink('/dev/tty1', '/dev/stderr'); - } - - // open default streams for the stdin, stdout and stderr devices - var stdin = FS.open('/dev/stdin', 0); - var stdout = FS.open('/dev/stdout', 1); - var stderr = FS.open('/dev/stderr', 1); - assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')'); - assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')'); - assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')'); - },ensureErrnoError:() => { - if (FS.ErrnoError) return; - FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) { - this.node = node; - this.setErrno = /** @this{Object} */ function(errno) { - this.errno = errno; - for (var key in ERRNO_CODES) { - if (ERRNO_CODES[key] === errno) { - this.code = key; - break; - } - } - }; - this.setErrno(errno); - this.message = ERRNO_MESSAGES[errno]; - - // Try to get a maximally helpful stack trace. On Node.js, getting Error.stack - // now ensures it shows what we want. - if (this.stack) { - // Define the stack property for Node.js 4, which otherwise errors on the next line. - Object.defineProperty(this, "stack", { value: (new Error).stack, writable: true }); - this.stack = demangleAll(this.stack); - } - }; - FS.ErrnoError.prototype = new Error(); - FS.ErrnoError.prototype.constructor = FS.ErrnoError; - // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info) - [44].forEach((code) => { - FS.genericErrors[code] = new FS.ErrnoError(code); - FS.genericErrors[code].stack = ''; - }); - },staticInit:() => { - FS.ensureErrnoError(); - - FS.nameTable = new Array(4096); - - FS.mount(MEMFS, {}, '/'); - - FS.createDefaultDirectories(); - FS.createDefaultDevices(); - FS.createSpecialDirectories(); - - FS.filesystems = { - 'MEMFS': MEMFS, - }; - },init:(input, output, error) => { - assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)'); - FS.init.initialized = true; - - FS.ensureErrnoError(); - - // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here - Module['stdin'] = input || Module['stdin']; - Module['stdout'] = output || Module['stdout']; - Module['stderr'] = error || Module['stderr']; - - FS.createStandardStreams(); - },quit:() => { - FS.init.initialized = false; - // force-flush all streams, so we get musl std streams printed out - _fflush(0); - // close all of our streams - for (var i = 0; i < FS.streams.length; i++) { - var stream = FS.streams[i]; - if (!stream) { - continue; - } - FS.close(stream); - } - },getMode:(canRead, canWrite) => { - var mode = 0; - if (canRead) mode |= 292 | 73; - if (canWrite) mode |= 146; - return mode; - },findObject:(path, dontResolveLastLink) => { - var ret = FS.analyzePath(path, dontResolveLastLink); - if (!ret.exists) { - return null; - } - return ret.object; - },analyzePath:(path, dontResolveLastLink) => { - // operate from within the context of the symlink's target - try { - var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); - path = lookup.path; - } catch (e) { - } - var ret = { - isRoot: false, exists: false, error: 0, name: null, path: null, object: null, - parentExists: false, parentPath: null, parentObject: null - }; - try { - var lookup = FS.lookupPath(path, { parent: true }); - ret.parentExists = true; - ret.parentPath = lookup.path; - ret.parentObject = lookup.node; - ret.name = PATH.basename(path); - lookup = FS.lookupPath(path, { follow: !dontResolveLastLink }); - ret.exists = true; - ret.path = lookup.path; - ret.object = lookup.node; - ret.name = lookup.node.name; - ret.isRoot = lookup.path === '/'; - } catch (e) { - ret.error = e.errno; - }; - return ret; - },createPath:(parent, path, canRead, canWrite) => { - parent = typeof parent == 'string' ? parent : FS.getPath(parent); - var parts = path.split('/').reverse(); - while (parts.length) { - var part = parts.pop(); - if (!part) continue; - var current = PATH.join2(parent, part); - try { - FS.mkdir(current); - } catch (e) { - // ignore EEXIST - } - parent = current; - } - return current; - },createFile:(parent, name, properties, canRead, canWrite) => { - var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name); - var mode = FS.getMode(canRead, canWrite); - return FS.create(path, mode); - },createDataFile:(parent, name, data, canRead, canWrite, canOwn) => { - var path = name; - if (parent) { - parent = typeof parent == 'string' ? parent : FS.getPath(parent); - path = name ? PATH.join2(parent, name) : parent; - } - var mode = FS.getMode(canRead, canWrite); - var node = FS.create(path, mode); - if (data) { - if (typeof data == 'string') { - var arr = new Array(data.length); - for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); - data = arr; - } - // make sure we can write to the file - FS.chmod(node, mode | 146); - var stream = FS.open(node, 577); - FS.write(stream, data, 0, data.length, 0, canOwn); - FS.close(stream); - FS.chmod(node, mode); - } - return node; - },createDevice:(parent, name, input, output) => { - var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name); - var mode = FS.getMode(!!input, !!output); - if (!FS.createDevice.major) FS.createDevice.major = 64; - var dev = FS.makedev(FS.createDevice.major++, 0); - // Create a fake device that a set of stream ops to emulate - // the old behavior. - FS.registerDevice(dev, { - open: (stream) => { - stream.seekable = false; - }, - close: (stream) => { - // flush any pending line data - if (output && output.buffer && output.buffer.length) { - output(10); - } - }, - read: (stream, buffer, offset, length, pos /* ignored */) => { - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = input(); - } catch (e) { - throw new FS.ErrnoError(29); - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6); - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset+i] = result; - } - if (bytesRead) { - stream.node.timestamp = Date.now(); - } - return bytesRead; - }, - write: (stream, buffer, offset, length, pos) => { - for (var i = 0; i < length; i++) { - try { - output(buffer[offset+i]); - } catch (e) { - throw new FS.ErrnoError(29); - } - } - if (length) { - stream.node.timestamp = Date.now(); - } - return i; - } - }); - return FS.mkdev(path, mode, dev); - },forceLoadFile:(obj) => { - if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; - if (typeof XMLHttpRequest != 'undefined') { - throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread."); - } else if (read_) { - // Command-line. - try { - // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as - // read() will try to parse UTF8. - obj.contents = intArrayFromString(read_(obj.url), true); - obj.usedBytes = obj.contents.length; - } catch (e) { - throw new FS.ErrnoError(29); - } - } else { - throw new Error('Cannot load without read() or XMLHttpRequest.'); - } - },createLazyFile:(parent, name, url, canRead, canWrite) => { - // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse. - /** @constructor */ - function LazyUint8Array() { - this.lengthKnown = false; - this.chunks = []; // Loaded chunks. Index is the chunk number - } - LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) { - if (idx > this.length-1 || idx < 0) { - return undefined; - } - var chunkOffset = idx % this.chunkSize; - var chunkNum = (idx / this.chunkSize)|0; - return this.getter(chunkNum)[chunkOffset]; - }; - LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { - this.getter = getter; - }; - LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { - // Find length - var xhr = new XMLHttpRequest(); - xhr.open('HEAD', url, false); - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - var datalength = Number(xhr.getResponseHeader("Content-length")); - var header; - var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; - var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; - - var chunkSize = 1024*1024; // Chunk size in bytes - - if (!hasByteServing) chunkSize = datalength; - - // Function to get a range from the remote URL. - var doXHR = (from, to) => { - if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); - if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!"); - - // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); - - // Some hints to the browser that we want binary data. - xhr.responseType = 'arraybuffer'; - if (xhr.overrideMimeType) { - xhr.overrideMimeType('text/plain; charset=x-user-defined'); - } - - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - if (xhr.response !== undefined) { - return new Uint8Array(/** @type{Array} */(xhr.response || [])); - } - return intArrayFromString(xhr.responseText || '', true); - }; - var lazyArray = this; - lazyArray.setDataGetter((chunkNum) => { - var start = chunkNum * chunkSize; - var end = (chunkNum+1) * chunkSize - 1; // including this byte - end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block - if (typeof lazyArray.chunks[chunkNum] == 'undefined') { - lazyArray.chunks[chunkNum] = doXHR(start, end); - } - if (typeof lazyArray.chunks[chunkNum] == 'undefined') throw new Error('doXHR failed!'); - return lazyArray.chunks[chunkNum]; - }); - - if (usesGzip || !datalength) { - // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length - chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file - datalength = this.getter(0).length; - chunkSize = datalength; - out("LazyFiles on gzip forces download of the whole file when length is accessed"); - } - - this._length = datalength; - this._chunkSize = chunkSize; - this.lengthKnown = true; - }; - if (typeof XMLHttpRequest != 'undefined') { - if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; - var lazyArray = new LazyUint8Array(); - Object.defineProperties(lazyArray, { - length: { - get: /** @this{Object} */ function() { - if (!this.lengthKnown) { - this.cacheLength(); - } - return this._length; - } - }, - chunkSize: { - get: /** @this{Object} */ function() { - if (!this.lengthKnown) { - this.cacheLength(); - } - return this._chunkSize; - } - } - }); - - var properties = { isDevice: false, contents: lazyArray }; - } else { - var properties = { isDevice: false, url: url }; - } - - var node = FS.createFile(parent, name, properties, canRead, canWrite); - // This is a total hack, but I want to get this lazy file code out of the - // core of MEMFS. If we want to keep this lazy file concept I feel it should - // be its own thin LAZYFS proxying calls to MEMFS. - if (properties.contents) { - node.contents = properties.contents; - } else if (properties.url) { - node.contents = null; - node.url = properties.url; - } - // Add a function that defers querying the file size until it is asked the first time. - Object.defineProperties(node, { - usedBytes: { - get: /** @this {FSNode} */ function() { return this.contents.length; } - } - }); - // override each stream op with one that tries to force load the lazy file first - var stream_ops = {}; - var keys = Object.keys(node.stream_ops); - keys.forEach((key) => { - var fn = node.stream_ops[key]; - stream_ops[key] = function forceLoadLazyFile() { - FS.forceLoadFile(node); - return fn.apply(null, arguments); - }; - }); - function writeChunks(stream, buffer, offset, length, position) { - var contents = stream.node.contents; - if (position >= contents.length) - return 0; - var size = Math.min(contents.length - position, length); - assert(size >= 0); - if (contents.slice) { // normal array - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents[position + i]; - } - } else { - for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR - buffer[offset + i] = contents.get(position + i); - } - } - return size; - } - // use a custom read function - stream_ops.read = (stream, buffer, offset, length, position) => { - FS.forceLoadFile(node); - return writeChunks(stream, buffer, offset, length, position) - }; - // use a custom mmap function - stream_ops.mmap = (stream, length, position, prot, flags) => { - FS.forceLoadFile(node); - var ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48); - } - writeChunks(stream, HEAP8, ptr, length, position); - return { ptr: ptr, allocated: true }; - }; - node.stream_ops = stream_ops; - return node; - },createPreloadedFile:(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => { - // TODO we should allow people to just pass in a complete filename instead - // of parent and name being that we just join them anyways - var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; - var dep = getUniqueRunDependency('cp ' + fullname); // might have several active requests for the same fullname - function processData(byteArray) { - function finish(byteArray) { - if (preFinish) preFinish(); - if (!dontCreateFile) { - FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); - } - if (onload) onload(); - removeRunDependency(dep); - } - if (Browser.handledByPreloadPlugin(byteArray, fullname, finish, () => { - if (onerror) onerror(); - removeRunDependency(dep); - })) { - return; - } - finish(byteArray); - } - addRunDependency(dep); - if (typeof url == 'string') { - asyncLoad(url, (byteArray) => processData(byteArray), onerror); - } else { - processData(url); - } - },indexedDB:() => { - return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; - },DB_NAME:() => { - return 'EM_FS_' + window.location.pathname; - },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(paths, onload, onerror) => { - onload = onload || (() => {}); - onerror = onerror || (() => {}); - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); - } catch (e) { - return onerror(e); - } - openRequest.onupgradeneeded = () => { - out('creating db'); - var db = openRequest.result; - db.createObjectStore(FS.DB_STORE_NAME); - }; - openRequest.onsuccess = () => { - var db = openRequest.result; - var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite'); - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0, fail = 0, total = paths.length; - function finish() { - if (fail == 0) onload(); else onerror(); - } - paths.forEach((path) => { - var putRequest = files.put(FS.analyzePath(path).object.contents, path); - putRequest.onsuccess = () => { ok++; if (ok + fail == total) finish() }; - putRequest.onerror = () => { fail++; if (ok + fail == total) finish() }; - }); - transaction.onerror = onerror; - }; - openRequest.onerror = onerror; - },loadFilesFromDB:(paths, onload, onerror) => { - onload = onload || (() => {}); - onerror = onerror || (() => {}); - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); - } catch (e) { - return onerror(e); - } - openRequest.onupgradeneeded = onerror; // no database to load from - openRequest.onsuccess = () => { - var db = openRequest.result; - try { - var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly'); - } catch(e) { - onerror(e); - return; - } - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0, fail = 0, total = paths.length; - function finish() { - if (fail == 0) onload(); else onerror(); - } - paths.forEach((path) => { - var getRequest = files.get(path); - getRequest.onsuccess = () => { - if (FS.analyzePath(path).exists) { - FS.unlink(path); - } - FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true); - ok++; - if (ok + fail == total) finish(); - }; - getRequest.onerror = () => { fail++; if (ok + fail == total) finish() }; - }); - transaction.onerror = onerror; - }; - openRequest.onerror = onerror; - },absolutePath:() => { - abort('FS.absolutePath has been removed; use PATH_FS.resolve instead'); - },createFolder:() => { - abort('FS.createFolder has been removed; use FS.mkdir instead'); - },createLink:() => { - abort('FS.createLink has been removed; use FS.symlink instead'); - },joinPath:() => { - abort('FS.joinPath has been removed; use PATH.join instead'); - },mmapAlloc:() => { - abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc'); - },standardizePath:() => { - abort('FS.standardizePath has been removed; use PATH.normalize instead'); - }}; - var SYSCALLS = {DEFAULT_POLLMASK:5,calculateAt:function(dirfd, path, allowEmpty) { - if (PATH.isAbs(path)) { - return path; - } - // relative path - var dir; - if (dirfd === -100) { - dir = FS.cwd(); - } else { - var dirstream = SYSCALLS.getStreamFromFD(dirfd); - dir = dirstream.path; - } - if (path.length == 0) { - if (!allowEmpty) { - throw new FS.ErrnoError(44);; - } - return dir; - } - return PATH.join2(dir, path); - },doStat:function(func, path, buf) { - try { - var stat = func(path); - } catch (e) { - if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { - // an error occurred while trying to look up the path; we should just report ENOTDIR - return -54; - } - throw e; - } - HEAP32[((buf)>>2)] = stat.dev; - HEAP32[(((buf)+(8))>>2)] = stat.ino; - HEAP32[(((buf)+(12))>>2)] = stat.mode; - HEAPU32[(((buf)+(16))>>2)] = stat.nlink; - HEAP32[(((buf)+(20))>>2)] = stat.uid; - HEAP32[(((buf)+(24))>>2)] = stat.gid; - HEAP32[(((buf)+(28))>>2)] = stat.rdev; - (tempI64 = [stat.size>>>0,(tempDouble=stat.size,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(40))>>2)] = tempI64[0],HEAP32[(((buf)+(44))>>2)] = tempI64[1]); - HEAP32[(((buf)+(48))>>2)] = 4096; - HEAP32[(((buf)+(52))>>2)] = stat.blocks; - (tempI64 = [Math.floor(stat.atime.getTime() / 1000)>>>0,(tempDouble=Math.floor(stat.atime.getTime() / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(56))>>2)] = tempI64[0],HEAP32[(((buf)+(60))>>2)] = tempI64[1]); - HEAPU32[(((buf)+(64))>>2)] = 0; - (tempI64 = [Math.floor(stat.mtime.getTime() / 1000)>>>0,(tempDouble=Math.floor(stat.mtime.getTime() / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(72))>>2)] = tempI64[0],HEAP32[(((buf)+(76))>>2)] = tempI64[1]); - HEAPU32[(((buf)+(80))>>2)] = 0; - (tempI64 = [Math.floor(stat.ctime.getTime() / 1000)>>>0,(tempDouble=Math.floor(stat.ctime.getTime() / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(88))>>2)] = tempI64[0],HEAP32[(((buf)+(92))>>2)] = tempI64[1]); - HEAPU32[(((buf)+(96))>>2)] = 0; - (tempI64 = [stat.ino>>>0,(tempDouble=stat.ino,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[(((buf)+(104))>>2)] = tempI64[0],HEAP32[(((buf)+(108))>>2)] = tempI64[1]); - return 0; - },doMsync:function(addr, stream, len, flags, offset) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - if (flags & 2) { - // MAP_PRIVATE calls need not to be synced back to underlying fs - return 0; - } - var buffer = HEAPU8.slice(addr, addr + len); - FS.msync(stream, buffer, offset, len, flags); - },varargs:undefined,get:function() { - assert(SYSCALLS.varargs != undefined); - SYSCALLS.varargs += 4; - var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)]; - return ret; - },getStr:function(ptr) { - var ret = UTF8ToString(ptr); - return ret; - },getStreamFromFD:function(fd) { - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - return stream; - }}; - function ___syscall_openat(dirfd, path, flags, varargs) { - SYSCALLS.varargs = varargs; +var zeroMemory = (address, size) => { + GROWABLE_HEAP_U8().fill(0, address, address + size); + return address; +}; + +var spawnThread = threadParams => { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! spawnThread() can only ever be called from main application thread!"); + assert(threadParams.pthread_ptr, "Internal error, no pthread ptr!"); + var worker = PThread.getNewWorker(); + if (!worker) { + return 6; + } + assert(!worker.pthread_ptr, "Internal error!"); + PThread.runningWorkers.push(worker); + PThread.pthreads[threadParams.pthread_ptr] = worker; + worker.pthread_ptr = threadParams.pthread_ptr; + var msg = { + "cmd": "run", + "start_routine": threadParams.startRoutine, + "arg": threadParams.arg, + "pthread_ptr": threadParams.pthread_ptr + }; + if (ENVIRONMENT_IS_NODE) { + worker.unref(); + } + worker.postMessage(msg, threadParams.transferList); + return 0; +}; + +var runtimeKeepaliveCounter = 0; + +var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0; + +var PATH = { + isAbs: path => path.charAt(0) === "/", + splitPath: filename => { + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + return splitPathRe.exec(filename).slice(1); + }, + normalizeArray: (parts, allowAboveRoot) => { + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === ".") { + parts.splice(i, 1); + } else if (last === "..") { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + if (allowAboveRoot) { + for (;up; up--) { + parts.unshift(".."); + } + } + return parts; + }, + normalize: path => { + var isAbsolute = PATH.isAbs(path), trailingSlash = path.substr(-1) === "/"; + path = PATH.normalizeArray(path.split("/").filter(p => !!p), !isAbsolute).join("/"); + if (!path && !isAbsolute) { + path = "."; + } + if (path && trailingSlash) { + path += "/"; + } + return (isAbsolute ? "/" : "") + path; + }, + dirname: path => { + var result = PATH.splitPath(path), root = result[0], dir = result[1]; + if (!root && !dir) { + return "."; + } + if (dir) { + dir = dir.substr(0, dir.length - 1); + } + return root + dir; + }, + basename: path => { + if (path === "/") return "/"; + path = PATH.normalize(path); + path = path.replace(/\/$/, ""); + var lastSlash = path.lastIndexOf("/"); + if (lastSlash === -1) return path; + return path.substr(lastSlash + 1); + }, + join: function() { + var paths = Array.prototype.slice.call(arguments); + return PATH.normalize(paths.join("/")); + }, + join2: (l, r) => PATH.normalize(l + "/" + r) +}; + +var initRandomFill = () => { + if (typeof crypto == "object" && typeof crypto["getRandomValues"] == "function") { + return view => (view.set(crypto.getRandomValues(new Uint8Array(view.byteLength))), + view); + } else if (ENVIRONMENT_IS_NODE) { try { - - path = SYSCALLS.getStr(path); - path = SYSCALLS.calculateAt(dirfd, path); - var mode = varargs ? SYSCALLS.get() : 0; - return FS.open(path, flags, mode).fd; - } catch (e) { - if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e; - return -e.errno; + var crypto_module = require("crypto"); + var randomFillSync = crypto_module["randomFillSync"]; + if (randomFillSync) { + return view => crypto_module["randomFillSync"](view); + } + var randomBytes = crypto_module["randomBytes"]; + return view => (view.set(randomBytes(view.byteLength)), view); + } catch (e) {} + } + abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: (array) => { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); +}; + +var randomFill = view => (randomFill = initRandomFill())(view); + +var PATH_FS = { + resolve: function() { + var resolvedPath = "", resolvedAbsolute = false; + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : FS.cwd(); + if (typeof path != "string") { + throw new TypeError("Arguments to path.resolve must be strings"); + } else if (!path) { + return ""; + } + resolvedPath = path + "/" + resolvedPath; + resolvedAbsolute = PATH.isAbs(path); } + resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(p => !!p), !resolvedAbsolute).join("/"); + return ((resolvedAbsolute ? "/" : "") + resolvedPath) || "."; + }, + relative: (from, to) => { + from = PATH_FS.resolve(from).substr(1); + to = PATH_FS.resolve(to).substr(1); + function trim(arr) { + var start = 0; + for (;start < arr.length; start++) { + if (arr[start] !== "") break; + } + var end = arr.length - 1; + for (;end >= 0; end--) { + if (arr[end] !== "") break; + } + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + var fromParts = trim(from.split("/")); + var toParts = trim(to.split("/")); + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } } + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push(".."); + } + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + return outputParts.join("/"); + } +}; - function __embind_register_bigint(primitiveType, name, size, minRange, maxRange) {} +var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined; - function getShiftFromSize(size) { - switch (size) { - case 1: return 0; - case 2: return 1; - case 4: return 2; - case 8: return 3; - default: - throw new TypeError('Unknown type size: ' + size); - } - } - - function 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 = undefined; - function readLatin1String(ptr) { - var ret = ""; - var c = ptr; - while (HEAPU8[c]) { - ret += embind_charCodes[HEAPU8[c++]]; - } - return ret; - } - - var awaitingDependencies = {}; - - var registeredTypes = {}; - - var typeDependencies = {}; - - var char_0 = 48; - - var char_9 = 57; - function makeLegalFunctionName(name) { - if (undefined === name) { - return '_unknown'; - } - name = name.replace(/[^a-zA-Z0-9_]/g, '$'); - var f = name.charCodeAt(0); - if (f >= char_0 && f <= char_9) { - return '_' + name; - } - return name; - } - function createNamedFunction(name, body) { - name = makeLegalFunctionName(name); - /*jshint evil:true*/ - return new Function( - "body", - "return function " + name + "() {\n" + - " \"use strict\";" + - " return body.apply(this, arguments);\n" + - "};\n" - )(body); +/** + * 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) => { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; + if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { + return UTF8Decoder.decode(heapOrArray.buffer instanceof SharedArrayBuffer ? heapOrArray.slice(idx, endPtr) : heapOrArray.subarray(idx, endPtr)); + } + var str = ""; + while (idx < endPtr) { + 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; +}; + +var FS_stdin_getChar_buffer = []; + +var lengthBytesUTF8 = str => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var c = str.charCodeAt(i); + 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) => { + assert(typeof str === "string", `stringToUTF8Array expects a string (got ${typeof str})`); + if (!(maxBytesToWrite > 0)) return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + 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++] = u; + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 192 | (u >> 6); + heap[outIdx++] = 128 | (u & 63); + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 224 | (u >> 12); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 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++] = 240 | (u >> 18); + heap[outIdx++] = 128 | ((u >> 12) & 63); + heap[outIdx++] = 128 | ((u >> 6) & 63); + heap[outIdx++] = 128 | (u & 63); + } + } + heap[outIdx] = 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 FS_stdin_getChar = () => { + if (!FS_stdin_getChar_buffer.length) { + var result = null; + if (ENVIRONMENT_IS_NODE) { + var BUFSIZE = 256; + var buf = Buffer.alloc(BUFSIZE); + var bytesRead = 0; + /** @suppress {missingProperties} */ var fd = process.stdin.fd; + try { + bytesRead = fs.readSync(fd, buf); + } catch (e) { + if (e.toString().includes("EOF")) bytesRead = 0; else throw e; + } + if (bytesRead > 0) { + result = buf.slice(0, bytesRead).toString("utf-8"); + } else { + result = null; + } + } else if (typeof window != "undefined" && typeof window.prompt == "function") { + result = window.prompt("Input: "); + if (result !== null) { + result += "\n"; + } + } else if (typeof readline == "function") { + result = readline(); + if (result !== null) { + result += "\n"; + } + } + if (!result) { + return null; + } + FS_stdin_getChar_buffer = intArrayFromString(result, true); + } + return FS_stdin_getChar_buffer.shift(); +}; + +var TTY = { + ttys: [], + init() {}, + shutdown() {}, + register(dev, ops) { + TTY.ttys[dev] = { + input: [], + output: [], + ops: ops + }; + FS.registerDevice(dev, TTY.stream_ops); + }, + stream_ops: { + open(stream) { + var tty = TTY.ttys[stream.node.rdev]; + if (!tty) { + throw new FS.ErrnoError(43); + } + stream.tty = tty; + stream.seekable = false; + }, + close(stream) { + stream.tty.ops.fsync(stream.tty); + }, + fsync(stream) { + stream.tty.ops.fsync(stream.tty); + }, + read(stream, buffer, offset, length, pos) { + /* ignored */ if (!stream.tty || !stream.tty.ops.get_char) { + throw new FS.ErrnoError(60); + } + var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = stream.tty.ops.get_char(stream.tty); + } catch (e) { + throw new FS.ErrnoError(29); } - function 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; + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); } - var BindingError = undefined; - function throwBindingError(message) { - throw new BindingError(message); + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + if (!stream.tty || !stream.tty.ops.put_char) { + throw new FS.ErrnoError(60); + } + try { + for (var i = 0; i < length; i++) { + stream.tty.ops.put_char(stream.tty, buffer[offset + i]); } - - var InternalError = undefined; - function throwInternalError(message) { - throw new InternalError(message); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + } + }, + default_tty_ops: { + get_char(tty) { + return FS_stdin_getChar(); + }, + put_char(tty, val) { + if (val === null || val === 10) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync(tty) { + if (tty.output && tty.output.length > 0) { + out(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + }, + ioctl_tcgets(tty) { + return { + c_iflag: 25856, + c_oflag: 5, + c_cflag: 191, + c_lflag: 35387, + c_cc: [ 3, 28, 127, 21, 4, 0, 1, 0, 17, 19, 26, 0, 18, 15, 23, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] + }; + }, + ioctl_tcsets(tty, optional_actions, data) { + return 0; + }, + ioctl_tiocgwinsz(tty) { + return [ 24, 80 ]; + } + }, + default_tty1_ops: { + put_char(tty, val) { + if (val === null || val === 10) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } else { + if (val != 0) tty.output.push(val); + } + }, + fsync(tty) { + if (tty.output && tty.output.length > 0) { + err(UTF8ArrayToString(tty.output, 0)); + tty.output = []; + } + } + } +}; + +var alignMemory = (size, alignment) => { + assert(alignment, "alignment argument is required"); + return Math.ceil(size / alignment) * alignment; +}; + +var mmapAlloc = size => { + abort("internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported"); +}; + +var MEMFS = { + ops_table: null, + mount(mount) { + return MEMFS.createNode(null, "/", 16384 | 511, /* 0777 */ 0); + }, + createNode(parent, name, mode, dev) { + if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { + throw new FS.ErrnoError(63); + } + if (!MEMFS.ops_table) { + MEMFS.ops_table = { + dir: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + lookup: MEMFS.node_ops.lookup, + mknod: MEMFS.node_ops.mknod, + rename: MEMFS.node_ops.rename, + unlink: MEMFS.node_ops.unlink, + rmdir: MEMFS.node_ops.rmdir, + readdir: MEMFS.node_ops.readdir, + symlink: MEMFS.node_ops.symlink + }, + stream: { + llseek: MEMFS.stream_ops.llseek + } + }, + file: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: { + llseek: MEMFS.stream_ops.llseek, + read: MEMFS.stream_ops.read, + write: MEMFS.stream_ops.write, + allocate: MEMFS.stream_ops.allocate, + mmap: MEMFS.stream_ops.mmap, + msync: MEMFS.stream_ops.msync + } + }, + link: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr, + readlink: MEMFS.node_ops.readlink + }, + stream: {} + }, + chrdev: { + node: { + getattr: MEMFS.node_ops.getattr, + setattr: MEMFS.node_ops.setattr + }, + stream: FS.chrdev_stream_ops + } + }; + } + var node = FS.createNode(parent, name, mode, dev); + if (FS.isDir(node.mode)) { + node.node_ops = MEMFS.ops_table.dir.node; + node.stream_ops = MEMFS.ops_table.dir.stream; + node.contents = {}; + } else if (FS.isFile(node.mode)) { + node.node_ops = MEMFS.ops_table.file.node; + node.stream_ops = MEMFS.ops_table.file.stream; + node.usedBytes = 0; + node.contents = null; + } else if (FS.isLink(node.mode)) { + node.node_ops = MEMFS.ops_table.link.node; + node.stream_ops = MEMFS.ops_table.link.stream; + } else if (FS.isChrdev(node.mode)) { + node.node_ops = MEMFS.ops_table.chrdev.node; + node.stream_ops = MEMFS.ops_table.chrdev.stream; + } + node.timestamp = Date.now(); + if (parent) { + parent.contents[name] = node; + parent.timestamp = node.timestamp; + } + return node; + }, + getFileDataAsTypedArray(node) { + if (!node.contents) return new Uint8Array(0); + if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); + return new Uint8Array(node.contents); + }, + expandFileStorage(node, newCapacity) { + var prevCapacity = node.contents ? node.contents.length : 0; + if (prevCapacity >= newCapacity) return; + var CAPACITY_DOUBLING_MAX = 1024 * 1024; + newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>> 0); + if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); + var oldContents = node.contents; + node.contents = new Uint8Array(newCapacity); + if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); + }, + resizeFileStorage(node, newSize) { + if (node.usedBytes == newSize) return; + if (newSize == 0) { + node.contents = null; + node.usedBytes = 0; + } else { + var oldContents = node.contents; + node.contents = new Uint8Array(newSize); + if (oldContents) { + node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); + } + node.usedBytes = newSize; + } + }, + node_ops: { + getattr(node) { + var attr = {}; + attr.dev = FS.isChrdev(node.mode) ? node.id : 1; + attr.ino = node.id; + attr.mode = node.mode; + attr.nlink = 1; + attr.uid = 0; + attr.gid = 0; + attr.rdev = node.rdev; + if (FS.isDir(node.mode)) { + attr.size = 4096; + } else if (FS.isFile(node.mode)) { + attr.size = node.usedBytes; + } else if (FS.isLink(node.mode)) { + attr.size = node.link.length; + } else { + attr.size = 0; + } + attr.atime = new Date(node.timestamp); + attr.mtime = new Date(node.timestamp); + attr.ctime = new Date(node.timestamp); + attr.blksize = 4096; + attr.blocks = Math.ceil(attr.size / attr.blksize); + return attr; + }, + setattr(node, attr) { + if (attr.mode !== undefined) { + node.mode = attr.mode; + } + if (attr.timestamp !== undefined) { + node.timestamp = attr.timestamp; + } + if (attr.size !== undefined) { + MEMFS.resizeFileStorage(node, attr.size); + } + }, + lookup(parent, name) { + throw FS.genericErrors[44]; + }, + mknod(parent, name, mode, dev) { + return MEMFS.createNode(parent, name, mode, dev); + }, + rename(old_node, new_dir, new_name) { + if (FS.isDir(old_node.mode)) { + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (new_node) { + for (var i in new_node.contents) { + throw new FS.ErrnoError(55); + } } - function 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); - } + } + delete old_node.parent.contents[old_node.name]; + old_node.parent.timestamp = Date.now(); + old_node.name = new_name; + new_dir.contents[new_name] = old_node; + new_dir.timestamp = old_node.parent.timestamp; + old_node.parent = new_dir; + }, + unlink(parent, name) { + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + rmdir(parent, name) { + var node = FS.lookupNode(parent, name); + for (var i in node.contents) { + throw new FS.ErrnoError(55); + } + delete parent.contents[name]; + parent.timestamp = Date.now(); + }, + readdir(node) { + var entries = [ ".", ".." ]; + for (var key in node.contents) { + if (!node.contents.hasOwnProperty(key)) { + continue; + } + entries.push(key); + } + return entries; + }, + symlink(parent, newname, oldpath) { + var node = MEMFS.createNode(parent, newname, 511 | /* 0777 */ 40960, 0); + node.link = oldpath; + return node; + }, + readlink(node) { + if (!FS.isLink(node.mode)) { + throw new FS.ErrnoError(28); + } + return node.link; + } + }, + stream_ops: { + read(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= stream.node.usedBytes) return 0; + var size = Math.min(stream.node.usedBytes - position, length); + assert(size >= 0); + if (size > 8 && contents.subarray) { + buffer.set(contents.subarray(position, position + size), offset); + } else { + for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i]; + } + return size; + }, + write(stream, buffer, offset, length, position, canOwn) { + assert(!(buffer instanceof ArrayBuffer)); + if (buffer.buffer === GROWABLE_HEAP_I8().buffer) { + canOwn = false; + } + if (!length) return 0; + var node = stream.node; + node.timestamp = Date.now(); + if (buffer.subarray && (!node.contents || node.contents.subarray)) { + if (canOwn) { + assert(position === 0, "canOwn must imply no weird position inside the file"); + node.contents = buffer.subarray(offset, offset + length); + node.usedBytes = length; + return length; + } else if (node.usedBytes === 0 && position === 0) { + node.contents = buffer.slice(offset, offset + length); + node.usedBytes = length; + return length; + } else if (position + length <= node.usedBytes) { + node.contents.set(buffer.subarray(offset, offset + length), position); + return length; } - /** @param {Object=} options */ - function registerType(rawType, registeredInstance, options = {}) { - if (!('argPackAdvance' in registeredInstance)) { - throw new TypeError('registerType registeredInstance requires argPackAdvance'); - } - - 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()); - } + } + MEMFS.expandFileStorage(node, position + length); + if (node.contents.subarray && buffer.subarray) { + node.contents.set(buffer.subarray(offset, offset + length), position); + } else { + for (var i = 0; i < length; i++) { + node.contents[position + i] = buffer[offset + i]; } - function __embind_register_bool(rawType, name, size, trueValue, falseValue) { - var shift = getShiftFromSize(size); - - name = readLatin1String(name); - registerType(rawType, { - name: 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': 8, - 'readValueFromPointer': function(pointer) { - // TODO: if heap is fixed (like in asm.js) this could be executed outside - var heap; - if (size === 1) { - heap = HEAP8; - } else if (size === 2) { - heap = HEAP16; - } else if (size === 4) { - heap = HEAP32; - } else { - throw new TypeError("Unknown boolean type size: " + name); - } - return this['fromWireType'](heap[pointer >> shift]); - }, - destructorFunction: null, // This type does not need a destructor - }); + } + node.usedBytes = Math.max(node.usedBytes, position + length); + return length; + }, + llseek(stream, offset, whence) { + var position = offset; + if (whence === 1) { + position += stream.position; + } else if (whence === 2) { + if (FS.isFile(stream.node.mode)) { + position += stream.node.usedBytes; } + } + if (position < 0) { + throw new FS.ErrnoError(28); + } + return position; + }, + allocate(stream, offset, length) { + MEMFS.expandFileStorage(stream.node, offset + length); + stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length); + }, + mmap(stream, length, position, prot, flags) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + var ptr; + var allocated; + var contents = stream.node.contents; + if (!(flags & 2) && contents.buffer === GROWABLE_HEAP_I8().buffer) { + allocated = false; + ptr = contents.byteOffset; + } else { + if (position > 0 || position + length < contents.length) { + if (contents.subarray) { + contents = contents.subarray(position, position + length); + } else { + contents = Array.prototype.slice.call(contents, position, position + length); + } + } + allocated = true; + ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + GROWABLE_HEAP_I8().set(contents, ptr); + } + return { + ptr: ptr, + allocated: allocated + }; + }, + msync(stream, buffer, offset, length, mmapFlags) { + MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); + return 0; + } + } +}; - var emval_free_list = []; - - var emval_handle_array = [{},{value:undefined},{value:null},{value:true},{value:false}]; - function __emval_decref(handle) { - if (handle > 4 && 0 === --emval_handle_array[handle].refcount) { - emval_handle_array[handle] = undefined; - emval_free_list.push(handle); - } - } - - function count_emval_handles() { - var count = 0; - for (var i = 5; i < emval_handle_array.length; ++i) { - if (emval_handle_array[i] !== undefined) { - ++count; - } - } - return count; +/** @param {boolean=} noRunDep */ var asyncLoad = (url, onload, onerror, noRunDep) => { + var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : ""; + readAsync(url, arrayBuffer => { + assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`); + onload(new Uint8Array(arrayBuffer)); + if (dep) removeRunDependency(dep); + }, event => { + if (onerror) { + onerror(); + } else { + throw `Loading data file "${url}" failed.`; + } + }); + if (dep) addRunDependency(dep); +}; + +var FS_createDataFile = (parent, name, fileData, canRead, canWrite, canOwn) => { + FS.createDataFile(parent, name, fileData, canRead, canWrite, canOwn); +}; + +var preloadPlugins = Module["preloadPlugins"] || []; + +var FS_handledByPreloadPlugin = (byteArray, fullname, finish, onerror) => { + if (typeof Browser != "undefined") Browser.init(); + var handled = false; + preloadPlugins.forEach(plugin => { + if (handled) return; + if (plugin["canHandle"](fullname)) { + plugin["handle"](byteArray, fullname, finish, onerror); + handled = true; + } + }); + return handled; +}; + +var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => { + var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; + var dep = getUniqueRunDependency(`cp ${fullname}`); + function processData(byteArray) { + function finish(byteArray) { + if (preFinish) preFinish(); + if (!dontCreateFile) { + FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn); + } + if (onload) onload(); + removeRunDependency(dep); + } + if (FS_handledByPreloadPlugin(byteArray, fullname, finish, () => { + if (onerror) onerror(); + removeRunDependency(dep); + })) { + return; + } + finish(byteArray); + } + addRunDependency(dep); + if (typeof url == "string") { + asyncLoad(url, byteArray => processData(byteArray), onerror); + } else { + processData(url); + } +}; + +var FS_modeStringToFlags = str => { + var flagModes = { + "r": 0, + "r+": 2, + "w": 512 | 64 | 1, + "w+": 512 | 64 | 2, + "a": 1024 | 64 | 1, + "a+": 1024 | 64 | 2 + }; + var flags = flagModes[str]; + if (typeof flags == "undefined") { + throw new Error(`Unknown file open mode: ${str}`); + } + return flags; +}; + +var FS_getMode = (canRead, canWrite) => { + var mode = 0; + if (canRead) mode |= 292 | 73; + if (canWrite) mode |= 146; + return mode; +}; + +var ERRNO_MESSAGES = { + 0: "Success", + 1: "Arg list too long", + 2: "Permission denied", + 3: "Address already in use", + 4: "Address not available", + 5: "Address family not supported by protocol family", + 6: "No more processes", + 7: "Socket already connected", + 8: "Bad file number", + 9: "Trying to read unreadable message", + 10: "Mount device busy", + 11: "Operation canceled", + 12: "No children", + 13: "Connection aborted", + 14: "Connection refused", + 15: "Connection reset by peer", + 16: "File locking deadlock error", + 17: "Destination address required", + 18: "Math arg out of domain of func", + 19: "Quota exceeded", + 20: "File exists", + 21: "Bad address", + 22: "File too large", + 23: "Host is unreachable", + 24: "Identifier removed", + 25: "Illegal byte sequence", + 26: "Connection already in progress", + 27: "Interrupted system call", + 28: "Invalid argument", + 29: "I/O error", + 30: "Socket is already connected", + 31: "Is a directory", + 32: "Too many symbolic links", + 33: "Too many open files", + 34: "Too many links", + 35: "Message too long", + 36: "Multihop attempted", + 37: "File or path name too long", + 38: "Network interface is not configured", + 39: "Connection reset by network", + 40: "Network is unreachable", + 41: "Too many open files in system", + 42: "No buffer space available", + 43: "No such device", + 44: "No such file or directory", + 45: "Exec format error", + 46: "No record locks available", + 47: "The link has been severed", + 48: "Not enough core", + 49: "No message of desired type", + 50: "Protocol not available", + 51: "No space left on device", + 52: "Function not implemented", + 53: "Socket is not connected", + 54: "Not a directory", + 55: "Directory not empty", + 56: "State not recoverable", + 57: "Socket operation on non-socket", + 59: "Not a typewriter", + 60: "No such device or address", + 61: "Value too large for defined data type", + 62: "Previous owner died", + 63: "Not super-user", + 64: "Broken pipe", + 65: "Protocol error", + 66: "Unknown protocol", + 67: "Protocol wrong type for socket", + 68: "Math result not representable", + 69: "Read only file system", + 70: "Illegal seek", + 71: "No such process", + 72: "Stale file handle", + 73: "Connection timed out", + 74: "Text file busy", + 75: "Cross-device link", + 100: "Device not a stream", + 101: "Bad font file fmt", + 102: "Invalid slot", + 103: "Invalid request code", + 104: "No anode", + 105: "Block device required", + 106: "Channel number out of range", + 107: "Level 3 halted", + 108: "Level 3 reset", + 109: "Link number out of range", + 110: "Protocol driver not attached", + 111: "No CSI structure available", + 112: "Level 2 halted", + 113: "Invalid exchange", + 114: "Invalid request descriptor", + 115: "Exchange full", + 116: "No data (for no delay io)", + 117: "Timer expired", + 118: "Out of streams resources", + 119: "Machine is not on the network", + 120: "Package not installed", + 121: "The object is remote", + 122: "Advertise error", + 123: "Srmount error", + 124: "Communication error on send", + 125: "Cross mount point (not really error)", + 126: "Given log. name not unique", + 127: "f.d. invalid for this operation", + 128: "Remote address changed", + 129: "Can access a needed shared lib", + 130: "Accessing a corrupted shared lib", + 131: ".lib section in a.out corrupted", + 132: "Attempting to link in too many libs", + 133: "Attempting to exec a shared library", + 135: "Streams pipe error", + 136: "Too many users", + 137: "Socket type not supported", + 138: "Not supported", + 139: "Protocol family not supported", + 140: "Can't send after socket shutdown", + 141: "Too many references", + 142: "Host is down", + 148: "No medium (in tape drive)", + 156: "Level 2 not synchronized" +}; + +var ERRNO_CODES = { + "EPERM": 63, + "ENOENT": 44, + "ESRCH": 71, + "EINTR": 27, + "EIO": 29, + "ENXIO": 60, + "E2BIG": 1, + "ENOEXEC": 45, + "EBADF": 8, + "ECHILD": 12, + "EAGAIN": 6, + "EWOULDBLOCK": 6, + "ENOMEM": 48, + "EACCES": 2, + "EFAULT": 21, + "ENOTBLK": 105, + "EBUSY": 10, + "EEXIST": 20, + "EXDEV": 75, + "ENODEV": 43, + "ENOTDIR": 54, + "EISDIR": 31, + "EINVAL": 28, + "ENFILE": 41, + "EMFILE": 33, + "ENOTTY": 59, + "ETXTBSY": 74, + "EFBIG": 22, + "ENOSPC": 51, + "ESPIPE": 70, + "EROFS": 69, + "EMLINK": 34, + "EPIPE": 64, + "EDOM": 18, + "ERANGE": 68, + "ENOMSG": 49, + "EIDRM": 24, + "ECHRNG": 106, + "EL2NSYNC": 156, + "EL3HLT": 107, + "EL3RST": 108, + "ELNRNG": 109, + "EUNATCH": 110, + "ENOCSI": 111, + "EL2HLT": 112, + "EDEADLK": 16, + "ENOLCK": 46, + "EBADE": 113, + "EBADR": 114, + "EXFULL": 115, + "ENOANO": 104, + "EBADRQC": 103, + "EBADSLT": 102, + "EDEADLOCK": 16, + "EBFONT": 101, + "ENOSTR": 100, + "ENODATA": 116, + "ETIME": 117, + "ENOSR": 118, + "ENONET": 119, + "ENOPKG": 120, + "EREMOTE": 121, + "ENOLINK": 47, + "EADV": 122, + "ESRMNT": 123, + "ECOMM": 124, + "EPROTO": 65, + "EMULTIHOP": 36, + "EDOTDOT": 125, + "EBADMSG": 9, + "ENOTUNIQ": 126, + "EBADFD": 127, + "EREMCHG": 128, + "ELIBACC": 129, + "ELIBBAD": 130, + "ELIBSCN": 131, + "ELIBMAX": 132, + "ELIBEXEC": 133, + "ENOSYS": 52, + "ENOTEMPTY": 55, + "ENAMETOOLONG": 37, + "ELOOP": 32, + "EOPNOTSUPP": 138, + "EPFNOSUPPORT": 139, + "ECONNRESET": 15, + "ENOBUFS": 42, + "EAFNOSUPPORT": 5, + "EPROTOTYPE": 67, + "ENOTSOCK": 57, + "ENOPROTOOPT": 50, + "ESHUTDOWN": 140, + "ECONNREFUSED": 14, + "EADDRINUSE": 3, + "ECONNABORTED": 13, + "ENETUNREACH": 40, + "ENETDOWN": 38, + "ETIMEDOUT": 73, + "EHOSTDOWN": 142, + "EHOSTUNREACH": 23, + "EINPROGRESS": 26, + "EALREADY": 7, + "EDESTADDRREQ": 17, + "EMSGSIZE": 35, + "EPROTONOSUPPORT": 66, + "ESOCKTNOSUPPORT": 137, + "EADDRNOTAVAIL": 4, + "ENETRESET": 39, + "EISCONN": 30, + "ENOTCONN": 53, + "ETOOMANYREFS": 141, + "EUSERS": 136, + "EDQUOT": 19, + "ESTALE": 72, + "ENOTSUP": 138, + "ENOMEDIUM": 148, + "EILSEQ": 25, + "EOVERFLOW": 61, + "ECANCELED": 11, + "ENOTRECOVERABLE": 56, + "EOWNERDEAD": 62, + "ESTRPIPE": 135 +}; + +var withStackSave = f => { + var stack = stackSave(); + var ret = f(); + stackRestore(stack); + return ret; +}; + +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, GROWABLE_HEAP_U8(), outPtr, maxBytesToWrite); +}; + +var stringToUTF8OnStack = str => { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8(str, ret, size); + return ret; +}; + +/** + * 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})`); + return ptr ? UTF8ArrayToString(GROWABLE_HEAP_U8(), ptr, maxBytesToRead) : ""; +}; + +var demangle = func => { + demangle.recursionGuard = (demangle.recursionGuard | 0) + 1; + if (demangle.recursionGuard > 1) return func; + return withStackSave(() => { + try { + var s = func; + if (s.startsWith("__Z")) s = s.substr(1); + var buf = stringToUTF8OnStack(s); + var status = stackAlloc(4); + var ret = ___cxa_demangle(buf, 0, 0, status); + if (GROWABLE_HEAP_I32()[((status) >> 2)] === 0 && ret) { + return UTF8ToString(ret); + } + } catch (e) {} finally { + _free(ret); + if (demangle.recursionGuard < 2) --demangle.recursionGuard; + } + return func; + }); +}; + +var demangleAll = text => { + var regex = /\b_Z[\w\d_]+/g; + return text.replace(regex, function(x) { + var y = demangle(x); + return x === y ? x : (y + " [" + x + "]"); + }); +}; + +var FS = { + root: null, + mounts: [], + devices: {}, + streams: [], + nextInode: 1, + nameTable: null, + currentPath: "/", + initialized: false, + ignorePermissions: true, + ErrnoError: null, + genericErrors: {}, + filesystems: null, + syncFSRequests: 0, + lookupPath(path, opts = {}) { + path = PATH_FS.resolve(path); + if (!path) return { + path: "", + node: null + }; + var defaults = { + follow_mount: true, + recurse_count: 0 + }; + opts = Object.assign(defaults, opts); + if (opts.recurse_count > 8) { + throw new FS.ErrnoError(32); + } + var parts = path.split("/").filter(p => !!p); + var current = FS.root; + var current_path = "/"; + for (var i = 0; i < parts.length; i++) { + var islast = (i === parts.length - 1); + if (islast && opts.parent) { + break; + } + current = FS.lookupNode(current, parts[i]); + current_path = PATH.join2(current_path, parts[i]); + if (FS.isMountpoint(current)) { + if (!islast || (islast && opts.follow_mount)) { + current = current.mounted.root; } - - function get_first_emval() { - for (var i = 5; i < emval_handle_array.length; ++i) { - if (emval_handle_array[i] !== undefined) { - return emval_handle_array[i]; - } - } - return null; + } + if (!islast || opts.follow) { + var count = 0; + while (FS.isLink(current.mode)) { + var link = FS.readlink(current_path); + current_path = PATH_FS.resolve(PATH.dirname(current_path), link); + var lookup = FS.lookupPath(current_path, { + recurse_count: opts.recurse_count + 1 + }); + current = lookup.node; + if (count++ > 40) { + throw new FS.ErrnoError(32); + } } - function init_emval() { - Module['count_emval_handles'] = count_emval_handles; - Module['get_first_emval'] = get_first_emval; + } + } + return { + path: current_path, + node: current + }; + }, + getPath(node) { + var path; + while (true) { + if (FS.isRoot(node)) { + var mount = node.mount.mountpoint; + if (!path) return mount; + return mount[mount.length - 1] !== "/" ? `${mount}/${path}` : mount + path; + } + path = path ? `${node.name}/${path}` : node.name; + node = node.parent; + } + }, + hashName(parentid, name) { + var hash = 0; + for (var i = 0; i < name.length; i++) { + hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0; + } + return ((parentid + hash) >>> 0) % FS.nameTable.length; + }, + hashAddNode(node) { + var hash = FS.hashName(node.parent.id, node.name); + node.name_next = FS.nameTable[hash]; + FS.nameTable[hash] = node; + }, + hashRemoveNode(node) { + var hash = FS.hashName(node.parent.id, node.name); + if (FS.nameTable[hash] === node) { + FS.nameTable[hash] = node.name_next; + } else { + var current = FS.nameTable[hash]; + while (current) { + if (current.name_next === node) { + current.name_next = node.name_next; + break; } - var Emval = {toValue:(handle) => { - if (!handle) { - throwBindingError('Cannot use deleted val. handle = ' + handle); - } - return emval_handle_array[handle].value; - },toHandle:(value) => { - switch (value) { - case undefined: return 1; - case null: return 2; - case true: return 3; - case false: return 4; - default:{ - var handle = emval_free_list.length ? - emval_free_list.pop() : - emval_handle_array.length; - - emval_handle_array[handle] = {refcount: 1, value: value}; - return handle; - } - } - }}; - - function simpleReadValueFromPointer(pointer) { - return this['fromWireType'](HEAP32[((pointer)>>2)]); + current = current.name_next; + } + } + }, + lookupNode(parent, name) { + var errCode = FS.mayLookup(parent); + if (errCode) { + throw new FS.ErrnoError(errCode, parent); + } + var hash = FS.hashName(parent.id, name); + for (var node = FS.nameTable[hash]; node; node = node.name_next) { + var nodeName = node.name; + if (node.parent.id === parent.id && nodeName === name) { + return node; + } + } + return FS.lookup(parent, name); + }, + createNode(parent, name, mode, rdev) { + assert(typeof parent == "object"); + var node = new FS.FSNode(parent, name, mode, rdev); + FS.hashAddNode(node); + return node; + }, + destroyNode(node) { + FS.hashRemoveNode(node); + }, + isRoot(node) { + return node === node.parent; + }, + isMountpoint(node) { + return !!node.mounted; + }, + isFile(mode) { + return (mode & 61440) === 32768; + }, + isDir(mode) { + return (mode & 61440) === 16384; + }, + isLink(mode) { + return (mode & 61440) === 40960; + }, + isChrdev(mode) { + return (mode & 61440) === 8192; + }, + isBlkdev(mode) { + return (mode & 61440) === 24576; + }, + isFIFO(mode) { + return (mode & 61440) === 4096; + }, + isSocket(mode) { + return (mode & 49152) === 49152; + }, + flagsToPermissionString(flag) { + var perms = [ "r", "w", "rw" ][flag & 3]; + if ((flag & 512)) { + perms += "w"; + } + return perms; + }, + nodePermissions(node, perms) { + if (FS.ignorePermissions) { + return 0; + } + if (perms.includes("r") && !(node.mode & 292)) { + return 2; + } else if (perms.includes("w") && !(node.mode & 146)) { + return 2; + } else if (perms.includes("x") && !(node.mode & 73)) { + return 2; + } + return 0; + }, + mayLookup(dir) { + var errCode = FS.nodePermissions(dir, "x"); + if (errCode) return errCode; + if (!dir.node_ops.lookup) return 2; + return 0; + }, + mayCreate(dir, name) { + try { + var node = FS.lookupNode(dir, name); + return 20; + } catch (e) {} + return FS.nodePermissions(dir, "wx"); + }, + mayDelete(dir, name, isdir) { + var node; + try { + node = FS.lookupNode(dir, name); + } catch (e) { + return e.errno; + } + var errCode = FS.nodePermissions(dir, "wx"); + if (errCode) { + return errCode; + } + if (isdir) { + if (!FS.isDir(node.mode)) { + return 54; + } + if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { + return 10; + } + } else { + if (FS.isDir(node.mode)) { + return 31; + } + } + return 0; + }, + mayOpen(node, flags) { + if (!node) { + return 44; + } + if (FS.isLink(node.mode)) { + return 32; + } else if (FS.isDir(node.mode)) { + if (FS.flagsToPermissionString(flags) !== "r" || (flags & 512)) { + return 31; + } + } + return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); + }, + MAX_OPEN_FDS: 4096, + nextfd() { + for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) { + if (!FS.streams[fd]) { + return fd; + } + } + throw new FS.ErrnoError(33); + }, + getStreamChecked(fd) { + var stream = FS.getStream(fd); + if (!stream) { + throw new FS.ErrnoError(8); + } + return stream; + }, + getStream: fd => FS.streams[fd], + createStream(stream, fd = -1) { + if (!FS.FSStream) { + FS.FSStream = /** @constructor */ function() { + this.shared = {}; + }; + FS.FSStream.prototype = {}; + Object.defineProperties(FS.FSStream.prototype, { + object: { + /** @this {FS.FSStream} */ get() { + return this.node; + }, + /** @this {FS.FSStream} */ set(val) { + this.node = val; + } + }, + isRead: { + /** @this {FS.FSStream} */ get() { + return (this.flags & 2097155) !== 1; + } + }, + isWrite: { + /** @this {FS.FSStream} */ get() { + return (this.flags & 2097155) !== 0; + } + }, + isAppend: { + /** @this {FS.FSStream} */ get() { + return (this.flags & 1024); + } + }, + flags: { + /** @this {FS.FSStream} */ get() { + return this.shared.flags; + }, + /** @this {FS.FSStream} */ set(val) { + this.shared.flags = val; + } + }, + position: { + /** @this {FS.FSStream} */ get() { + return this.shared.position; + }, + /** @this {FS.FSStream} */ set(val) { + this.shared.position = val; + } + } + }); + } + stream = Object.assign(new FS.FSStream, stream); + if (fd == -1) { + fd = FS.nextfd(); + } + stream.fd = fd; + FS.streams[fd] = stream; + return stream; + }, + closeStream(fd) { + FS.streams[fd] = null; + }, + chrdev_stream_ops: { + open(stream) { + var device = FS.getDevice(stream.node.rdev); + stream.stream_ops = device.stream_ops; + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + }, + llseek() { + throw new FS.ErrnoError(70); + } + }, + major: dev => ((dev) >> 8), + minor: dev => ((dev) & 255), + makedev: (ma, mi) => ((ma) << 8 | (mi)), + registerDevice(dev, ops) { + FS.devices[dev] = { + stream_ops: ops + }; + }, + getDevice: dev => FS.devices[dev], + getMounts(mount) { + var mounts = []; + var check = [ mount ]; + while (check.length) { + var m = check.pop(); + mounts.push(m); + check.push.apply(check, m.mounts); + } + return mounts; + }, + syncfs(populate, callback) { + if (typeof populate == "function") { + callback = populate; + populate = false; + } + FS.syncFSRequests++; + if (FS.syncFSRequests > 1) { + err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`); + } + var mounts = FS.getMounts(FS.root.mount); + var completed = 0; + function doCallback(errCode) { + assert(FS.syncFSRequests > 0); + FS.syncFSRequests--; + return callback(errCode); + } + function done(errCode) { + if (errCode) { + if (!done.errored) { + done.errored = true; + return doCallback(errCode); + } + return; + } + if (++completed >= mounts.length) { + doCallback(null); + } + } + mounts.forEach(mount => { + if (!mount.type.syncfs) { + return done(null); + } + mount.type.syncfs(mount, populate, done); + }); + }, + mount(type, opts, mountpoint) { + if (typeof type == "string") { + throw type; + } + var root = mountpoint === "/"; + var pseudo = !mountpoint; + var node; + if (root && FS.root) { + throw new FS.ErrnoError(10); + } else if (!root && !pseudo) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + mountpoint = lookup.path; + node = lookup.node; + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + if (!FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + } + var mount = { + type: type, + opts: opts, + mountpoint: mountpoint, + mounts: [] + }; + var mountRoot = type.mount(mount); + mountRoot.mount = mount; + mount.root = mountRoot; + if (root) { + FS.root = mountRoot; + } else if (node) { + node.mounted = mount; + if (node.mount) { + node.mount.mounts.push(mount); + } + } + return mountRoot; + }, + unmount(mountpoint) { + var lookup = FS.lookupPath(mountpoint, { + follow_mount: false + }); + if (!FS.isMountpoint(lookup.node)) { + throw new FS.ErrnoError(28); + } + var node = lookup.node; + var mount = node.mounted; + var mounts = FS.getMounts(mount); + Object.keys(FS.nameTable).forEach(hash => { + var current = FS.nameTable[hash]; + while (current) { + var next = current.name_next; + if (mounts.includes(current.mount)) { + FS.destroyNode(current); + } + current = next; + } + }); + node.mounted = null; + var idx = node.mount.mounts.indexOf(mount); + assert(idx !== -1); + node.mount.mounts.splice(idx, 1); + }, + lookup(parent, name) { + return parent.node_ops.lookup(parent, name); + }, + mknod(path, mode, dev) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + if (!name || name === "." || name === "..") { + throw new FS.ErrnoError(28); + } + var errCode = FS.mayCreate(parent, name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.mknod) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.mknod(parent, name, mode, dev); + }, + create(path, mode) { + mode = mode !== undefined ? mode : 438; + /* 0666 */ mode &= 4095; + mode |= 32768; + return FS.mknod(path, mode, 0); + }, + mkdir(path, mode) { + mode = mode !== undefined ? mode : 511; + /* 0777 */ mode &= 511 | 512; + mode |= 16384; + return FS.mknod(path, mode, 0); + }, + mkdirTree(path, mode) { + var dirs = path.split("/"); + var d = ""; + for (var i = 0; i < dirs.length; ++i) { + if (!dirs[i]) continue; + d += "/" + dirs[i]; + try { + FS.mkdir(d, mode); + } catch (e) { + if (e.errno != 20) throw e; + } + } + }, + mkdev(path, mode, dev) { + if (typeof dev == "undefined") { + dev = mode; + mode = 438; + } + /* 0666 */ mode |= 8192; + return FS.mknod(path, mode, dev); + }, + symlink(oldpath, newpath) { + if (!PATH_FS.resolve(oldpath)) { + throw new FS.ErrnoError(44); + } + var lookup = FS.lookupPath(newpath, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var newname = PATH.basename(newpath); + var errCode = FS.mayCreate(parent, newname); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.symlink) { + throw new FS.ErrnoError(63); + } + return parent.node_ops.symlink(parent, newname, oldpath); + }, + rename(old_path, new_path) { + var old_dirname = PATH.dirname(old_path); + var new_dirname = PATH.dirname(new_path); + var old_name = PATH.basename(old_path); + var new_name = PATH.basename(new_path); + var lookup, old_dir, new_dir; + lookup = FS.lookupPath(old_path, { + parent: true + }); + old_dir = lookup.node; + lookup = FS.lookupPath(new_path, { + parent: true + }); + new_dir = lookup.node; + if (!old_dir || !new_dir) throw new FS.ErrnoError(44); + if (old_dir.mount !== new_dir.mount) { + throw new FS.ErrnoError(75); + } + var old_node = FS.lookupNode(old_dir, old_name); + var relative = PATH_FS.relative(old_path, new_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(28); + } + relative = PATH_FS.relative(new_path, old_dirname); + if (relative.charAt(0) !== ".") { + throw new FS.ErrnoError(55); + } + var new_node; + try { + new_node = FS.lookupNode(new_dir, new_name); + } catch (e) {} + if (old_node === new_node) { + return; + } + var isdir = FS.isDir(old_node.mode); + var errCode = FS.mayDelete(old_dir, old_name, isdir); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!old_dir.node_ops.rename) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) { + throw new FS.ErrnoError(10); + } + if (new_dir !== old_dir) { + errCode = FS.nodePermissions(old_dir, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + FS.hashRemoveNode(old_node); + try { + old_dir.node_ops.rename(old_node, new_dir, new_name); + } catch (e) { + throw e; + } finally { + FS.hashAddNode(old_node); + } + }, + rmdir(path) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, true); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.rmdir) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.rmdir(parent, name); + FS.destroyNode(node); + }, + readdir(path) { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + if (!node.node_ops.readdir) { + throw new FS.ErrnoError(54); + } + return node.node_ops.readdir(node); + }, + unlink(path) { + var lookup = FS.lookupPath(path, { + parent: true + }); + var parent = lookup.node; + if (!parent) { + throw new FS.ErrnoError(44); + } + var name = PATH.basename(path); + var node = FS.lookupNode(parent, name); + var errCode = FS.mayDelete(parent, name, false); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + if (!parent.node_ops.unlink) { + throw new FS.ErrnoError(63); + } + if (FS.isMountpoint(node)) { + throw new FS.ErrnoError(10); + } + parent.node_ops.unlink(parent, name); + FS.destroyNode(node); + }, + readlink(path) { + var lookup = FS.lookupPath(path); + var link = lookup.node; + if (!link) { + throw new FS.ErrnoError(44); + } + if (!link.node_ops.readlink) { + throw new FS.ErrnoError(28); + } + return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link)); + }, + stat(path, dontFollow) { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + var node = lookup.node; + if (!node) { + throw new FS.ErrnoError(44); + } + if (!node.node_ops.getattr) { + throw new FS.ErrnoError(63); + } + return node.node_ops.getattr(node); + }, + lstat(path) { + return FS.stat(path, true); + }, + chmod(path, mode, dontFollow) { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { + mode: (mode & 4095) | (node.mode & ~4095), + timestamp: Date.now() + }); + }, + lchmod(path, mode) { + FS.chmod(path, mode, true); + }, + fchmod(fd, mode) { + var stream = FS.getStreamChecked(fd); + FS.chmod(stream.node, mode); + }, + chown(path, uid, gid, dontFollow) { + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: !dontFollow + }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + node.node_ops.setattr(node, { + timestamp: Date.now() + }); + }, + lchown(path, uid, gid) { + FS.chown(path, uid, gid, true); + }, + fchown(fd, uid, gid) { + var stream = FS.getStreamChecked(fd); + FS.chown(stream.node, uid, gid); + }, + truncate(path, len) { + if (len < 0) { + throw new FS.ErrnoError(28); + } + var node; + if (typeof path == "string") { + var lookup = FS.lookupPath(path, { + follow: true + }); + node = lookup.node; + } else { + node = path; + } + if (!node.node_ops.setattr) { + throw new FS.ErrnoError(63); + } + if (FS.isDir(node.mode)) { + throw new FS.ErrnoError(31); + } + if (!FS.isFile(node.mode)) { + throw new FS.ErrnoError(28); + } + var errCode = FS.nodePermissions(node, "w"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + node.node_ops.setattr(node, { + size: len, + timestamp: Date.now() + }); + }, + ftruncate(fd, len) { + var stream = FS.getStreamChecked(fd); + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(28); + } + FS.truncate(stream.node, len); + }, + utime(path, atime, mtime) { + var lookup = FS.lookupPath(path, { + follow: true + }); + var node = lookup.node; + node.node_ops.setattr(node, { + timestamp: Math.max(atime, mtime) + }); + }, + open(path, flags, mode) { + if (path === "") { + throw new FS.ErrnoError(44); + } + flags = typeof flags == "string" ? FS_modeStringToFlags(flags) : flags; + mode = typeof mode == "undefined" ? 438 : /* 0666 */ mode; + if ((flags & 64)) { + mode = (mode & 4095) | 32768; + } else { + mode = 0; + } + var node; + if (typeof path == "object") { + node = path; + } else { + path = PATH.normalize(path); + try { + var lookup = FS.lookupPath(path, { + follow: !(flags & 131072) + }); + node = lookup.node; + } catch (e) {} + } + var created = false; + if ((flags & 64)) { + if (node) { + if ((flags & 128)) { + throw new FS.ErrnoError(20); + } + } else { + node = FS.mknod(path, mode, 0); + created = true; + } + } + if (!node) { + throw new FS.ErrnoError(44); + } + if (FS.isChrdev(node.mode)) { + flags &= ~512; + } + if ((flags & 65536) && !FS.isDir(node.mode)) { + throw new FS.ErrnoError(54); + } + if (!created) { + var errCode = FS.mayOpen(node, flags); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + } + if ((flags & 512) && !created) { + FS.truncate(node, 0); + } + flags &= ~(128 | 512 | 131072); + var stream = FS.createStream({ + node: node, + path: FS.getPath(node), + flags: flags, + seekable: true, + position: 0, + stream_ops: node.stream_ops, + ungotten: [], + error: false + }); + if (stream.stream_ops.open) { + stream.stream_ops.open(stream); + } + if (Module["logReadFiles"] && !(flags & 1)) { + if (!FS.readFiles) FS.readFiles = {}; + if (!(path in FS.readFiles)) { + FS.readFiles[path] = 1; + } + } + return stream; + }, + close(stream) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (stream.getdents) stream.getdents = null; + try { + if (stream.stream_ops.close) { + stream.stream_ops.close(stream); + } + } catch (e) { + throw e; + } finally { + FS.closeStream(stream.fd); + } + stream.fd = null; + }, + isClosed(stream) { + return stream.fd === null; + }, + llseek(stream, offset, whence) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (!stream.seekable || !stream.stream_ops.llseek) { + throw new FS.ErrnoError(70); + } + if (whence != 0 && whence != 1 && whence != 2) { + throw new FS.ErrnoError(28); + } + stream.position = stream.stream_ops.llseek(stream, offset, whence); + stream.ungotten = []; + return stream.position; + }, + read(stream, buffer, offset, length, position) { + assert(offset >= 0); + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.read) { + throw new FS.ErrnoError(28); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); + if (!seeking) stream.position += bytesRead; + return bytesRead; + }, + write(stream, buffer, offset, length, position, canOwn) { + assert(offset >= 0); + if (length < 0 || position < 0) { + throw new FS.ErrnoError(28); + } + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(31); + } + if (!stream.stream_ops.write) { + throw new FS.ErrnoError(28); + } + if (stream.seekable && stream.flags & 1024) { + FS.llseek(stream, 0, 2); + } + var seeking = typeof position != "undefined"; + if (!seeking) { + position = stream.position; + } else if (!stream.seekable) { + throw new FS.ErrnoError(70); + } + var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); + if (!seeking) stream.position += bytesWritten; + return bytesWritten; + }, + allocate(stream, offset, length) { + if (FS.isClosed(stream)) { + throw new FS.ErrnoError(8); + } + if (offset < 0 || length <= 0) { + throw new FS.ErrnoError(28); + } + if ((stream.flags & 2097155) === 0) { + throw new FS.ErrnoError(8); + } + if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (!stream.stream_ops.allocate) { + throw new FS.ErrnoError(138); + } + stream.stream_ops.allocate(stream, offset, length); + }, + mmap(stream, length, position, prot, flags) { + if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { + throw new FS.ErrnoError(2); + } + if ((stream.flags & 2097155) === 1) { + throw new FS.ErrnoError(2); + } + if (!stream.stream_ops.mmap) { + throw new FS.ErrnoError(43); + } + return stream.stream_ops.mmap(stream, length, position, prot, flags); + }, + msync(stream, buffer, offset, length, mmapFlags) { + assert(offset >= 0); + if (!stream.stream_ops.msync) { + return 0; + } + return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags); + }, + munmap: stream => 0, + ioctl(stream, cmd, arg) { + if (!stream.stream_ops.ioctl) { + throw new FS.ErrnoError(59); + } + return stream.stream_ops.ioctl(stream, cmd, arg); + }, + readFile(path, opts = {}) { + opts.flags = opts.flags || 0; + opts.encoding = opts.encoding || "binary"; + if (opts.encoding !== "utf8" && opts.encoding !== "binary") { + throw new Error(`Invalid encoding type "${opts.encoding}"`); + } + var ret; + var stream = FS.open(path, opts.flags); + var stat = FS.stat(path); + var length = stat.size; + var buf = new Uint8Array(length); + FS.read(stream, buf, 0, length, 0); + if (opts.encoding === "utf8") { + ret = UTF8ArrayToString(buf, 0); + } else if (opts.encoding === "binary") { + ret = buf; + } + FS.close(stream); + return ret; + }, + writeFile(path, data, opts = {}) { + opts.flags = opts.flags || 577; + var stream = FS.open(path, opts.flags, opts.mode); + if (typeof data == "string") { + var buf = new Uint8Array(lengthBytesUTF8(data) + 1); + var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); + FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn); + } else if (ArrayBuffer.isView(data)) { + FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn); + } else { + throw new Error("Unsupported data type"); + } + FS.close(stream); + }, + cwd: () => FS.currentPath, + chdir(path) { + var lookup = FS.lookupPath(path, { + follow: true + }); + if (lookup.node === null) { + throw new FS.ErrnoError(44); + } + if (!FS.isDir(lookup.node.mode)) { + throw new FS.ErrnoError(54); + } + var errCode = FS.nodePermissions(lookup.node, "x"); + if (errCode) { + throw new FS.ErrnoError(errCode); + } + FS.currentPath = lookup.path; + }, + createDefaultDirectories() { + FS.mkdir("/tmp"); + FS.mkdir("/home"); + FS.mkdir("/home/web_user"); + }, + createDefaultDevices() { + FS.mkdir("/dev"); + FS.registerDevice(FS.makedev(1, 3), { + read: () => 0, + write: (stream, buffer, offset, length, pos) => length + }); + FS.mkdev("/dev/null", FS.makedev(1, 3)); + TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); + TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); + FS.mkdev("/dev/tty", FS.makedev(5, 0)); + FS.mkdev("/dev/tty1", FS.makedev(6, 0)); + var randomBuffer = new Uint8Array(1024), randomLeft = 0; + var randomByte = () => { + if (randomLeft === 0) { + randomLeft = randomFill(randomBuffer).byteLength; + } + return randomBuffer[--randomLeft]; + }; + FS.createDevice("/dev", "random", randomByte); + FS.createDevice("/dev", "urandom", randomByte); + FS.mkdir("/dev/shm"); + FS.mkdir("/dev/shm/tmp"); + }, + createSpecialDirectories() { + FS.mkdir("/proc"); + var proc_self = FS.mkdir("/proc/self"); + FS.mkdir("/proc/self/fd"); + FS.mount({ + mount() { + var node = FS.createNode(proc_self, "fd", 16384 | 511, /* 0777 */ 73); + node.node_ops = { + lookup(parent, name) { + var fd = +name; + var stream = FS.getStreamChecked(fd); + var ret = { + parent: null, + mount: { + mountpoint: "fake" + }, + node_ops: { + readlink: () => stream.path + } + }; + ret.parent = ret; + return ret; + } + }; + return node; + } + }, {}, "/proc/self/fd"); + }, + createStandardStreams() { + if (Module["stdin"]) { + FS.createDevice("/dev", "stdin", Module["stdin"]); + } else { + FS.symlink("/dev/tty", "/dev/stdin"); + } + if (Module["stdout"]) { + FS.createDevice("/dev", "stdout", null, Module["stdout"]); + } else { + FS.symlink("/dev/tty", "/dev/stdout"); + } + if (Module["stderr"]) { + FS.createDevice("/dev", "stderr", null, Module["stderr"]); + } else { + FS.symlink("/dev/tty1", "/dev/stderr"); + } + var stdin = FS.open("/dev/stdin", 0); + var stdout = FS.open("/dev/stdout", 1); + var stderr = FS.open("/dev/stderr", 1); + assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`); + assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`); + assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`); + }, + ensureErrnoError() { + if (FS.ErrnoError) return; + FS.ErrnoError = /** @this{Object} */ function ErrnoError(errno, node) { + this.name = "ErrnoError"; + this.node = node; + this.setErrno = /** @this{Object} */ function(errno) { + this.errno = errno; + for (var key in ERRNO_CODES) { + if (ERRNO_CODES[key] === errno) { + this.code = key; + break; + } + } + }; + this.setErrno(errno); + this.message = ERRNO_MESSAGES[errno]; + if (this.stack) { + Object.defineProperty(this, "stack", { + value: (new Error).stack, + writable: true + }); + this.stack = demangleAll(this.stack); + } + }; + FS.ErrnoError.prototype = new Error; + FS.ErrnoError.prototype.constructor = FS.ErrnoError; + [ 44 ].forEach(code => { + FS.genericErrors[code] = new FS.ErrnoError(code); + FS.genericErrors[code].stack = ""; + }); + }, + staticInit() { + FS.ensureErrnoError(); + FS.nameTable = new Array(4096); + FS.mount(MEMFS, {}, "/"); + FS.createDefaultDirectories(); + FS.createDefaultDevices(); + FS.createSpecialDirectories(); + FS.filesystems = { + "MEMFS": MEMFS + }; + }, + init(input, output, error) { + assert(!FS.init.initialized, "FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)"); + FS.init.initialized = true; + FS.ensureErrnoError(); + Module["stdin"] = input || Module["stdin"]; + Module["stdout"] = output || Module["stdout"]; + Module["stderr"] = error || Module["stderr"]; + FS.createStandardStreams(); + }, + quit() { + FS.init.initialized = false; + _fflush(0); + for (var i = 0; i < FS.streams.length; i++) { + var stream = FS.streams[i]; + if (!stream) { + continue; + } + FS.close(stream); + } + }, + findObject(path, dontResolveLastLink) { + var ret = FS.analyzePath(path, dontResolveLastLink); + if (!ret.exists) { + return null; + } + return ret.object; + }, + analyzePath(path, dontResolveLastLink) { + try { + var lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + path = lookup.path; + } catch (e) {} + var ret = { + isRoot: false, + exists: false, + error: 0, + name: null, + path: null, + object: null, + parentExists: false, + parentPath: null, + parentObject: null + }; + try { + var lookup = FS.lookupPath(path, { + parent: true + }); + ret.parentExists = true; + ret.parentPath = lookup.path; + ret.parentObject = lookup.node; + ret.name = PATH.basename(path); + lookup = FS.lookupPath(path, { + follow: !dontResolveLastLink + }); + ret.exists = true; + ret.path = lookup.path; + ret.object = lookup.node; + ret.name = lookup.node.name; + ret.isRoot = lookup.path === "/"; + } catch (e) { + ret.error = e.errno; + } + return ret; + }, + createPath(parent, path, canRead, canWrite) { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + var parts = path.split("/").reverse(); + while (parts.length) { + var part = parts.pop(); + if (!part) continue; + var current = PATH.join2(parent, part); + try { + FS.mkdir(current); + } catch (e) {} + parent = current; + } + return current; + }, + createFile(parent, name, properties, canRead, canWrite) { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(canRead, canWrite); + return FS.create(path, mode); + }, + createDataFile(parent, name, data, canRead, canWrite, canOwn) { + var path = name; + if (parent) { + parent = typeof parent == "string" ? parent : FS.getPath(parent); + path = name ? PATH.join2(parent, name) : parent; + } + var mode = FS_getMode(canRead, canWrite); + var node = FS.create(path, mode); + if (data) { + if (typeof data == "string") { + var arr = new Array(data.length); + for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); + data = arr; + } + FS.chmod(node, mode | 146); + var stream = FS.open(node, 577); + FS.write(stream, data, 0, data.length, 0, canOwn); + FS.close(stream); + FS.chmod(node, mode); + } + }, + createDevice(parent, name, input, output) { + var path = PATH.join2(typeof parent == "string" ? parent : FS.getPath(parent), name); + var mode = FS_getMode(!!input, !!output); + if (!FS.createDevice.major) FS.createDevice.major = 64; + var dev = FS.makedev(FS.createDevice.major++, 0); + FS.registerDevice(dev, { + open(stream) { + stream.seekable = false; + }, + close(stream) { + if (output && output.buffer && output.buffer.length) { + output(10); } - function __embind_register_emval(rawType, name) { - name = readLatin1String(name); - registerType(rawType, { - name: name, - 'fromWireType': function(handle) { - var rv = Emval.toValue(handle); - __emval_decref(handle); - return rv; - }, - 'toWireType': function(destructors, value) { - return Emval.toHandle(value); - }, - 'argPackAdvance': 8, - 'readValueFromPointer': simpleReadValueFromPointer, - 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 - }); + }, + read(stream, buffer, offset, length, pos) { + /* ignored */ var bytesRead = 0; + for (var i = 0; i < length; i++) { + var result; + try { + result = input(); + } catch (e) { + throw new FS.ErrnoError(29); + } + if (result === undefined && bytesRead === 0) { + throw new FS.ErrnoError(6); + } + if (result === null || result === undefined) break; + bytesRead++; + buffer[offset + i] = result; + } + if (bytesRead) { + stream.node.timestamp = Date.now(); + } + return bytesRead; + }, + write(stream, buffer, offset, length, pos) { + for (var i = 0; i < length; i++) { + try { + output(buffer[offset + i]); + } catch (e) { + throw new FS.ErrnoError(29); + } + } + if (length) { + stream.node.timestamp = Date.now(); + } + return i; + } + }); + return FS.mkdev(path, mode, dev); + }, + forceLoadFile(obj) { + if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; + if (typeof XMLHttpRequest != "undefined") { + throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread."); + } else if (read_) { + try { + obj.contents = intArrayFromString(read_(obj.url), true); + obj.usedBytes = obj.contents.length; + } catch (e) { + throw new FS.ErrnoError(29); + } + } else { + throw new Error("Cannot load without read() or XMLHttpRequest."); + } + }, + createLazyFile(parent, name, url, canRead, canWrite) { + /** @constructor */ function LazyUint8Array() { + this.lengthKnown = false; + this.chunks = []; + } + LazyUint8Array.prototype.get = /** @this{Object} */ function LazyUint8Array_get(idx) { + if (idx > this.length - 1 || idx < 0) { + return undefined; + } + var chunkOffset = idx % this.chunkSize; + var chunkNum = (idx / this.chunkSize) | 0; + return this.getter(chunkNum)[chunkOffset]; + }; + LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { + this.getter = getter; + }; + LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { + var xhr = new XMLHttpRequest; + xhr.open("HEAD", url, false); + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); + var datalength = Number(xhr.getResponseHeader("Content-length")); + var header; + var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; + var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; + var chunkSize = 1024 * 1024; + if (!hasByteServing) chunkSize = datalength; + var doXHR = (from, to) => { + if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); + if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); + xhr.responseType = "arraybuffer"; + if (xhr.overrideMimeType) { + xhr.overrideMimeType("text/plain; charset=x-user-defined"); + } + xhr.send(null); + if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); + if (xhr.response !== undefined) { + return new Uint8Array(/** @type{Array} */ (xhr.response || [])); + } + return intArrayFromString(xhr.responseText || "", true); + }; + var lazyArray = this; + lazyArray.setDataGetter(chunkNum => { + var start = chunkNum * chunkSize; + var end = (chunkNum + 1) * chunkSize - 1; + end = Math.min(end, datalength - 1); + if (typeof lazyArray.chunks[chunkNum] == "undefined") { + lazyArray.chunks[chunkNum] = doXHR(start, end); + } + if (typeof lazyArray.chunks[chunkNum] == "undefined") throw new Error("doXHR failed!"); + return lazyArray.chunks[chunkNum]; + }); + if (usesGzip || !datalength) { + chunkSize = datalength = 1; + datalength = this.getter(0).length; + chunkSize = datalength; + out("LazyFiles on gzip forces download of the whole file when length is accessed"); + } + this._length = datalength; + this._chunkSize = chunkSize; + this.lengthKnown = true; + }; + if (typeof XMLHttpRequest != "undefined") { + if (!ENVIRONMENT_IS_WORKER) throw "Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"; + var lazyArray = new LazyUint8Array; + Object.defineProperties(lazyArray, { + length: { + get: /** @this{Object} */ function() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._length; + } + }, + chunkSize: { + get: /** @this{Object} */ function() { + if (!this.lengthKnown) { + this.cacheLength(); + } + return this._chunkSize; + } + } + }); + var properties = { + isDevice: false, + contents: lazyArray + }; + } else { + var properties = { + isDevice: false, + url: url + }; + } + var node = FS.createFile(parent, name, properties, canRead, canWrite); + if (properties.contents) { + node.contents = properties.contents; + } else if (properties.url) { + node.contents = null; + node.url = properties.url; + } + Object.defineProperties(node, { + usedBytes: { + get: /** @this {FSNode} */ function() { + return this.contents.length; + } + } + }); + var stream_ops = {}; + var keys = Object.keys(node.stream_ops); + keys.forEach(key => { + var fn = node.stream_ops[key]; + stream_ops[key] = function forceLoadLazyFile() { + FS.forceLoadFile(node); + return fn.apply(null, arguments); + }; + }); + function writeChunks(stream, buffer, offset, length, position) { + var contents = stream.node.contents; + if (position >= contents.length) return 0; + var size = Math.min(contents.length - position, length); + assert(size >= 0); + if (contents.slice) { + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents[position + i]; + } + } else { + for (var i = 0; i < size; i++) { + buffer[offset + i] = contents.get(position + i); } + } + return size; + } + stream_ops.read = (stream, buffer, offset, length, position) => { + FS.forceLoadFile(node); + return writeChunks(stream, buffer, offset, length, position); + }; + stream_ops.mmap = (stream, length, position, prot, flags) => { + FS.forceLoadFile(node); + var ptr = mmapAlloc(length); + if (!ptr) { + throw new FS.ErrnoError(48); + } + writeChunks(stream, GROWABLE_HEAP_I8(), ptr, length, position); + return { + ptr: ptr, + allocated: true + }; + }; + node.stream_ops = stream_ops; + return node; + }, + absolutePath() { + abort("FS.absolutePath has been removed; use PATH_FS.resolve instead"); + }, + createFolder() { + abort("FS.createFolder has been removed; use FS.mkdir instead"); + }, + createLink() { + abort("FS.createLink has been removed; use FS.symlink instead"); + }, + joinPath() { + abort("FS.joinPath has been removed; use PATH.join instead"); + }, + mmapAlloc() { + abort("FS.mmapAlloc has been replaced by the top level function mmapAlloc"); + }, + standardizePath() { + abort("FS.standardizePath has been removed; use PATH.normalize instead"); + } +}; + +var SYSCALLS = { + DEFAULT_POLLMASK: 5, + calculateAt(dirfd, path, allowEmpty) { + if (PATH.isAbs(path)) { + return path; + } + var dir; + if (dirfd === -100) { + dir = FS.cwd(); + } else { + var dirstream = SYSCALLS.getStreamFromFD(dirfd); + dir = dirstream.path; + } + if (path.length == 0) { + if (!allowEmpty) { + throw new FS.ErrnoError(44); + } + return dir; + } + return PATH.join2(dir, path); + }, + doStat(func, path, buf) { + try { + var stat = func(path); + } catch (e) { + if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { + return -54; + } + throw e; + } + GROWABLE_HEAP_I32()[((buf) >> 2)] = stat.dev; + checkInt32(stat.dev); + GROWABLE_HEAP_I32()[(((buf) + (4)) >> 2)] = stat.mode; + checkInt32(stat.mode); + GROWABLE_HEAP_U32()[(((buf) + (8)) >> 2)] = stat.nlink; + checkInt32(stat.nlink); + GROWABLE_HEAP_I32()[(((buf) + (12)) >> 2)] = stat.uid; + checkInt32(stat.uid); + GROWABLE_HEAP_I32()[(((buf) + (16)) >> 2)] = stat.gid; + checkInt32(stat.gid); + GROWABLE_HEAP_I32()[(((buf) + (20)) >> 2)] = stat.rdev; + checkInt32(stat.rdev); + (tempI64 = [ stat.size >>> 0, (tempDouble = stat.size, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + GROWABLE_HEAP_I32()[(((buf) + (24)) >> 2)] = tempI64[0], GROWABLE_HEAP_I32()[(((buf) + (28)) >> 2)] = tempI64[1]); + checkInt64(stat.size); + GROWABLE_HEAP_I32()[(((buf) + (32)) >> 2)] = 4096; + checkInt32(4096); + GROWABLE_HEAP_I32()[(((buf) + (36)) >> 2)] = stat.blocks; + checkInt32(stat.blocks); + var atime = stat.atime.getTime(); + var mtime = stat.mtime.getTime(); + var ctime = stat.ctime.getTime(); + (tempI64 = [ Math.floor(atime / 1e3) >>> 0, (tempDouble = Math.floor(atime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + GROWABLE_HEAP_I32()[(((buf) + (40)) >> 2)] = tempI64[0], GROWABLE_HEAP_I32()[(((buf) + (44)) >> 2)] = tempI64[1]); + checkInt64(Math.floor(atime / 1e3)); + GROWABLE_HEAP_U32()[(((buf) + (48)) >> 2)] = (atime % 1e3) * 1e3; + checkInt32((atime % 1e3) * 1e3); + (tempI64 = [ Math.floor(mtime / 1e3) >>> 0, (tempDouble = Math.floor(mtime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + GROWABLE_HEAP_I32()[(((buf) + (56)) >> 2)] = tempI64[0], GROWABLE_HEAP_I32()[(((buf) + (60)) >> 2)] = tempI64[1]); + checkInt64(Math.floor(mtime / 1e3)); + GROWABLE_HEAP_U32()[(((buf) + (64)) >> 2)] = (mtime % 1e3) * 1e3; + checkInt32((mtime % 1e3) * 1e3); + (tempI64 = [ Math.floor(ctime / 1e3) >>> 0, (tempDouble = Math.floor(ctime / 1e3), + (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + GROWABLE_HEAP_I32()[(((buf) + (72)) >> 2)] = tempI64[0], GROWABLE_HEAP_I32()[(((buf) + (76)) >> 2)] = tempI64[1]); + checkInt64(Math.floor(ctime / 1e3)); + GROWABLE_HEAP_U32()[(((buf) + (80)) >> 2)] = (ctime % 1e3) * 1e3; + checkInt32((ctime % 1e3) * 1e3); + (tempI64 = [ stat.ino >>> 0, (tempDouble = stat.ino, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + GROWABLE_HEAP_I32()[(((buf) + (88)) >> 2)] = tempI64[0], GROWABLE_HEAP_I32()[(((buf) + (92)) >> 2)] = tempI64[1]); + checkInt64(stat.ino); + return 0; + }, + doMsync(addr, stream, len, flags, offset) { + if (!FS.isFile(stream.node.mode)) { + throw new FS.ErrnoError(43); + } + if (flags & 2) { + return 0; + } + var buffer = GROWABLE_HEAP_U8().slice(addr, addr + len); + FS.msync(stream, buffer, offset, len, flags); + }, + varargs: undefined, + get() { + assert(SYSCALLS.varargs != undefined); + var ret = GROWABLE_HEAP_I32()[((+SYSCALLS.varargs) >> 2)]; + SYSCALLS.varargs += 4; + return ret; + }, + getp() { + return SYSCALLS.get(); + }, + getStr(ptr) { + var ret = UTF8ToString(ptr); + return ret; + }, + getStreamFromFD(fd) { + var stream = FS.getStreamChecked(fd); + return stream; + } +}; + +var convertI32PairToI53Checked = (lo, hi) => { + assert(lo == (lo >>> 0) || lo == (lo | 0)); + assert(hi === (hi | 0)); + return ((hi + 2097152) >>> 0 < 4194305 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN; +}; + +/** @type{function(number, (number|boolean), ...(number|boolean))} */ var proxyToMainThread = function(index, sync) { + var numCallArgs = arguments.length - 2; + var outerArgs = arguments; + return withStackSave(() => { + var serializedNumCallArgs = numCallArgs; + var args = stackAlloc(serializedNumCallArgs * 8); + var b = ((args) >> 3); + for (var i = 0; i < numCallArgs; i++) { + var arg = outerArgs[2 + i]; + GROWABLE_HEAP_F64()[b + i] = arg; + } + return __emscripten_run_on_main_thread_js(index, serializedNumCallArgs, args, sync); + }); +}; + +function _proc_exit(code) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(0, 1, code); + EXITSTATUS = code; + if (!keepRuntimeAlive()) { + PThread.terminateAllThreads(); + if (Module["onExit"]) Module["onExit"](code); + ABORT = true; + } + quit_(code, new ExitStatus(code)); +} + +/** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => { + EXITSTATUS = status; + checkUnflushedContent(); + if (ENVIRONMENT_IS_PTHREAD) { + assert(!implicit); + exitOnMainThread(status); + throw "unwind"; + } + 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)`; + readyPromiseReject(msg); + err(msg); + } + _proc_exit(status); +}; + +var _exit = exitJS; + +var ptrToString = ptr => { + assert(typeof ptr === "number"); + ptr >>>= 0; + return "0x" + ptr.toString(16).padStart(8, "0"); +}; + +var handleException = e => { + 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 PThread = { + unusedWorkers: [], + runningWorkers: [], + tlsInitFunctions: [], + pthreads: {}, + nextWorkerID: 1, + debugInit() { + function pthreadLogPrefix() { + var t = 0; + if (runtimeInitialized && typeof _pthread_self != "undefined") { + t = _pthread_self(); + } + return "w:" + (Module["workerID"] || 0) + ",t:" + ptrToString(t) + ": "; + } + var origDbg = dbg; + dbg = message => origDbg(pthreadLogPrefix() + message); + }, + init() { + PThread.debugInit(); + if (ENVIRONMENT_IS_PTHREAD) { + PThread.initWorker(); + } else { + PThread.initMainThread(); + } + }, + initMainThread() { + addOnPreRun(() => { + addRunDependency("loading-workers"); + PThread.loadWasmModuleToAllWorkers(() => removeRunDependency("loading-workers")); + }); + }, + initWorker() { + PThread["receiveObjectTransfer"] = PThread.receiveObjectTransfer; + PThread["threadInitTLS"] = PThread.threadInitTLS; + PThread["setExitStatus"] = PThread.setExitStatus; + noExitRuntime = false; + }, + setExitStatus: status => { + EXITSTATUS = status; + }, + terminateAllThreads__deps: [ "$terminateWorker" ], + terminateAllThreads: () => { + assert(!ENVIRONMENT_IS_PTHREAD, "Internal Error! terminateAllThreads() can only ever be called from main application thread!"); + for (var worker of PThread.runningWorkers) { + terminateWorker(worker); + } + for (var worker of PThread.unusedWorkers) { + terminateWorker(worker); + } + PThread.unusedWorkers = []; + PThread.runningWorkers = []; + PThread.pthreads = []; + }, + returnWorkerToPool: worker => { + var pthread_ptr = worker.pthread_ptr; + delete PThread.pthreads[pthread_ptr]; + PThread.unusedWorkers.push(worker); + PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker), 1); + worker.pthread_ptr = 0; + __emscripten_thread_free_data(pthread_ptr); + }, + receiveObjectTransfer(data) {}, + threadInitTLS() { + PThread.tlsInitFunctions.forEach(f => f()); + }, + loadWasmModuleToWorker: worker => new Promise(onFinishedLoading => { + worker.onmessage = e => { + var d = e["data"]; + var cmd = d["cmd"]; + if (d["targetThread"] && d["targetThread"] != _pthread_self()) { + var targetWorker = PThread.pthreads[d["targetThread"]]; + if (targetWorker) { + targetWorker.postMessage(d, d["transferList"]); + } else { + err(`Internal error! Worker sent a message "${cmd}" to target pthread ${d["targetThread"]}, but that thread no longer exists!`); + } + return; + } + if (cmd === "checkMailbox") { + checkMailbox(); + } else if (cmd === "spawnThread") { + spawnThread(d); + } else if (cmd === "cleanupThread") { + cleanupThread(d["thread"]); + } else if (cmd === "killThread") { + killThread(d["thread"]); + } else if (cmd === "cancelThread") { + cancelThread(d["thread"]); + } else if (cmd === "loaded") { + worker.loaded = true; + onFinishedLoading(worker); + } else if (cmd === "alert") { + alert(`Thread ${d["threadId"]}: ${d["text"]}`); + } else if (d.target === "setimmediate") { + worker.postMessage(d); + } else if (cmd === "callHandler") { + Module[d["handler"]](...d["args"]); + } else if (cmd) { + err(`worker sent an unknown command ${cmd}`); + } + }; + worker.onerror = e => { + var message = "worker sent an error!"; + if (worker.pthread_ptr) { + message = `Pthread ${ptrToString(worker.pthread_ptr)} sent an error!`; + } + err(`${message} ${e.filename}:${e.lineno}: ${e.message}`); + throw e; + }; + if (ENVIRONMENT_IS_NODE) { + worker.on("message", data => worker.onmessage({ + data: data + })); + worker.on("error", e => worker.onerror(e)); + } + assert(wasmMemory instanceof WebAssembly.Memory, "WebAssembly memory should have been loaded by now!"); + assert(wasmModule instanceof WebAssembly.Module, "WebAssembly Module should have been loaded by now!"); + var handlers = []; + var knownHandlers = [ "onExit", "onAbort", "print", "printErr" ]; + for (var handler of knownHandlers) { + if (Module.hasOwnProperty(handler)) { + handlers.push(handler); + } + } + worker.workerID = PThread.nextWorkerID++; + worker.postMessage({ + "cmd": "load", + "handlers": handlers, + "urlOrBlob": Module["mainScriptUrlOrBlob"] || _scriptDir, + "wasmMemory": wasmMemory, + "wasmModule": wasmModule, + "workerID": worker.workerID + }); + }), + loadWasmModuleToAllWorkers(onMaybeReady) { + onMaybeReady(); + }, + allocateUnusedWorker() { + var worker; + var pthreadMainJs = locateFile("BeldexLibAppCpp_WASM.worker.js"); + worker = new Worker(pthreadMainJs); + PThread.unusedWorkers.push(worker); + }, + getNewWorker() { + if (PThread.unusedWorkers.length == 0) { + if (!ENVIRONMENT_IS_NODE) { + err("Tried to spawn a new thread, but the thread pool is exhausted.\n" + "This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.\n" + "If you want to increase the pool size, use setting `-sPTHREAD_POOL_SIZE=...`." + "\nIf you want to throw an explicit error instead of the risk of deadlocking in those cases, use setting `-sPTHREAD_POOL_SIZE_STRICT=2`."); + } + PThread.allocateUnusedWorker(); + PThread.loadWasmModuleToWorker(PThread.unusedWorkers[0]); + } + return PThread.unusedWorkers.pop(); + } +}; + +Module["PThread"] = PThread; + +var callRuntimeCallbacks = callbacks => { + while (callbacks.length > 0) { + callbacks.shift()(Module); + } +}; + +var decrementExceptionRefcount = ptr => ___cxa_decrement_exception_refcount(ptr); + +var establishStackSpace = () => { + var pthread_ptr = _pthread_self(); + var stackHigh = GROWABLE_HEAP_U32()[(((pthread_ptr) + (52)) >> 2)]; + var stackSize = GROWABLE_HEAP_U32()[(((pthread_ptr) + (56)) >> 2)]; + var stackLow = stackHigh - stackSize; + assert(stackHigh != 0); + assert(stackLow != 0); + assert(stackHigh > stackLow, "stackHigh must be higher then stackLow"); + _emscripten_stack_set_limits(stackHigh, stackLow); + setStackLimits(); + stackRestore(stackHigh); + writeStackCookie(); +}; + +Module["establishStackSpace"] = establishStackSpace; + +function exitOnMainThread(returnCode) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(1, 0, returnCode); + _exit(returnCode); +} + +var getExceptionMessageCommon = ptr => withStackSave(() => { + 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 = GROWABLE_HEAP_U32()[((type_addr_addr) >> 2)]; + var message_addr = GROWABLE_HEAP_U32()[((message_addr_addr) >> 2)]; + var type = UTF8ToString(type_addr); + _free(type_addr); + var message; + if (message_addr) { + message = UTF8ToString(message_addr); + _free(message_addr); + } + return [ type, message ]; +}); + +var getExceptionMessage = ptr => getExceptionMessageCommon(ptr); + +Module["getExceptionMessage"] = getExceptionMessage; + +/** + * @param {number} ptr + * @param {string} type + */ function getValue(ptr, type = "i8") { + if (type.endsWith("*")) type = "*"; + switch (type) { + case "i1": + return GROWABLE_HEAP_I8()[((ptr) >> 0)]; + + case "i8": + return GROWABLE_HEAP_I8()[((ptr) >> 0)]; + + case "i16": + return GROWABLE_HEAP_I16()[((ptr) >> 1)]; + + case "i32": + return GROWABLE_HEAP_I32()[((ptr) >> 2)]; + + case "i64": + abort("to do getValue(i64) use WASM_BIGINT"); + + case "float": + return GROWABLE_HEAP_F32()[((ptr) >> 2)]; + + case "double": + return GROWABLE_HEAP_F64()[((ptr) >> 3)]; + + case "*": + return GROWABLE_HEAP_U32()[((ptr) >> 2)]; + + default: + abort(`invalid type for getValue: ${type}`); + } +} + +var incrementExceptionRefcount = ptr => ___cxa_increment_exception_refcount(ptr); + +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 invokeEntryPoint = (ptr, arg) => { + var result = getWasmTableEntry(ptr)(arg); + checkStackCookie(); + function finish(result) { + if (keepRuntimeAlive()) { + PThread.setExitStatus(result); + } else { + __emscripten_thread_exit(result); + } + } + finish(result); +}; + +Module["invokeEntryPoint"] = invokeEntryPoint; + +var noExitRuntime = Module["noExitRuntime"] || true; + +var registerTLSInit = tlsInitFunc => { + PThread.tlsInitFunctions.push(tlsInitFunc); +}; + +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": + GROWABLE_HEAP_I8()[((ptr) >> 0)] = value; + checkInt8(value); + break; + + case "i8": + GROWABLE_HEAP_I8()[((ptr) >> 0)] = value; + checkInt8(value); + break; + + case "i16": + GROWABLE_HEAP_I16()[((ptr) >> 1)] = value; + checkInt16(value); + break; + + case "i32": + GROWABLE_HEAP_I32()[((ptr) >> 2)] = value; + checkInt32(value); + break; + + case "i64": + abort("to do setValue(i64) use WASM_BIGINT"); + + case "float": + GROWABLE_HEAP_F32()[((ptr) >> 2)] = value; + break; + + case "double": + GROWABLE_HEAP_F64()[((ptr) >> 3)] = value; + break; + + case "*": + GROWABLE_HEAP_U32()[((ptr) >> 2)] = value; + break; + + default: + abort(`invalid type for setValue: ${type}`); + } +} + +function jsStackTrace() { + var error = new Error; + if (!error.stack) { + try { + throw new Error; + } catch (e) { + error = e; + } + if (!error.stack) { + return "(no stack trace available)"; + } + } + return error.stack.toString(); +} + +function stackTrace() { + var js = jsStackTrace(); + if (Module["extraStackTrace"]) js += "\n" + Module["extraStackTrace"](); + return demangleAll(js); +} + +var warnOnce = text => { + if (!warnOnce.shown) warnOnce.shown = {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + if (ENVIRONMENT_IS_NODE) text = "warning: " + text; + err(text); + } +}; + +var ___assert_fail = (condition, filename, line, func) => { + abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]); +}; + +var exceptionCaught = []; + +var uncaughtExceptionCount = 0; + +var ___cxa_begin_catch = ptr => { + 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 = () => { + _setThrew(0, 0); + assert(exceptionCaught.length > 0); + var info = exceptionCaught.pop(); + ___cxa_decrement_exception_refcount(info.excPtr); + exceptionLast = 0; +}; + +/** @constructor */ function ExceptionInfo(excPtr) { + this.excPtr = excPtr; + this.ptr = excPtr - 24; + this.set_type = function(type) { + GROWABLE_HEAP_U32()[(((this.ptr) + (4)) >> 2)] = type; + }; + this.get_type = function() { + return GROWABLE_HEAP_U32()[(((this.ptr) + (4)) >> 2)]; + }; + this.set_destructor = function(destructor) { + GROWABLE_HEAP_U32()[(((this.ptr) + (8)) >> 2)] = destructor; + }; + this.get_destructor = function() { + return GROWABLE_HEAP_U32()[(((this.ptr) + (8)) >> 2)]; + }; + this.set_caught = function(caught) { + caught = caught ? 1 : 0; + GROWABLE_HEAP_I8()[(((this.ptr) + (12)) >> 0)] = caught; + checkInt8(caught); + }; + this.get_caught = function() { + return GROWABLE_HEAP_I8()[(((this.ptr) + (12)) >> 0)] != 0; + }; + this.set_rethrown = function(rethrown) { + rethrown = rethrown ? 1 : 0; + GROWABLE_HEAP_I8()[(((this.ptr) + (13)) >> 0)] = rethrown; + checkInt8(rethrown); + }; + this.get_rethrown = function() { + return GROWABLE_HEAP_I8()[(((this.ptr) + (13)) >> 0)] != 0; + }; + this.init = function(type, destructor) { + this.set_adjusted_ptr(0); + this.set_type(type); + this.set_destructor(destructor); + }; + this.set_adjusted_ptr = function(adjustedPtr) { + GROWABLE_HEAP_U32()[(((this.ptr) + (16)) >> 2)] = adjustedPtr; + }; + this.get_adjusted_ptr = function() { + return GROWABLE_HEAP_U32()[(((this.ptr) + (16)) >> 2)]; + }; + this.get_exception_ptr = function() { + var isPointer = ___cxa_is_pointer_type(this.get_type()); + if (isPointer) { + return GROWABLE_HEAP_U32()[((this.excPtr) >> 2)]; + } + var adjusted = this.get_adjusted_ptr(); + if (adjusted !== 0) return adjusted; + return this.excPtr; + }; +} + +var ___resumeException = ptr => { + if (!exceptionLast) { + exceptionLast = new CppException(ptr); + } + throw exceptionLast; +}; + +var findMatchingCatch = args => { + var thrown = exceptionLast && exceptionLast.excPtr; + if (!thrown) { + setTempRet0(0); + return 0; + } + var info = new ExceptionInfo(thrown); + info.set_adjusted_ptr(thrown); + var thrownType = info.get_type(); + if (!thrownType) { + setTempRet0(0); + return thrown; + } + for (var arg in args) { + var caughtType = args[arg]; + if (caughtType === 0 || caughtType === thrownType) { + 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; +}; + +var ___cxa_find_matching_catch_2 = () => findMatchingCatch([]); + +var ___cxa_find_matching_catch_3 = arg0 => findMatchingCatch([ arg0 ]); + +var ___cxa_rethrow = () => { + var info = exceptionCaught.pop(); + if (!info) { + abort("no exception to throw"); + } + var ptr = info.excPtr; + if (!info.get_rethrown()) { + exceptionCaught.push(info); + info.set_rethrown(true); + info.set_caught(false); + uncaughtExceptionCount++; + } + exceptionLast = new CppException(ptr); + throw exceptionLast; +}; + +var ___cxa_throw = (ptr, type, destructor) => { + var info = new ExceptionInfo(ptr); + info.init(type, destructor); + exceptionLast = new CppException(ptr); + uncaughtExceptionCount++; + throw exceptionLast; +}; + +var ___cxa_uncaught_exceptions = () => uncaughtExceptionCount; + +var ___emscripten_init_main_thread_js = tb => { + __emscripten_thread_init(tb, /*is_main=*/ !ENVIRONMENT_IS_WORKER, /*is_runtime=*/ 1, /*can_block=*/ !ENVIRONMENT_IS_WEB, /*default_stacksize=*/ 65536, /*start_profiling=*/ false); + PThread.threadInitTLS(); +}; + +var ___emscripten_thread_cleanup = thread => { + if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread); else postMessage({ + "cmd": "cleanupThread", + "thread": thread + }); +}; + +var ___handle_stack_overflow = requested => { + 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="); +}; + +function ___syscall_openat(dirfd, path, flags, varargs) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(2, 1, dirfd, path, flags, varargs); + SYSCALLS.varargs = varargs; + try { + path = SYSCALLS.getStr(path); + path = SYSCALLS.calculateAt(dirfd, path); + var mode = varargs ? SYSCALLS.get() : 0; + return FS.open(path, flags, mode).fd; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return -e.errno; + } +} + +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 (GROWABLE_HEAP_U8()[c]) { + ret += embind_charCodes[GROWABLE_HEAP_U8()[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: name, + "fromWireType": function(wt) { + return !!wt; + }, + "toWireType": function(destructors, o) { + return o ? trueValue : falseValue; + }, + "argPackAdvance": GenericWireTypeSize, + "readValueFromPointer": function(pointer) { + return this["fromWireType"](GROWABLE_HEAP_U8()[pointer]); + }, + destructorFunction: null + }); +}; + +function handleAllocatorInit() { + Object.assign(HandleAllocator.prototype, /** @lends {HandleAllocator.prototype} */ { + get(id) { + assert(this.allocated[id] !== undefined, `invalid handle: ${id}`); + return this.allocated[id]; + }, + has(id) { + return this.allocated[id] !== undefined; + }, + allocate(handle) { + var id = this.freelist.pop() || this.allocated.length; + this.allocated[id] = handle; + return id; + }, + free(id) { + assert(this.allocated[id] !== undefined); + this.allocated[id] = undefined; + this.freelist.push(id); + } + }); +} + +/** @constructor */ function HandleAllocator() { + this.allocated = [ undefined ]; + this.freelist = []; +} + +var emval_handles = new HandleAllocator; + +var __emval_decref = handle => { + if (handle >= emval_handles.reserved && 0 === --emval_handles.get(handle).refcount) { + emval_handles.free(handle); + } +}; + +var count_emval_handles = () => { + var count = 0; + for (var i = emval_handles.reserved; i < emval_handles.allocated.length; ++i) { + if (emval_handles.allocated[i] !== undefined) { + ++count; + } + } + return count; +}; + +var init_emval = () => { + emval_handles.allocated.push({ + value: undefined + }, { + value: null + }, { + value: true + }, { + value: false + }); + emval_handles.reserved = emval_handles.allocated.length; + Module["count_emval_handles"] = count_emval_handles; +}; + +var Emval = { + toValue: handle => { + if (!handle) { + throwBindingError("Cannot use deleted val. handle = " + handle); + } + return emval_handles.get(handle).value; + }, + toHandle: value => { + switch (value) { + case undefined: + return 1; + + case null: + return 2; + + case true: + return 3; + + case false: + return 4; + + default: + { + return emval_handles.allocate({ + refcount: 1, + value: value + }); + } + } + } +}; + +/** @suppress {globalThis} */ function simpleReadValueFromPointer(pointer) { + return this["fromWireType"](GROWABLE_HEAP_I32()[((pointer) >> 2)]); +} + +var __embind_register_emval = (rawType, name) => { + name = readLatin1String(name); + registerType(rawType, { + name: name, + "fromWireType": handle => { + var rv = Emval.toValue(handle); + __emval_decref(handle); + return rv; + }, + "toWireType": (destructors, value) => Emval.toHandle(value), + "argPackAdvance": GenericWireTypeSize, + "readValueFromPointer": simpleReadValueFromPointer, + destructorFunction: null + }); +}; + +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"](GROWABLE_HEAP_F32()[((pointer) >> 2)]); + }; + + case 8: + return function(pointer) { + return this["fromWireType"](GROWABLE_HEAP_F64()[((pointer) >> 3)]); + }; + + default: + throw new TypeError(`invalid float width (${width}): ${name}`); + } +}; + +var __embind_register_float = (rawType, name, size) => { + name = readLatin1String(name); + registerType(rawType, { + name: name, + "fromWireType": value => value, + "toWireType": (destructors, value) => { + if (typeof value != "number" && typeof value != "boolean") { + throw new TypeError(`Cannot convert ${embindRepr(value)} to ${this.name}`); + } + return value; + }, + "argPackAdvance": GenericWireTypeSize, + "readValueFromPointer": floatReadValueFromPointer(name, size), + destructorFunction: null + }); +}; + +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 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. Doublely-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 craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc, /** boolean= */ isAsync) { + 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); + var needsDestructorStack = false; + for (var i = 1; i < argTypes.length; ++i) { + if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { + needsDestructorStack = true; + break; + } + } + var returns = (argTypes[0].name !== "void"); + 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 = `\n return function (${argsList}) {\n if (arguments.length !== ${argCount - 2}) {\n throwBindingError('function ${humanName} called with ' + arguments.length + ' arguments, expected ${argCount - 2}');\n }`; + if (needsDestructorStack) { + invokerFnBody += "var destructors = [];\n"; + } + var dtorStack = needsDestructorStack ? "destructors" : "null"; + var args1 = [ "throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam" ]; + var args2 = [ throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1] ]; + 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 + "); // " + argTypes[i + 2].name + "\n"; + args1.push("argType" + i); + args2.push(argTypes[i + 2]); + } + if (isClassMethodFunc) { + argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired; + } + invokerFnBody += (returns || isAsync ? "var rv = " : "") + "invoker(fn" + (argsListWired.length > 0 ? ", " : "") + argsListWired + ");\n"; + if (needsDestructorStack) { + invokerFnBody += "runDestructors(destructors);\n"; + } else { + for (var i = isClassMethodFunc ? 1 : 2; i < argTypes.length; ++i) { + var paramName = (i === 1 ? "thisWired" : ("arg" + (i - 2) + "Wired")); + if (argTypes[i].destructorFunction !== null) { + invokerFnBody += paramName + "_dtor(" + paramName + "); // " + argTypes[i].name + "\n"; + args1.push(paramName + "_dtor"); + args2.push(argTypes[i].destructorFunction); + } + } + } + if (returns) { + invokerFnBody += "var ret = retType.fromWireType(rv);\n" + "return ret;\n"; + } else {} + invokerFnBody += "}\n"; + args1.push(invokerFnBody); + var invokerFn = newFunc(Function, args1).apply(null, args2); + return createNamedFunction(humanName, invokerFn); +} + +var ensureOverloadTable = (proto, methodName, humanName) => { + if (undefined === proto[methodName].overloadTable) { + var prevFunc = proto[methodName]; + proto[methodName] = function() { + if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) { + throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`); + } + return proto[methodName].overloadTable[arguments.length].apply(this, arguments); + }; + 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`); + } + ensureOverloadTable(Module, name, name); + if (Module.hasOwnProperty(numArguments)) { + throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`); + } + 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++) { + array.push(GROWABLE_HEAP_U32()[(((firstElement) + (i * 4)) >> 2)]); + } + return array; +}; + +/** @param {number=} numArguments */ var replacePublicSymbol = (name, value, numArguments) => { + if (!Module.hasOwnProperty(name)) { + throwInternalError("Replacing nonexistant public symbol"); + } + 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) => { + assert(("dynCall_" + sig) in Module, `bad function pointer type - dynCall function not found for sig '${sig}'`); + if (args && args.length) { + assert(args.length === sig.substring(1).replace(/j/g, "--").length); + } else { + assert(sig.length == 1); + } + var f = Module["dynCall_" + sig]; + return args && args.length ? f.apply(null, [ ptr ].concat(args)) : f.call(null, ptr); +}; + +/** @param {Object=} args */ var dynCall = (sig, ptr, args) => { + if (sig.includes("j")) { + return dynCallLegacy(sig, ptr, args); + } + assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`); + var rtn = getWasmTableEntry(ptr).apply(null, args); + return rtn; +}; + +var getDynCaller = (sig, ptr) => { + assert(sig.includes("j") || sig.includes("p"), "getDynCaller should only be called with i64 sigs"); + var argCache = []; + return function() { + argCache.length = 0; + Object.assign(argCache, arguments); + return dynCall(sig, ptr, argCache); + }; +}; + +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; +}; - function embindRepr(v) { - if (v === null) { - return 'null'; - } - var t = typeof v; - if (t === 'object' || t === 'array' || t === 'function') { - return v.toString(); - } else { - return '' + v; - } - } - - function floatReadValueFromPointer(name, shift) { - switch (shift) { - case 2: return function(pointer) { - return this['fromWireType'](HEAPF32[pointer >> 2]); - }; - case 3: return function(pointer) { - return this['fromWireType'](HEAPF64[pointer >> 3]); - }; - default: - throw new TypeError("Unknown float type: " + name); - } - } - function __embind_register_float(rawType, name, size) { - var shift = getShiftFromSize(size); - name = readLatin1String(name); - registerType(rawType, { - name: name, - 'fromWireType': function(value) { - return value; - }, - 'toWireType': function(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': 8, - 'readValueFromPointer': floatReadValueFromPointer(name, shift), - destructorFunction: null, // This type does not need a destructor - }); - } +var UnboundTypeError; - function new_(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. Doublely-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 runDestructors(destructors) { - while (destructors.length) { - var ptr = destructors.pop(); - var del = destructors.pop(); - del(ptr); - } - } - function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) { - // 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. - var argCount = argTypes.length; - - if (argCount < 2) { - throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!"); - } - - 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 = false; - - for (var i = 1; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. - if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { // The type does not define a destructor function - must use dynamic stack - needsDestructorStack = true; - break; - } - } - - var returns = (argTypes[0].name !== "void"); - - 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 "+makeLegalFunctionName(humanName)+"("+argsList+") {\n" + - "if (arguments.length !== "+(argCount - 2)+") {\n" + - "throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount - 2)+" args!');\n" + - "}\n"; - - if (needsDestructorStack) { - invokerFnBody += "var destructors = [];\n"; - } - - var dtorStack = needsDestructorStack ? "destructors" : "null"; - var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"]; - var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; - - 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+"); // "+argTypes[i+2].name+"\n"; - args1.push("argType"+i); - args2.push(argTypes[i+2]); - } - - if (isClassMethodFunc) { - argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired; - } - - invokerFnBody += - (returns?"var rv = ":"") + "invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n"; - - 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+"); // "+argTypes[i].name+"\n"; - args1.push(paramName+"_dtor"); - args2.push(argTypes[i].destructorFunction); - } - } - } - - if (returns) { - invokerFnBody += "var ret = retType.fromWireType(rv);\n" + - "return ret;\n"; - } else { - } - - invokerFnBody += "}\n"; - - args1.push(invokerFnBody); - - var invokerFunction = new_(Function, args1).apply(null, args2); - return invokerFunction; - } - - function 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() { - // TODO This check can be removed in -O3 level "unsafe" optimizations. - if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) { - throwBindingError("Function '" + humanName + "' called with an invalid number of arguments (" + arguments.length + ") - expects one of (" + proto[methodName].overloadTable + ")!"); - } - return proto[methodName].overloadTable[arguments.length].apply(this, arguments); - }; - // Move the previous function into the overload table. - proto[methodName].overloadTable = []; - proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; - } - } - /** @param {number=} numArguments */ - function 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; - } - } - } - - function 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 */ - function replacePublicSymbol(name, value, numArguments) { - if (!Module.hasOwnProperty(name)) { - throwInternalError('Replacing nonexistant 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; - } - } - - function dynCallLegacy(sig, ptr, args) { - assert(('dynCall_' + sig) in Module, 'bad function pointer type - dynCall function not found for sig \'' + sig + '\''); - if (args && 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); +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, function(argTypes) { + var invokerArgsArray = [ argTypes[0], /* return value */ null ].concat(/* no class 'this'*/ 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) => { + switch (width) { + case 1: + return signed ? pointer => GROWABLE_HEAP_I8()[((pointer) >> 0)] : pointer => GROWABLE_HEAP_U8()[((pointer) >> 0)]; + + case 2: + return signed ? pointer => GROWABLE_HEAP_I16()[((pointer) >> 1)] : pointer => GROWABLE_HEAP_U16()[((pointer) >> 1)]; + + case 4: + return signed ? pointer => GROWABLE_HEAP_I32()[((pointer) >> 2)] : pointer => GROWABLE_HEAP_U32()[((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); + 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); + return value; + }; + } + registerType(primitiveType, { + name: name, + "fromWireType": fromWireType, + "toWireType": toWireType, + "argPackAdvance": GenericWireTypeSize, + "readValueFromPointer": integerReadValueFromPointer(name, size, minRange !== 0), + destructorFunction: null + }); +}; + +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 = GROWABLE_HEAP_U32()[((handle) >> 2)]; + var data = GROWABLE_HEAP_U32()[(((handle) + (4)) >> 2)]; + return new TA(GROWABLE_HEAP_I8().buffer, data, size); + } + name = readLatin1String(name); + registerType(rawType, { + name: name, + "fromWireType": decodeMemoryView, + "argPackAdvance": GenericWireTypeSize, + "readValueFromPointer": decodeMemoryView + }, { + ignoreDuplicateRegistrations: true + }); +}; + +/** @suppress {globalThis} */ function readPointer(pointer) { + return this["fromWireType"](GROWABLE_HEAP_U32()[((pointer) >> 2)]); +} + +var __embind_register_std_string = (rawType, name) => { + name = readLatin1String(name); + var stdStringIsUTF8 = (name === "std::string"); + registerType(rawType, { + name: name, + "fromWireType"(value) { + var length = GROWABLE_HEAP_U32()[((value) >> 2)]; + var payload = value + 4; + var str; + if (stdStringIsUTF8) { + var decodeStartPtr = payload; + for (var i = 0; i <= length; ++i) { + var currentBytePtr = payload + i; + if (i == length || GROWABLE_HEAP_U8()[currentBytePtr] == 0) { + var maxRead = currentBytePtr - decodeStartPtr; + var stringSegment = UTF8ToString(decodeStartPtr, maxRead); + if (str === undefined) { + str = stringSegment; } else { - assert(sig.length == 1); - } - var f = Module['dynCall_' + sig]; - return args && args.length ? f.apply(null, [ptr].concat(args)) : f.call(null, ptr); - } - /** @param {Object=} args */ - function dynCall(sig, ptr, args) { - // Without WASM_BIGINT support we cannot directly call function with i64 as - // part of thier signature, so we rely 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).apply(null, args); - return rtn; - } - function getDynCaller(sig, ptr) { - assert(sig.includes('j') || sig.includes('p'), 'getDynCaller should only be called with i64 sigs') - var argCache = []; - return function() { - argCache.length = 0; - Object.assign(argCache, arguments); - return dynCall(sig, ptr, argCache); - }; - } - function embind__requireFunction(signature, rawFunction) { - signature = readLatin1String(signature); - - function makeDynCaller() { - if (signature.includes('j')) { - return getDynCaller(signature, rawFunction); - } - return getWasmTableEntry(rawFunction); + str += String.fromCharCode(0); + str += stringSegment; } - - var fp = makeDynCaller(); - if (typeof fp != "function") { - throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction); - } - return fp; + decodeStartPtr = currentBytePtr + 1; + } } - - var UnboundTypeError = undefined; - - function getTypeName(type) { - var ptr = ___getTypeName(type); - var rv = readLatin1String(ptr); - _free(ptr); - return rv; + } else { + var a = new Array(length); + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(GROWABLE_HEAP_U8()[payload + i]); } - function 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; + 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; + } + var base = _malloc(4 + length + 1); + var ptr = base + 4; + GROWABLE_HEAP_U32()[((base) >> 2)] = length; + checkInt32(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"); } - types.forEach(visit); - - throw new UnboundTypeError(message + ': ' + unboundTypes.map(getTypeName).join([', '])); - } - function __embind_register_function(name, argCount, rawArgTypesAddr, signature, rawInvoker, fn) { - var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr); - name = readLatin1String(name); - - rawInvoker = embind__requireFunction(signature, rawInvoker); - - exposePublicSymbol(name, function() { - throwUnboundTypeError('Cannot call ' + name + ' due to unbound types', argTypes); - }, argCount - 1); - - whenDependentTypesAreResolved([], argTypes, function(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), argCount - 1); - return []; - }); + GROWABLE_HEAP_U8()[ptr + i] = charCode; + } + } else { + for (var i = 0; i < length; ++i) { + GROWABLE_HEAP_U8()[ptr + i] = value[i]; + } } + } + if (destructors !== null) { + destructors.push(_free, base); + } + return base; + }, + "argPackAdvance": GenericWireTypeSize, + "readValueFromPointer": readPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); +}; - function integerReadValueFromPointer(name, shift, signed) { - // integers are quite common, so generate very specialized functions - switch (shift) { - case 0: return signed ? - function readS8FromPointer(pointer) { return HEAP8[pointer]; } : - function readU8FromPointer(pointer) { return HEAPU8[pointer]; }; - case 1: return signed ? - function readS16FromPointer(pointer) { return HEAP16[pointer >> 1]; } : - function readU16FromPointer(pointer) { return HEAPU16[pointer >> 1]; }; - case 2: return signed ? - function readS32FromPointer(pointer) { return HEAP32[pointer >> 2]; } : - function readU32FromPointer(pointer) { return HEAPU32[pointer >> 2]; }; - default: - throw new TypeError("Unknown integer type: " + name); - } - } - function __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 shift = getShiftFromSize(size); - - 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: name, - 'fromWireType': fromWireType, - 'toWireType': toWireType, - 'argPackAdvance': 8, - 'readValueFromPointer': integerReadValueFromPointer(name, shift, minRange !== 0), - destructorFunction: null, // This type does not need a destructor - }); - } +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; + var idx = endPtr >> 1; + var maxIdx = idx + maxBytesToRead / 2; + while (!(idx >= maxIdx) && GROWABLE_HEAP_U16()[idx]) ++idx; + endPtr = idx << 1; + if (endPtr - ptr > 32 && UTF16Decoder) return UTF16Decoder.decode(GROWABLE_HEAP_U8().slice(ptr, endPtr)); + var str = ""; + for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { + var codeUnit = GROWABLE_HEAP_I16()[(((ptr) + (i * 2)) >> 1)]; + if (codeUnit == 0) break; + str += String.fromCharCode(codeUnit); + } + return str; +}; - function __embind_register_memory_view(rawType, dataTypeIndex, name) { - var typeMapping = [ - Int8Array, - Uint8Array, - Int16Array, - Uint16Array, - Int32Array, - Uint32Array, - Float32Array, - Float64Array, - ]; - - var TA = typeMapping[dataTypeIndex]; - - function decodeMemoryView(handle) { - handle = handle >> 2; - var heap = HEAPU32; - var size = heap[handle]; // in elements - var data = heap[handle + 1]; // byte offset into emscripten heap - return new TA(buffer, data, size); - } - - name = readLatin1String(name); - registerType(rawType, { - name: name, - 'fromWireType': decodeMemoryView, - 'argPackAdvance': 8, - 'readValueFromPointer': decodeMemoryView, - }, { - ignoreDuplicateRegistrations: true, - }); - } +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!"); + if (maxBytesToWrite === undefined) { + maxBytesToWrite = 2147483647; + } + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; + var startPtr = outPtr; + var numCharsToWrite = (maxBytesToWrite < str.length * 2) ? (maxBytesToWrite / 2) : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + var codeUnit = str.charCodeAt(i); + GROWABLE_HEAP_I16()[((outPtr) >> 1)] = codeUnit; + checkInt16(codeUnit); + outPtr += 2; + } + GROWABLE_HEAP_I16()[((outPtr) >> 1)] = 0; + checkInt16(0); + return outPtr - startPtr; +}; - function __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: name, - 'fromWireType': function(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': function(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 4-byte 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': 8, - 'readValueFromPointer': simpleReadValueFromPointer, - destructorFunction: function(ptr) { _free(ptr); }, - }); - } +var lengthBytesUTF16 = str => 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 = ""; + while (!(i >= maxBytesToRead / 4)) { + var utf32 = GROWABLE_HEAP_I32()[(((ptr) + (i * 4)) >> 2)]; + if (utf32 == 0) break; + ++i; + if (utf32 >= 65536) { + var ch = utf32 - 65536; + str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023)); + } else { + str += String.fromCharCode(utf32); + } + } + return str; +}; - var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined;; - function 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; - } - - function 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. - if (maxBytesToWrite === undefined) { - 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; - } - - function lengthBytesUTF16(str) { - return str.length*2; - } - - function 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; - } - - function 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. - if (maxBytesToWrite === undefined) { - 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; - } - - function 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; - } - function __embind_register_std_wstring(rawType, charSize, name) { - name = readLatin1String(name); - var decodeString, encodeString, getHeap, lengthBytesUTF, shift; - if (charSize === 2) { - decodeString = UTF16ToString; - encodeString = stringToUTF16; - lengthBytesUTF = lengthBytesUTF16; - getHeap = () => HEAPU16; - shift = 1; - } else if (charSize === 4) { - decodeString = UTF32ToString; - encodeString = stringToUTF32; - lengthBytesUTF = lengthBytesUTF32; - getHeap = () => HEAPU32; - shift = 2; - } - registerType(rawType, { - name: name, - 'fromWireType': function(value) { - // Code mostly taken from _embind_register_std_string fromWireType - var length = HEAPU32[value >> 2]; - var HEAP = getHeap(); - 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 || HEAP[currentBytePtr >> shift] == 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': function(destructors, value) { - if (!(typeof value == 'string')) { - throwBindingError('Cannot pass non-string to C++ string type ' + name); - } - - // assumes 4-byte alignment - var length = lengthBytesUTF(value); - var ptr = _malloc(4 + length + charSize); - HEAPU32[ptr >> 2] = length >> shift; - - encodeString(value, ptr + 4, length + charSize); - - if (destructors !== null) { - destructors.push(_free, ptr); - } - return ptr; - }, - 'argPackAdvance': 8, - 'readValueFromPointer': simpleReadValueFromPointer, - destructorFunction: function(ptr) { _free(ptr); }, - }); - } +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!"); + if (maxBytesToWrite === undefined) { + maxBytesToWrite = 2147483647; + } + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + for (var i = 0; i < str.length; ++i) { + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 55296 && codeUnit <= 57343) { + var trailSurrogate = str.charCodeAt(++i); + codeUnit = 65536 + ((codeUnit & 1023) << 10) | (trailSurrogate & 1023); + } + GROWABLE_HEAP_I32()[((outPtr) >> 2)] = codeUnit; + checkInt32(codeUnit); + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + GROWABLE_HEAP_I32()[((outPtr) >> 2)] = 0; + checkInt32(0); + return outPtr - startPtr; +}; - function __embind_register_void(rawType, name) { - name = readLatin1String(name); - registerType(rawType, { - isVoid: true, // void return values can be optimized out sometimes - name: name, - 'argPackAdvance': 0, - 'fromWireType': function() { - return undefined; - }, - 'toWireType': function(destructors, o) { - // TODO: assert if anything else is given? - return undefined; - }, - }); - } +var lengthBytesUTF32 = str => { + var len = 0; + for (var i = 0; i < str.length; ++i) { + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 55296 && codeUnit <= 57343) ++i; + len += 4; + } + return len; +}; - function __emscripten_get_progname(str, len) { - assert(typeof str == 'number'); - assert(typeof len == 'number'); - stringToUTF8(thisProgram, str, len); +var __embind_register_std_wstring = (rawType, charSize, name) => { + name = readLatin1String(name); + var decodeString, encodeString, getHeap, lengthBytesUTF, shift; + if (charSize === 2) { + decodeString = UTF16ToString; + encodeString = stringToUTF16; + lengthBytesUTF = lengthBytesUTF16; + getHeap = () => GROWABLE_HEAP_U16(); + shift = 1; + } else if (charSize === 4) { + decodeString = UTF32ToString; + encodeString = stringToUTF32; + lengthBytesUTF = lengthBytesUTF32; + getHeap = () => GROWABLE_HEAP_U32(); + shift = 2; + } + registerType(rawType, { + name: name, + "fromWireType": value => { + var length = GROWABLE_HEAP_U32()[((value) >> 2)]; + var HEAP = getHeap(); + var str; + var decodeStartPtr = value + 4; + for (var i = 0; i <= length; ++i) { + var currentBytePtr = value + 4 + i * charSize; + if (i == length || HEAP[currentBytePtr >> shift] == 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}`); + } + var length = lengthBytesUTF(value); + var ptr = _malloc(4 + length + charSize); + GROWABLE_HEAP_U32()[ptr >> 2] = length >> shift; + encodeString(value, ptr + 4, length + charSize); + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + "argPackAdvance": GenericWireTypeSize, + "readValueFromPointer": simpleReadValueFromPointer, + destructorFunction(ptr) { + _free(ptr); + } + }); +}; - function readI53FromI64(ptr) { - return HEAPU32[ptr>>2] + HEAP32[ptr+4>>2] * 4294967296; - } - function __gmtime_js(time, tmPtr) { - var date = new Date(readI53FromI64(time)*1000); - HEAP32[((tmPtr)>>2)] = date.getUTCSeconds(); - HEAP32[(((tmPtr)+(4))>>2)] = date.getUTCMinutes(); - HEAP32[(((tmPtr)+(8))>>2)] = date.getUTCHours(); - HEAP32[(((tmPtr)+(12))>>2)] = date.getUTCDate(); - HEAP32[(((tmPtr)+(16))>>2)] = date.getUTCMonth(); - HEAP32[(((tmPtr)+(20))>>2)] = date.getUTCFullYear()-1900; - HEAP32[(((tmPtr)+(24))>>2)] = date.getUTCDay(); - var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); - var yday = ((date.getTime() - start) / (1000 * 60 * 60 * 24))|0; - HEAP32[(((tmPtr)+(28))>>2)] = yday; - } +var __embind_register_void = (rawType, name) => { + name = readLatin1String(name); + registerType(rawType, { + isVoid: true, + name: name, + "argPackAdvance": 0, + "fromWireType": () => undefined, + "toWireType": (destructors, o) => undefined + }); +}; + +var nowIsMonotonic = 1; + +var __emscripten_get_now_is_monotonic = () => nowIsMonotonic; + +var __emscripten_get_progname = (str, len) => { + assert(typeof str == "number"); + assert(typeof len == "number"); + stringToUTF8(thisProgram, str, len); +}; + +var maybeExit = () => { + if (!keepRuntimeAlive()) { + try { + if (ENVIRONMENT_IS_PTHREAD) __emscripten_thread_exit(EXITSTATUS); else _exit(EXITSTATUS); + } catch (e) { + handleException(e); + } + } +}; + +var callUserCallback = func => { + if (ABORT) { + err("user callback triggered after runtime exited or application aborted. Ignoring."); + return; + } + try { + func(); + maybeExit(); + } catch (e) { + handleException(e); + } +}; + +var __emscripten_thread_mailbox_await = pthread_ptr => { + if (typeof Atomics.waitAsync === "function") { + var wait = Atomics.waitAsync(GROWABLE_HEAP_I32(), ((pthread_ptr) >> 2), pthread_ptr); + assert(wait.async); + wait.value.then(checkMailbox); + var waitingAsync = pthread_ptr + 128; + Atomics.store(GROWABLE_HEAP_I32(), ((waitingAsync) >> 2), 1); + } +}; + +Module["__emscripten_thread_mailbox_await"] = __emscripten_thread_mailbox_await; + +var checkMailbox = () => { + var pthread_ptr = _pthread_self(); + if (pthread_ptr) { + __emscripten_thread_mailbox_await(pthread_ptr); + callUserCallback(__emscripten_check_mailbox); + } +}; + +Module["checkMailbox"] = checkMailbox; + +var __emscripten_notify_mailbox_postmessage = (targetThreadId, currThreadId, mainThreadId) => { + if (targetThreadId == currThreadId) { + setTimeout(() => checkMailbox()); + } else if (ENVIRONMENT_IS_PTHREAD) { + postMessage({ + "targetThread": targetThreadId, + "cmd": "checkMailbox" + }); + } else { + var worker = PThread.pthreads[targetThreadId]; + if (!worker) { + err(`Cannot send message to thread with ID ${targetThreadId}, unknown thread ID!`); + return; + } + worker.postMessage({ + "cmd": "checkMailbox" + }); + } +}; + +var proxiedJSCallArgs = []; + +var __emscripten_receive_on_main_thread_js = (index, callingThread, numCallArgs, args) => { + proxiedJSCallArgs.length = numCallArgs; + var b = ((args) >> 3); + for (var i = 0; i < numCallArgs; i++) { + proxiedJSCallArgs[i] = GROWABLE_HEAP_F64()[b + i]; + } + var isEmAsmConst = index < 0; + var func = !isEmAsmConst ? proxiedFunctionTable[index] : ASM_CONSTS[-index - 1]; + assert(func.length == numCallArgs, "Call args mismatch in _emscripten_receive_on_main_thread_js"); + PThread.currentProxiedOperationCallerThread = callingThread; + var rtn = func.apply(null, proxiedJSCallArgs); + PThread.currentProxiedOperationCallerThread = 0; + assert(typeof rtn != "bigint"); + return rtn; +}; + +var __emscripten_thread_set_strongref = thread => { + if (ENVIRONMENT_IS_NODE) { + PThread.pthreads[thread].ref(); + } +}; + +function __gmtime_js(time_low, time_high, tmPtr) { + var time = convertI32PairToI53Checked(time_low, time_high); + var date = new Date(time * 1e3); + GROWABLE_HEAP_I32()[((tmPtr) >> 2)] = date.getUTCSeconds(); + checkInt32(date.getUTCSeconds()); + GROWABLE_HEAP_I32()[(((tmPtr) + (4)) >> 2)] = date.getUTCMinutes(); + checkInt32(date.getUTCMinutes()); + GROWABLE_HEAP_I32()[(((tmPtr) + (8)) >> 2)] = date.getUTCHours(); + checkInt32(date.getUTCHours()); + GROWABLE_HEAP_I32()[(((tmPtr) + (12)) >> 2)] = date.getUTCDate(); + checkInt32(date.getUTCDate()); + GROWABLE_HEAP_I32()[(((tmPtr) + (16)) >> 2)] = date.getUTCMonth(); + checkInt32(date.getUTCMonth()); + GROWABLE_HEAP_I32()[(((tmPtr) + (20)) >> 2)] = date.getUTCFullYear() - 1900; + checkInt32(date.getUTCFullYear() - 1900); + GROWABLE_HEAP_I32()[(((tmPtr) + (24)) >> 2)] = date.getUTCDay(); + checkInt32(date.getUTCDay()); + var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); + var yday = ((date.getTime() - start) / (1e3 * 60 * 60 * 24)) | 0; + GROWABLE_HEAP_I32()[(((tmPtr) + (28)) >> 2)] = yday; + checkInt32(yday); +} + +var isLeapYear = year => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); + +var MONTH_DAYS_LEAP_CUMULATIVE = [ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ]; + +var MONTH_DAYS_REGULAR_CUMULATIVE = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ]; + +var ydayFromDate = date => { + var leap = isLeapYear(date.getFullYear()); + var monthDaysCumulative = (leap ? MONTH_DAYS_LEAP_CUMULATIVE : MONTH_DAYS_REGULAR_CUMULATIVE); + var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1; + return yday; +}; + +var setErrNo = value => { + GROWABLE_HEAP_I32()[((___errno_location()) >> 2)] = value; + checkInt32(value); + return value; +}; + +var __mktime_js = function(tmPtr) { + var ret = (() => { + var date = new Date(GROWABLE_HEAP_I32()[(((tmPtr) + (20)) >> 2)] + 1900, GROWABLE_HEAP_I32()[(((tmPtr) + (16)) >> 2)], GROWABLE_HEAP_I32()[(((tmPtr) + (12)) >> 2)], GROWABLE_HEAP_I32()[(((tmPtr) + (8)) >> 2)], GROWABLE_HEAP_I32()[(((tmPtr) + (4)) >> 2)], GROWABLE_HEAP_I32()[((tmPtr) >> 2)], 0); + var dst = GROWABLE_HEAP_I32()[(((tmPtr) + (32)) >> 2)]; + var guessedOffset = date.getTimezoneOffset(); + var start = new Date(date.getFullYear(), 0, 1); + var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); + var winterOffset = start.getTimezoneOffset(); + var dstOffset = Math.min(winterOffset, summerOffset); + if (dst < 0) { + GROWABLE_HEAP_I32()[(((tmPtr) + (32)) >> 2)] = Number(summerOffset != winterOffset && dstOffset == guessedOffset); + checkInt32(Number(summerOffset != winterOffset && dstOffset == guessedOffset)); + } else if ((dst > 0) != (dstOffset == guessedOffset)) { + var nonDstOffset = Math.max(winterOffset, summerOffset); + var trueOffset = dst > 0 ? dstOffset : nonDstOffset; + date.setTime(date.getTime() + (trueOffset - guessedOffset) * 6e4); + } + GROWABLE_HEAP_I32()[(((tmPtr) + (24)) >> 2)] = date.getDay(); + checkInt32(date.getDay()); + var yday = ydayFromDate(date) | 0; + GROWABLE_HEAP_I32()[(((tmPtr) + (28)) >> 2)] = yday; + checkInt32(yday); + GROWABLE_HEAP_I32()[((tmPtr) >> 2)] = date.getSeconds(); + checkInt32(date.getSeconds()); + GROWABLE_HEAP_I32()[(((tmPtr) + (4)) >> 2)] = date.getMinutes(); + checkInt32(date.getMinutes()); + GROWABLE_HEAP_I32()[(((tmPtr) + (8)) >> 2)] = date.getHours(); + checkInt32(date.getHours()); + GROWABLE_HEAP_I32()[(((tmPtr) + (12)) >> 2)] = date.getDate(); + checkInt32(date.getDate()); + GROWABLE_HEAP_I32()[(((tmPtr) + (16)) >> 2)] = date.getMonth(); + checkInt32(date.getMonth()); + GROWABLE_HEAP_I32()[(((tmPtr) + (20)) >> 2)] = date.getYear(); + checkInt32(date.getYear()); + var timeMs = date.getTime(); + if (isNaN(timeMs)) { + setErrNo(61); + return -1; + } + return timeMs / 1e3; + })(); + return (setTempRet0((tempDouble = ret, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0)), + ret >>> 0); +}; + +var stringToNewUTF8 = str => { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8(str, ret, size); + return ret; +}; + +var __tzset_js = (timezone, daylight, tzname) => { + var currentYear = (new Date).getFullYear(); + var winter = new Date(currentYear, 0, 1); + var summer = new Date(currentYear, 6, 1); + var winterOffset = winter.getTimezoneOffset(); + var summerOffset = summer.getTimezoneOffset(); + var stdTimezoneOffset = Math.max(winterOffset, summerOffset); + GROWABLE_HEAP_U32()[((timezone) >> 2)] = stdTimezoneOffset * 60; + checkInt32(stdTimezoneOffset * 60); + GROWABLE_HEAP_I32()[((daylight) >> 2)] = Number(winterOffset != summerOffset); + checkInt32(Number(winterOffset != summerOffset)); + function extractZone(date) { + var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/); + return match ? match[1] : "GMT"; + } + var winterName = extractZone(winter); + var summerName = extractZone(summer); + var winterNamePtr = stringToNewUTF8(winterName); + var summerNamePtr = stringToNewUTF8(summerName); + if (summerOffset < winterOffset) { + GROWABLE_HEAP_U32()[((tzname) >> 2)] = winterNamePtr; + checkInt32(winterNamePtr); + GROWABLE_HEAP_U32()[(((tzname) + (4)) >> 2)] = summerNamePtr; + checkInt32(summerNamePtr); + } else { + GROWABLE_HEAP_U32()[((tzname) >> 2)] = summerNamePtr; + checkInt32(summerNamePtr); + GROWABLE_HEAP_U32()[(((tzname) + (4)) >> 2)] = winterNamePtr; + checkInt32(winterNamePtr); + } +}; + +var _abort = () => { + abort("native code called abort()"); +}; + +var readEmAsmArgsArray = []; + +var readEmAsmArgs = (sigPtr, buf) => { + assert(Array.isArray(readEmAsmArgsArray)); + assert(buf % 16 == 0); + readEmAsmArgsArray.length = 0; + var ch; + while (ch = GROWABLE_HEAP_U8()[sigPtr++]) { + var chr = String.fromCharCode(ch); + var validChars = [ "d", "f", "i", "p" ]; + assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`); + var wide = (ch != 105); + wide &= (ch != 112); + buf += wide && (buf % 8) ? 4 : 0; + readEmAsmArgsArray.push( ch == 112 ? GROWABLE_HEAP_U32()[((buf) >> 2)] : ch == 105 ? GROWABLE_HEAP_I32()[((buf) >> 2)] : GROWABLE_HEAP_F64()[((buf) >> 3)]); + buf += wide ? 8 : 4; + } + return readEmAsmArgsArray; +}; + +var runEmAsmFunction = (code, sigPtr, argbuf) => { + var args = readEmAsmArgs(sigPtr, argbuf); + assert(ASM_CONSTS.hasOwnProperty(code), `No EM_ASM constant found at address ${code}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`); + return ASM_CONSTS[code].apply(null, args); +}; + +var _emscripten_asm_const_int = (code, sigPtr, argbuf) => runEmAsmFunction(code, sigPtr, argbuf); + +var _emscripten_check_blocking_allowed = () => { + if (ENVIRONMENT_IS_NODE) return; + if (ENVIRONMENT_IS_WORKER) return; + warnOnce("Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread"); +}; + +var _emscripten_date_now = () => Date.now(); + +var _emscripten_err = str => err(UTF8ToString(str)); + +var runtimeKeepalivePush = () => { + runtimeKeepaliveCounter += 1; +}; + +var _emscripten_exit_with_live_runtime = () => { + runtimeKeepalivePush(); + throw "unwind"; +}; + +var getHeapMax = () => 2147483648; + +var _emscripten_get_heap_max = () => getHeapMax(); + +var _emscripten_get_now; + +_emscripten_get_now = () => performance.timeOrigin + performance.now(); + +var _emscripten_num_logical_cores = () => { + if (ENVIRONMENT_IS_NODE) return require("os").cpus().length; + return navigator["hardwareConcurrency"]; +}; + +var growMemory = size => { + var b = wasmMemory.buffer; + var pages = (size - b.byteLength + 65535) / 65536; + try { + wasmMemory.grow(pages); + updateMemoryViews(); + return 1; + } /*success*/ catch (e) { + err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`); + } +}; + +var _emscripten_resize_heap = requestedSize => { + var oldSize = GROWABLE_HEAP_U8().length; + requestedSize >>>= 0; + if (requestedSize <= oldSize) { + return false; + } + 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; + for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + .2 / cutDown); + overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); + var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); + var t0 = _emscripten_get_now(); + var replacement = growMemory(newSize); + var t1 = _emscripten_get_now(); + dbg(`Heap resize call from ${oldSize} to ${newSize} took ${(t1 - t0)} msecs. Success: ${!!replacement}`); + if (replacement) { + return true; + } + } + err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`); + return false; +}; + +var ENV = {}; + +var getExecutableName = () => thisProgram || "./this.program"; + +var getEnvStrings = () => { + if (!getEnvStrings.strings) { + var lang = ((typeof navigator == "object" && navigator.languages && navigator.languages[0]) || "C").replace("-", "_") + ".UTF-8"; + var env = { + "USER": "web_user", + "LOGNAME": "web_user", + "PATH": "/", + "PWD": "/", + "HOME": "/home/web_user", + "LANG": lang, + "_": getExecutableName() + }; + for (var x in ENV) { + if (ENV[x] === undefined) delete env[x]; else env[x] = ENV[x]; + } + var strings = []; + for (var x in env) { + strings.push(`${x}=${env[x]}`); + } + getEnvStrings.strings = strings; + } + return getEnvStrings.strings; +}; + +var stringToAscii = (str, buffer) => { + for (var i = 0; i < str.length; ++i) { + assert(str.charCodeAt(i) === (str.charCodeAt(i) & 255)); + GROWABLE_HEAP_I8()[((buffer++) >> 0)] = str.charCodeAt(i); + checkInt8(str.charCodeAt(i)); + } + GROWABLE_HEAP_I8()[((buffer) >> 0)] = 0; + checkInt8(0); +}; + +var _environ_get = function(__environ, environ_buf) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(3, 1, __environ, environ_buf); + var bufSize = 0; + getEnvStrings().forEach((string, i) => { + var ptr = environ_buf + bufSize; + GROWABLE_HEAP_U32()[(((__environ) + (i * 4)) >> 2)] = ptr; + checkInt32(ptr); + stringToAscii(string, ptr); + bufSize += string.length + 1; + }); + return 0; +}; + +var _environ_sizes_get = function(penviron_count, penviron_buf_size) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(4, 1, penviron_count, penviron_buf_size); + var strings = getEnvStrings(); + GROWABLE_HEAP_U32()[((penviron_count) >> 2)] = strings.length; + checkInt32(strings.length); + var bufSize = 0; + strings.forEach(string => bufSize += string.length + 1); + GROWABLE_HEAP_U32()[((penviron_buf_size) >> 2)] = bufSize; + checkInt32(bufSize); + return 0; +}; + +function _fd_close(fd) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(5, 1, fd); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +/** @param {number=} offset */ var doReadv = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = GROWABLE_HEAP_U32()[((iov) >> 2)]; + var len = GROWABLE_HEAP_U32()[(((iov) + (4)) >> 2)]; + iov += 8; + var curr = FS.read(stream, GROWABLE_HEAP_I8(), ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (curr < len) break; + if (typeof offset !== "undefined") { + offset += curr; + } + } + return ret; +}; + +function _fd_read(fd, iov, iovcnt, pnum) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(6, 1, fd, iov, iovcnt, pnum); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doReadv(stream, iov, iovcnt); + GROWABLE_HEAP_U32()[((pnum) >> 2)] = num; + checkInt32(num); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(7, 1, fd, offset_low, offset_high, whence, newOffset); + var offset = convertI32PairToI53Checked(offset_low, offset_high); + try { + if (isNaN(offset)) return 61; + var stream = SYSCALLS.getStreamFromFD(fd); + FS.llseek(stream, offset, whence); + (tempI64 = [ stream.position >>> 0, (tempDouble = stream.position, (+(Math.abs(tempDouble))) >= 1 ? (tempDouble > 0 ? (+(Math.floor((tempDouble) / 4294967296))) >>> 0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble))) >>> 0)) / 4294967296))))) >>> 0) : 0) ], + GROWABLE_HEAP_I32()[((newOffset) >> 2)] = tempI64[0], GROWABLE_HEAP_I32()[(((newOffset) + (4)) >> 2)] = tempI64[1]); + checkInt64(stream.position); + if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +/** @param {number=} offset */ var doWritev = (stream, iov, iovcnt, offset) => { + var ret = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = GROWABLE_HEAP_U32()[((iov) >> 2)]; + var len = GROWABLE_HEAP_U32()[(((iov) + (4)) >> 2)]; + iov += 8; + var curr = FS.write(stream, GROWABLE_HEAP_I8(), ptr, len, offset); + if (curr < 0) return -1; + ret += curr; + if (typeof offset !== "undefined") { + offset += curr; + } + } + return ret; +}; + +function _fd_write(fd, iov, iovcnt, pnum) { + if (ENVIRONMENT_IS_PTHREAD) return proxyToMainThread(8, 1, fd, iov, iovcnt, pnum); + try { + var stream = SYSCALLS.getStreamFromFD(fd); + var num = doWritev(stream, iov, iovcnt); + GROWABLE_HEAP_U32()[((pnum) >> 2)] = num; + checkInt32(num); + return 0; + } catch (e) { + if (typeof FS == "undefined" || !(e.name === "ErrnoError")) throw e; + return e.errno; + } +} + +var arraySum = (array, index) => { + var sum = 0; + for (var i = 0; i <= index; sum += array[i++]) {} + return sum; +}; + +var MONTH_DAYS_LEAP = [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + +var MONTH_DAYS_REGULAR = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + +var addDays = (date, days) => { + var newDate = new Date(date.getTime()); + while (days > 0) { + var leap = isLeapYear(newDate.getFullYear()); + var currentMonth = newDate.getMonth(); + var daysInCurrentMonth = (leap ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR)[currentMonth]; + if (days > daysInCurrentMonth - newDate.getDate()) { + days -= (daysInCurrentMonth - newDate.getDate() + 1); + newDate.setDate(1); + if (currentMonth < 11) { + newDate.setMonth(currentMonth + 1); + } else { + newDate.setMonth(0); + newDate.setFullYear(newDate.getFullYear() + 1); + } + } else { + newDate.setDate(newDate.getDate() + days); + return newDate; + } + } + return newDate; +}; + +var writeArrayToMemory = (array, buffer) => { + assert(array.length >= 0, "writeArrayToMemory array must have a length (should be an array or typed array)"); + GROWABLE_HEAP_I8().set(array, buffer); +}; + +var _strftime = (s, maxsize, format, tm) => { + var tm_zone = GROWABLE_HEAP_U32()[(((tm) + (40)) >> 2)]; + var date = { + tm_sec: GROWABLE_HEAP_I32()[((tm) >> 2)], + tm_min: GROWABLE_HEAP_I32()[(((tm) + (4)) >> 2)], + tm_hour: GROWABLE_HEAP_I32()[(((tm) + (8)) >> 2)], + tm_mday: GROWABLE_HEAP_I32()[(((tm) + (12)) >> 2)], + tm_mon: GROWABLE_HEAP_I32()[(((tm) + (16)) >> 2)], + tm_year: GROWABLE_HEAP_I32()[(((tm) + (20)) >> 2)], + tm_wday: GROWABLE_HEAP_I32()[(((tm) + (24)) >> 2)], + tm_yday: GROWABLE_HEAP_I32()[(((tm) + (28)) >> 2)], + tm_isdst: GROWABLE_HEAP_I32()[(((tm) + (32)) >> 2)], + tm_gmtoff: GROWABLE_HEAP_I32()[(((tm) + (36)) >> 2)], + tm_zone: tm_zone ? UTF8ToString(tm_zone) : "" + }; + var pattern = UTF8ToString(format); + var EXPANSION_RULES_1 = { + "%c": "%a %b %d %H:%M:%S %Y", + "%D": "%m/%d/%y", + "%F": "%Y-%m-%d", + "%h": "%b", + "%r": "%I:%M:%S %p", + "%R": "%H:%M", + "%T": "%H:%M:%S", + "%x": "%m/%d/%y", + "%X": "%H:%M:%S", + "%Ec": "%c", + "%EC": "%C", + "%Ex": "%m/%d/%y", + "%EX": "%H:%M:%S", + "%Ey": "%y", + "%EY": "%Y", + "%Od": "%d", + "%Oe": "%e", + "%OH": "%H", + "%OI": "%I", + "%Om": "%m", + "%OM": "%M", + "%OS": "%S", + "%Ou": "%u", + "%OU": "%U", + "%OV": "%V", + "%Ow": "%w", + "%OW": "%W", + "%Oy": "%y" + }; + for (var rule in EXPANSION_RULES_1) { + pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_1[rule]); + } + var WEEKDAYS = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ]; + var MONTHS = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; + function leadingSomething(value, digits, character) { + var str = typeof value == "number" ? value.toString() : (value || ""); + while (str.length < digits) { + str = character[0] + str; + } + return str; + } + function leadingNulls(value, digits) { + return leadingSomething(value, digits, "0"); + } + function compareByDay(date1, date2) { + function sgn(value) { + return value < 0 ? -1 : (value > 0 ? 1 : 0); + } + var compare; + if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) { + if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) { + compare = sgn(date1.getDate() - date2.getDate()); + } + } + return compare; + } + function getFirstWeekStartDate(janFourth) { + switch (janFourth.getDay()) { + case 0: + return new Date(janFourth.getFullYear() - 1, 11, 29); + + case 1: + return janFourth; + + case 2: + return new Date(janFourth.getFullYear(), 0, 3); + + case 3: + return new Date(janFourth.getFullYear(), 0, 2); + + case 4: + return new Date(janFourth.getFullYear(), 0, 1); + + case 5: + return new Date(janFourth.getFullYear() - 1, 11, 31); + + case 6: + return new Date(janFourth.getFullYear() - 1, 11, 30); + } + } + function getWeekBasedYear(date) { + var thisDate = addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); + var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); + var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4); + var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); + var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); + if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { + if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { + return thisDate.getFullYear() + 1; + } + return thisDate.getFullYear(); + } + return thisDate.getFullYear() - 1; + } + var EXPANSION_RULES_2 = { + "%a": date => WEEKDAYS[date.tm_wday].substring(0, 3), + "%A": date => WEEKDAYS[date.tm_wday], + "%b": date => MONTHS[date.tm_mon].substring(0, 3), + "%B": date => MONTHS[date.tm_mon], + "%C": date => { + var year = date.tm_year + 1900; + return leadingNulls((year / 100) | 0, 2); + }, + "%d": date => leadingNulls(date.tm_mday, 2), + "%e": date => leadingSomething(date.tm_mday, 2, " "), + "%g": date => getWeekBasedYear(date).toString().substring(2), + "%G": date => getWeekBasedYear(date), + "%H": date => leadingNulls(date.tm_hour, 2), + "%I": date => { + var twelveHour = date.tm_hour; + if (twelveHour == 0) twelveHour = 12; else if (twelveHour > 12) twelveHour -= 12; + return leadingNulls(twelveHour, 2); + }, + "%j": date => leadingNulls(date.tm_mday + arraySum(isLeapYear(date.tm_year + 1900) ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR, date.tm_mon - 1), 3), + "%m": date => leadingNulls(date.tm_mon + 1, 2), + "%M": date => leadingNulls(date.tm_min, 2), + "%n": () => "\n", + "%p": date => { + if (date.tm_hour >= 0 && date.tm_hour < 12) { + return "AM"; + } + return "PM"; + }, + "%S": date => leadingNulls(date.tm_sec, 2), + "%t": () => "\t", + "%u": date => date.tm_wday || 7, + "%U": date => { + var days = date.tm_yday + 7 - date.tm_wday; + return leadingNulls(Math.floor(days / 7), 2); + }, + "%V": date => { + var val = Math.floor((date.tm_yday + 7 - (date.tm_wday + 6) % 7) / 7); + if ((date.tm_wday + 371 - date.tm_yday - 2) % 7 <= 2) { + val++; + } + if (!val) { + val = 52; + var dec31 = (date.tm_wday + 7 - date.tm_yday - 1) % 7; + if (dec31 == 4 || (dec31 == 5 && isLeapYear(date.tm_year % 400 - 1))) { + val++; + } + } else if (val == 53) { + var jan1 = (date.tm_wday + 371 - date.tm_yday) % 7; + if (jan1 != 4 && (jan1 != 3 || !isLeapYear(date.tm_year))) val = 1; + } + return leadingNulls(val, 2); + }, + "%w": date => date.tm_wday, + "%W": date => { + var days = date.tm_yday + 7 - ((date.tm_wday + 6) % 7); + return leadingNulls(Math.floor(days / 7), 2); + }, + "%y": date => (date.tm_year + 1900).toString().substring(2), + "%Y": date => date.tm_year + 1900, + "%z": date => { + var off = date.tm_gmtoff; + var ahead = off >= 0; + off = Math.abs(off) / 60; + off = (off / 60) * 100 + (off % 60); + return (ahead ? "+" : "-") + String("0000" + off).slice(-4); + }, + "%Z": date => date.tm_zone, + "%%": () => "%" + }; + pattern = pattern.replace(/%%/g, "\0\0"); + for (var rule in EXPANSION_RULES_2) { + if (pattern.includes(rule)) { + pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_2[rule](date)); + } + } + pattern = pattern.replace(/\0\0/g, "%"); + var bytes = intArrayFromString(pattern, false); + if (bytes.length > maxsize) { + return 0; + } + writeArrayToMemory(bytes, s); + return bytes.length - 1; +}; + +var _strftime_l = (s, maxsize, format, tm, loc) => _strftime(s, maxsize, format, tm); + +function intArrayToString(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + var chr = array[i]; + if (chr > 255) { + assert(false, `Character code ${chr} (${String.fromCharCode(chr)}) at offset ${i} not in 0x00-0xFF.`); + chr &= 255; + } + ret.push(String.fromCharCode(chr)); + } + return ret.join(""); +} + +var uleb128Encode = (n, target) => { + assert(n < 16384); + if (n < 128) { + target.push(n); + } else { + target.push((n % 128) | 128, n >> 7); + } +}; - function __mktime_js(tmPtr) { - var date = new Date(HEAP32[(((tmPtr)+(20))>>2)] + 1900, - HEAP32[(((tmPtr)+(16))>>2)], - HEAP32[(((tmPtr)+(12))>>2)], - HEAP32[(((tmPtr)+(8))>>2)], - HEAP32[(((tmPtr)+(4))>>2)], - HEAP32[((tmPtr)>>2)], - 0); - - // There's an ambiguous hour when the time goes back; the tm_isdst field is - // used to disambiguate it. Date() basically guesses, so we fix it up if it - // guessed wrong, or fill in tm_isdst with the guess if it's -1. - var dst = HEAP32[(((tmPtr)+(32))>>2)]; - var guessedOffset = date.getTimezoneOffset(); - var start = new Date(date.getFullYear(), 0, 1); - var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); - var winterOffset = start.getTimezoneOffset(); - var dstOffset = Math.min(winterOffset, summerOffset); // DST is in December in South - if (dst < 0) { - // Attention: some regions don't have DST at all. - HEAP32[(((tmPtr)+(32))>>2)] = Number(summerOffset != winterOffset && dstOffset == guessedOffset); - } else if ((dst > 0) != (dstOffset == guessedOffset)) { - var nonDstOffset = Math.max(winterOffset, summerOffset); - var trueOffset = dst > 0 ? dstOffset : nonDstOffset; - // Don't try setMinutes(date.getMinutes() + ...) -- it's messed up. - date.setTime(date.getTime() + (trueOffset - guessedOffset)*60000); - } - - HEAP32[(((tmPtr)+(24))>>2)] = date.getDay(); - var yday = ((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24))|0; - HEAP32[(((tmPtr)+(28))>>2)] = yday; - // To match expected behavior, update fields from date - HEAP32[((tmPtr)>>2)] = date.getSeconds(); - HEAP32[(((tmPtr)+(4))>>2)] = date.getMinutes(); - HEAP32[(((tmPtr)+(8))>>2)] = date.getHours(); - HEAP32[(((tmPtr)+(12))>>2)] = date.getDate(); - HEAP32[(((tmPtr)+(16))>>2)] = date.getMonth(); - HEAP32[(((tmPtr)+(20))>>2)] = date.getYear(); - - return (date.getTime() / 1000)|0; - } +var sigToWasmTypes = sig => { + assert(!sig.includes("j"), "i64 not permitted in function signatures when WASM_BIGINT is disabled"); + var typeNames = { + "i": "i32", + "j": "i64", + "f": "f32", + "d": "f64", + "e": "externref", + "p": "i32" + }; + var type = { + parameters: [], + results: sig[0] == "v" ? [] : [ typeNames[sig[0]] ] + }; + for (var i = 1; i < sig.length; ++i) { + assert(sig[i] in typeNames, "invalid signature char: " + sig[i]); + type.parameters.push(typeNames[sig[i]]); + } + return type; +}; - function allocateUTF8(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = _malloc(size); - if (ret) stringToUTF8Array(str, HEAP8, ret, size); - return ret; - } - function _tzset_impl(timezone, daylight, tzname) { - var currentYear = new Date().getFullYear(); - var winter = new Date(currentYear, 0, 1); - var summer = new Date(currentYear, 6, 1); - var winterOffset = winter.getTimezoneOffset(); - var summerOffset = summer.getTimezoneOffset(); - - // Local standard timezone offset. Local standard time is not adjusted for daylight savings. - // This code uses the fact that getTimezoneOffset returns a greater value during Standard Time versus Daylight Saving Time (DST). - // Thus it determines the expected output during Standard Time, and it compares whether the output of the given date the same (Standard) or less (DST). - var stdTimezoneOffset = Math.max(winterOffset, summerOffset); - - // timezone is specified as seconds west of UTC ("The external variable - // `timezone` shall be set to the difference, in seconds, between - // Coordinated Universal Time (UTC) and local standard time."), the same - // as returned by stdTimezoneOffset. - // See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html - HEAP32[((timezone)>>2)] = stdTimezoneOffset * 60; - - HEAP32[((daylight)>>2)] = Number(winterOffset != summerOffset); - - function extractZone(date) { - var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/); - return match ? match[1] : "GMT"; - }; - var winterName = extractZone(winter); - var summerName = extractZone(summer); - var winterNamePtr = allocateUTF8(winterName); - var summerNamePtr = allocateUTF8(summerName); - if (summerOffset < winterOffset) { - // Northern hemisphere - HEAPU32[((tzname)>>2)] = winterNamePtr; - HEAPU32[(((tzname)+(4))>>2)] = summerNamePtr; - } else { - HEAPU32[((tzname)>>2)] = summerNamePtr; - HEAPU32[(((tzname)+(4))>>2)] = winterNamePtr; - } - } - function __tzset_js(timezone, daylight, tzname) { - // TODO: Use (malleable) environment variables instead of system settings. - if (__tzset_js.called) return; - __tzset_js.called = true; - _tzset_impl(timezone, daylight, tzname); - } +var generateFuncType = (sig, target) => { + var sigRet = sig.slice(0, 1); + var sigParam = sig.slice(1); + var typeCodes = { + "i": 127, + "p": 127, + "j": 126, + "f": 125, + "d": 124, + "e": 111 + }; + target.push(96); + /* form: func */ uleb128Encode(sigParam.length, target); + for (var i = 0; i < sigParam.length; ++i) { + assert(sigParam[i] in typeCodes, "invalid signature char: " + sigParam[i]); + target.push(typeCodes[sigParam[i]]); + } + if (sigRet == "v") { + target.push(0); + } else { + target.push(1, typeCodes[sigRet]); + } +}; - function _abort() { - abort('native code called abort()'); - } +var convertJsFunctionToWasm = (func, sig) => { + assert(!sig.includes("j"), "i64 not permitted in function signatures when WASM_BIGINT is disabled"); + if (typeof WebAssembly.Function == "function") { + return new WebAssembly.Function(sigToWasmTypes(sig), func); + } + var typeSectionBody = [ 1 ]; + generateFuncType(sig, typeSectionBody); + var bytes = [ 0, 97, 115, 109, 1, 0, 0, 0, 1 ]; + uleb128Encode(typeSectionBody.length, bytes); + bytes.push.apply(bytes, typeSectionBody); + bytes.push(2, 7, 1, 1, 101, 1, 102, 0, 0, 7, 5, 1, 1, 102, 0, 0); + var module = new WebAssembly.Module(new Uint8Array(bytes)); + var instance = new WebAssembly.Instance(module, { + "e": { + "f": func + } + }); + var wrappedFunc = instance.exports["f"]; + return wrappedFunc; +}; - var readAsmConstArgsArray = []; - function readAsmConstArgs(sigPtr, buf) { - // Nobody should have mutated _readAsmConstArgsArray underneath us to be something else than an array. - assert(Array.isArray(readAsmConstArgsArray)); - // The input buffer is allocated on the stack, so it must be stack-aligned. - assert(buf % 16 == 0); - readAsmConstArgsArray.length = 0; - var ch; - // Most arguments are i32s, so shift the buffer pointer so it is a plain - // index into HEAP32. - buf >>= 2; - while (ch = HEAPU8[sigPtr++]) { - var chr = String.fromCharCode(ch); - var validChars = ['d', 'f', 'i']; - assert(validChars.includes(chr), 'Invalid character ' + ch + '("' + chr + '") in readAsmConstArgs! Use only [' + validChars + '], and do not specify "v" for void return argument.'); - // Floats are always passed as doubles, and doubles and int64s take up 8 - // bytes (two 32-bit slots) in memory, align reads to these: - buf += (ch != 105/*i*/) & buf; - readAsmConstArgsArray.push( - ch == 105/*i*/ ? HEAP32[buf] : - HEAPF64[buf++ >> 1] - ); - ++buf; - } - return readAsmConstArgsArray; - } - function _emscripten_asm_const_int(code, sigPtr, argbuf) { - var args = readAsmConstArgs(sigPtr, argbuf); - if (!ASM_CONSTS.hasOwnProperty(code)) abort('No EM_ASM constant found at address ' + code); - return ASM_CONSTS[code].apply(null, args); - } +var updateTableMap = (offset, count) => { + if (functionsInTableMap) { + for (var i = offset; i < offset + count; i++) { + var item = getWasmTableEntry(i); + if (item) { + functionsInTableMap.set(item, i); + } + } + } +}; - function _emscripten_console_error(str) { - assert(typeof str == 'number'); - console.error(UTF8ToString(str)); - } +var functionsInTableMap; - function _emscripten_date_now() { - return Date.now(); - } +var getFunctionAddress = func => { + if (!functionsInTableMap) { + functionsInTableMap = new WeakMap; + updateTableMap(0, wasmTable.length); + } + return functionsInTableMap.get(func) || 0; +}; - function 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. - return 2147483648; - } - function _emscripten_get_heap_max() { - return getHeapMax(); - } +var freeTableIndexes = []; + +var getEmptyTableSlot = () => { + if (freeTableIndexes.length) { + return freeTableIndexes.pop(); + } + try { + wasmTable.grow(1); + } catch (err) { + if (!(err instanceof RangeError)) { + throw err; + } + throw "Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."; + } + return wasmTable.length - 1; +}; - function _emscripten_memcpy_big(dest, src, num) { - HEAPU8.copyWithin(dest, src, src + num); - } +var setWasmTableEntry = (idx, func) => { + wasmTable.set(idx, func); + wasmTableMirror[idx] = wasmTable.get(idx); +}; - var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) { - _emscripten_get_now = () => { - var t = process['hrtime'](); - return t[0] * 1e3 + t[1] / 1e6; - }; - } else _emscripten_get_now = () => performance.now(); - ; - - function emscripten_realloc_buffer(size) { - try { - // round size grow request up to wasm page size (fixed 64KB per spec) - wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size - updateGlobalBufferAndViews(wasmMemory.buffer); - return 1 /*success*/; - } catch(e) { - err('emscripten_realloc_buffer: Attempted to grow heap from ' + buffer.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) { - var oldSize = HEAPU8.length; - requestedSize = requestedSize >>> 0; - // 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, asked to go up to ' + requestedSize + ' bytes, but the limit is ' + maxHeapSize + ' bytes!'); - return false; - } - - let 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 + 0.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 t0 = _emscripten_get_now(); - var replacement = emscripten_realloc_buffer(newSize); - var t1 = _emscripten_get_now(); - out('Heap resize call from ' + oldSize + ' to ' + newSize + ' took ' + (t1 - t0) + ' msecs. Success: ' + !!replacement); - if (replacement) { - - return true; - } - } - err('Failed to grow the heap from ' + oldSize + ' bytes to ' + newSize + ' bytes, not enough memory!'); - return false; - } +/** @param {string=} sig */ var addFunction = (func, sig) => { + assert(typeof func != "undefined"); + var rtn = getFunctionAddress(func); + if (rtn) { + return rtn; + } + for (var i = 0; i < wasmTable.length; i++) { + assert(getWasmTableEntry(i) != func, "function in Table but not functionsInTableMap"); + } + var ret = getEmptyTableSlot(); + try { + setWasmTableEntry(ret, func); + } catch (err) { + if (!(err instanceof TypeError)) { + throw err; + } + assert(typeof sig != "undefined", "Missing signature argument to addFunction: " + func); + var wrapped = convertJsFunctionToWasm(func, sig); + setWasmTableEntry(ret, wrapped); + } + functionsInTableMap.set(func, ret); + return ret; +}; - var ENV = {}; - - function getExecutableName() { - return thisProgram || './this.program'; - } - function getEnvStrings() { - if (!getEnvStrings.strings) { - // Default values. - // Browser language detection #8751 - var lang = ((typeof navigator == 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') + '.UTF-8'; - var env = { - 'USER': 'web_user', - 'LOGNAME': 'web_user', - 'PATH': '/', - 'PWD': '/', - 'HOME': '/home/web_user', - 'LANG': lang, - '_': getExecutableName() - }; - // Apply the user-provided values, if any. - for (var x in ENV) { - // x is a key in ENV; if ENV[x] is undefined, that means it was - // explicitly set to be so. We allow user code to do that to - // force variables with default values to remain unset. - if (ENV[x] === undefined) delete env[x]; - else env[x] = ENV[x]; - } - var strings = []; - for (var x in env) { - strings.push(x + '=' + env[x]); - } - getEnvStrings.strings = strings; - } - return getEnvStrings.strings; - } - - /** @param {boolean=} dontAddNull */ - function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff)); - HEAP8[((buffer++)>>0)] = str.charCodeAt(i); - } - // Null-terminate the pointer to the HEAP. - if (!dontAddNull) HEAP8[((buffer)>>0)] = 0; - } - function _environ_get(__environ, environ_buf) { - var bufSize = 0; - getEnvStrings().forEach(function(string, i) { - var ptr = environ_buf + bufSize; - HEAPU32[(((__environ)+(i*4))>>2)] = ptr; - writeAsciiToMemory(string, ptr); - bufSize += string.length + 1; - }); - return 0; - } +PThread.init(); + +var FSNode = /** @constructor */ function(parent, name, mode, rdev) { + if (!parent) { + parent = this; + } + this.parent = parent; + this.mount = parent.mount; + this.mounted = null; + this.id = FS.nextInode++; + this.name = name; + this.mode = mode; + this.node_ops = {}; + this.stream_ops = {}; + this.rdev = rdev; +}; - function _environ_sizes_get(penviron_count, penviron_buf_size) { - var strings = getEnvStrings(); - HEAPU32[((penviron_count)>>2)] = strings.length; - var bufSize = 0; - strings.forEach(function(string) { - bufSize += string.length + 1; - }); - HEAPU32[((penviron_buf_size)>>2)] = bufSize; - return 0; - } +var readMode = 292 | /*292*/ 73; - function _proc_exit(code) { - EXITSTATUS = code; - if (!keepRuntimeAlive()) { - if (Module['onExit']) Module['onExit'](code); - ABORT = true; - } - quit_(code, new ExitStatus(code)); - } - /** @param {boolean|number=} implicit */ - function 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 EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)'; - readyPromiseReject(msg); - err(msg); - } - - _proc_exit(status); - } - var _exit = exitJS; +/*73*/ var writeMode = 146; - function _fd_close(fd) { - try { - - var stream = SYSCALLS.getStreamFromFD(fd); - FS.close(stream); - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e; - return e.errno; - } - } - - /** @param {number=} offset */ - function doReadv(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAPU32[((iov)>>2)]; - var len = HEAPU32[(((iov)+(4))>>2)]; - iov += 8; - var curr = FS.read(stream, HEAP8,ptr, len, offset); - if (curr < 0) return -1; - ret += curr; - if (curr < len) break; // nothing more to read - } - return ret; - } - function _fd_read(fd, iov, iovcnt, pnum) { - try { - - var stream = SYSCALLS.getStreamFromFD(fd); - var num = doReadv(stream, iov, iovcnt); - HEAPU32[((pnum)>>2)] = num; - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e; - return e.errno; +/*146*/ Object.defineProperties(FSNode.prototype, { + read: { + get: /** @this{FSNode} */ function() { + return (this.mode & readMode) === readMode; + }, + set: /** @this{FSNode} */ function(val) { + val ? this.mode |= readMode : this.mode &= ~readMode; } + }, + write: { + get: /** @this{FSNode} */ function() { + return (this.mode & writeMode) === writeMode; + }, + set: /** @this{FSNode} */ function(val) { + val ? this.mode |= writeMode : this.mode &= ~writeMode; } - - function 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) { - try { - - var offset = convertI32PairToI53Checked(offset_low, offset_high); if (isNaN(offset)) return 61; - var stream = SYSCALLS.getStreamFromFD(fd); - FS.llseek(stream, offset, whence); - (tempI64 = [stream.position>>>0,(tempDouble=stream.position,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((newOffset)>>2)] = tempI64[0],HEAP32[(((newOffset)+(4))>>2)] = tempI64[1]); - if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e; - return e.errno; + }, + isFolder: { + get: /** @this{FSNode} */ function() { + return FS.isDir(this.mode); } + }, + isDevice: { + get: /** @this{FSNode} */ function() { + return FS.isChrdev(this.mode); } + } +}); - /** @param {number=} offset */ - function doWritev(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAPU32[((iov)>>2)]; - var len = HEAPU32[(((iov)+(4))>>2)]; - iov += 8; - var curr = FS.write(stream, HEAP8,ptr, len, offset); - if (curr < 0) return -1; - ret += curr; - } - return ret; - } - function _fd_write(fd, iov, iovcnt, pnum) { - try { - - var stream = SYSCALLS.getStreamFromFD(fd); - var num = doWritev(stream, iov, iovcnt); - HEAPU32[((pnum)>>2)] = num; - return 0; - } catch (e) { - if (typeof FS == 'undefined' || !(e instanceof FS.ErrnoError)) throw e; - return e.errno; - } - } +FS.FSNode = FSNode; - function __isLeapYear(year) { - return year%4 === 0 && (year%100 !== 0 || year%400 === 0); - } - - function __arraySum(array, index) { - var sum = 0; - for (var i = 0; i <= index; sum += array[i++]) { - // no-op - } - return sum; - } - - var __MONTH_DAYS_LEAP = [31,29,31,30,31,30,31,31,30,31,30,31]; - - var __MONTH_DAYS_REGULAR = [31,28,31,30,31,30,31,31,30,31,30,31]; - function __addDays(date, days) { - var newDate = new Date(date.getTime()); - while (days > 0) { - var leap = __isLeapYear(newDate.getFullYear()); - var currentMonth = newDate.getMonth(); - var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth]; - - if (days > daysInCurrentMonth-newDate.getDate()) { - // we spill over to next month - days -= (daysInCurrentMonth-newDate.getDate()+1); - newDate.setDate(1); - if (currentMonth < 11) { - newDate.setMonth(currentMonth+1) - } else { - newDate.setMonth(0); - newDate.setFullYear(newDate.getFullYear()+1); - } - } else { - // we stay in current month - newDate.setDate(newDate.getDate()+days); - return newDate; - } - } - - return newDate; - } - - function writeArrayToMemory(array, buffer) { - assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)') - HEAP8.set(array, buffer); - } - function _strftime(s, maxsize, format, tm) { - // size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr); - // http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html - - var tm_zone = HEAP32[(((tm)+(40))>>2)]; - - var date = { - tm_sec: HEAP32[((tm)>>2)], - tm_min: HEAP32[(((tm)+(4))>>2)], - tm_hour: HEAP32[(((tm)+(8))>>2)], - tm_mday: HEAP32[(((tm)+(12))>>2)], - tm_mon: HEAP32[(((tm)+(16))>>2)], - tm_year: HEAP32[(((tm)+(20))>>2)], - tm_wday: HEAP32[(((tm)+(24))>>2)], - tm_yday: HEAP32[(((tm)+(28))>>2)], - tm_isdst: HEAP32[(((tm)+(32))>>2)], - tm_gmtoff: HEAP32[(((tm)+(36))>>2)], - tm_zone: tm_zone ? UTF8ToString(tm_zone) : '' - }; - - var pattern = UTF8ToString(format); - - // expand format - var EXPANSION_RULES_1 = { - '%c': '%a %b %d %H:%M:%S %Y', // Replaced by the locale's appropriate date and time representation - e.g., Mon Aug 3 14:02:01 2013 - '%D': '%m/%d/%y', // Equivalent to %m / %d / %y - '%F': '%Y-%m-%d', // Equivalent to %Y - %m - %d - '%h': '%b', // Equivalent to %b - '%r': '%I:%M:%S %p', // Replaced by the time in a.m. and p.m. notation - '%R': '%H:%M', // Replaced by the time in 24-hour notation - '%T': '%H:%M:%S', // Replaced by the time - '%x': '%m/%d/%y', // Replaced by the locale's appropriate date representation - '%X': '%H:%M:%S', // Replaced by the locale's appropriate time representation - // Modified Conversion Specifiers - '%Ec': '%c', // Replaced by the locale's alternative appropriate date and time representation. - '%EC': '%C', // Replaced by the name of the base year (period) in the locale's alternative representation. - '%Ex': '%m/%d/%y', // Replaced by the locale's alternative date representation. - '%EX': '%H:%M:%S', // Replaced by the locale's alternative time representation. - '%Ey': '%y', // Replaced by the offset from %EC (year only) in the locale's alternative representation. - '%EY': '%Y', // Replaced by the full alternative year representation. - '%Od': '%d', // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading zeros if there is any alternative symbol for zero; otherwise, with leading characters. - '%Oe': '%e', // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading characters. - '%OH': '%H', // Replaced by the hour (24-hour clock) using the locale's alternative numeric symbols. - '%OI': '%I', // Replaced by the hour (12-hour clock) using the locale's alternative numeric symbols. - '%Om': '%m', // Replaced by the month using the locale's alternative numeric symbols. - '%OM': '%M', // Replaced by the minutes using the locale's alternative numeric symbols. - '%OS': '%S', // Replaced by the seconds using the locale's alternative numeric symbols. - '%Ou': '%u', // Replaced by the weekday as a number in the locale's alternative representation (Monday=1). - '%OU': '%U', // Replaced by the week number of the year (Sunday as the first day of the week, rules corresponding to %U ) using the locale's alternative numeric symbols. - '%OV': '%V', // Replaced by the week number of the year (Monday as the first day of the week, rules corresponding to %V ) using the locale's alternative numeric symbols. - '%Ow': '%w', // Replaced by the number of the weekday (Sunday=0) using the locale's alternative numeric symbols. - '%OW': '%W', // Replaced by the week number of the year (Monday as the first day of the week) using the locale's alternative numeric symbols. - '%Oy': '%y', // Replaced by the year (offset from %C ) using the locale's alternative numeric symbols. - }; - for (var rule in EXPANSION_RULES_1) { - pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_1[rule]); - } - - var WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; - var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; - - function leadingSomething(value, digits, character) { - var str = typeof value == 'number' ? value.toString() : (value || ''); - while (str.length < digits) { - str = character[0]+str; - } - return str; - } - - function leadingNulls(value, digits) { - return leadingSomething(value, digits, '0'); - } - - function compareByDay(date1, date2) { - function sgn(value) { - return value < 0 ? -1 : (value > 0 ? 1 : 0); - } - - var compare; - if ((compare = sgn(date1.getFullYear()-date2.getFullYear())) === 0) { - if ((compare = sgn(date1.getMonth()-date2.getMonth())) === 0) { - compare = sgn(date1.getDate()-date2.getDate()); - } - } - return compare; - } - - function getFirstWeekStartDate(janFourth) { - switch (janFourth.getDay()) { - case 0: // Sunday - return new Date(janFourth.getFullYear()-1, 11, 29); - case 1: // Monday - return janFourth; - case 2: // Tuesday - return new Date(janFourth.getFullYear(), 0, 3); - case 3: // Wednesday - return new Date(janFourth.getFullYear(), 0, 2); - case 4: // Thursday - return new Date(janFourth.getFullYear(), 0, 1); - case 5: // Friday - return new Date(janFourth.getFullYear()-1, 11, 31); - case 6: // Saturday - return new Date(janFourth.getFullYear()-1, 11, 30); - } - } - - function getWeekBasedYear(date) { - var thisDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday); - - var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); - var janFourthNextYear = new Date(thisDate.getFullYear()+1, 0, 4); - - var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); - - if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { - // this date is after the start of the first week of this year - if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { - return thisDate.getFullYear()+1; - } - return thisDate.getFullYear(); - } - return thisDate.getFullYear()-1; - } - - var EXPANSION_RULES_2 = { - '%a': function(date) { - return WEEKDAYS[date.tm_wday].substring(0,3); - }, - '%A': function(date) { - return WEEKDAYS[date.tm_wday]; - }, - '%b': function(date) { - return MONTHS[date.tm_mon].substring(0,3); - }, - '%B': function(date) { - return MONTHS[date.tm_mon]; - }, - '%C': function(date) { - var year = date.tm_year+1900; - return leadingNulls((year/100)|0,2); - }, - '%d': function(date) { - return leadingNulls(date.tm_mday, 2); - }, - '%e': function(date) { - return leadingSomething(date.tm_mday, 2, ' '); - }, - '%g': function(date) { - // %g, %G, and %V give values according to the ISO 8601:2000 standard week-based year. - // In this system, weeks begin on a Monday and week 1 of the year is the week that includes - // January 4th, which is also the week that includes the first Thursday of the year, and - // is also the first week that contains at least four days in the year. - // If the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of - // the last week of the preceding year; thus, for Saturday 2nd January 1999, - // %G is replaced by 1998 and %V is replaced by 53. If December 29th, 30th, - // or 31st is a Monday, it and any following days are part of week 1 of the following year. - // Thus, for Tuesday 30th December 1997, %G is replaced by 1998 and %V is replaced by 01. - - return getWeekBasedYear(date).toString().substring(2); - }, - '%G': function(date) { - return getWeekBasedYear(date); - }, - '%H': function(date) { - return leadingNulls(date.tm_hour, 2); - }, - '%I': function(date) { - var twelveHour = date.tm_hour; - if (twelveHour == 0) twelveHour = 12; - else if (twelveHour > 12) twelveHour -= 12; - return leadingNulls(twelveHour, 2); - }, - '%j': function(date) { - // Day of the year (001-366) - return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon-1), 3); - }, - '%m': function(date) { - return leadingNulls(date.tm_mon+1, 2); - }, - '%M': function(date) { - return leadingNulls(date.tm_min, 2); - }, - '%n': function() { - return '\n'; - }, - '%p': function(date) { - if (date.tm_hour >= 0 && date.tm_hour < 12) { - return 'AM'; - } - return 'PM'; - }, - '%S': function(date) { - return leadingNulls(date.tm_sec, 2); - }, - '%t': function() { - return '\t'; - }, - '%u': function(date) { - return date.tm_wday || 7; - }, - '%U': function(date) { - var days = date.tm_yday + 7 - date.tm_wday; - return leadingNulls(Math.floor(days / 7), 2); - }, - '%V': function(date) { - // Replaced by the week number of the year (Monday as the first day of the week) - // as a decimal number [01,53]. If the week containing 1 January has four - // or more days in the new year, then it is considered week 1. - // Otherwise, it is the last week of the previous year, and the next week is week 1. - // Both January 4th and the first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday] - var val = Math.floor((date.tm_yday + 7 - (date.tm_wday + 6) % 7 ) / 7); - // If 1 Jan is just 1-3 days past Monday, the previous week - // is also in this year. - if ((date.tm_wday + 371 - date.tm_yday - 2) % 7 <= 2) { - val++; - } - if (!val) { - val = 52; - // If 31 December of prev year a Thursday, or Friday of a - // leap year, then the prev year has 53 weeks. - var dec31 = (date.tm_wday + 7 - date.tm_yday - 1) % 7; - if (dec31 == 4 || (dec31 == 5 && __isLeapYear(date.tm_year%400-1))) { - val++; - } - } else if (val == 53) { - // If 1 January is not a Thursday, and not a Wednesday of a - // leap year, then this year has only 52 weeks. - var jan1 = (date.tm_wday + 371 - date.tm_yday) % 7; - if (jan1 != 4 && (jan1 != 3 || !__isLeapYear(date.tm_year))) - val = 1; - } - return leadingNulls(val, 2); - }, - '%w': function(date) { - return date.tm_wday; - }, - '%W': function(date) { - var days = date.tm_yday + 7 - ((date.tm_wday + 6) % 7); - return leadingNulls(Math.floor(days / 7), 2); - }, - '%y': function(date) { - // Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year] - return (date.tm_year+1900).toString().substring(2); - }, - '%Y': function(date) { - // Replaced by the year as a decimal number (for example, 1997). [ tm_year] - return date.tm_year+1900; - }, - '%z': function(date) { - // Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ). - // For example, "-0430" means 4 hours 30 minutes behind UTC (west of Greenwich). - var off = date.tm_gmtoff; - var ahead = off >= 0; - off = Math.abs(off) / 60; - // convert from minutes into hhmm format (which means 60 minutes = 100 units) - off = (off / 60)*100 + (off % 60); - return (ahead ? '+' : '-') + String("0000" + off).slice(-4); - }, - '%Z': function(date) { - return date.tm_zone; - }, - '%%': function() { - return '%'; - } - }; - - // Replace %% with a pair of NULLs (which cannot occur in a C string), then - // re-inject them after processing. - pattern = pattern.replace(/%%/g, '\0\0') - for (var rule in EXPANSION_RULES_2) { - if (pattern.includes(rule)) { - pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_2[rule](date)); - } - } - pattern = pattern.replace(/\0\0/g, '%') - - var bytes = intArrayFromString(pattern, false); - if (bytes.length > maxsize) { - return 0; - } - - writeArrayToMemory(bytes, s); - return bytes.length-1; - } - function _strftime_l(s, maxsize, format, tm, loc) { - return _strftime(s, maxsize, format, tm); // no locale support yet - } +FS.createPreloadedFile = FS_createPreloadedFile; +FS.staticInit(); - function 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; - } - quit_(1, e); - } +embind_init_charCodes(); +BindingError = Module["BindingError"] = class BindingError extends Error { + constructor(message) { + super(message); + this.name = "BindingError"; + } +}; - function intArrayToString(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - var chr = array[i]; - if (chr > 0xFF) { - if (ASSERTIONS) { - assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); - } - chr &= 0xFF; - } - ret.push(String.fromCharCode(chr)); - } - return ret.join(''); - } +InternalError = Module["InternalError"] = class InternalError extends Error { + constructor(message) { + super(message); + this.name = "InternalError"; + } +}; - function uleb128Encode(n, target) { - assert(n < 16384); - if (n < 128) { - target.push(n); - } else { - target.push((n % 128) | 128, n >> 7); - } - } - - function sigToWasmTypes(sig) { - var typeNames = { - 'i': 'i32', - // i64 values will be split into two i32s. - 'j': 'i32', - 'f': 'f32', - 'd': 'f64', - 'p': 'i32', - }; - var type = { - parameters: [], - results: sig[0] == 'v' ? [] : [typeNames[sig[0]]] - }; - for (var i = 1; i < sig.length; ++i) { - assert(sig[i] in typeNames, 'invalid signature char: ' + sig[i]); - type.parameters.push(typeNames[sig[i]]); - if (sig[i] === 'j') { - type.parameters.push('i32'); - } - } - return type; - } - - function generateFuncType(sig, target){ - var sigRet = sig.slice(0, 1); - var sigParam = sig.slice(1); - var typeCodes = { - 'i': 0x7f, // i32 - 'p': 0x7f, // i32 - 'j': 0x7e, // i64 - 'f': 0x7d, // f32 - 'd': 0x7c, // f64 - }; - - // Parameters, length + signatures - target.push(0x60 /* form: func */); - uleb128Encode(sigParam.length, target); - for (var i = 0; i < sigParam.length; ++i) { - assert(sigParam[i] in typeCodes, 'invalid signature char: ' + sigParam[i]); - target.push(typeCodes[sigParam[i]]); - } - - // Return values, length + signatures - // With no multi-return in MVP, either 0 (void) or 1 (anything else) - if (sigRet == 'v') { - target.push(0x00); - } else { - target.push(0x01, typeCodes[sigRet]); - } - } - function convertJsFunctionToWasm(func, sig) { - - // If the type reflection proposal is available, use the new - // "WebAssembly.Function" constructor. - // Otherwise, construct a minimal wasm module importing the JS function and - // re-exporting it. - if (typeof WebAssembly.Function == "function") { - return new WebAssembly.Function(sigToWasmTypes(sig), func); - } - - // The module is static, with the exception of the type section, which is - // generated based on the signature passed in. - var typeSectionBody = [ - 0x01, // count: 1 - ]; - generateFuncType(sig, typeSectionBody); - - // Rest of the module is static - var bytes = [ - 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm") - 0x01, 0x00, 0x00, 0x00, // version: 1 - 0x01, // Type section code - ]; - // Write the overall length of the type section followed by the body - uleb128Encode(typeSectionBody.length, bytes); - bytes.push.apply(bytes, typeSectionBody); - - // The rest of the module is static - bytes.push( - 0x02, 0x07, // import section - // (import "e" "f" (func 0 (type 0))) - 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00, - 0x07, 0x05, // export section - // (export "f" (func 0 (type 0))) - 0x01, 0x01, 0x66, 0x00, 0x00, - ); - - // We can compile this wasm module synchronously because it is very small. - // This accepts an import (at "e.f"), that it reroutes to an export (at "f") - var module = new WebAssembly.Module(new Uint8Array(bytes)); - var instance = new WebAssembly.Instance(module, { 'e': { 'f': func } }); - var wrappedFunc = instance.exports['f']; - return wrappedFunc; - } - - function updateTableMap(offset, count) { - if (functionsInTableMap) { - for (var i = offset; i < offset + count; i++) { - var item = getWasmTableEntry(i); - // Ignore null values. - if (item) { - functionsInTableMap.set(item, i); - } - } - } - } - - var functionsInTableMap = undefined; - - var freeTableIndexes = []; - function getEmptyTableSlot() { - // Reuse a free index if there is one, otherwise grow. - if (freeTableIndexes.length) { - return freeTableIndexes.pop(); - } - // Grow the table - try { - wasmTable.grow(1); - } catch (err) { - if (!(err instanceof RangeError)) { - throw err; - } - throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.'; - } - return wasmTable.length - 1; - } - - function setWasmTableEntry(idx, func) { - wasmTable.set(idx, func); - // With ABORT_ON_WASM_EXCEPTIONS wasmTable.get is overriden to return wrapped - // functions so we need to call it here to retrieve the potential wrapper correctly - // instead of just storing 'func' directly into wasmTableMirror - wasmTableMirror[idx] = wasmTable.get(idx); - } - /** @param {string=} sig */ - function addFunction(func, sig) { - assert(typeof func != 'undefined'); - - // Check if the function is already in the table, to ensure each function - // gets a unique index. First, create the map if this is the first use. - if (!functionsInTableMap) { - functionsInTableMap = new WeakMap(); - updateTableMap(0, wasmTable.length); - } - if (functionsInTableMap.has(func)) { - return functionsInTableMap.get(func); - } - - // It's not in the table, add it now. - - // Make sure functionsInTableMap is actually up to date, that is, that this - // function is not actually in the wasm Table despite not being tracked in - // functionsInTableMap. - for (var i = 0; i < wasmTable.length; i++) { - assert(getWasmTableEntry(i) != func, 'function in Table but not functionsInTableMap'); - } - - var ret = getEmptyTableSlot(); - - // Set the new value. - try { - // Attempting to call this with JS function will cause of table.set() to fail - setWasmTableEntry(ret, func); - } catch (err) { - if (!(err instanceof TypeError)) { - throw err; - } - assert(typeof sig != 'undefined', 'Missing signature argument to addFunction: ' + func); - var wrapped = convertJsFunctionToWasm(func, sig); - setWasmTableEntry(ret, wrapped); - } - - functionsInTableMap.set(func, ret); - - return ret; - } +handleAllocatorInit(); - var FSNode = /** @constructor */ function(parent, name, mode, rdev) { - if (!parent) { - parent = this; // root node sets parent to itself - } - this.parent = parent; - this.mount = parent.mount; - this.mounted = null; - this.id = FS.nextInode++; - this.name = name; - this.mode = mode; - this.node_ops = {}; - this.stream_ops = {}; - this.rdev = rdev; - }; - var readMode = 292/*292*/ | 73/*73*/; - var writeMode = 146/*146*/; - Object.defineProperties(FSNode.prototype, { - read: { - get: /** @this{FSNode} */function() { - return (this.mode & readMode) === readMode; - }, - set: /** @this{FSNode} */function(val) { - val ? this.mode |= readMode : this.mode &= ~readMode; - } - }, - write: { - get: /** @this{FSNode} */function() { - return (this.mode & writeMode) === writeMode; - }, - set: /** @this{FSNode} */function(val) { - val ? this.mode |= writeMode : this.mode &= ~writeMode; - } - }, - isFolder: { - get: /** @this{FSNode} */function() { - return FS.isDir(this.mode); - } - }, - isDevice: { - get: /** @this{FSNode} */function() { - return FS.isChrdev(this.mode); - } - } - }); - FS.FSNode = FSNode; - FS.staticInit();; -ERRNO_CODES = { - 'EPERM': 63, - 'ENOENT': 44, - 'ESRCH': 71, - 'EINTR': 27, - 'EIO': 29, - 'ENXIO': 60, - 'E2BIG': 1, - 'ENOEXEC': 45, - 'EBADF': 8, - 'ECHILD': 12, - 'EAGAIN': 6, - 'EWOULDBLOCK': 6, - 'ENOMEM': 48, - 'EACCES': 2, - 'EFAULT': 21, - 'ENOTBLK': 105, - 'EBUSY': 10, - 'EEXIST': 20, - 'EXDEV': 75, - 'ENODEV': 43, - 'ENOTDIR': 54, - 'EISDIR': 31, - 'EINVAL': 28, - 'ENFILE': 41, - 'EMFILE': 33, - 'ENOTTY': 59, - 'ETXTBSY': 74, - 'EFBIG': 22, - 'ENOSPC': 51, - 'ESPIPE': 70, - 'EROFS': 69, - 'EMLINK': 34, - 'EPIPE': 64, - 'EDOM': 18, - 'ERANGE': 68, - 'ENOMSG': 49, - 'EIDRM': 24, - 'ECHRNG': 106, - 'EL2NSYNC': 156, - 'EL3HLT': 107, - 'EL3RST': 108, - 'ELNRNG': 109, - 'EUNATCH': 110, - 'ENOCSI': 111, - 'EL2HLT': 112, - 'EDEADLK': 16, - 'ENOLCK': 46, - 'EBADE': 113, - 'EBADR': 114, - 'EXFULL': 115, - 'ENOANO': 104, - 'EBADRQC': 103, - 'EBADSLT': 102, - 'EDEADLOCK': 16, - 'EBFONT': 101, - 'ENOSTR': 100, - 'ENODATA': 116, - 'ETIME': 117, - 'ENOSR': 118, - 'ENONET': 119, - 'ENOPKG': 120, - 'EREMOTE': 121, - 'ENOLINK': 47, - 'EADV': 122, - 'ESRMNT': 123, - 'ECOMM': 124, - 'EPROTO': 65, - 'EMULTIHOP': 36, - 'EDOTDOT': 125, - 'EBADMSG': 9, - 'ENOTUNIQ': 126, - 'EBADFD': 127, - 'EREMCHG': 128, - 'ELIBACC': 129, - 'ELIBBAD': 130, - 'ELIBSCN': 131, - 'ELIBMAX': 132, - 'ELIBEXEC': 133, - 'ENOSYS': 52, - 'ENOTEMPTY': 55, - 'ENAMETOOLONG': 37, - 'ELOOP': 32, - 'EOPNOTSUPP': 138, - 'EPFNOSUPPORT': 139, - 'ECONNRESET': 15, - 'ENOBUFS': 42, - 'EAFNOSUPPORT': 5, - 'EPROTOTYPE': 67, - 'ENOTSOCK': 57, - 'ENOPROTOOPT': 50, - 'ESHUTDOWN': 140, - 'ECONNREFUSED': 14, - 'EADDRINUSE': 3, - 'ECONNABORTED': 13, - 'ENETUNREACH': 40, - 'ENETDOWN': 38, - 'ETIMEDOUT': 73, - 'EHOSTDOWN': 142, - 'EHOSTUNREACH': 23, - 'EINPROGRESS': 26, - 'EALREADY': 7, - 'EDESTADDRREQ': 17, - 'EMSGSIZE': 35, - 'EPROTONOSUPPORT': 66, - 'ESOCKTNOSUPPORT': 137, - 'EADDRNOTAVAIL': 4, - 'ENETRESET': 39, - 'EISCONN': 30, - 'ENOTCONN': 53, - 'ETOOMANYREFS': 141, - 'EUSERS': 136, - 'EDQUOT': 19, - 'ESTALE': 72, - 'ENOTSUP': 138, - 'ENOMEDIUM': 148, - 'EILSEQ': 25, - 'EOVERFLOW': 61, - 'ECANCELED': 11, - 'ENOTRECOVERABLE': 56, - 'EOWNERDEAD': 62, - 'ESTRPIPE': 135, - };; -embind_init_charCodes(); -BindingError = Module['BindingError'] = extendError(Error, 'BindingError');; -InternalError = Module['InternalError'] = extendError(Error, 'InternalError');; -init_emval();; -UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');; -var ASSERTIONS = true; +init_emval(); + +UnboundTypeError = Module["UnboundTypeError"] = extendError(Error, "UnboundTypeError"); + +var proxiedFunctionTable = [ _proc_exit, exitOnMainThread, ___syscall_openat, _environ_get, _environ_sizes_get, _fd_close, _fd_read, _fd_seek, _fd_write ]; function checkIncomingModuleAPI() { - ignoredModuleProp('fetchSettings'); + ignoredModuleProp("fetchSettings"); } -var asmLibraryArg = { - "__assert_fail": ___assert_fail, - "__cxa_allocate_exception": ___cxa_allocate_exception, - "__cxa_begin_catch": ___cxa_begin_catch, - "__cxa_call_unexpected": ___cxa_call_unexpected, - "__cxa_end_catch": ___cxa_end_catch, - "__cxa_find_matching_catch_2": ___cxa_find_matching_catch_2, - "__cxa_find_matching_catch_3": ___cxa_find_matching_catch_3, - "__cxa_free_exception": ___cxa_free_exception, - "__cxa_rethrow": ___cxa_rethrow, - "__cxa_throw": ___cxa_throw, - "__cxa_uncaught_exceptions": ___cxa_uncaught_exceptions, - "__handle_stack_overflow": ___handle_stack_overflow, - "__resumeException": ___resumeException, - "__syscall_openat": ___syscall_openat, - "_embind_register_bigint": __embind_register_bigint, - "_embind_register_bool": __embind_register_bool, - "_embind_register_emval": __embind_register_emval, - "_embind_register_float": __embind_register_float, - "_embind_register_function": __embind_register_function, - "_embind_register_integer": __embind_register_integer, - "_embind_register_memory_view": __embind_register_memory_view, - "_embind_register_std_string": __embind_register_std_string, - "_embind_register_std_wstring": __embind_register_std_wstring, - "_embind_register_void": __embind_register_void, - "_emscripten_get_progname": __emscripten_get_progname, - "_gmtime_js": __gmtime_js, - "_mktime_js": __mktime_js, - "_tzset_js": __tzset_js, - "abort": _abort, - "emscripten_asm_const_int": _emscripten_asm_const_int, - "emscripten_console_error": _emscripten_console_error, - "emscripten_date_now": _emscripten_date_now, - "emscripten_get_heap_max": _emscripten_get_heap_max, - "emscripten_memcpy_big": _emscripten_memcpy_big, - "emscripten_resize_heap": _emscripten_resize_heap, - "environ_get": _environ_get, - "environ_sizes_get": _environ_sizes_get, - "exit": _exit, - "fd_close": _fd_close, - "fd_read": _fd_read, - "fd_seek": _fd_seek, - "fd_write": _fd_write, - "invoke_i": invoke_i, - "invoke_ii": invoke_ii, - "invoke_iii": invoke_iii, - "invoke_iiii": invoke_iiii, - "invoke_iiiii": invoke_iiiii, - "invoke_iiiiii": invoke_iiiiii, - "invoke_iiiiiii": invoke_iiiiiii, - "invoke_iiiiiiii": invoke_iiiiiiii, - "invoke_iiiiiiiiiiii": invoke_iiiiiiiiiiii, - "invoke_iiiiij": invoke_iiiiij, - "invoke_iiij": invoke_iiij, - "invoke_jiiii": invoke_jiiii, - "invoke_v": invoke_v, - "invoke_vi": invoke_vi, - "invoke_vii": invoke_vii, - "invoke_viii": invoke_viii, - "invoke_viiii": invoke_viiii, - "invoke_viiiiii": invoke_viiiiii, - "invoke_viiiiiii": invoke_viiiiiii, - "invoke_viiiiiiiiii": invoke_viiiiiiiiii, - "invoke_viiiiiiiiiiiiiii": invoke_viiiiiiiiiiiiiii, - "invoke_viijii": invoke_viijii, - "strftime_l": _strftime_l -}; -var asm = createWasm(); -/** @type {function(...*):?} */ -var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors"); - -/** @type {function(...*):?} */ -var _malloc = Module["_malloc"] = createExportWrapper("malloc"); - -/** @type {function(...*):?} */ + +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_rethrow: ___cxa_rethrow, + /** @export */ __cxa_throw: ___cxa_throw, + /** @export */ __cxa_uncaught_exceptions: ___cxa_uncaught_exceptions, + /** @export */ __emscripten_init_main_thread_js: ___emscripten_init_main_thread_js, + /** @export */ __emscripten_thread_cleanup: ___emscripten_thread_cleanup, + /** @export */ __handle_stack_overflow: ___handle_stack_overflow, + /** @export */ __resumeException: ___resumeException, + /** @export */ __syscall_openat: ___syscall_openat, + /** @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_get_now_is_monotonic: __emscripten_get_now_is_monotonic, + /** @export */ _emscripten_get_progname: __emscripten_get_progname, + /** @export */ _emscripten_notify_mailbox_postmessage: __emscripten_notify_mailbox_postmessage, + /** @export */ _emscripten_receive_on_main_thread_js: __emscripten_receive_on_main_thread_js, + /** @export */ _emscripten_thread_mailbox_await: __emscripten_thread_mailbox_await, + /** @export */ _emscripten_thread_set_strongref: __emscripten_thread_set_strongref, + /** @export */ _gmtime_js: __gmtime_js, + /** @export */ _mktime_js: __mktime_js, + /** @export */ _tzset_js: __tzset_js, + /** @export */ abort: _abort, + /** @export */ emscripten_asm_const_int: _emscripten_asm_const_int, + /** @export */ emscripten_check_blocking_allowed: _emscripten_check_blocking_allowed, + /** @export */ emscripten_date_now: _emscripten_date_now, + /** @export */ emscripten_err: _emscripten_err, + /** @export */ emscripten_exit_with_live_runtime: _emscripten_exit_with_live_runtime, + /** @export */ emscripten_get_heap_max: _emscripten_get_heap_max, + /** @export */ emscripten_get_now: _emscripten_get_now, + /** @export */ emscripten_num_logical_cores: _emscripten_num_logical_cores, + /** @export */ emscripten_resize_heap: _emscripten_resize_heap, + /** @export */ environ_get: _environ_get, + /** @export */ environ_sizes_get: _environ_sizes_get, + /** @export */ exit: _exit, + /** @export */ fd_close: _fd_close, + /** @export */ fd_read: _fd_read, + /** @export */ fd_seek: _fd_seek, + /** @export */ fd_write: _fd_write, + /** @export */ invoke_i: invoke_i, + /** @export */ invoke_ii: invoke_ii, + /** @export */ invoke_iii: invoke_iii, + /** @export */ invoke_iiii: invoke_iiii, + /** @export */ invoke_iiiii: invoke_iiiii, + /** @export */ invoke_iiiiii: invoke_iiiiii, + /** @export */ invoke_iiiiiii: invoke_iiiiiii, + /** @export */ invoke_iiiiiiii: invoke_iiiiiiii, + /** @export */ invoke_iiiiiiiiiiii: invoke_iiiiiiiiiiii, + /** @export */ invoke_iiiiij: invoke_iiiiij, + /** @export */ invoke_iiij: invoke_iiij, + /** @export */ invoke_jiiii: invoke_jiiii, + /** @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 */ invoke_viiiiii: invoke_viiiiii, + /** @export */ invoke_viiiiiii: invoke_viiiiiii, + /** @export */ invoke_viiiiiiiiii: invoke_viiiiiiiiii, + /** @export */ invoke_viiiiiiiiiiiiiii: invoke_viiiiiiiiiiiiiii, + /** @export */ invoke_viijii: invoke_viijii, + /** @export */ memory: wasmMemory || Module["wasmMemory"], + /** @export */ strftime_l: _strftime_l +}; + +var wasmExports = createWasm(); + +var ___wasm_call_ctors = createExportWrapper("__wasm_call_ctors"); + +var _malloc = createExportWrapper("malloc"); + var _main = Module["_main"] = createExportWrapper("main"); -/** @type {function(...*):?} */ -var ___cxa_demangle = Module["___cxa_demangle"] = createExportWrapper("__cxa_demangle"); +var ___cxa_demangle = createExportWrapper("__cxa_demangle"); -/** @type {function(...*):?} */ var _free = Module["_free"] = createExportWrapper("free"); -/** @type {function(...*):?} */ -var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location"); +var ___errno_location = createExportWrapper("__errno_location"); + +var _pthread_self = Module["_pthread_self"] = () => (_pthread_self = Module["_pthread_self"] = wasmExports["pthread_self"])(); -/** @type {function(...*):?} */ -var ___getTypeName = Module["___getTypeName"] = createExportWrapper("__getTypeName"); +var __emscripten_tls_init = Module["__emscripten_tls_init"] = createExportWrapper("_emscripten_tls_init"); + +var ___getTypeName = createExportWrapper("__getTypeName"); -/** @type {function(...*):?} */ var __embind_initialize_bindings = Module["__embind_initialize_bindings"] = createExportWrapper("_embind_initialize_bindings"); -/** @type {function(...*):?} */ +var __emscripten_thread_init = Module["__emscripten_thread_init"] = createExportWrapper("_emscripten_thread_init"); + +var __emscripten_thread_crashed = Module["__emscripten_thread_crashed"] = createExportWrapper("_emscripten_thread_crashed"); + var _fflush = Module["_fflush"] = createExportWrapper("fflush"); -/** @type {function(...*):?} */ -var _setThrew = Module["_setThrew"] = createExportWrapper("setThrew"); +var _emscripten_main_thread_process_queued_calls = createExportWrapper("emscripten_main_thread_process_queued_calls"); -/** @type {function(...*):?} */ -var setTempRet0 = Module["setTempRet0"] = createExportWrapper("setTempRet0"); +var _emscripten_main_runtime_thread_id = createExportWrapper("emscripten_main_runtime_thread_id"); -/** @type {function(...*):?} */ -var getTempRet0 = Module["getTempRet0"] = createExportWrapper("getTempRet0"); +var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports["emscripten_stack_get_base"])(); -/** @type {function(...*):?} */ -var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() { - return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments); -}; +var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports["emscripten_stack_get_end"])(); -/** @type {function(...*):?} */ -var _emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = function() { - return (_emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments); -}; +var __emscripten_run_on_main_thread_js = createExportWrapper("_emscripten_run_on_main_thread_js"); -/** @type {function(...*):?} */ -var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() { - return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments); -}; +var __emscripten_thread_free_data = createExportWrapper("_emscripten_thread_free_data"); -/** @type {function(...*):?} */ -var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() { - return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments); -}; +var __emscripten_thread_exit = Module["__emscripten_thread_exit"] = createExportWrapper("_emscripten_thread_exit"); + +var __emscripten_check_mailbox = createExportWrapper("_emscripten_check_mailbox"); + +var _setThrew = createExportWrapper("setThrew"); + +var setTempRet0 = createExportWrapper("setTempRet0"); + +var getTempRet0 = createExportWrapper("getTempRet0"); + +var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports["emscripten_stack_init"])(); + +var _emscripten_stack_set_limits = (a0, a1) => (_emscripten_stack_set_limits = wasmExports["emscripten_stack_set_limits"])(a0, a1); + +var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports["emscripten_stack_get_free"])(); + +var stackSave = createExportWrapper("stackSave"); + +var stackRestore = createExportWrapper("stackRestore"); -/** @type {function(...*):?} */ -var stackSave = Module["stackSave"] = createExportWrapper("stackSave"); +var stackAlloc = createExportWrapper("stackAlloc"); -/** @type {function(...*):?} */ -var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore"); +var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports["emscripten_stack_get_current"])(); -/** @type {function(...*):?} */ -var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc"); +var ___cxa_decrement_exception_refcount = createExportWrapper("__cxa_decrement_exception_refcount"); -/** @type {function(...*):?} */ -var ___cxa_can_catch = Module["___cxa_can_catch"] = createExportWrapper("__cxa_can_catch"); +var ___cxa_increment_exception_refcount = createExportWrapper("__cxa_increment_exception_refcount"); -/** @type {function(...*):?} */ -var ___cxa_is_pointer_type = Module["___cxa_is_pointer_type"] = createExportWrapper("__cxa_is_pointer_type"); +var ___cxa_free_exception = createExportWrapper("__cxa_free_exception"); + +var ___get_exception_message = Module["___get_exception_message"] = createExportWrapper("__get_exception_message"); + +var ___cxa_can_catch = createExportWrapper("__cxa_can_catch"); + +var ___cxa_is_pointer_type = createExportWrapper("__cxa_is_pointer_type"); -/** @type {function(...*):?} */ var ___set_stack_limits = Module["___set_stack_limits"] = createExportWrapper("__set_stack_limits"); -/** @type {function(...*):?} */ var dynCall_iij = Module["dynCall_iij"] = createExportWrapper("dynCall_iij"); -/** @type {function(...*):?} */ var dynCall_viijii = Module["dynCall_viijii"] = createExportWrapper("dynCall_viijii"); -/** @type {function(...*):?} */ var dynCall_iiiij = Module["dynCall_iiiij"] = createExportWrapper("dynCall_iiiij"); -/** @type {function(...*):?} */ var dynCall_iiiiij = Module["dynCall_iiiiij"] = createExportWrapper("dynCall_iiiiij"); -/** @type {function(...*):?} */ var dynCall_iiij = Module["dynCall_iiij"] = createExportWrapper("dynCall_iiij"); -/** @type {function(...*):?} */ var dynCall_jiiii = Module["dynCall_jiiii"] = createExportWrapper("dynCall_jiiii"); -/** @type {function(...*):?} */ var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji"); -/** @type {function(...*):?} */ var dynCall_iiiiijj = Module["dynCall_iiiiijj"] = createExportWrapper("dynCall_iiiiijj"); -/** @type {function(...*):?} */ var dynCall_iiiiiijj = Module["dynCall_iiiiiijj"] = createExportWrapper("dynCall_iiiiiijj"); - -function invoke_vii(index,a1,a2) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(a1,a2); - } catch(e) { - stackRestore(sp); - if (e !== e+0) 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_ii(index,a1) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(a1); - } catch(e) { - stackRestore(sp); - if (e !== e+0) 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_iii(index,a1,a2) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(a1,a2); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +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_vi(index,a1) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(a1); - } catch(e) { - stackRestore(sp); - if (e !== e+0) 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_v(index) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } + var sp = stackSave(); + try { + getWasmTableEntry(index)(); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_viiiiii(index, a1, a2, a3, a4, a5, a6) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6); + } 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 !== e+0) 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_iiiiii(index,a1,a2,a3,a4,a5) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(a1,a2,a3,a4,a5); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_iiiiii(index, a1, a2, a3, a4, a5) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3, a4, a5); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_iiiiiiii(index,a1,a2,a3,a4,a5,a6,a7) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_iiiiiiii(index, a1, a2, a3, a4, a5, a6, a7) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7); + } 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 !== e+0) 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_viii(index,a1,a2,a3) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(a1,a2,a3); - } catch(e) { - stackRestore(sp); - if (e !== e+0) 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_viiiiiii(index,a1,a2,a3,a4,a5,a6,a7) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_viiiiiii(index, a1, a2, a3, a4, a5, a6, a7) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_iiiiiii(index,a1,a2,a3,a4,a5,a6) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_iiiiiii(index, a1, a2, a3, a4, a5, a6) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_iiiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_iiiiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) { + var sp = stackSave(); + try { + return getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_viiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_viiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_viiiiiiiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) { - var sp = stackSave(); - try { - getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_viiiiiiiiiiiiiii(index, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) { + var sp = stackSave(); + try { + getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } function invoke_i(index) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } + var sp = stackSave(); + try { + return getWasmTableEntry(index)(); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_iiiii(index,a1,a2,a3,a4) { - var sp = stackSave(); - try { - return getWasmTableEntry(index)(a1,a2,a3,a4); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_iiiii(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_viijii(index,a1,a2,a3,a4,a5,a6) { - var sp = stackSave(); - try { - dynCall_viijii(index,a1,a2,a3,a4,a5,a6); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_viijii(index, a1, a2, a3, a4, a5, a6) { + var sp = stackSave(); + try { + dynCall_viijii(index, a1, a2, a3, a4, a5, a6); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_iiiiij(index,a1,a2,a3,a4,a5,a6) { - var sp = stackSave(); - try { - return dynCall_iiiiij(index,a1,a2,a3,a4,a5,a6); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_iiiiij(index, a1, a2, a3, a4, a5, a6) { + var sp = stackSave(); + try { + return dynCall_iiiiij(index, a1, a2, a3, a4, a5, a6); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_iiij(index,a1,a2,a3,a4) { - var sp = stackSave(); - try { - return dynCall_iiij(index,a1,a2,a3,a4); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_iiij(index, a1, a2, a3, a4) { + var sp = stackSave(); + try { + return dynCall_iiij(index, a1, a2, a3, a4); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } -function invoke_jiiii(index,a1,a2,a3,a4) { - var sp = stackSave(); - try { - return dynCall_jiiii(index,a1,a2,a3,a4); - } catch(e) { - stackRestore(sp); - if (e !== e+0) throw e; - _setThrew(1, 0); - } +function invoke_jiiii(index, a1, a2, a3, a4) { + var sp = stackSave(); + try { + return dynCall_jiiii(index, a1, a2, a3, a4); + } catch (e) { + stackRestore(sp); + if (!(e instanceof EmscriptenEH)) throw e; + _setThrew(1, 0); + } } +Module["wasmMemory"] = wasmMemory; +Module["getTempRet0"] = getTempRet0; +Module["keepRuntimeAlive"] = keepRuntimeAlive; -// === Auto-generated postamble setup entry stuff === +Module["addFunction"] = addFunction; Module["UTF8ToString"] = UTF8ToString; + Module["stringToUTF8"] = stringToUTF8; + Module["lengthBytesUTF8"] = lengthBytesUTF8; -Module["getTempRet0"] = getTempRet0; -Module["addFunction"] = addFunction; + Module["intArrayToString"] = intArrayToString; -var unexportedRuntimeSymbols = [ - 'run', - 'UTF8ArrayToString', - 'stringToUTF8Array', - 'addOnPreRun', - 'addOnInit', - 'addOnPreMain', - 'addOnExit', - 'addOnPostRun', - 'addRunDependency', - 'removeRunDependency', - 'FS_createFolder', - 'FS_createPath', - 'FS_createDataFile', - 'FS_createPreloadedFile', - 'FS_createLazyFile', - 'FS_createLink', - 'FS_createDevice', - 'FS_unlink', - 'getLEB', - 'getFunctionTables', - 'alignFunctionTables', - 'registerFunctions', - 'prettyPrint', - 'getCompilerSetting', - 'print', - 'printErr', - 'callMain', - 'abort', - 'keepRuntimeAlive', - 'wasmMemory', - 'stackAlloc', - 'stackSave', - 'stackRestore', - 'setTempRet0', - 'writeStackCookie', - 'checkStackCookie', - 'ptrToString', - 'zeroMemory', - 'stringToNewUTF8', - 'exitJS', - 'getHeapMax', - 'emscripten_realloc_buffer', - 'ENV', - 'ERRNO_CODES', - 'ERRNO_MESSAGES', - 'setErrNo', - 'inetPton4', - 'inetNtop4', - 'inetPton6', - 'inetNtop6', - 'readSockaddr', - 'writeSockaddr', - 'DNS', - 'getHostByName', - 'Protocols', - 'Sockets', - 'getRandomDevice', - 'warnOnce', - 'traverseStack', - 'UNWIND_CACHE', - 'convertPCtoSourceLocation', - 'readAsmConstArgsArray', - 'readAsmConstArgs', - 'mainThreadEM_ASM', - 'jstoi_q', - 'jstoi_s', - 'getExecutableName', - 'listenOnce', - 'autoResumeAudioContext', - 'dynCallLegacy', - 'getDynCaller', - 'dynCall', - 'handleException', - 'runtimeKeepalivePush', - 'runtimeKeepalivePop', - 'callUserCallback', - 'maybeExit', - 'safeSetTimeout', - 'asmjsMangle', - 'asyncLoad', - 'alignMemory', - 'mmapAlloc', - 'writeI53ToI64', - 'writeI53ToI64Clamped', - 'writeI53ToI64Signaling', - 'writeI53ToU64Clamped', - 'writeI53ToU64Signaling', - 'readI53FromI64', - 'readI53FromU64', - 'convertI32PairToI53', - 'convertI32PairToI53Checked', - 'convertU32PairToI53', - 'getCFunc', - 'ccall', - 'cwrap', - 'uleb128Encode', - 'sigToWasmTypes', - 'generateFuncType', - 'convertJsFunctionToWasm', - 'freeTableIndexes', - 'functionsInTableMap', - 'getEmptyTableSlot', - 'updateTableMap', - 'removeFunction', - 'reallyNegative', - 'unSign', - 'strLen', - 'reSign', - 'formatString', - 'setValue', - 'getValue', - 'PATH', - 'PATH_FS', - 'intArrayFromString', - 'AsciiToString', - 'stringToAscii', - 'UTF16Decoder', - 'UTF16ToString', - 'stringToUTF16', - 'lengthBytesUTF16', - 'UTF32ToString', - 'stringToUTF32', - 'lengthBytesUTF32', - 'allocateUTF8', - 'allocateUTF8OnStack', - 'writeStringToMemory', - 'writeArrayToMemory', - 'writeAsciiToMemory', - 'SYSCALLS', - 'getSocketFromFD', - 'getSocketAddress', - 'JSEvents', - 'registerKeyEventCallback', - 'specialHTMLTargets', - 'maybeCStringToJsString', - 'findEventTarget', - 'findCanvasEventTarget', - 'getBoundingClientRect', - 'fillMouseEventData', - 'registerMouseEventCallback', - 'registerWheelEventCallback', - 'registerUiEventCallback', - 'registerFocusEventCallback', - 'fillDeviceOrientationEventData', - 'registerDeviceOrientationEventCallback', - 'fillDeviceMotionEventData', - 'registerDeviceMotionEventCallback', - 'screenOrientation', - 'fillOrientationChangeEventData', - 'registerOrientationChangeEventCallback', - 'fillFullscreenChangeEventData', - 'registerFullscreenChangeEventCallback', - 'JSEvents_requestFullscreen', - 'JSEvents_resizeCanvasForFullscreen', - 'registerRestoreOldStyle', - 'hideEverythingExceptGivenElement', - 'restoreHiddenElements', - 'setLetterbox', - 'currentFullscreenStrategy', - 'restoreOldWindowedStyle', - 'softFullscreenResizeWebGLRenderTarget', - 'doRequestFullscreen', - 'fillPointerlockChangeEventData', - 'registerPointerlockChangeEventCallback', - 'registerPointerlockErrorEventCallback', - 'requestPointerLock', - 'fillVisibilityChangeEventData', - 'registerVisibilityChangeEventCallback', - 'registerTouchEventCallback', - 'fillGamepadEventData', - 'registerGamepadEventCallback', - 'registerBeforeUnloadEventCallback', - 'fillBatteryEventData', - 'battery', - 'registerBatteryEventCallback', - 'setCanvasElementSize', - 'getCanvasElementSize', - 'demangle', - 'demangleAll', - 'jsStackTrace', - 'stackTrace', - 'ExitStatus', - 'getEnvStrings', - 'checkWasiClock', - 'doReadv', - 'doWritev', - 'dlopenMissingError', - 'createDyncallWrapper', - 'setImmediateWrapped', - 'clearImmediateWrapped', - 'polyfillSetImmediate', - 'uncaughtExceptionCount', - 'exceptionLast', - 'exceptionCaught', - 'ExceptionInfo', - 'exception_addRef', - 'exception_decRef', - 'getExceptionMessageCommon', - 'incrementExceptionRefcount', - 'decrementExceptionRefcount', - 'getExceptionMessage', - 'Browser', - 'setMainLoop', - 'wget', - 'FS', - 'MEMFS', - 'TTY', - 'PIPEFS', - 'SOCKFS', - '_setNetworkCallback', - 'tempFixedLengthArray', - 'miniTempWebGLFloatBuffers', - 'heapObjectForWebGLType', - 'heapAccessShiftForWebGLHeap', - 'GL', - 'emscriptenWebGLGet', - 'computeUnpackAlignedImageSize', - 'emscriptenWebGLGetTexPixelData', - 'emscriptenWebGLGetUniform', - 'webglGetUniformLocation', - 'webglPrepareUniformLocationsBeforeFirstUse', - 'webglGetLeftBracePos', - 'emscriptenWebGLGetVertexAttrib', - 'writeGLArray', - 'AL', - 'SDL_unicode', - 'SDL_ttfContext', - 'SDL_audio', - 'SDL', - 'SDL_gfx', - 'GLUT', - 'EGL', - 'GLFW_Window', - 'GLFW', - 'GLEW', - 'IDBStore', - 'runAndAbortIfError', - 'ALLOC_NORMAL', - 'ALLOC_STACK', - 'allocate', - 'InternalError', - 'BindingError', - 'UnboundTypeError', - 'PureVirtualError', - 'init_embind', - 'throwInternalError', - 'throwBindingError', - 'throwUnboundTypeError', - 'ensureOverloadTable', - 'exposePublicSymbol', - 'replacePublicSymbol', - 'extendError', - 'createNamedFunction', - 'embindRepr', - 'registeredInstances', - 'getBasestPointer', - 'registerInheritedInstance', - 'unregisterInheritedInstance', - 'getInheritedInstance', - 'getInheritedInstanceCount', - 'getLiveInheritedInstances', - 'registeredTypes', - 'awaitingDependencies', - 'typeDependencies', - 'registeredPointers', - 'registerType', - 'whenDependentTypesAreResolved', - 'embind_charCodes', - 'embind_init_charCodes', - 'readLatin1String', - 'getTypeName', - 'heap32VectorToArray', - 'requireRegisteredType', - 'getShiftFromSize', - 'integerReadValueFromPointer', - 'enumReadValueFromPointer', - 'floatReadValueFromPointer', - 'simpleReadValueFromPointer', - 'runDestructors', - 'new_', - 'craftInvokerFunction', - 'embind__requireFunction', - 'tupleRegistrations', - 'structRegistrations', - 'genericPointerToWireType', - 'constNoSmartPtrRawPointerToWireType', - 'nonConstNoSmartPtrRawPointerToWireType', - 'init_RegisteredPointer', - 'RegisteredPointer', - 'RegisteredPointer_getPointee', - 'RegisteredPointer_destructor', - 'RegisteredPointer_deleteObject', - 'RegisteredPointer_fromWireType', - 'runDestructor', - 'releaseClassHandle', - 'finalizationRegistry', - 'detachFinalizer_deps', - 'detachFinalizer', - 'attachFinalizer', - 'makeClassHandle', - 'init_ClassHandle', - 'ClassHandle', - 'ClassHandle_isAliasOf', - 'throwInstanceAlreadyDeleted', - 'ClassHandle_clone', - 'ClassHandle_delete', - 'deletionQueue', - 'ClassHandle_isDeleted', - 'ClassHandle_deleteLater', - 'flushPendingDeletes', - 'delayFunction', - 'setDelayFunction', - 'RegisteredClass', - 'shallowCopyInternalPointer', - 'downcastPointer', - 'upcastPointer', - 'validateThis', - 'char_0', - 'char_9', - 'makeLegalFunctionName', - 'emval_handle_array', - 'emval_free_list', - 'emval_symbols', - 'init_emval', - 'count_emval_handles', - 'get_first_emval', - 'getStringOrSymbol', - 'Emval', - 'emval_newers', - 'craftEmvalAllocator', - 'emval_get_global', - 'emval_lookupTypes', - 'emval_allocateDestructors', - 'emval_methodCallers', - 'emval_addMethodCaller', - 'emval_registeredMethods', -]; -unexportedRuntimeSymbols.forEach(unexportedRuntimeSymbol); -var missingLibrarySymbols = [ - 'ptrToString', - 'stringToNewUTF8', - 'setErrNo', - 'inetPton4', - 'inetNtop4', - 'inetPton6', - 'inetNtop6', - 'readSockaddr', - 'writeSockaddr', - 'getHostByName', - 'traverseStack', - 'convertPCtoSourceLocation', - 'mainThreadEM_ASM', - 'jstoi_q', - 'jstoi_s', - 'listenOnce', - 'autoResumeAudioContext', - 'runtimeKeepalivePush', - 'runtimeKeepalivePop', - 'callUserCallback', - 'maybeExit', - 'safeSetTimeout', - 'asmjsMangle', - 'writeI53ToI64', - 'writeI53ToI64Clamped', - 'writeI53ToI64Signaling', - 'writeI53ToU64Clamped', - 'writeI53ToU64Signaling', - 'readI53FromU64', - 'convertI32PairToI53', - 'convertU32PairToI53', - 'getCFunc', - 'ccall', - 'cwrap', - 'removeFunction', - 'reallyNegative', - 'unSign', - 'strLen', - 'reSign', - 'formatString', - 'AsciiToString', - 'stringToAscii', - 'allocateUTF8OnStack', - 'writeStringToMemory', - 'getSocketFromFD', - 'getSocketAddress', - 'registerKeyEventCallback', - 'maybeCStringToJsString', - 'findEventTarget', - 'findCanvasEventTarget', - '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', - 'checkWasiClock', - 'createDyncallWrapper', - 'setImmediateWrapped', - 'clearImmediateWrapped', - 'polyfillSetImmediate', - 'getExceptionMessageCommon', - 'incrementExceptionRefcount', - 'decrementExceptionRefcount', - 'getExceptionMessage', - 'setMainLoop', - '_setNetworkCallback', - 'heapObjectForWebGLType', - 'heapAccessShiftForWebGLHeap', - 'emscriptenWebGLGet', - 'computeUnpackAlignedImageSize', - 'emscriptenWebGLGetTexPixelData', - 'emscriptenWebGLGetUniform', - 'webglGetUniformLocation', - 'webglPrepareUniformLocationsBeforeFirstUse', - 'webglGetLeftBracePos', - 'emscriptenWebGLGetVertexAttrib', - 'writeGLArray', - 'SDL_unicode', - 'SDL_ttfContext', - 'SDL_audio', - 'GLFW_Window', - 'runAndAbortIfError', - 'ALLOC_NORMAL', - 'ALLOC_STACK', - 'allocate', - 'init_embind', - 'getBasestPointer', - 'registerInheritedInstance', - 'unregisterInheritedInstance', - 'getInheritedInstance', - 'getInheritedInstanceCount', - 'getLiveInheritedInstances', - 'requireRegisteredType', - 'enumReadValueFromPointer', - 'genericPointerToWireType', - 'constNoSmartPtrRawPointerToWireType', - 'nonConstNoSmartPtrRawPointerToWireType', - 'init_RegisteredPointer', - 'RegisteredPointer', - 'RegisteredPointer_getPointee', - 'RegisteredPointer_destructor', - 'RegisteredPointer_deleteObject', - 'RegisteredPointer_fromWireType', - 'runDestructor', - 'releaseClassHandle', - 'detachFinalizer', - 'attachFinalizer', - 'makeClassHandle', - 'init_ClassHandle', - 'ClassHandle', - 'ClassHandle_isAliasOf', - 'throwInstanceAlreadyDeleted', - 'ClassHandle_clone', - 'ClassHandle_delete', - 'ClassHandle_isDeleted', - 'ClassHandle_deleteLater', - 'flushPendingDeletes', - 'setDelayFunction', - 'RegisteredClass', - 'shallowCopyInternalPointer', - 'downcastPointer', - 'upcastPointer', - 'validateThis', - 'getStringOrSymbol', - 'craftEmvalAllocator', - 'emval_get_global', - 'emval_lookupTypes', - 'emval_allocateDestructors', - 'emval_addMethodCaller', -]; -missingLibrarySymbols.forEach(missingLibrarySymbol) +Module["ExitStatus"] = ExitStatus; -var calledRun; +Module["PThread"] = PThread; -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 -}; +var missingLibrarySymbols = [ "writeI53ToI64", "writeI53ToI64Clamped", "writeI53ToI64Signaling", "writeI53ToU64Clamped", "writeI53ToU64Signaling", "readI53FromI64", "readI53FromU64", "convertI32PairToI53", "convertU32PairToI53", "inetPton4", "inetNtop4", "inetPton6", "inetNtop6", "readSockaddr", "writeSockaddr", "getHostByName", "getCallstack", "emscriptenLog", "convertPCtoSourceLocation", "runMainThreadEmAsm", "jstoi_q", "jstoi_s", "listenOnce", "autoResumeAudioContext", "runtimeKeepalivePop", "asmjsMangle", "getNativeTypeSize", "STACK_SIZE", "STACK_ALIGN", "POINTER_SIZE", "ASSERTIONS", "getCFunc", "ccall", "cwrap", "removeFunction", "reallyNegative", "unSign", "strLen", "reSign", "formatString", "AsciiToString", "registerKeyEventCallback", "maybeCStringToJsString", "findEventTarget", "findCanvasEventTarget", "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", "setCanvasElementSizeCallingThread", "setCanvasElementSizeMainThread", "setCanvasElementSize", "getCanvasSizeCallingThread", "getCanvasSizeMainThread", "getCanvasElementSize", "checkWasiClock", "wasiRightsToMuslOFlags", "wasiOFlagsToMuslOFlags", "createDyncallWrapper", "safeSetTimeout", "setImmediateWrapped", "clearImmediateWrapped", "polyfillSetImmediate", "getPromise", "makePromise", "idsToPromises", "makePromiseCallback", "setMainLoop", "getSocketFromFD", "getSocketAddress", "FS_unlink", "FS_mkdirTree", "_setNetworkCallback", "heapObjectForWebGLType", "heapAccessShiftForWebGLHeap", "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", "__glGenObject", "emscriptenWebGLGetUniform", "webglGetUniformLocation", "webglPrepareUniformLocationsBeforeFirstUse", "webglGetLeftBracePos", "emscriptenWebGLGetVertexAttrib", "__glGetActiveAttribOrUniform", "writeGLArray", "emscripten_webgl_destroy_context_before_on_calling_thread", "registerWebGlEventCallback", "runAndAbortIfError", "SDL_unicode", "SDL_ttfContext", "SDL_audio", "ALLOC_NORMAL", "ALLOC_STACK", "allocate", "writeStringToMemory", "writeAsciiToMemory", "getFunctionArgsName", "requireRegisteredType", "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" ]; -function callMain(args) { - assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])'); - assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called'); +missingLibrarySymbols.forEach(missingLibrarySymbol); - var entryFunction = Module['_main']; +var unexportedSymbols = [ "run", "addOnPreRun", "addOnInit", "addOnPreMain", "addOnExit", "addOnPostRun", "addRunDependency", "removeRunDependency", "FS_createFolder", "FS_createPath", "FS_createLazyFile", "FS_createLink", "FS_createDevice", "FS_readFile", "out", "err", "callMain", "abort", "wasmExports", "stackAlloc", "stackSave", "stackRestore", "setTempRet0", "GROWABLE_HEAP_I8", "GROWABLE_HEAP_U8", "GROWABLE_HEAP_I16", "GROWABLE_HEAP_U16", "GROWABLE_HEAP_I32", "GROWABLE_HEAP_U32", "GROWABLE_HEAP_F32", "GROWABLE_HEAP_F64", "writeStackCookie", "checkStackCookie", "convertI32PairToI53Checked", "ptrToString", "zeroMemory", "exitJS", "getHeapMax", "growMemory", "ENV", "setStackLimits", "MONTH_DAYS_REGULAR", "MONTH_DAYS_LEAP", "MONTH_DAYS_REGULAR_CUMULATIVE", "MONTH_DAYS_LEAP_CUMULATIVE", "isLeapYear", "ydayFromDate", "arraySum", "addDays", "ERRNO_CODES", "ERRNO_MESSAGES", "setErrNo", "DNS", "Protocols", "Sockets", "initRandomFill", "randomFill", "timers", "warnOnce", "UNWIND_CACHE", "readEmAsmArgsArray", "readEmAsmArgs", "runEmAsmFunction", "getExecutableName", "dynCallLegacy", "getDynCaller", "dynCall", "handleException", "runtimeKeepalivePush", "callUserCallback", "maybeExit", "asyncLoad", "alignMemory", "mmapAlloc", "handleAllocatorInit", "HandleAllocator", "wasmTable", "noExitRuntime", "uleb128Encode", "sigToWasmTypes", "generateFuncType", "convertJsFunctionToWasm", "freeTableIndexes", "functionsInTableMap", "getEmptyTableSlot", "updateTableMap", "getFunctionAddress", "setValue", "getValue", "PATH", "PATH_FS", "UTF8Decoder", "UTF8ArrayToString", "stringToUTF8Array", "intArrayFromString", "stringToAscii", "UTF16Decoder", "UTF16ToString", "stringToUTF16", "lengthBytesUTF16", "UTF32ToString", "stringToUTF32", "lengthBytesUTF32", "stringToNewUTF8", "stringToUTF8OnStack", "writeArrayToMemory", "JSEvents", "specialHTMLTargets", "currentFullscreenStrategy", "restoreOldWindowedStyle", "demangle", "demangleAll", "jsStackTrace", "stackTrace", "getEnvStrings", "doReadv", "doWritev", "promiseMap", "uncaughtExceptionCount", "exceptionLast", "exceptionCaught", "ExceptionInfo", "findMatchingCatch", "getExceptionMessageCommon", "incrementExceptionRefcount", "decrementExceptionRefcount", "getExceptionMessage", "Browser", "wget", "SYSCALLS", "preloadPlugins", "FS_createPreloadedFile", "FS_modeStringToFlags", "FS_getMode", "FS_stdin_getChar_buffer", "FS_stdin_getChar", "FS", "FS_createDataFile", "MEMFS", "TTY", "PIPEFS", "SOCKFS", "tempFixedLengthArray", "miniTempWebGLFloatBuffers", "miniTempWebGLIntBuffers", "GL", "emscripten_webgl_power_preferences", "AL", "GLUT", "EGL", "GLEW", "IDBStore", "SDL", "SDL_gfx", "allocateUTF8", "allocateUTF8OnStack", "terminateWorker", "killThread", "cleanupThread", "registerTLSInit", "cancelThread", "spawnThread", "exitOnMainThread", "proxyToMainThread", "proxiedJSCallArgs", "invokeEntryPoint", "checkMailbox", "InternalError", "BindingError", "throwInternalError", "throwBindingError", "registeredTypes", "awaitingDependencies", "typeDependencies", "tupleRegistrations", "structRegistrations", "sharedRegisterType", "whenDependentTypesAreResolved", "embind_charCodes", "embind_init_charCodes", "readLatin1String", "getTypeName", "getFunctionName", "heap32VectorToArray", "UnboundTypeError", "PureVirtualError", "GenericWireTypeSize", "throwUnboundTypeError", "ensureOverloadTable", "exposePublicSymbol", "replacePublicSymbol", "extendError", "createNamedFunction", "embindRepr", "registeredInstances", "registeredPointers", "registerType", "integerReadValueFromPointer", "floatReadValueFromPointer", "simpleReadValueFromPointer", "readPointer", "runDestructors", "newFunc", "craftInvokerFunction", "embind__requireFunction", "finalizationRegistry", "detachFinalizer_deps", "deletionQueue", "delayFunction", "emval_handles", "emval_symbols", "init_emval", "count_emval_handles", "Emval", "emval_methodCallers", "reflectConstruct" ]; - var argc = 0; - var argv = 0; +unexportedSymbols.forEach(unexportedRuntimeSymbol); - try { +var calledRun; - var ret = entryFunction(argc, argv); +dependenciesFulfilled = function runCaller() { + if (!calledRun) run(); + if (!calledRun) dependenciesFulfilled = runCaller; +}; - // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as - // execution is asynchronously handed off to a pthread. - // if we're not running an evented main loop, it's time to exit - exitJS(ret, /* implicit = */ true); - return ret; - } - catch (e) { - return handleException(e); - } +function callMain() { + assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])'); + assert(__ATPRERUN__.length == 0, "cannot call main when preRun functions remain to be called"); + var entryFunction = _main; + var argc = 0; + var argv = 0; + try { + var ret = entryFunction(argc, argv); + exitJS(ret, /* implicit = */ true); + return ret; + } catch (e) { + return handleException(e); + } } 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(); + assert(!ENVIRONMENT_IS_PTHREAD); + _emscripten_stack_init(); + writeStackCookie(); } -/** @type {function(Array=)} */ -function run(args) { - args = args || arguments_; - - 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(); - - preMain(); - - readyPromiseResolve(Module); - if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized'](); - - if (shouldRunNow) callMain(args); - - postRun(); - } - - if (Module['setStatus']) { - Module['setStatus']('Running...'); - setTimeout(function() { - setTimeout(function() { - Module['setStatus'](''); - }, 1); - doRun(); - }, 1); - } else - { - doRun(); - } - checkStackCookie(); +function run() { + if (runDependencies > 0) { + return; + } + if (!ENVIRONMENT_IS_PTHREAD) stackCheckInit(); + if (ENVIRONMENT_IS_PTHREAD) { + readyPromiseResolve(Module); + initRuntime(); + startWorker(Module); + return; + } + preRun(); + if (runDependencies > 0) { + return; + } + function doRun() { + if (calledRun) return; + calledRun = true; + Module["calledRun"] = true; + if (ABORT) return; + initRuntime(); + preMain(); + readyPromiseResolve(Module); + if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"](); + if (shouldRunNow) callMain(); + 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) => { + var oldOut = out; + var oldErr = err; + var has = false; + out = err = x => { + has = true; + }; + try { + _fflush(0); + [ "stdout", "stderr" ].forEach(function(name) { + var info = FS.analyzePath("/dev/" + name); + if (!info) return; + var stream = info.object; + var rdev = stream.rdev; + var tty = TTY.ttys[rdev]; + if (tty && tty.output && tty.output.length) { has = true; - } - try { // it doesn't matter if it fails - _fflush(0); - // also flush in the JS FS layer - ['stdout', 'stderr'].forEach(function(name) { - var info = FS.analyzePath('/dev/' + name); - if (!info) return; - var stream = info.object; - var rdev = stream.rdev; - var tty = TTY.ttys[rdev]; - if (tty && tty.output && tty.output.length) { - has = true; - } - }); - } 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 FAQ), or make sure to emit a newline when you printf etc.'); - } + } + }); + } 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."); + } } -if (Module['preInit']) { - if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; - while (Module['preInit'].length > 0) { - Module['preInit'].pop()(); - } +if (Module["preInit"]) { + if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ]; + while (Module["preInit"].length > 0) { + Module["preInit"].pop()(); + } } -// shouldRunNow refers to calling main(), not run(). var shouldRunNow = true; -if (Module['noInitialRun']) shouldRunNow = false; +if (Module["noInitialRun"]) shouldRunNow = false; run(); +Module["ready"] = new Promise(function(resolve, reject) { + delete Module["then"]; + Module["onAbort"] = function(what) { + reject(what); + }; + addOnPostRun(function() { + resolve(Module); + }); +}); - - -Module['ready'] = new Promise(function (resolve, reject) { - delete Module['then'] - Module['onAbort'] = function (what) { - reject(what) - } - addOnPostRun(function () { - resolve(Module) - }) -}) - - return BeldexLibAppCpp.ready + return moduleArg.ready } ); })(); +; if (typeof exports === 'object' && typeof module === 'object') module.exports = BeldexLibAppCpp; else if (typeof define === 'function' && define['amd']) - define([], function() { return BeldexLibAppCpp; }); -else if (typeof exports === 'object') - exports["BeldexLibAppCpp"] = BeldexLibAppCpp; + define([], () => BeldexLibAppCpp); diff --git a/libapp_js/BeldexLibAppCpp_WASM.wasm b/libapp_js/BeldexLibAppCpp_WASM.wasm index 8af590e..293619b 100755 Binary files a/libapp_js/BeldexLibAppCpp_WASM.wasm and b/libapp_js/BeldexLibAppCpp_WASM.wasm differ diff --git a/package.json b/package.json index db0a042..8ec8ed2 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "git+https://github.com/mymonero/mymonero-libapp-js.git" }, "scripts": { - "build": "docker run --rm -it -v $(pwd):/app -w /app -e EMSCRIPTEN=/emsdk/upstream/emscripten emscripten/emsdk ./bin/archive-emcpp.sh", + "build": "docker run --rm -it -v $(pwd):/app -w /app devinsa/mymonerolibappjs ./bin/archive-emcpp.sh", "format": "find . -name '*.js*' | xargs prettier --write --config ./.prettierrc --config-precedence file-override", "test": "mocha" }, diff --git a/src/emscr_SendFunds_bridge.cpp b/src/emscr_SendFunds_bridge.cpp index 4a1085d..2201ca7 100644 --- a/src/emscr_SendFunds_bridge.cpp +++ b/src/emscr_SendFunds_bridge.cpp @@ -43,6 +43,7 @@ #include "wallet_errors.h" // #include "serial_bridge_utils.hpp" +#include "register_mn_data.hpp" #include "SendFundsFormSubmissionController.hpp" // // @@ -130,7 +131,7 @@ void send_app_handler__success(const Success_RetVals &success_retVals) root.put(ret_json_key__send__tx_hash(), std::move(success_retVals.tx_hash_string)); root.put(ret_json_key__send__tx_key(), std::move(success_retVals.tx_key_string)); root.put(ret_json_key__send__tx_pub_key(), std::move(success_retVals.tx_pub_key_string)); - + string target_address_str; size_t nTargAddrs = success_retVals.target_addresses.size(); for (size_t i = 0; i < nTargAddrs; ++i){ @@ -174,26 +175,162 @@ void send_app_handler__success(const Success_RetVals &success_retVals) } // // From-JS function decls + +void emscr_SendFunds_bridge::register_new_wallet(const boost::property_tree::ptree &json_root, + master_node_data &mn_data, + vector &dest_addrs, + vector &dest_amounts) +{ + + std::string registration_string = json_root.get("registration_string"); + std::vector local_args; + std::istringstream registration_stream(registration_string); + std::string token; + + while (std::getline(registration_stream, token, ' ')) + { + local_args.push_back(token); + } + + local_args.erase(local_args.begin()); + // std::cout << "local_args.size() is " << local_args.size() << std::endl; + + if (local_args.empty() || local_args.size() < 6) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node Invalid Input registration string")); + return; + } + + uint32_t priority = (uint32_t)stoul(json_root.get("priority")); + if (priority == 5) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node registrations cannot use flash priority")); + return; + } + + uint64_t staking_requirement = (uint64_t)1000000000 * 10000; + std::vector address_args = std::vector(local_args.begin(), local_args.begin() + local_args.size() - 3); + + std::optional hf_version = 18; + cryptonote::network_type networkType = nettype_from_string(json_root.get("nettype_string")); + + master_nodes::contributor_args_t contributor_args = master_nodes::convert_registration_args(networkType, address_args, staking_requirement, *hf_version); + if (!contributor_args.success) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node convert_registration_args_failed")); + return; + } + + size_t const timestamp_index = local_args.size() - 3; + size_t const key_index = local_args.size() - 2; + size_t const signature_index = local_args.size() - 1; + const std::string &master_node_key_as_str = local_args[key_index]; + + crypto::public_key master_node_key; + crypto::signature signature; + uint64_t expiration_timestamp = 0; + + try + { + expiration_timestamp = boost::lexical_cast(local_args[timestamp_index]); + if (expiration_timestamp <= (uint64_t)time(nullptr) + 600) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node registration_timestamp_expired")); + return; + } + } + catch (const std::exception &e) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node master_node_registration_timestamp_parse_fail")); + return; + } + + if (!tools::hex_to_type(local_args[key_index], master_node_key)) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node master_node_key_parse_fail")); + return; + } + + if (!tools::hex_to_type(local_args[signature_index], signature)) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node master_node_signature_parse_fail")); + return; + } + + try + { + master_nodes::validate_contributor_args(*hf_version, contributor_args); + master_nodes::validate_contributor_args_signature(contributor_args, expiration_timestamp, master_node_key, signature); + } + catch (const master_nodes::invalid_contributions &e) + { + send_app_handler__error_msg(error_ret_json_from_message("Master node validate_contributor_args_fail")); + return; + } + + mn_data.contributor_args = contributor_args; + mn_data.time_stamp = expiration_timestamp; + mn_data.master_node_key = master_node_key; + mn_data.signature = signature; + + uint64_t amount_payable_by_operator = 0; + { + const uint64_t DUST = MAX_NUMBER_OF_CONTRIBUTORS; + uint64_t amount_left = staking_requirement; + + for (size_t i = 0; i < contributor_args.portions.size(); i++) + { + uint64_t amount = master_nodes::portions_to_amount(staking_requirement, contributor_args.portions[i]); + if (i == 0) + amount_payable_by_operator += amount; + amount_left -= amount; + } + + if (amount_left <= DUST) + amount_payable_by_operator += amount_left; + } + + std::string amount_payable_by_operator_str = std::to_string(amount_payable_by_operator / 1000000000); + dest_addrs.emplace_back(local_args[1]); + dest_amounts.emplace_back(amount_payable_by_operator_str); +} + void emscr_SendFunds_bridge::send_funds(const string &args_string) { boost::property_tree::ptree json_root; - if (!parsed_json_root(args_string, json_root)) { + if (!parsed_json_root(args_string, json_root)) + { // (it will already have thrown an exception) send_app_handler__error_msg(error_ret_json_from_message("Invalid JSON")); return; } - const auto& destinations = json_root.get_child("destinations"); - vector dest_addrs, dest_amounts; - dest_addrs.reserve(destinations.size()); - dest_amounts.reserve(destinations.size()); + // Parsing MN data from the args_string + master_nodes::contributor_args_t contributor_args = {}; + vector dest_addrs, dest_amounts; + master_node_data mn_data = {}; - for (const auto& dest : destinations) { - dest_addrs.emplace_back(dest.second.get("to_address")); - dest_amounts.emplace_back(dest.second.get("send_amount")); - } + const bool isRegister = json_root.get("isRegisterStr"); + if (isRegister) + { + register_new_wallet(json_root, mn_data, dest_addrs, dest_amounts); + } + + else + { + const auto &destinations = json_root.get_child("destinations"); + dest_addrs.reserve(destinations.size()); + dest_amounts.reserve(destinations.size()); + + for (const auto &dest : destinations) + { + dest_addrs.emplace_back(dest.second.get("to_address")); + dest_amounts.emplace_back(dest.second.get("send_amount")); + } + } Parameters parameters{ + std::move(mn_data), json_root.get("fromWallet_didFailToInitialize"), json_root.get("fromWallet_didFailToBoot"), json_root.get("fromWallet_needsImport"), @@ -227,60 +364,53 @@ void emscr_SendFunds_bridge::send_funds(const string &args_string) json_root.get_optional("resolvedPaymentID"), json_root.get("resolvedPaymentID_fieldIsVisible"), // - [] ( // preSuccess_nonTerminal_validationMessageUpdate_fn - ProcessStep step - ) -> void { + []( // preSuccess_nonTerminal_validationMessageUpdate_fn + ProcessStep step) -> void + { send_app_handler__status_update(step); }, - [] ( // failure_fn + []( // failure_fn SendFunds::PreSuccessTerminalCode code, boost::optional msg, boost::optional createTx_errCode, boost::optional spendable_balance, - boost::optional required_balance - ) -> void { + boost::optional required_balance) -> void + { send_app_handler__error_code(code, msg, createTx_errCode, spendable_balance, required_balance); }, - [] () -> void { // preSuccess_passedValidation_willBeginSending + []() -> void { // preSuccess_passedValidation_willBeginSending EM_ASM_( { Module.fromCpp__SendFundsFormSubmission__willBeginSending({}); // Module must implement this! - } - ); + }); }, // - [] () -> void { // canceled_fn + []() -> void { // canceled_fn EM_ASM_( { Module.fromCpp__SendFundsFormSubmission__canceled({}); // Module must implement this! - } - ); + }); THROW_WALLET_EXCEPTION_IF(controller_ptr == NULL, error::wallet_internal_error, "expected non-NULL controller_ptr"); delete controller_ptr; // having finished controller_ptr = NULL; }, - [] (SendFunds::Success_RetVals retVals) -> void // success_fn + [](SendFunds::Success_RetVals retVals) -> void // success_fn { send_app_handler__success(retVals); - } - }; + }}; controller_ptr = new FormSubmissionController{parameters}; // heap alloc - if (!controller_ptr) { // exception will be thrown if oom but JIC, since null ptrs are somehow legal in WASM + if (!controller_ptr) + { // exception will be thrown if oom but JIC, since null ptrs are somehow legal in WASM send_app_handler__error_msg("Out of memory (heap vals container)"); return; } - (*controller_ptr).set__authenticate_fn( - [] () -> void - { // authenticate_fn - this is not guaranteed to be called but it will be if requireAuthentication is true - EM_ASM_( - { - Module.fromCpp__SendFundsFormSubmission__authenticate(); // Module must implement this! - } - ); - } - ); - (*controller_ptr).set__get_unspent_outs_fn([] (LightwalletAPI_Req_GetUnspentOuts req_params) -> void - { // get_unspent_outs + (*controller_ptr).set__authenticate_fn([]() -> void { // authenticate_fn - this is not guaranteed to be called but it will be if requireAuthentication is true + EM_ASM_( + { + Module.fromCpp__SendFundsFormSubmission__authenticate(); // Module must implement this! + }); + }); + (*controller_ptr).set__get_unspent_outs_fn([](LightwalletAPI_Req_GetUnspentOuts req_params) -> void { // get_unspent_outs boost::property_tree::ptree req_params_root; req_params_root.put("address", req_params.address); req_params_root.put("view_key", req_params.view_key); @@ -289,21 +419,19 @@ void emscr_SendFunds_bridge::send_funds(const string &args_string) req_params_root.put("use_dust", req_params.use_dust); req_params_root.put("mixin", req_params.mixin); stringstream req_params_ss; - boost::property_tree::write_json(req_params_ss, req_params_root, false/*pretty*/); + boost::property_tree::write_json(req_params_ss, req_params_root, false /*pretty*/); EM_ASM_( { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__get_unspent_outs(JS__req_params); // Module must implement this! }, - req_params_ss.str().c_str() - ); + req_params_ss.str().c_str()); }); - (*controller_ptr).set__get_random_outs_fn([] (LightwalletAPI_Req_GetRandomOuts req_params) -> void - { // get_random_outs + (*controller_ptr).set__get_random_outs_fn([](LightwalletAPI_Req_GetRandomOuts req_params) -> void { // get_random_outs boost::property_tree::ptree req_params_root; boost::property_tree::ptree amounts_ptree; - BOOST_FOREACH(const string &amount_string, req_params.amounts) + BOOST_FOREACH (const string &amount_string, req_params.amounts) { property_tree::ptree amount_child; amount_child.put("", amount_string); @@ -312,18 +440,16 @@ void emscr_SendFunds_bridge::send_funds(const string &args_string) req_params_root.add_child("amounts", amounts_ptree); req_params_root.put("count", req_params.count); stringstream req_params_ss; - boost::property_tree::write_json(req_params_ss, req_params_root, false/*pretty*/); + boost::property_tree::write_json(req_params_ss, req_params_root, false /*pretty*/); EM_ASM_( { const JS__req_params_string = Module.UTF8ToString($0); const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__get_random_outs(JS__req_params); // Module must implement this! }, - req_params_ss.str().c_str() - ); + req_params_ss.str().c_str()); }); - (*controller_ptr).set__submit_raw_tx_fn([] (LightwalletAPI_Req_SubmitRawTx req_params) -> void - { // submit_raw_tx + (*controller_ptr).set__submit_raw_tx_fn([](LightwalletAPI_Req_SubmitRawTx req_params) -> void { // submit_raw_tx boost::property_tree::ptree req_params_root; boost::property_tree::ptree amounts_ptree; req_params_root.put("address", std::move(req_params.address)); @@ -331,7 +457,7 @@ void emscr_SendFunds_bridge::send_funds(const string &args_string) req_params_root.put("tx", std::move(req_params.tx)); req_params_root.put("fee", std::move(req_params.priority)); stringstream req_params_ss; - boost::property_tree::write_json(req_params_ss, req_params_root, false/*pretty*/); + boost::property_tree::write_json(req_params_ss, req_params_root, false /*pretty*/); auto req_params_string = req_params_ss.str(); EM_ASM_( { @@ -339,8 +465,7 @@ void emscr_SendFunds_bridge::send_funds(const string &args_string) const JS__req_params = JSON.parse(JS__req_params_string); Module.fromCpp__SendFundsFormSubmission__submit_raw_tx(JS__req_params); // Module must implement this! }, - req_params_ss.str().c_str() - ); + req_params_ss.str().c_str()); }); (*controller_ptr).handle(); } diff --git a/src/emscr_SendFunds_bridge.hpp b/src/emscr_SendFunds_bridge.hpp index 09a9534..55d817f 100644 --- a/src/emscr_SendFunds_bridge.hpp +++ b/src/emscr_SendFunds_bridge.hpp @@ -35,7 +35,7 @@ // #include #include -#include "cryptonote_config.h" +#include "cryptonote_config.h" #include "SendFundsFormSubmissionController.hpp" // namespace emscr_SendFunds_bridge @@ -50,6 +50,10 @@ namespace emscr_SendFunds_bridge // To use these functions, the appropriate emscripten-side JS fn handlers must exist, which must be hooked up to perform the e.g. networking or transport requests they are specced to perform, then upon the async completion of those requests, call the appropate "cb_I+"-named function to allow the internal evaluation of the routine entrypoint to complete. // // Public interface: + void register_new_wallet(const boost::property_tree::ptree &json_root, + master_node_data &mn_data, + vector &dest_addrs, + vector &dest_amounts); void send_funds(const string &args_string); void send_cb__authentication(const string &args_string); void send_cb_I__got_unspent_outs(const string &args_string); diff --git a/src/submodules/beldex-libapp-cpp b/src/submodules/beldex-libapp-cpp index f527e3a..5c20a72 160000 --- a/src/submodules/beldex-libapp-cpp +++ b/src/submodules/beldex-libapp-cpp @@ -1 +1 @@ -Subproject commit f527e3adbcb6a2408f36083a6aebcf579965672c +Subproject commit 5c20a726ffcadd5d20cf78225a588916d30a6d5e