aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/php-on-wasm
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-07-09 08:27:57 +0900
committernsfisis <nsfisis@gmail.com>2024-07-09 08:27:57 +0900
commit925f7f4a11341fb950f4f6cd6390187b780ba419 (patch)
tree78d1e1717234675da5e9ce36b6d3408cef586085 /examples/php-on-wasm
parent61d6fdffb161c8b4130eb4982f021fbc0c77c445 (diff)
downloadphp-waddiwasi-925f7f4a11341fb950f4f6cd6390187b780ba419.tar.gz
php-waddiwasi-925f7f4a11341fb950f4f6cd6390187b780ba419.tar.zst
php-waddiwasi-925f7f4a11341fb950f4f6cd6390187b780ba419.zip
feat: add examples/compile-php-to-wasm
Diffstat (limited to 'examples/php-on-wasm')
-rw-r--r--examples/php-on-wasm/php-wasm.mjs8308
-rw-r--r--examples/php-on-wasm/php-wasm.php2
l---------[-rwxr-xr-x]examples/php-on-wasm/php-wasm.wasmbin4863136 -> 36 bytes
3 files changed, 1 insertions, 8309 deletions
diff --git a/examples/php-on-wasm/php-wasm.mjs b/examples/php-on-wasm/php-wasm.mjs
deleted file mode 100644
index 8477416..0000000
--- a/examples/php-on-wasm/php-wasm.mjs
+++ /dev/null
@@ -1,8308 +0,0 @@
-
-import { createRequire } from 'module';
-const require = createRequire(import.meta.url);
-
-var Module = (() => {
- var _scriptDir = import.meta.url;
-
- return (
-function(moduleArg = {}) {
-
-// include: shell.js
-// The Module object: Our interface to the outside world. We import
-// and export values on it. There are various ways Module can be used:
-// 1. Not defined. We create it here
-// 2. A function parameter, function(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 = moduleArg;
-
-// Set up the promise that indicates the Module is initialized
-var readyPromiseResolve, readyPromiseReject;
-Module['ready'] = new Promise((resolve, reject) => {
- readyPromiseResolve = resolve;
- readyPromiseReject = reject;
-});
-["_main","_memory","_php_wasm_run","_fflush","___indirect_function_table","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)
-
-
-// Sometimes an existing Module object exists with properties
-// meant to overwrite the default module functionality. Here
-// we collect those properties and reapply _after_ we configure
-// the current environment's defaults to avoid having to be so
-// defensive during initialization.
-var moduleOverrides = Object.assign({}, Module);
-
-var arguments_ = [];
-var thisProgram = './this.program';
-var quit_ = (status, toThrow) => {
- throw toThrow;
-};
-
-// 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 = false;
-var ENVIRONMENT_IS_WORKER = false;
-var ENVIRONMENT_IS_NODE = true;
-var ENVIRONMENT_IS_SHELL = false;
-
-if (Module['ENVIRONMENT']) {
- throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
-}
-
-// `/` should be present at the end if `scriptDirectory` is not empty
-var scriptDirectory = '';
-function locateFile(path) {
- if (Module['locateFile']) {
- return Module['locateFile'](path, scriptDirectory);
- }
- return scriptDirectory + path;
-}
-
-// Hooks that are implemented differently in different runtime environments.
-var read_,
- readAsync,
- readBinary;
-
-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] * 10000) + (numericVersion[1] * 100) + (numericVersion[2].split('-')[0] * 1);
- var minVersion = 160000;
- if (numericVersion < 160000) {
- throw new Error('This emscripten-generated code requires node v16.0.0 (detected v' + nodeVersion + ')');
- }
-
- // `require()` is no-op in an ESM module, use `createRequire()` to construct
- // the require()` function. This is only necessary for multi-environment
- // builds, `-sENVIRONMENT=node` emits a static import declaration instead.
- // TODO: Swap all `require()`'s with `import()`'s?
- // These modules will usually be used on Node.js. Load them eagerly to avoid
- // the complexity of lazy-loading.
- var fs = require('fs');
- var nodePath = require('path');
-
- if (ENVIRONMENT_IS_WORKER) {
- scriptDirectory = nodePath.dirname(scriptDirectory) + '/';
- } else {
- // EXPORT_ES6 + ENVIRONMENT_IS_NODE always requires use of import.meta.url,
- // since there's no way getting the current absolute path of the module when
- // support for that is not available.
- scriptDirectory = require('url').fileURLToPath(new URL('./', import.meta.url)); // includes trailing slash
- }
-
-// include: node_shell_read.js
-read_ = (filename, binary) => {
- // We need to re-wrap `file://` strings to URLs. Normalizing isn't
- // necessary in that case, the path should already be absolute.
- 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);
- }
- assert(ret.buffer);
- return ret;
-};
-
-readAsync = (filename, onload, onerror, binary = true) => {
- // See the comment in the `read_` function.
- 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 (!Module['thisProgram'] && process.argv.length > 1) {
- thisProgram = process.argv[1].replace(/\\/g, '/');
- }
-
- arguments_ = process.argv.slice(2);
-
- // MODULARIZE will export the module in the proper place outside, we don't need to export here
-
- quit_ = (status, toThrow) => {
- process.exitCode = status;
- throw toThrow;
- };
-
- Module['inspect'] = () => '[Emscripten Module object]';
-
-} 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') {
- // spidermonkey lacks setTimeout but we use it above in readAsync.
- globalThis.setTimeout = (f) => (typeof f == 'function') ? f() : abort();
- }
-
- if (typeof scriptArgs != 'undefined') {
- arguments_ = scriptArgs;
- } else if (typeof arguments != 'undefined') {
- arguments_ = arguments;
- }
-
- if (typeof quit == 'function') {
- quit_ = (status, toThrow) => {
- // Unlike node which has process.exitCode, d8 has no such mechanism. So we
- // have no way to set the exit code and then let the program exit with
- // that code when it naturally stops running (say, when all setTimeouts
- // have completed). For that reason, we must call `quit` - the only way to
- // set the exit code - but quit also halts immediately. To increase
- // consistency with node (and the web) we schedule the actual quit call
- // using a setTimeout to give the current stack and any exception handlers
- // a chance to run. This enables features such as addOnPostRun (which
- // expected to be able to run code after main returns).
- setTimeout(() => {
- if (!(toThrow instanceof ExitStatus)) {
- let toLog = toThrow;
- if (toThrow && typeof toThrow == 'object' && toThrow.stack) {
- toLog = [toThrow, toThrow.stack];
- }
- err(`exiting due to exception: ${toLog}`);
- }
- quit(status);
- });
- throw toThrow;
- };
- }
-
- if (typeof print != 'undefined') {
- // Prefer to use print/printErr where they exist, as they usually work better.
- if (typeof console == 'undefined') console = /** @type{!Console} */({});
- console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
- console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr != 'undefined' ? printErr : print);
- }
-
-} else
-
-// Note that this includes Node.js workers when relevant (pthreads is enabled).
-// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
-// ENVIRONMENT_IS_NODE.
-{
- throw new Error('environment detection error');
-}
-
-var out = Module['print'] || console.log.bind(console);
-var err = Module['printErr'] || console.error.bind(console);
-
-// Merge back in the overrides
-Object.assign(Module, moduleOverrides);
-// Free the object hierarchy contained in the overrides, this lets the GC
-// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
-moduleOverrides = null;
-checkIncomingModuleAPI();
-
-// Emit code to handle expected values on the Module object. This applies Module.x
-// to the proper local x. This has two benefits: first, we only emit it if it is
-// expected to arrive, and second, by using a local everywhere else that can be
-// minified.
-
-if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
-
-if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
-
-if (Module['quit']) quit_ = Module['quit'];legacyModuleProp('quit', 'quit_');
-
-// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
-// Assertions on removed incoming Module JS APIs.
-assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
-assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
-assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
-assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
-assert(typeof Module['read'] == 'undefined', 'Module.read option was removed (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 emscripten_set_window_title in JS)');
-assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
-legacyModuleProp('asm', 'wasmExports');
-legacyModuleProp('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 FETCHFS = 'FETCHFS is no longer included by default; build with -lfetchfs.js';
-var ICASEFS = 'ICASEFS is no longer included by default; build with -licasefs.js';
-var JSFILEFS = 'JSFILEFS is no longer included by default; build with -ljsfilefs.js';
-var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
-
-var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
-
-assert(!ENVIRONMENT_IS_WEB, "web environment detected but not enabled at build time. Add 'web' to `-sENVIRONMENT` to enable.");
-
-assert(!ENVIRONMENT_IS_WORKER, "worker environment detected but not enabled at build time. Add 'worker' to `-sENVIRONMENT` to enable.");
-
-assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");
-
-
-// end include: shell.js
-// include: preamble.js
-// === Preamble library stuff ===
-
-// Documentation for the public APIs defined in this file must be updated in:
-// site/source/docs/api_reference/preamble.js.rst
-// A prebuilt local version of the documentation is available at:
-// site/build/text/docs/api_reference/preamble.js.txt
-// You can also build docs locally as HTML or other formats in site/
-// An online HTML version (which may be of a different version of Emscripten)
-// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
-
-var wasmBinary;
-if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
-var noExitRuntime = Module['noExitRuntime'] || true;legacyModuleProp('noExitRuntime', 'noExitRuntime');
-
-if (typeof WebAssembly != 'object') {
- abort('no native wasm support detected');
-}
-
-// Wasm globals
-
-var wasmMemory;
-
-//========================================
-// Runtime essentials
-//========================================
-
-// whether we are quitting the application. no code should run after this.
-// set in exit() and abort()
-var ABORT = false;
-
-// set by exit() and abort(). Passed to 'onExit' handler.
-// NOTE: This is also used as the process return code code in shell environments
-// but only when noExitRuntime is false.
-var EXITSTATUS;
-
-/** @type {function(*, string=)} */
-function assert(condition, text) {
- if (!condition) {
- abort('Assertion failed' + (text ? ': ' + text : ''));
- }
-}
-
-// We used to include malloc/free by default in the past. Show a helpful error in
-// builds with assertions.
-
-// Memory management
-
-var HEAP,
-/** @type {!Int8Array} */
- HEAP8,
-/** @type {!Uint8Array} */
- HEAPU8,
-/** @type {!Int16Array} */
- HEAP16,
-/** @type {!Uint16Array} */
- HEAPU16,
-/** @type {!Int32Array} */
- HEAP32,
-/** @type {!Uint32Array} */
- HEAPU32,
-/** @type {!Float32Array} */
- HEAPF32,
-/** @type {!Float64Array} */
- HEAPF64;
-
-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);
-}
-
-assert(!Module['STACK_SIZE'], 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
-
-assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
- 'JS engine does not provide full typed array support');
-
-// If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY
-assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
-assert(!Module['INITIAL_MEMORY'], 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
-
-// include: runtime_stack_check.js
-// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
-function writeStackCookie() {
- var max = _emscripten_stack_get_end();
- assert((max & 3) == 0);
- // If the stack ends at address zero we write our cookies 4 bytes into the
- // stack. This prevents interference with SAFE_HEAP and ASAN which also
- // monitor writes to address zero.
- if (max == 0) {
- max += 4;
- }
- // The stack grow downwards towards _emscripten_stack_get_end.
- // We write cookies to the final two words in the stack and detect if they are
- // ever overwritten.
- HEAPU32[((max)>>2)] = 0x02135467;
- HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
- // Also test the global address 0 for integrity.
- HEAPU32[((0)>>2)] = 1668509029;
-}
-
-function checkStackCookie() {
- if (ABORT) return;
- var max = _emscripten_stack_get_end();
- // See writeStackCookie().
- if (max == 0) {
- max += 4;
- }
- var cookie1 = HEAPU32[((max)>>2)];
- var cookie2 = HEAPU32[(((max)+(4))>>2)];
- if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
- abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
- }
- // Also test the global address 0 for integrity.
- if (HEAPU32[((0)>>2)] != 0x63736d65 /* '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)';
-})();
-
-// end include: runtime_assertions.js
-var __ATPRERUN__ = []; // functions called before the runtime is initialized
-var __ATINIT__ = []; // functions called during startup
-var __ATEXIT__ = []; // functions called during shutdown
-var __ATPOSTRUN__ = []; // functions called after the main() is called
-
-var runtimeInitialized = false;
-
-var runtimeKeepaliveCounter = 0;
-
-function keepRuntimeAlive() {
- return noExitRuntime || runtimeKeepaliveCounter > 0;
-}
-
-function preRun() {
- if (Module['preRun']) {
- if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
- while (Module['preRun'].length) {
- addOnPreRun(Module['preRun'].shift());
- }
- }
- callRuntimeCallbacks(__ATPRERUN__);
-}
-
-function initRuntime() {
- assert(!runtimeInitialized);
- runtimeInitialized = true;
-
- checkStackCookie();
-
-
-if (!Module["noFSInit"] && !FS.init.initialized)
- FS.init();
-FS.ignorePermissions = false;
-
-TTY.init();
-SOCKFS.root = FS.mount(SOCKFS, {}, null);
-PIPEFS.root = FS.mount(PIPEFS, {}, null);
- callRuntimeCallbacks(__ATINIT__);
-}
-
-function postRun() {
- checkStackCookie();
-
- if (Module['postRun']) {
- if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
- while (Module['postRun'].length) {
- addOnPostRun(Module['postRun'].shift());
- }
- }
-
- callRuntimeCallbacks(__ATPOSTRUN__);
-}
-
-function addOnPreRun(cb) {
- __ATPRERUN__.unshift(cb);
-}
-
-function addOnInit(cb) {
- __ATINIT__.unshift(cb);
-}
-
-function addOnExit(cb) {
-}
-
-function addOnPostRun(cb) {
- __ATPOSTRUN__.unshift(cb);
-}
-
-// include: runtime_math.js
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
-
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
-
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
-
-// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
-
-assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
-assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
-assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
-assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
-// end include: runtime_math.js
-// A counter of dependencies for calling run(). If we need to
-// do asynchronous work before running, increment this and
-// decrement it. Incrementing must happen in a place like
-// Module.preRun (used by emcc to add file preloading).
-// Note that you can add dependencies in preRun, even though
-// it happens right before run - run will be postponed until
-// the dependencies are met.
-var runDependencies = 0;
-var runDependencyWatcher = null;
-var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
-var runDependencyTracking = {};
-
-function getUniqueRunDependency(id) {
- var orig = id;
- while (1) {
- if (!runDependencyTracking[id]) return id;
- id = orig + Math.random();
- }
-}
-
-function addRunDependency(id) {
- runDependencies++;
-
- 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(() => {
- 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');
- }
-}
-
-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');
- }
- if (runDependencies == 0) {
- if (runDependencyWatcher !== null) {
- clearInterval(runDependencyWatcher);
- runDependencyWatcher = null;
- }
- if (dependenciesFulfilled) {
- var callback = dependenciesFulfilled;
- dependenciesFulfilled = null;
- callback(); // can add another dependenciesFulfilled
- }
- }
-}
-
-/** @param {string|number=} what */
-function abort(what) {
- if (Module['onAbort']) {
- Module['onAbort'](what);
- }
-
- what = 'Aborted(' + what + ')';
- // TODO(sbc): Should we remove printing and leave it up to whoever
- // catches the exception?
- err(what);
-
- ABORT = true;
- EXITSTATUS = 1;
-
- // Use a wasm runtime error, because a JS error might be seen as a foreign
- // exception, which means we'd run destructors on it. We need the error to
- // simply make the program stop.
- // FIXME This approach does not work in Wasm EH because it currently does not assume
- // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
- // a trap or not based on a hidden field within the object. So at the moment
- // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
- // allows this in the wasm spec.
-
- // Suppress closure compiler warning here. Closure compiler's builtin extern
- // 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;
-}
-
-// include: memoryprofiler.js
-// end include: memoryprofiler.js
-// include: URIUtils.js
-// Prefix of data URIs emitted by SINGLE_FILE and related options.
-var dataURIPrefix = 'data:application/octet-stream;base64,';
-
-// Indicates whether filename is a base64 data URI.
-function isDataURI(filename) {
- // Prefix of data URIs emitted by SINGLE_FILE and related options.
- return filename.startsWith(dataURIPrefix);
-}
-
-// Indicates whether filename is delivered via file protocol (as opposed to http/https)
-function isFileURI(filename) {
- return filename.startsWith('file://');
-}
-// end include: URIUtils.js
-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: runtime_exceptions.js
-// end include: runtime_exceptions.js
-var wasmBinaryFile;
-if (Module['locateFile']) {
- wasmBinaryFile = 'php-wasm.wasm';
- if (!isDataURI(wasmBinaryFile)) {
- wasmBinaryFile = locateFile(wasmBinaryFile);
- }
-} else {
- // Use bundler-friendly `new URL(..., import.meta.url)` pattern; works in browsers too.
- wasmBinaryFile = new URL('php-wasm.wasm', import.meta.url).href;
-}
-
-function getBinarySync(file) {
- if (file == wasmBinaryFile && wasmBinary) {
- return new Uint8Array(wasmBinary);
- }
- if (readBinary) {
- return readBinary(file);
- }
- throw "both async and sync fetching of the wasm failed";
-}
-
-function getBinaryPromise(binaryFile) {
- // If we don't have the binary yet, try 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'
- ) {
- 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));
- }
- }
-
- // Otherwise, getBinarySync should be able to get it synchronously
- return Promise.resolve().then(() => getBinarySync(binaryFile));
-}
-
-function instantiateArrayBuffer(binaryFile, imports, receiver) {
- return getBinaryPromise(binaryFile).then((binary) => {
- return WebAssembly.instantiate(binary, imports);
- }).then((instance) => {
- return instance;
- }).then(receiver, (reason) => {
- err(`failed to asynchronously prepare wasm: ${reason}`);
-
- // Warn on some common problems.
- if (isFileURI(wasmBinaryFile)) {
- err(`warning: Loading from a file URI (${wasmBinaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`);
- }
- abort(reason);
- });
-}
-
-function instantiateAsync(binary, binaryFile, imports, callback) {
- if (!binary &&
- typeof WebAssembly.instantiateStreaming == 'function' &&
- !isDataURI(binaryFile) &&
- // 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(binaryFile, { credentials: 'same-origin' }).then((response) => {
- // Suppress closure warning here since the upstream definition for
- // instantiateStreaming only allows Promise<Repsponse> rather than
- // an actual Response.
- // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
- /** @suppress {checkTypes} */
- var result = WebAssembly.instantiateStreaming(response, imports);
-
- return result.then(
- callback,
- function(reason) {
- // We expect the most common failure cause to be a bad MIME type for the binary,
- // in which case falling back to ArrayBuffer instantiation should work.
- err(`wasm streaming compile failed: ${reason}`);
- err('falling back to ArrayBuffer instantiation');
- return instantiateArrayBuffer(binaryFile, imports, callback);
- });
- });
- }
- return instantiateArrayBuffer(binaryFile, imports, callback);
-}
-
-// Create the wasm instance.
-// Receives the wasm imports, returns the exports.
-function createWasm() {
- // prepare imports
- var info = {
- 'env': wasmImports,
- 'wasi_snapshot_preview1': wasmImports,
- };
- // Load the wasm module and create an instance of using native support in the JS engine.
- // handle a generated wasm instance, receiving its exports and
- // performing other necessary setup
- /** @param {WebAssembly.Module=} module*/
- function receiveInstance(instance, module) {
- wasmExports = instance.exports;
-
-
-
- wasmMemory = wasmExports['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);
- updateMemoryViews();
-
- wasmTable = wasmExports['__indirect_function_table'];
-
- assert(wasmTable, "table not found in wasm exports");
-
- addOnInit(wasmExports['__wasm_call_ctors']);
-
- removeRunDependency('wasm-instantiate');
- return wasmExports;
- }
- // wait for the pthread pool (if any)
- addRunDependency('wasm-instantiate');
-
- // Prefer streaming instantiation if available.
- // Async compilation can be confusing when an error on the page overwrites Module
- // (for example, if the order of elements is wrong, and the one defining Module is
- // later), so we save Module and check it later.
- var trueModule = Module;
- function receiveInstantiationResult(result) {
- // 'result' is a ResultObject object which has both the module and instance.
- // receiveInstance() will swap in the exports (to Module.asm) so they can be called
- assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
- trueModule = null;
- // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
- // When the regression is fixed, can restore the above PTHREADS-enabled path.
- receiveInstance(result['instance']);
- }
-
- // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
- // to manually instantiate the Wasm module themselves. This allows pages to
- // run the instantiation parallel to any other async startup actions they are
- // performing.
- // Also pthreads and wasm workers initialize the wasm instance through this
- // path.
- if (Module['instantiateWasm']) {
-
- try {
- return Module['instantiateWasm'](info, receiveInstance);
- } catch(e) {
- err(`Module.instantiateWasm callback failed with error: ${e}`);
- // If instantiation fails, reject the module ready promise.
- readyPromiseReject(e);
- }
- }
-
- // If instantiation fails, reject the module ready promise.
- instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject);
- return {}; // no exports yet; we'll fill them in later
-}
-
-// Globals used by JS i64 conversions (see makeSetValue)
-var tempDouble;
-var tempI64;
-
-// include: runtime_debug.js
-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 ignoredModuleProp(prop) {
- if (Object.getOwnPropertyDescriptor(Module, prop)) {
- abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`);
- }
-}
-
-// forcing the filesystem exports a few things by default
-function isExportedByForceFilesystem(name) {
- return name === 'FS_createPath' ||
- name === 'FS_createDataFile' ||
- name === 'FS_createPreloadedFile' ||
- name === 'FS_unlink' ||
- name === 'addRunDependency' ||
- // The old FS has some functionality that WasmFS lacks.
- name === 'FS_createLazyFile' ||
- name === 'FS_createDevice' ||
- name === 'removeRunDependency';
-}
-
-function missingGlobal(sym, msg) {
- if (typeof globalThis !== 'undefined') {
- Object.defineProperty(globalThis, sym, {
- configurable: true,
- get() {
- warnOnce('`' + sym + '` is not longer defined by emscripten. ' + msg);
- return undefined;
- }
- });
- }
-}
-
-missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
-missingGlobal('asm', 'Please use wasmExports instead');
-
-function missingLibrarySymbol(sym) {
- if (typeof globalThis !== 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
- Object.defineProperty(globalThis, sym, {
- configurable: true,
- get() {
- // Can't `abort()` here because it would break code that does runtime
- // checks. e.g. `if (typeof SDL === 'undefined')`.
- var msg = '`' + sym + '` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line';
- // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
- // library.js, which means $name for a JS name with no prefix, or name
- // for a JS name like _name.
- var librarySymbol = sym;
- if (!librarySymbol.startsWith('_')) {
- librarySymbol = '$' + sym;
- }
- msg += " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='" + librarySymbol + "')";
- if (isExportedByForceFilesystem(sym)) {
- msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
- }
- warnOnce(msg);
- return undefined;
- }
- });
- }
- // Any symbol that is not included from the JS libary is also (by definition)
- // not exported on the Module object.
- unexportedRuntimeSymbol(sym);
-}
-
-function unexportedRuntimeSymbol(sym) {
- if (!Object.getOwnPropertyDescriptor(Module, sym)) {
- Object.defineProperty(Module, sym, {
- configurable: true,
- get() {
- var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)";
- if (isExportedByForceFilesystem(sym)) {
- msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
- }
- abort(msg);
- }
- });
- }
-}
-
-// Used by XXXXX_DEBUG settings to output debug messages.
-function dbg(text) {
- // TODO(sbc): Make this configurable somehow. Its not always convenient for
- // logging to show up as warnings.
- console.warn.apply(console, arguments);
-}
-// end include: runtime_debug.js
-// === Body ===
-
-// end include: preamble.js
-
- /** @constructor */
- function ExitStatus(status) {
- this.name = 'ExitStatus';
- this.message = `Program terminated with exit(${status})`;
- this.status = status;
- }
-
- var callRuntimeCallbacks = (callbacks) => {
- while (callbacks.length > 0) {
- // Pass the module as the first argument.
- callbacks.shift()(Module);
- }
- };
-
-
- /**
- * @param {number} ptr
- * @param {string} type
- */
- function getValue(ptr, type = 'i8') {
- if (type.endsWith('*')) type = '*';
- switch (type) {
- case 'i1': return HEAP8[((ptr)>>0)];
- case 'i8': return HEAP8[((ptr)>>0)];
- case 'i16': return HEAP16[((ptr)>>1)];
- case 'i32': return HEAP32[((ptr)>>2)];
- case 'i64': abort('to do getValue(i64) use WASM_BIGINT');
- case 'float': return HEAPF32[((ptr)>>2)];
- case 'double': return HEAPF64[((ptr)>>3)];
- case '*': return HEAPU32[((ptr)>>2)];
- default: abort(`invalid type for getValue: ${type}`);
- }
- }
-
- var ptrToString = (ptr) => {
- assert(typeof ptr === 'number');
- // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
- ptr >>>= 0;
- return '0x' + ptr.toString(16).padStart(8, '0');
- };
-
-
- /**
- * @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': abort('to do setValue(i64) use WASM_BIGINT');
- 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 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 UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined;
-
- /**
- * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
- * array that contains uint8 values, returns a copy of that string as a
- * Javascript String object.
- * heapOrArray is either a regular array, or a JavaScript typed array view.
- * @param {number} idx
- * @param {number=} maxBytesToRead
- * @return {string}
- */
- var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => {
- 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 ' + 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 < 0x10000) {
- str += String.fromCharCode(u0);
- } else {
- var ch = u0 - 0x10000;
- str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
- }
- }
- return str;
- };
-
- /**
- * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
- * emscripten HEAP, returns a copy of that string as a Javascript String object.
- *
- * @param {number} ptr
- * @param {number=} maxBytesToRead - An optional length that specifies the
- * maximum number of bytes to read. You can omit this parameter to scan the
- * string until the first 0 byte. If maxBytesToRead is passed, and the string
- * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
- * string will cut short at that byte index (i.e. maxBytesToRead will not
- * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
- * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
- * JS JIT optimizations off, so it is worth to consider consistently using one
- * @return {string}
- */
- var UTF8ToString = (ptr, maxBytesToRead) => {
- assert(typeof ptr == 'number');
- return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
- };
- var ___assert_fail = (condition, filename, line, func) => {
- abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
- };
-
- 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 ___call_sighandler = (fp, sig) => getWasmTableEntry(fp)(sig);
-
- 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);
- },
- };
-
- var initRandomFill = () => {
- if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') {
- // for modern web browsers
- return (view) => crypto.getRandomValues(view);
- } else
- if (ENVIRONMENT_IS_NODE) {
- // for nodejs with or without crypto support included
- try {
- var crypto_module = require('crypto');
- var randomFillSync = crypto_module['randomFillSync'];
- if (randomFillSync) {
- // nodejs with LTS crypto support
- return (view) => crypto_module['randomFillSync'](view);
- }
- // very old nodejs with the original crypto API
- var randomBytes = crypto_module['randomBytes'];
- return (view) => (
- view.set(randomBytes(view.byteLength)),
- // Return the original view to match modern native implementations.
- view
- );
- } 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
- 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) => {
- // Lazily init on the first invocation.
- return (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();
- // 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('/');
- },
- };
-
-
-
- var FS_stdin_getChar_buffer = [];
-
- var lengthBytesUTF8 = (str) => {
- var len = 0;
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
- // unit, not a Unicode code point of the character! So decode
- // UTF16->UTF32->UTF8.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- var c = str.charCodeAt(i); // possibly a lead surrogate
- if (c <= 0x7F) {
- len++;
- } else if (c <= 0x7FF) {
- len += 2;
- } else if (c >= 0xD800 && c <= 0xDFFF) {
- len += 4; ++i;
- } else {
- len += 3;
- }
- }
- return len;
- };
-
- var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
- assert(typeof str === 'string');
- // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
- // undefined and false each don't write out any bytes.
- if (!(maxBytesToWrite > 0))
- return 0;
-
- var startIdx = outIdx;
- var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
- for (var i = 0; i < str.length; ++i) {
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
- // unit, not a Unicode code point of the character! So decode
- // UTF16->UTF32->UTF8.
- // See http://unicode.org/faq/utf_bom.html#utf16-3
- // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
- // and https://www.ietf.org/rfc/rfc2279.txt
- // and https://tools.ietf.org/html/rfc3629
- var u = str.charCodeAt(i); // possibly a lead surrogate
- if (u >= 0xD800 && u <= 0xDFFF) {
- var u1 = str.charCodeAt(++i);
- u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF);
- }
- if (u <= 0x7F) {
- if (outIdx >= endIdx) break;
- heap[outIdx++] = u;
- } else if (u <= 0x7FF) {
- if (outIdx + 1 >= endIdx) break;
- heap[outIdx++] = 0xC0 | (u >> 6);
- heap[outIdx++] = 0x80 | (u & 63);
- } else if (u <= 0xFFFF) {
- if (outIdx + 2 >= endIdx) break;
- heap[outIdx++] = 0xE0 | (u >> 12);
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
- heap[outIdx++] = 0x80 | (u & 63);
- } else {
- if (outIdx + 3 >= endIdx) break;
- if (u > 0x10FFFF) warnOnce('Invalid Unicode code point ' + ptrToString(u) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).');
- heap[outIdx++] = 0xF0 | (u >> 18);
- heap[outIdx++] = 0x80 | ((u >> 12) & 63);
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
- heap[outIdx++] = 0x80 | (u & 63);
- }
- }
- // Null-terminate the pointer to the buffer.
- heap[outIdx] = 0;
- return outIdx - startIdx;
- };
- /** @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) {
- // we will read data by chunks of BUFSIZE
- var BUFSIZE = 256;
- var buf = Buffer.alloc(BUFSIZE);
- var bytesRead = 0;
-
- // For some reason we must suppress a closure warning here, even though
- // fd definitely exists on process.stdin, and is even the proper way to
- // get the fd of stdin,
- // https://github.com/nodejs/help/issues/2136#issuecomment-523649904
- // This started to happen after moving this logic out of library_tty.js,
- // so it is related to the surrounding code in some unclear manner.
- /** @suppress {missingProperties} */
- var fd = process.stdin.fd;
-
- try {
- bytesRead = fs.readSync(fd, buf);
- } 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;
- }
- FS_stdin_getChar_buffer = intArrayFromString(result, true);
- }
- return FS_stdin_getChar_buffer.shift();
- };
- var TTY = {
- ttys:[],
- init() {
- // 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() {
- // 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(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) {
- // flush any pending line data
- 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);
- }
- 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) {
- 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(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); // val == 0 would cut text output off in the middle.
- }
- },
- fsync(tty) {
- if (tty.output && tty.output.length > 0) {
- out(UTF8ArrayToString(tty.output, 0));
- tty.output = [];
- }
- },
- ioctl_tcgets(tty) {
- // typical setting
- return {
- c_iflag: 25856,
- c_oflag: 5,
- c_cflag: 191,
- c_lflag: 35387,
- c_cc: [
- 0x03, 0x1c, 0x7f, 0x15, 0x04, 0x00, 0x01, 0x00, 0x11, 0x13, 0x1a, 0x00,
- 0x12, 0x0f, 0x17, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- };
- },
- ioctl_tcsets(tty, optional_actions, data) {
- // currently just ignore
- 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 zeroMemory = (address, size) => {
- HEAPU8.fill(0, address, address + size);
- return address;
- };
-
- var alignMemory = (size, alignment) => {
- assert(alignment, "alignment argument is required");
- return Math.ceil(size / alignment) * alignment;
- };
- var mmapAlloc = (size) => {
- size = alignMemory(size, 65536);
- var ptr = _emscripten_builtin_memalign(65536, size);
- if (!ptr) return 0;
- return zeroMemory(ptr, size);
- };
- 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)) {
- // 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(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(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(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(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(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 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(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) { // 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(stream, buffer, offset, length, position, canOwn) {
- // The data buffer should be a typed array view
- assert(!(buffer instanceof ArrayBuffer));
-
- 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(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;
- // Only make a new copy when MAP_PRIVATE is specified.
- if (!(flags & 2) && contents.buffer === HEAP8.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, allocated };
- },
- msync(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 */
- 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) => {
- return FS.createDataFile(parent, name, fileData, canRead, canWrite, canOwn);
- };
-
- var preloadPlugins = Module['preloadPlugins'] || [];
- var FS_handledByPreloadPlugin = (byteArray, fullname, finish, onerror) => {
- // Ensure plugins are ready.
- 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) => {
- // 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 (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 = {
- };
-
- var demangle = (func) => {
- warnOnce('warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling');
- 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) { // max recursive lookup of 8
- throw new FS.ErrnoError(32);
- }
-
- // split the absolute path
- var parts = path.split('/').filter((p) => !!p);
-
- // 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;
- },
- 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() {
- 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; },
- },
- });
- }
- // clone it, so we can return an instance of FSStream
- 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);
- // 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,
- opts,
- 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.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()
- // we ignore the uid / gid for 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) {
- // 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,
- path: FS.getPath(node), // we want the absolute path to the node
- 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) {
- 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) {
- // 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) {
- 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() {
- // 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
- // use a buffer to avoid overhead of individual crypto calls per byte
- 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);
- // 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.getStreamChecked(fd);
- 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) {
- // We set the `name` property to be able to identify `FS.ErrnoError`
- // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
- // - when using PROXYFS, an error can come from an underlying FS
- // as different FS objects have their own FS.ErrnoError each,
- // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
- // we'll use the reliable test `err.name == "ErrnoError"` instead
- 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];
-
- // 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 = '<generic error, no 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);
- }
- },
- 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<number>} */(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, 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;
- }
- // 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(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)+(4))>>2)] = stat.mode;
- HEAPU32[(((buf)+(8))>>2)] = stat.nlink;
- HEAP32[(((buf)+(12))>>2)] = stat.uid;
- HEAP32[(((buf)+(16))>>2)] = stat.gid;
- HEAP32[(((buf)+(20))>>2)] = stat.rdev;
- (tempI64 = [stat.size>>>0,(tempDouble=stat.size,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[(((buf)+(24))>>2)] = tempI64[0],HEAP32[(((buf)+(28))>>2)] = tempI64[1]);
- HEAP32[(((buf)+(32))>>2)] = 4096;
- HEAP32[(((buf)+(36))>>2)] = stat.blocks;
- var atime = stat.atime.getTime();
- var mtime = stat.mtime.getTime();
- var ctime = stat.ctime.getTime();
- (tempI64 = [Math.floor(atime / 1000)>>>0,(tempDouble=Math.floor(atime / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[(((buf)+(40))>>2)] = tempI64[0],HEAP32[(((buf)+(44))>>2)] = tempI64[1]);
- HEAPU32[(((buf)+(48))>>2)] = (atime % 1000) * 1000;
- (tempI64 = [Math.floor(mtime / 1000)>>>0,(tempDouble=Math.floor(mtime / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.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)] = (mtime % 1000) * 1000;
- (tempI64 = [Math.floor(ctime / 1000)>>>0,(tempDouble=Math.floor(ctime / 1000),(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.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)] = (ctime % 1000) * 1000;
- (tempI64 = [stat.ino>>>0,(tempDouble=stat.ino,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[(((buf)+(88))>>2)] = tempI64[0],HEAP32[(((buf)+(92))>>2)] = tempI64[1]);
- return 0;
- },
- doMsync(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() {
- assert(SYSCALLS.varargs != undefined);
- // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number.
- var ret = HEAP32[((+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;
- },
- };
- function ___syscall__newselect(nfds, readfds, writefds, exceptfds, timeout) {
- try {
-
- // readfds are supported,
- // writefds checks socket open status
- // exceptfds are supported, although on web, such exceptional conditions never arise in web sockets
- // and so the exceptfds list will always return empty.
- // timeout is supported, although on SOCKFS and PIPEFS these are ignored and always treated as 0 - fully async
- assert(nfds <= 64, 'nfds must be less than or equal to 64'); // fd sets have 64 bits // TODO: this could be 1024 based on current musl headers
-
- var total = 0;
-
- var srcReadLow = (readfds ? HEAP32[((readfds)>>2)] : 0),
- srcReadHigh = (readfds ? HEAP32[(((readfds)+(4))>>2)] : 0);
- var srcWriteLow = (writefds ? HEAP32[((writefds)>>2)] : 0),
- srcWriteHigh = (writefds ? HEAP32[(((writefds)+(4))>>2)] : 0);
- var srcExceptLow = (exceptfds ? HEAP32[((exceptfds)>>2)] : 0),
- srcExceptHigh = (exceptfds ? HEAP32[(((exceptfds)+(4))>>2)] : 0);
-
- var dstReadLow = 0,
- dstReadHigh = 0;
- var dstWriteLow = 0,
- dstWriteHigh = 0;
- var dstExceptLow = 0,
- dstExceptHigh = 0;
-
- var allLow = (readfds ? HEAP32[((readfds)>>2)] : 0) |
- (writefds ? HEAP32[((writefds)>>2)] : 0) |
- (exceptfds ? HEAP32[((exceptfds)>>2)] : 0);
- var allHigh = (readfds ? HEAP32[(((readfds)+(4))>>2)] : 0) |
- (writefds ? HEAP32[(((writefds)+(4))>>2)] : 0) |
- (exceptfds ? HEAP32[(((exceptfds)+(4))>>2)] : 0);
-
- var check = function(fd, low, high, val) {
- return (fd < 32 ? (low & val) : (high & val));
- };
-
- for (var fd = 0; fd < nfds; fd++) {
- var mask = 1 << (fd % 32);
- if (!(check(fd, allLow, allHigh, mask))) {
- continue; // index isn't in the set
- }
-
- var stream = SYSCALLS.getStreamFromFD(fd);
-
- var flags = SYSCALLS.DEFAULT_POLLMASK;
-
- if (stream.stream_ops.poll) {
- var timeoutInMillis = -1;
- if (timeout) {
- var tv_sec = (readfds ? HEAP32[((timeout)>>2)] : 0),
- tv_usec = (readfds ? HEAP32[(((timeout)+(8))>>2)] : 0);
- timeoutInMillis = (tv_sec + tv_usec / 1000000) * 1000;
- }
- flags = stream.stream_ops.poll(stream, timeoutInMillis);
- }
-
- if ((flags & 1) && check(fd, srcReadLow, srcReadHigh, mask)) {
- fd < 32 ? (dstReadLow = dstReadLow | mask) : (dstReadHigh = dstReadHigh | mask);
- total++;
- }
- if ((flags & 4) && check(fd, srcWriteLow, srcWriteHigh, mask)) {
- fd < 32 ? (dstWriteLow = dstWriteLow | mask) : (dstWriteHigh = dstWriteHigh | mask);
- total++;
- }
- if ((flags & 2) && check(fd, srcExceptLow, srcExceptHigh, mask)) {
- fd < 32 ? (dstExceptLow = dstExceptLow | mask) : (dstExceptHigh = dstExceptHigh | mask);
- total++;
- }
- }
-
- if (readfds) {
- HEAP32[((readfds)>>2)] = dstReadLow;
- HEAP32[(((readfds)+(4))>>2)] = dstReadHigh;
- }
- if (writefds) {
- HEAP32[((writefds)>>2)] = dstWriteLow;
- HEAP32[(((writefds)+(4))>>2)] = dstWriteHigh;
- }
- if (exceptfds) {
- HEAP32[((exceptfds)>>2)] = dstExceptLow;
- HEAP32[(((exceptfds)+(4))>>2)] = dstExceptHigh;
- }
-
- return total;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- var SOCKFS = {
- mount(mount) {
- // If Module['websocket'] has already been defined (e.g. for configuring
- // the subprotocol/url) use that, if not initialise it to a new object.
- Module['websocket'] = (Module['websocket'] &&
- ('object' === typeof Module['websocket'])) ? Module['websocket'] : {};
-
- // Add the Event registration mechanism to the exported websocket configuration
- // object so we can register network callbacks from native JavaScript too.
- // For more documentation see system/include/emscripten/emscripten.h
- Module['websocket']._callbacks = {};
- Module['websocket']['on'] = /** @this{Object} */ function(event, callback) {
- if ('function' === typeof callback) {
- this._callbacks[event] = callback;
- }
- return this;
- };
-
- Module['websocket'].emit = /** @this{Object} */ function(event, param) {
- if ('function' === typeof this._callbacks[event]) {
- this._callbacks[event].call(this, param);
- }
- };
-
- // If debug is enabled register simple default logging callbacks for each Event.
-
- return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
- },
- createSocket(family, type, protocol) {
- type &= ~526336; // Some applications may pass it; it makes no sense for a single process.
- var streaming = type == 1;
- if (streaming && protocol && protocol != 6) {
- throw new FS.ErrnoError(66); // if SOCK_STREAM, must be tcp or 0.
- }
-
- // create our internal socket structure
- var sock = {
- family,
- type,
- protocol,
- server: null,
- error: null, // Used in getsockopt for SOL_SOCKET/SO_ERROR test
- peers: {},
- pending: [],
- recv_queue: [],
- sock_ops: SOCKFS.websocket_sock_ops
- };
-
- // create the filesystem node to store the socket structure
- var name = SOCKFS.nextname();
- var node = FS.createNode(SOCKFS.root, name, 49152, 0);
- node.sock = sock;
-
- // and the wrapping stream that enables library functions such
- // as read and write to indirectly interact with the socket
- var stream = FS.createStream({
- path: name,
- node,
- flags: 2,
- seekable: false,
- stream_ops: SOCKFS.stream_ops
- });
-
- // map the new stream to the socket structure (sockets have a 1:1
- // relationship with a stream)
- sock.stream = stream;
-
- return sock;
- },
- getSocket(fd) {
- var stream = FS.getStream(fd);
- if (!stream || !FS.isSocket(stream.node.mode)) {
- return null;
- }
- return stream.node.sock;
- },
- stream_ops:{
- poll(stream) {
- var sock = stream.node.sock;
- return sock.sock_ops.poll(sock);
- },
- ioctl(stream, request, varargs) {
- var sock = stream.node.sock;
- return sock.sock_ops.ioctl(sock, request, varargs);
- },
- read(stream, buffer, offset, length, position /* ignored */) {
- var sock = stream.node.sock;
- var msg = sock.sock_ops.recvmsg(sock, length);
- if (!msg) {
- // socket is closed
- return 0;
- }
- buffer.set(msg.buffer, offset);
- return msg.buffer.length;
- },
- write(stream, buffer, offset, length, position /* ignored */) {
- var sock = stream.node.sock;
- return sock.sock_ops.sendmsg(sock, buffer, offset, length);
- },
- close(stream) {
- var sock = stream.node.sock;
- sock.sock_ops.close(sock);
- },
- },
- nextname() {
- if (!SOCKFS.nextname.current) {
- SOCKFS.nextname.current = 0;
- }
- return 'socket[' + (SOCKFS.nextname.current++) + ']';
- },
- websocket_sock_ops:{
- createPeer(sock, addr, port) {
- var ws;
-
- if (typeof addr == 'object') {
- ws = addr;
- addr = null;
- port = null;
- }
-
- if (ws) {
- // for sockets that've already connected (e.g. we're the server)
- // we can inspect the _socket property for the address
- if (ws._socket) {
- addr = ws._socket.remoteAddress;
- port = ws._socket.remotePort;
- }
- // if we're just now initializing a connection to the remote,
- // inspect the url property
- else {
- var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
- if (!result) {
- throw new Error('WebSocket URL must be in the format ws(s)://address:port');
- }
- addr = result[1];
- port = parseInt(result[2], 10);
- }
- } else {
- // create the actual websocket object and connect
- try {
- // runtimeConfig gets set to true if WebSocket runtime configuration is available.
- var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
-
- // The default value is 'ws://' the replace is needed because the compiler replaces '//' comments with '#'
- // comments without checking context, so we'd end up with ws:#, the replace swaps the '#' for '//' again.
- var url = 'ws:#'.replace('#', '//');
-
- if (runtimeConfig) {
- if ('string' === typeof Module['websocket']['url']) {
- url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
- }
- }
-
- if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
- var parts = addr.split('/');
- url = url + parts[0] + ":" + port + "/" + parts.slice(1).join('/');
- }
-
- // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
- var subProtocols = 'binary'; // The default value is 'binary'
-
- if (runtimeConfig) {
- if ('string' === typeof Module['websocket']['subprotocol']) {
- subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
- }
- }
-
- // The default WebSocket options
- var opts = undefined;
-
- if (subProtocols !== 'null') {
- // The regex trims the string (removes spaces at the beginning and end, then splits the string by
- // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
- subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
-
- opts = subProtocols;
- }
-
- // some webservers (azure) does not support subprotocol header
- if (runtimeConfig && null === Module['websocket']['subprotocol']) {
- subProtocols = 'null';
- opts = undefined;
- }
-
- // If node we use the ws library.
- var WebSocketConstructor;
- if (ENVIRONMENT_IS_NODE) {
- WebSocketConstructor = /** @type{(typeof WebSocket)} */(require('ws'));
- } else
- {
- WebSocketConstructor = WebSocket;
- }
- ws = new WebSocketConstructor(url, opts);
- ws.binaryType = 'arraybuffer';
- } catch (e) {
- throw new FS.ErrnoError(23);
- }
- }
-
- var peer = {
- addr,
- port,
- socket: ws,
- dgram_send_queue: []
- };
-
- SOCKFS.websocket_sock_ops.addPeer(sock, peer);
- SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
-
- // if this is a bound dgram socket, send the port number first to allow
- // us to override the ephemeral port reported to us by remotePort on the
- // remote end.
- if (sock.type === 2 && typeof sock.sport != 'undefined') {
- peer.dgram_send_queue.push(new Uint8Array([
- 255, 255, 255, 255,
- 'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
- ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
- ]));
- }
-
- return peer;
- },
- getPeer(sock, addr, port) {
- return sock.peers[addr + ':' + port];
- },
- addPeer(sock, peer) {
- sock.peers[peer.addr + ':' + peer.port] = peer;
- },
- removePeer(sock, peer) {
- delete sock.peers[peer.addr + ':' + peer.port];
- },
- handlePeerEvents(sock, peer) {
- var first = true;
-
- var handleOpen = function () {
-
- Module['websocket'].emit('open', sock.stream.fd);
-
- try {
- var queued = peer.dgram_send_queue.shift();
- while (queued) {
- peer.socket.send(queued);
- queued = peer.dgram_send_queue.shift();
- }
- } catch (e) {
- // not much we can do here in the way of proper error handling as we've already
- // lied and said this data was sent. shut it down.
- peer.socket.close();
- }
- };
-
- function handleMessage(data) {
- if (typeof data == 'string') {
- var encoder = new TextEncoder(); // should be utf-8
- data = encoder.encode(data); // make a typed array from the string
- } else {
- assert(data.byteLength !== undefined); // must receive an ArrayBuffer
- if (data.byteLength == 0) {
- // An empty ArrayBuffer will emit a pseudo disconnect event
- // as recv/recvmsg will return zero which indicates that a socket
- // has performed a shutdown although the connection has not been disconnected yet.
- return;
- }
- data = new Uint8Array(data); // make a typed array view on the array buffer
- }
-
- // if this is the port message, override the peer's port with it
- var wasfirst = first;
- first = false;
- if (wasfirst &&
- data.length === 10 &&
- data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
- data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
- // update the peer's port and it's key in the peer map
- var newport = ((data[8] << 8) | data[9]);
- SOCKFS.websocket_sock_ops.removePeer(sock, peer);
- peer.port = newport;
- SOCKFS.websocket_sock_ops.addPeer(sock, peer);
- return;
- }
-
- sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
- Module['websocket'].emit('message', sock.stream.fd);
- };
-
- if (ENVIRONMENT_IS_NODE) {
- peer.socket.on('open', handleOpen);
- peer.socket.on('message', function(data, isBinary) {
- if (!isBinary) {
- return;
- }
- handleMessage((new Uint8Array(data)).buffer); // copy from node Buffer -> ArrayBuffer
- });
- peer.socket.on('close', function() {
- Module['websocket'].emit('close', sock.stream.fd);
- });
- peer.socket.on('error', function(error) {
- // Although the ws library may pass errors that may be more descriptive than
- // ECONNREFUSED they are not necessarily the expected error code e.g.
- // ENOTFOUND on getaddrinfo seems to be node.js specific, so using ECONNREFUSED
- // is still probably the most useful thing to do.
- sock.error = 14; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
- Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']);
- // don't throw
- });
- } else {
- peer.socket.onopen = handleOpen;
- peer.socket.onclose = function() {
- Module['websocket'].emit('close', sock.stream.fd);
- };
- peer.socket.onmessage = function peer_socket_onmessage(event) {
- handleMessage(event.data);
- };
- peer.socket.onerror = function(error) {
- // The WebSocket spec only allows a 'simple event' to be thrown on error,
- // so we only really know as much as ECONNREFUSED.
- sock.error = 14; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
- Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']);
- };
- }
- },
- poll(sock) {
- if (sock.type === 1 && sock.server) {
- // listen sockets should only say they're available for reading
- // if there are pending clients.
- return sock.pending.length ? (64 | 1) : 0;
- }
-
- var mask = 0;
- var dest = sock.type === 1 ? // we only care about the socket state for connection-based sockets
- SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
- null;
-
- if (sock.recv_queue.length ||
- !dest || // connection-less sockets are always ready to read
- (dest && dest.socket.readyState === dest.socket.CLOSING) ||
- (dest && dest.socket.readyState === dest.socket.CLOSED)) { // let recv return 0 once closed
- mask |= (64 | 1);
- }
-
- if (!dest || // connection-less sockets are always ready to write
- (dest && dest.socket.readyState === dest.socket.OPEN)) {
- mask |= 4;
- }
-
- if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
- (dest && dest.socket.readyState === dest.socket.CLOSED)) {
- mask |= 16;
- }
-
- return mask;
- },
- ioctl(sock, request, arg) {
- switch (request) {
- case 21531:
- var bytes = 0;
- if (sock.recv_queue.length) {
- bytes = sock.recv_queue[0].data.length;
- }
- HEAP32[((arg)>>2)] = bytes;
- return 0;
- default:
- return 28;
- }
- },
- close(sock) {
- // if we've spawned a listen server, close it
- if (sock.server) {
- try {
- sock.server.close();
- } catch (e) {
- }
- sock.server = null;
- }
- // close any peer connections
- var peers = Object.keys(sock.peers);
- for (var i = 0; i < peers.length; i++) {
- var peer = sock.peers[peers[i]];
- try {
- peer.socket.close();
- } catch (e) {
- }
- SOCKFS.websocket_sock_ops.removePeer(sock, peer);
- }
- return 0;
- },
- bind(sock, addr, port) {
- if (typeof sock.saddr != 'undefined' || typeof sock.sport != 'undefined') {
- throw new FS.ErrnoError(28); // already bound
- }
- sock.saddr = addr;
- sock.sport = port;
- // in order to emulate dgram sockets, we need to launch a listen server when
- // binding on a connection-less socket
- // note: this is only required on the server side
- if (sock.type === 2) {
- // close the existing server if it exists
- if (sock.server) {
- sock.server.close();
- sock.server = null;
- }
- // swallow error operation not supported error that occurs when binding in the
- // browser where this isn't supported
- try {
- sock.sock_ops.listen(sock, 0);
- } catch (e) {
- if (!(e.name === 'ErrnoError')) throw e;
- if (e.errno !== 138) throw e;
- }
- }
- },
- connect(sock, addr, port) {
- if (sock.server) {
- throw new FS.ErrnoError(138);
- }
-
- // TODO autobind
- // if (!sock.addr && sock.type == 2) {
- // }
-
- // early out if we're already connected / in the middle of connecting
- if (typeof sock.daddr != 'undefined' && typeof sock.dport != 'undefined') {
- var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
- if (dest) {
- if (dest.socket.readyState === dest.socket.CONNECTING) {
- throw new FS.ErrnoError(7);
- } else {
- throw new FS.ErrnoError(30);
- }
- }
- }
-
- // add the socket to our peer list and set our
- // destination address / port to match
- var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
- sock.daddr = peer.addr;
- sock.dport = peer.port;
-
- // always "fail" in non-blocking mode
- throw new FS.ErrnoError(26);
- },
- listen(sock, backlog) {
- if (!ENVIRONMENT_IS_NODE) {
- throw new FS.ErrnoError(138);
- }
- if (sock.server) {
- throw new FS.ErrnoError(28); // already listening
- }
- var WebSocketServer = require('ws').Server;
- var host = sock.saddr;
- sock.server = new WebSocketServer({
- host,
- port: sock.sport
- // TODO support backlog
- });
- Module['websocket'].emit('listen', sock.stream.fd); // Send Event with listen fd.
-
- sock.server.on('connection', function(ws) {
- if (sock.type === 1) {
- var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
-
- // create a peer on the new socket
- var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
- newsock.daddr = peer.addr;
- newsock.dport = peer.port;
-
- // push to queue for accept to pick up
- sock.pending.push(newsock);
- Module['websocket'].emit('connection', newsock.stream.fd);
- } else {
- // create a peer on the listen socket so calling sendto
- // with the listen socket and an address will resolve
- // to the correct client
- SOCKFS.websocket_sock_ops.createPeer(sock, ws);
- Module['websocket'].emit('connection', sock.stream.fd);
- }
- });
- sock.server.on('close', function() {
- Module['websocket'].emit('close', sock.stream.fd);
- sock.server = null;
- });
- sock.server.on('error', function(error) {
- // Although the ws library may pass errors that may be more descriptive than
- // ECONNREFUSED they are not necessarily the expected error code e.g.
- // ENOTFOUND on getaddrinfo seems to be node.js specific, so using EHOSTUNREACH
- // is still probably the most useful thing to do. This error shouldn't
- // occur in a well written app as errors should get trapped in the compiled
- // app's own getaddrinfo call.
- sock.error = 23; // Used in getsockopt for SOL_SOCKET/SO_ERROR test.
- Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'EHOSTUNREACH: Host is unreachable']);
- // don't throw
- });
- },
- accept(listensock) {
- if (!listensock.server || !listensock.pending.length) {
- throw new FS.ErrnoError(28);
- }
- var newsock = listensock.pending.shift();
- newsock.stream.flags = listensock.stream.flags;
- return newsock;
- },
- getname(sock, peer) {
- var addr, port;
- if (peer) {
- if (sock.daddr === undefined || sock.dport === undefined) {
- throw new FS.ErrnoError(53);
- }
- addr = sock.daddr;
- port = sock.dport;
- } else {
- // TODO saddr and sport will be set for bind()'d UDP sockets, but what
- // should we be returning for TCP sockets that've been connect()'d?
- addr = sock.saddr || 0;
- port = sock.sport || 0;
- }
- return { addr, port };
- },
- sendmsg(sock, buffer, offset, length, addr, port) {
- if (sock.type === 2) {
- // connection-less sockets will honor the message address,
- // and otherwise fall back to the bound destination address
- if (addr === undefined || port === undefined) {
- addr = sock.daddr;
- port = sock.dport;
- }
- // if there was no address to fall back to, error out
- if (addr === undefined || port === undefined) {
- throw new FS.ErrnoError(17);
- }
- } else {
- // connection-based sockets will only use the bound
- addr = sock.daddr;
- port = sock.dport;
- }
-
- // find the peer for the destination address
- var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
-
- // early out if not connected with a connection-based socket
- if (sock.type === 1) {
- if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
- throw new FS.ErrnoError(53);
- } else if (dest.socket.readyState === dest.socket.CONNECTING) {
- throw new FS.ErrnoError(6);
- }
- }
-
- // create a copy of the incoming data to send, as the WebSocket API
- // doesn't work entirely with an ArrayBufferView, it'll just send
- // the entire underlying buffer
- if (ArrayBuffer.isView(buffer)) {
- offset += buffer.byteOffset;
- buffer = buffer.buffer;
- }
-
- var data;
- data = buffer.slice(offset, offset + length);
-
- // if we're emulating a connection-less dgram socket and don't have
- // a cached connection, queue the buffer to send upon connect and
- // lie, saying the data was sent now.
- if (sock.type === 2) {
- if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
- // if we're not connected, open a new connection
- if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
- dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
- }
- dest.dgram_send_queue.push(data);
- return length;
- }
- }
-
- try {
- // send the actual data
- dest.socket.send(data);
- return length;
- } catch (e) {
- throw new FS.ErrnoError(28);
- }
- },
- recvmsg(sock, length) {
- // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
- if (sock.type === 1 && sock.server) {
- // tcp servers should not be recv()'ing on the listen socket
- throw new FS.ErrnoError(53);
- }
-
- var queued = sock.recv_queue.shift();
- if (!queued) {
- if (sock.type === 1) {
- var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
-
- if (!dest) {
- // if we have a destination address but are not connected, error out
- throw new FS.ErrnoError(53);
- }
- if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
- // return null if the socket has closed
- return null;
- }
- // else, our socket is in a valid state but truly has nothing available
- throw new FS.ErrnoError(6);
- }
- throw new FS.ErrnoError(6);
- }
-
- // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
- // requeued TCP data it'll be an ArrayBufferView
- var queuedLength = queued.data.byteLength || queued.data.length;
- var queuedOffset = queued.data.byteOffset || 0;
- var queuedBuffer = queued.data.buffer || queued.data;
- var bytesRead = Math.min(length, queuedLength);
- var res = {
- buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
- addr: queued.addr,
- port: queued.port
- };
-
- // push back any unread data for TCP connections
- if (sock.type === 1 && bytesRead < queuedLength) {
- var bytesRemaining = queuedLength - bytesRead;
- queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
- sock.recv_queue.unshift(queued);
- }
-
- return res;
- },
- },
- };
-
- var getSocketFromFD = (fd) => {
- var socket = SOCKFS.getSocket(fd);
- if (!socket) throw new FS.ErrnoError(8);
- return socket;
- };
-
- var setErrNo = (value) => {
- HEAP32[((___errno_location())>>2)] = value;
- return value;
- };
- var Sockets = {
- BUFFER_SIZE:10240,
- MAX_BUFFER_SIZE:10485760,
- nextFd:1,
- fds:{
- },
- nextport:1,
- maxport:65535,
- peer:null,
- connections:{
- },
- portmap:{
- },
- localAddr:4261412874,
- addrPool:[33554442,50331658,67108874,83886090,100663306,117440522,134217738,150994954,167772170,184549386,201326602,218103818,234881034],
- };
-
- var inetPton4 = (str) => {
- var b = str.split('.');
- for (var i = 0; i < 4; i++) {
- var tmp = Number(b[i]);
- if (isNaN(tmp)) return null;
- b[i] = tmp;
- }
- return (b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24)) >>> 0;
- };
-
-
- /** @suppress {checkTypes} */
- var jstoi_q = (str) => parseInt(str);
- var inetPton6 = (str) => {
- var words;
- var w, offset, z, i;
- /* http://home.deds.nl/~aeron/regex/ */
- var valid6regx = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i
- var parts = [];
- if (!valid6regx.test(str)) {
- return null;
- }
- if (str === "::") {
- return [0, 0, 0, 0, 0, 0, 0, 0];
- }
- // Z placeholder to keep track of zeros when splitting the string on ":"
- if (str.startsWith("::")) {
- str = str.replace("::", "Z:"); // leading zeros case
- } else {
- str = str.replace("::", ":Z:");
- }
-
- if (str.indexOf(".") > 0) {
- // parse IPv4 embedded stress
- str = str.replace(new RegExp('[.]', 'g'), ":");
- words = str.split(":");
- words[words.length-4] = jstoi_q(words[words.length-4]) + jstoi_q(words[words.length-3])*256;
- words[words.length-3] = jstoi_q(words[words.length-2]) + jstoi_q(words[words.length-1])*256;
- words = words.slice(0, words.length-2);
- } else {
- words = str.split(":");
- }
-
- offset = 0; z = 0;
- for (w=0; w < words.length; w++) {
- if (typeof words[w] == 'string') {
- if (words[w] === 'Z') {
- // compressed zeros - write appropriate number of zero words
- for (z = 0; z < (8 - words.length+1); z++) {
- parts[w+z] = 0;
- }
- offset = z-1;
- } else {
- // parse hex to field to 16-bit value and write it in network byte-order
- parts[w+offset] = _htons(parseInt(words[w],16));
- }
- } else {
- // parsed IPv4 words
- parts[w+offset] = words[w];
- }
- }
- return [
- (parts[1] << 16) | parts[0],
- (parts[3] << 16) | parts[2],
- (parts[5] << 16) | parts[4],
- (parts[7] << 16) | parts[6]
- ];
- };
-
-
- /** @param {number=} addrlen */
- var writeSockaddr = (sa, family, addr, port, addrlen) => {
- switch (family) {
- case 2:
- addr = inetPton4(addr);
- zeroMemory(sa, 16);
- if (addrlen) {
- HEAP32[((addrlen)>>2)] = 16;
- }
- HEAP16[((sa)>>1)] = family;
- HEAP32[(((sa)+(4))>>2)] = addr;
- HEAP16[(((sa)+(2))>>1)] = _htons(port);
- break;
- case 10:
- addr = inetPton6(addr);
- zeroMemory(sa, 28);
- if (addrlen) {
- HEAP32[((addrlen)>>2)] = 28;
- }
- HEAP32[((sa)>>2)] = family;
- HEAP32[(((sa)+(8))>>2)] = addr[0];
- HEAP32[(((sa)+(12))>>2)] = addr[1];
- HEAP32[(((sa)+(16))>>2)] = addr[2];
- HEAP32[(((sa)+(20))>>2)] = addr[3];
- HEAP16[(((sa)+(2))>>1)] = _htons(port);
- break;
- default:
- return 5;
- }
- return 0;
- };
-
-
- var DNS = {
- address_map:{
- id:1,
- addrs:{
- },
- names:{
- },
- },
- lookup_name(name) {
- // If the name is already a valid ipv4 / ipv6 address, don't generate a fake one.
- var res = inetPton4(name);
- if (res !== null) {
- return name;
- }
- res = inetPton6(name);
- if (res !== null) {
- return name;
- }
-
- // See if this name is already mapped.
- var addr;
-
- if (DNS.address_map.addrs[name]) {
- addr = DNS.address_map.addrs[name];
- } else {
- var id = DNS.address_map.id++;
- assert(id < 65535, 'exceeded max address mappings of 65535');
-
- addr = '172.29.' + (id & 0xff) + '.' + (id & 0xff00);
-
- DNS.address_map.names[addr] = name;
- DNS.address_map.addrs[name] = addr;
- }
-
- return addr;
- },
- lookup_addr(addr) {
- if (DNS.address_map.names[addr]) {
- return DNS.address_map.names[addr];
- }
-
- return null;
- },
- };
-
- function ___syscall_accept4(fd, addr, addrlen, flags, d1, d2) {
- try {
-
- var sock = getSocketFromFD(fd);
- var newsock = sock.sock_ops.accept(sock);
- if (addr) {
- var errno = writeSockaddr(addr, newsock.family, DNS.lookup_name(newsock.daddr), newsock.dport, addrlen);
- assert(!errno);
- }
- return newsock.stream.fd;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
-
- var inetNtop4 = (addr) => {
- return (addr & 0xff) + '.' + ((addr >> 8) & 0xff) + '.' + ((addr >> 16) & 0xff) + '.' + ((addr >> 24) & 0xff)
- };
-
-
- var inetNtop6 = (ints) => {
- // ref: http://www.ietf.org/rfc/rfc2373.txt - section 2.5.4
- // Format for IPv4 compatible and mapped 128-bit IPv6 Addresses
- // 128-bits are split into eight 16-bit words
- // stored in network byte order (big-endian)
- // | 80 bits | 16 | 32 bits |
- // +-----------------------------------------------------------------+
- // | 10 bytes | 2 | 4 bytes |
- // +--------------------------------------+--------------------------+
- // + 5 words | 1 | 2 words |
- // +--------------------------------------+--------------------------+
- // |0000..............................0000|0000| IPv4 ADDRESS | (compatible)
- // +--------------------------------------+----+---------------------+
- // |0000..............................0000|FFFF| IPv4 ADDRESS | (mapped)
- // +--------------------------------------+----+---------------------+
- var str = "";
- var word = 0;
- var longest = 0;
- var lastzero = 0;
- var zstart = 0;
- var len = 0;
- var i = 0;
- var parts = [
- ints[0] & 0xffff,
- (ints[0] >> 16),
- ints[1] & 0xffff,
- (ints[1] >> 16),
- ints[2] & 0xffff,
- (ints[2] >> 16),
- ints[3] & 0xffff,
- (ints[3] >> 16)
- ];
-
- // Handle IPv4-compatible, IPv4-mapped, loopback and any/unspecified addresses
-
- var hasipv4 = true;
- var v4part = "";
- // check if the 10 high-order bytes are all zeros (first 5 words)
- for (i = 0; i < 5; i++) {
- if (parts[i] !== 0) { hasipv4 = false; break; }
- }
-
- if (hasipv4) {
- // low-order 32-bits store an IPv4 address (bytes 13 to 16) (last 2 words)
- v4part = inetNtop4(parts[6] | (parts[7] << 16));
- // IPv4-mapped IPv6 address if 16-bit value (bytes 11 and 12) == 0xFFFF (6th word)
- if (parts[5] === -1) {
- str = "::ffff:";
- str += v4part;
- return str;
- }
- // IPv4-compatible IPv6 address if 16-bit value (bytes 11 and 12) == 0x0000 (6th word)
- if (parts[5] === 0) {
- str = "::";
- //special case IPv6 addresses
- if (v4part === "0.0.0.0") v4part = ""; // any/unspecified address
- if (v4part === "0.0.0.1") v4part = "1";// loopback address
- str += v4part;
- return str;
- }
- }
-
- // Handle all other IPv6 addresses
-
- // first run to find the longest contiguous zero words
- for (word = 0; word < 8; word++) {
- if (parts[word] === 0) {
- if (word - lastzero > 1) {
- len = 0;
- }
- lastzero = word;
- len++;
- }
- if (len > longest) {
- longest = len;
- zstart = word - longest + 1;
- }
- }
-
- for (word = 0; word < 8; word++) {
- if (longest > 1) {
- // compress contiguous zeros - to produce "::"
- if (parts[word] === 0 && word >= zstart && word < (zstart + longest) ) {
- if (word === zstart) {
- str += ":";
- if (zstart === 0) str += ":"; //leading zeros case
- }
- continue;
- }
- }
- // converts 16-bit words from big-endian to little-endian before converting to hex string
- str += Number(_ntohs(parts[word] & 0xffff)).toString(16);
- str += word < 7 ? ":" : "";
- }
- return str;
- };
-
- var readSockaddr = (sa, salen) => {
- // family / port offsets are common to both sockaddr_in and sockaddr_in6
- var family = HEAP16[((sa)>>1)];
- var port = _ntohs(HEAPU16[(((sa)+(2))>>1)]);
- var addr;
-
- switch (family) {
- case 2:
- if (salen !== 16) {
- return { errno: 28 };
- }
- addr = HEAP32[(((sa)+(4))>>2)];
- addr = inetNtop4(addr);
- break;
- case 10:
- if (salen !== 28) {
- return { errno: 28 };
- }
- addr = [
- HEAP32[(((sa)+(8))>>2)],
- HEAP32[(((sa)+(12))>>2)],
- HEAP32[(((sa)+(16))>>2)],
- HEAP32[(((sa)+(20))>>2)]
- ];
- addr = inetNtop6(addr);
- break;
- default:
- return { errno: 5 };
- }
-
- return { family: family, addr: addr, port: port };
- };
-
-
- /** @param {boolean=} allowNull */
- var getSocketAddress = (addrp, addrlen, allowNull) => {
- if (allowNull && addrp === 0) return null;
- var info = readSockaddr(addrp, addrlen);
- if (info.errno) throw new FS.ErrnoError(info.errno);
- info.addr = DNS.lookup_addr(info.addr) || info.addr;
- return info;
- };
-
- function ___syscall_bind(fd, addr, addrlen, d1, d2, d3) {
- try {
-
- var sock = getSocketFromFD(fd);
- var info = getSocketAddress(addr, addrlen);
- sock.sock_ops.bind(sock, info.addr, info.port);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_chdir(path) {
- try {
-
- path = SYSCALLS.getStr(path);
- FS.chdir(path);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_chmod(path, mode) {
- try {
-
- path = SYSCALLS.getStr(path);
- FS.chmod(path, mode);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
-
- function ___syscall_connect(fd, addr, addrlen, d1, d2, d3) {
- try {
-
- var sock = getSocketFromFD(fd);
- var info = getSocketAddress(addr, addrlen);
- sock.sock_ops.connect(sock, info.addr, info.port);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_dup(fd) {
- try {
-
- var old = SYSCALLS.getStreamFromFD(fd);
- return FS.createStream(old).fd;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_dup3(fd, newfd, flags) {
- try {
-
- var old = SYSCALLS.getStreamFromFD(fd);
- assert(!flags);
- if (old.fd === newfd) return -28;
- var existing = FS.getStream(newfd);
- if (existing) FS.close(existing);
- return FS.createStream(old, newfd).fd;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_faccessat(dirfd, path, amode, flags) {
- try {
-
- path = SYSCALLS.getStr(path);
- assert(flags === 0);
- path = SYSCALLS.calculateAt(dirfd, path);
- if (amode & ~7) {
- // need a valid mode
- return -28;
- }
- var lookup = FS.lookupPath(path, { follow: true });
- var node = lookup.node;
- if (!node) {
- return -44;
- }
- var perms = '';
- if (amode & 4) perms += 'r';
- if (amode & 2) perms += 'w';
- if (amode & 1) perms += 'x';
- if (perms /* otherwise, they've just passed F_OK */ && FS.nodePermissions(node, perms)) {
- return -2;
- }
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_fchownat(dirfd, path, owner, group, flags) {
- try {
-
- path = SYSCALLS.getStr(path);
- var nofollow = flags & 256;
- flags = flags & (~256);
- assert(flags === 0);
- path = SYSCALLS.calculateAt(dirfd, path);
- (nofollow ? FS.lchown : FS.chown)(path, owner, group);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
- function ___syscall_fcntl64(fd, cmd, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- switch (cmd) {
- case 0: {
- var arg = SYSCALLS.get();
- if (arg < 0) {
- return -28;
- }
- while (FS.streams[arg]) {
- arg++;
- }
- var newStream;
- newStream = FS.createStream(stream, arg);
- return newStream.fd;
- }
- case 1:
- case 2:
- return 0; // FD_CLOEXEC makes no sense for a single process.
- case 3:
- return stream.flags;
- case 4: {
- var arg = SYSCALLS.get();
- stream.flags |= arg;
- return 0;
- }
- case 5: {
- var arg = SYSCALLS.getp();
- var offset = 0;
- // We're always unlocked.
- HEAP16[(((arg)+(offset))>>1)] = 2;
- return 0;
- }
- case 6:
- case 7:
- return 0; // Pretend that the locking is successful.
- case 16:
- case 8:
- return -28; // These are for sockets. We don't have them fully implemented yet.
- case 9:
- // musl trusts getown return values, due to a bug where they must be, as they overlap with errors. just return -1 here, so fcntl() returns that, and we set errno ourselves.
- setErrNo(28);
- return -1;
- default: {
- return -28;
- }
- }
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_fdatasync(fd) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- return 0; // we can't do anything synchronously; the in-memory FS is already synced to
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_fstat64(fd, buf) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- return SYSCALLS.doStat(FS.stat, stream.path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
- var convertI32PairToI53Checked = (lo, hi) => {
- assert(lo == (lo >>> 0) || lo == (lo|0)); // lo should either be a i32 or a u32
- assert(hi === (hi|0)); // hi should be a i32
- return ((hi + 0x200000) >>> 0 < 0x400001 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN;
- };
- function ___syscall_ftruncate64(fd,length_low, length_high) {
- var length = convertI32PairToI53Checked(length_low, length_high);;
-
-
- try {
-
- if (isNaN(length)) return 61;
- FS.ftruncate(fd, length);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- ;
- }
-
-
- var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
- assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
- return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
- };
-
- function ___syscall_getcwd(buf, size) {
- try {
-
- if (size === 0) return -28;
- var cwd = FS.cwd();
- var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
- if (size < cwdLengthInBytes) return -68;
- stringToUTF8(cwd, buf, size);
- return cwdLengthInBytes;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
- function ___syscall_getdents64(fd, dirp, count) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd)
- if (!stream.getdents) {
- stream.getdents = FS.readdir(stream.path);
- }
-
- var struct_size = 280;
- var pos = 0;
- var off = FS.llseek(stream, 0, 1);
-
- var idx = Math.floor(off / struct_size);
-
- while (idx < stream.getdents.length && pos + struct_size <= count) {
- var id;
- var type;
- var name = stream.getdents[idx];
- if (name === '.') {
- id = stream.node.id;
- type = 4; // DT_DIR
- }
- else if (name === '..') {
- var lookup = FS.lookupPath(stream.path, { parent: true });
- id = lookup.node.id;
- type = 4; // DT_DIR
- }
- else {
- var child = FS.lookupNode(stream.node, name);
- id = child.id;
- type = FS.isChrdev(child.mode) ? 2 : // DT_CHR, character device.
- FS.isDir(child.mode) ? 4 : // DT_DIR, directory.
- FS.isLink(child.mode) ? 10 : // DT_LNK, symbolic link.
- 8; // DT_REG, regular file.
- }
- assert(id);
- (tempI64 = [id>>>0,(tempDouble=id,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[((dirp + pos)>>2)] = tempI64[0],HEAP32[(((dirp + pos)+(4))>>2)] = tempI64[1]);
- (tempI64 = [(idx + 1) * struct_size>>>0,(tempDouble=(idx + 1) * struct_size,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[(((dirp + pos)+(8))>>2)] = tempI64[0],HEAP32[(((dirp + pos)+(12))>>2)] = tempI64[1]);
- HEAP16[(((dirp + pos)+(16))>>1)] = 280;
- HEAP8[(((dirp + pos)+(18))>>0)] = type;
- stringToUTF8(name, dirp + pos + 19, 256);
- pos += struct_size;
- idx += 1;
- }
- FS.llseek(stream, idx * struct_size, 0);
- return pos;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
-
-
- function ___syscall_getpeername(fd, addr, addrlen, d1, d2, d3) {
- try {
-
- var sock = getSocketFromFD(fd);
- if (!sock.daddr) {
- return -53; // The socket is not connected.
- }
- var errno = writeSockaddr(addr, sock.family, DNS.lookup_name(sock.daddr), sock.dport, addrlen);
- assert(!errno);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
-
-
- function ___syscall_getsockname(fd, addr, addrlen, d1, d2, d3) {
- try {
-
- var sock = getSocketFromFD(fd);
- // TODO: sock.saddr should never be undefined, see TODO in websocket_sock_ops.getname
- var errno = writeSockaddr(addr, sock.family, DNS.lookup_name(sock.saddr || '0.0.0.0'), sock.sport, addrlen);
- assert(!errno);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
- function ___syscall_getsockopt(fd, level, optname, optval, optlen, d1) {
- try {
-
- var sock = getSocketFromFD(fd);
- // Minimal getsockopt aimed at resolving https://github.com/emscripten-core/emscripten/issues/2211
- // so only supports SOL_SOCKET with SO_ERROR.
- if (level === 1) {
- if (optname === 4) {
- HEAP32[((optval)>>2)] = sock.error;
- HEAP32[((optlen)>>2)] = 4;
- sock.error = null; // Clear the error (The SO_ERROR option obtains and then clears this field).
- return 0;
- }
- }
- return -50; // The option is unknown at the level indicated.
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_ioctl(fd, op, varargs) {
- SYSCALLS.varargs = varargs;
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- switch (op) {
- case 21509: {
- if (!stream.tty) return -59;
- return 0;
- }
- case 21505: {
- if (!stream.tty) return -59;
- if (stream.tty.ops.ioctl_tcgets) {
- var termios = stream.tty.ops.ioctl_tcgets(stream);
- var argp = SYSCALLS.getp();
- HEAP32[((argp)>>2)] = termios.c_iflag || 0;
- HEAP32[(((argp)+(4))>>2)] = termios.c_oflag || 0;
- HEAP32[(((argp)+(8))>>2)] = termios.c_cflag || 0;
- HEAP32[(((argp)+(12))>>2)] = termios.c_lflag || 0;
- for (var i = 0; i < 32; i++) {
- HEAP8[(((argp + i)+(17))>>0)] = termios.c_cc[i] || 0;
- }
- return 0;
- }
- return 0;
- }
- case 21510:
- case 21511:
- case 21512: {
- if (!stream.tty) return -59;
- return 0; // no-op, not actually adjusting terminal settings
- }
- case 21506:
- case 21507:
- case 21508: {
- if (!stream.tty) return -59;
- if (stream.tty.ops.ioctl_tcsets) {
- var argp = SYSCALLS.getp();
- var c_iflag = HEAP32[((argp)>>2)];
- var c_oflag = HEAP32[(((argp)+(4))>>2)];
- var c_cflag = HEAP32[(((argp)+(8))>>2)];
- var c_lflag = HEAP32[(((argp)+(12))>>2)];
- var c_cc = []
- for (var i = 0; i < 32; i++) {
- c_cc.push(HEAP8[(((argp + i)+(17))>>0)]);
- }
- return stream.tty.ops.ioctl_tcsets(stream.tty, op, { c_iflag, c_oflag, c_cflag, c_lflag, c_cc });
- }
- return 0; // no-op, not actually adjusting terminal settings
- }
- case 21519: {
- if (!stream.tty) return -59;
- var argp = SYSCALLS.getp();
- HEAP32[((argp)>>2)] = 0;
- return 0;
- }
- case 21520: {
- if (!stream.tty) return -59;
- return -28; // not supported
- }
- case 21531: {
- var argp = SYSCALLS.getp();
- return FS.ioctl(stream, op, argp);
- }
- case 21523: {
- // TODO: in theory we should write to the winsize struct that gets
- // passed in, but for now musl doesn't read anything on it
- if (!stream.tty) return -59;
- if (stream.tty.ops.ioctl_tiocgwinsz) {
- var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty);
- var argp = SYSCALLS.getp();
- HEAP16[((argp)>>1)] = winsize[0];
- HEAP16[(((argp)+(2))>>1)] = winsize[1];
- }
- return 0;
- }
- case 21524: {
- // TODO: technically, this ioctl call should change the window size.
- // but, since emscripten doesn't have any concept of a terminal window
- // yet, we'll just silently throw it away as we do TIOCGWINSZ
- if (!stream.tty) return -59;
- return 0;
- }
- case 21515: {
- if (!stream.tty) return -59;
- return 0;
- }
- default: return -28; // not supported
- }
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
- function ___syscall_listen(fd, backlog) {
- try {
-
- var sock = getSocketFromFD(fd);
- sock.sock_ops.listen(sock, backlog);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_lstat64(path, buf) {
- try {
-
- path = SYSCALLS.getStr(path);
- return SYSCALLS.doStat(FS.lstat, path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_mkdirat(dirfd, path, mode) {
- try {
-
- path = SYSCALLS.getStr(path);
- path = SYSCALLS.calculateAt(dirfd, path);
- // remove a trailing slash, if one - /a/b/ has basename of '', but
- // we want to create b in the context of this function
- path = PATH.normalize(path);
- if (path[path.length-1] === '/') path = path.substr(0, path.length-1);
- FS.mkdir(path, mode, 0);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_newfstatat(dirfd, path, buf, flags) {
- try {
-
- path = SYSCALLS.getStr(path);
- var nofollow = flags & 256;
- var allowEmpty = flags & 4096;
- flags = flags & (~6400);
- assert(!flags, `unknown flags in __syscall_newfstatat: ${flags}`);
- path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
- return SYSCALLS.doStat(nofollow ? FS.lstat : FS.stat, path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_openat(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 PIPEFS = {
- BUCKET_BUFFER_SIZE:8192,
- mount(mount) {
- // Do not pollute the real root directory or its child nodes with pipes
- // Looks like it is OK to create another pseudo-root node not linked to the FS.root hierarchy this way
- return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
- },
- createPipe() {
- var pipe = {
- buckets: [],
- // refcnt 2 because pipe has a read end and a write end. We need to be
- // able to read from the read end after write end is closed.
- refcnt : 2,
- };
-
- pipe.buckets.push({
- buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
- offset: 0,
- roffset: 0
- });
-
- var rName = PIPEFS.nextname();
- var wName = PIPEFS.nextname();
- var rNode = FS.createNode(PIPEFS.root, rName, 4096, 0);
- var wNode = FS.createNode(PIPEFS.root, wName, 4096, 0);
-
- rNode.pipe = pipe;
- wNode.pipe = pipe;
-
- var readableStream = FS.createStream({
- path: rName,
- node: rNode,
- flags: 0,
- seekable: false,
- stream_ops: PIPEFS.stream_ops
- });
- rNode.stream = readableStream;
-
- var writableStream = FS.createStream({
- path: wName,
- node: wNode,
- flags: 1,
- seekable: false,
- stream_ops: PIPEFS.stream_ops
- });
- wNode.stream = writableStream;
-
- return {
- readable_fd: readableStream.fd,
- writable_fd: writableStream.fd
- };
- },
- stream_ops:{
- poll(stream) {
- var pipe = stream.node.pipe;
-
- if ((stream.flags & 2097155) === 1) {
- return (256 | 4);
- }
- if (pipe.buckets.length > 0) {
- for (var i = 0; i < pipe.buckets.length; i++) {
- var bucket = pipe.buckets[i];
- if (bucket.offset - bucket.roffset > 0) {
- return (64 | 1);
- }
- }
- }
-
- return 0;
- },
- ioctl(stream, request, varargs) {
- return 28;
- },
- fsync(stream) {
- return 28;
- },
- read(stream, buffer, offset, length, position /* ignored */) {
- var pipe = stream.node.pipe;
- var currentLength = 0;
-
- for (var i = 0; i < pipe.buckets.length; i++) {
- var bucket = pipe.buckets[i];
- currentLength += bucket.offset - bucket.roffset;
- }
-
- assert(buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer));
- var data = buffer.subarray(offset, offset + length);
-
- if (length <= 0) {
- return 0;
- }
- if (currentLength == 0) {
- // Behave as if the read end is always non-blocking
- throw new FS.ErrnoError(6);
- }
- var toRead = Math.min(currentLength, length);
-
- var totalRead = toRead;
- var toRemove = 0;
-
- for (var i = 0; i < pipe.buckets.length; i++) {
- var currBucket = pipe.buckets[i];
- var bucketSize = currBucket.offset - currBucket.roffset;
-
- if (toRead <= bucketSize) {
- var tmpSlice = currBucket.buffer.subarray(currBucket.roffset, currBucket.offset);
- if (toRead < bucketSize) {
- tmpSlice = tmpSlice.subarray(0, toRead);
- currBucket.roffset += toRead;
- } else {
- toRemove++;
- }
- data.set(tmpSlice);
- break;
- } else {
- var tmpSlice = currBucket.buffer.subarray(currBucket.roffset, currBucket.offset);
- data.set(tmpSlice);
- data = data.subarray(tmpSlice.byteLength);
- toRead -= tmpSlice.byteLength;
- toRemove++;
- }
- }
-
- if (toRemove && toRemove == pipe.buckets.length) {
- // Do not generate excessive garbage in use cases such as
- // write several bytes, read everything, write several bytes, read everything...
- toRemove--;
- pipe.buckets[toRemove].offset = 0;
- pipe.buckets[toRemove].roffset = 0;
- }
-
- pipe.buckets.splice(0, toRemove);
-
- return totalRead;
- },
- write(stream, buffer, offset, length, position /* ignored */) {
- var pipe = stream.node.pipe;
-
- assert(buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer));
- var data = buffer.subarray(offset, offset + length);
-
- var dataLen = data.byteLength;
- if (dataLen <= 0) {
- return 0;
- }
-
- var currBucket = null;
-
- if (pipe.buckets.length == 0) {
- currBucket = {
- buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
- offset: 0,
- roffset: 0
- };
- pipe.buckets.push(currBucket);
- } else {
- currBucket = pipe.buckets[pipe.buckets.length - 1];
- }
-
- assert(currBucket.offset <= PIPEFS.BUCKET_BUFFER_SIZE);
-
- var freeBytesInCurrBuffer = PIPEFS.BUCKET_BUFFER_SIZE - currBucket.offset;
- if (freeBytesInCurrBuffer >= dataLen) {
- currBucket.buffer.set(data, currBucket.offset);
- currBucket.offset += dataLen;
- return dataLen;
- } else if (freeBytesInCurrBuffer > 0) {
- currBucket.buffer.set(data.subarray(0, freeBytesInCurrBuffer), currBucket.offset);
- currBucket.offset += freeBytesInCurrBuffer;
- data = data.subarray(freeBytesInCurrBuffer, data.byteLength);
- }
-
- var numBuckets = (data.byteLength / PIPEFS.BUCKET_BUFFER_SIZE) | 0;
- var remElements = data.byteLength % PIPEFS.BUCKET_BUFFER_SIZE;
-
- for (var i = 0; i < numBuckets; i++) {
- var newBucket = {
- buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
- offset: PIPEFS.BUCKET_BUFFER_SIZE,
- roffset: 0
- };
- pipe.buckets.push(newBucket);
- newBucket.buffer.set(data.subarray(0, PIPEFS.BUCKET_BUFFER_SIZE));
- data = data.subarray(PIPEFS.BUCKET_BUFFER_SIZE, data.byteLength);
- }
-
- if (remElements > 0) {
- var newBucket = {
- buffer: new Uint8Array(PIPEFS.BUCKET_BUFFER_SIZE),
- offset: data.byteLength,
- roffset: 0
- };
- pipe.buckets.push(newBucket);
- newBucket.buffer.set(data);
- }
-
- return dataLen;
- },
- close(stream) {
- var pipe = stream.node.pipe;
- pipe.refcnt--;
- if (pipe.refcnt === 0) {
- pipe.buckets = null;
- }
- },
- },
- nextname() {
- if (!PIPEFS.nextname.current) {
- PIPEFS.nextname.current = 0;
- }
- return 'pipe[' + (PIPEFS.nextname.current++) + ']';
- },
- };
-
- function ___syscall_pipe(fdPtr) {
- try {
-
- if (fdPtr == 0) {
- throw new FS.ErrnoError(21);
- }
-
- var res = PIPEFS.createPipe();
-
- HEAP32[((fdPtr)>>2)] = res.readable_fd;
- HEAP32[(((fdPtr)+(4))>>2)] = res.writable_fd;
-
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_poll(fds, nfds, timeout) {
- try {
-
- var nonzero = 0;
- for (var i = 0; i < nfds; i++) {
- var pollfd = fds + 8 * i;
- var fd = HEAP32[((pollfd)>>2)];
- var events = HEAP16[(((pollfd)+(4))>>1)];
- var mask = 32;
- var stream = FS.getStream(fd);
- if (stream) {
- mask = SYSCALLS.DEFAULT_POLLMASK;
- if (stream.stream_ops.poll) {
- mask = stream.stream_ops.poll(stream, -1);
- }
- }
- mask &= events | 8 | 16;
- if (mask) nonzero++;
- HEAP16[(((pollfd)+(6))>>1)] = mask;
- }
- return nonzero;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
-
- function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
- try {
-
- path = SYSCALLS.getStr(path);
- path = SYSCALLS.calculateAt(dirfd, path);
- if (bufsize <= 0) return -28;
- var ret = FS.readlink(path);
-
- var len = Math.min(bufsize, lengthBytesUTF8(ret));
- var endChar = HEAP8[buf+len];
- stringToUTF8(ret, buf, bufsize+1);
- // readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)
- // stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.
- HEAP8[buf+len] = endChar;
- return len;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
-
-
- function ___syscall_recvfrom(fd, buf, len, flags, addr, addrlen) {
- try {
-
- var sock = getSocketFromFD(fd);
- var msg = sock.sock_ops.recvmsg(sock, len);
- if (!msg) return 0; // socket is closed
- if (addr) {
- var errno = writeSockaddr(addr, sock.family, DNS.lookup_name(msg.addr), msg.port, addrlen);
- assert(!errno);
- }
- HEAPU8.set(msg.buffer, buf);
- return msg.buffer.byteLength;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_renameat(olddirfd, oldpath, newdirfd, newpath) {
- try {
-
- oldpath = SYSCALLS.getStr(oldpath);
- newpath = SYSCALLS.getStr(newpath);
- oldpath = SYSCALLS.calculateAt(olddirfd, oldpath);
- newpath = SYSCALLS.calculateAt(newdirfd, newpath);
- FS.rename(oldpath, newpath);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_rmdir(path) {
- try {
-
- path = SYSCALLS.getStr(path);
- FS.rmdir(path);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
-
- function ___syscall_sendto(fd, message, length, flags, addr, addr_len) {
- try {
-
- var sock = getSocketFromFD(fd);
- var dest = getSocketAddress(addr, addr_len, true);
- if (!dest) {
- // send, no address provided
- return FS.write(sock.stream, HEAP8, message, length);
- }
- // sendto an address
- return sock.sock_ops.sendmsg(sock, HEAP8, message, length, dest.addr, dest.port);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
-
- function ___syscall_socket(domain, type, protocol) {
- try {
-
- var sock = SOCKFS.createSocket(domain, type, protocol);
- assert(sock.stream.fd < 64); // XXX ? select() assumes socket fd values are in 0..63
- return sock.stream.fd;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_stat64(path, buf) {
- try {
-
- path = SYSCALLS.getStr(path);
- return SYSCALLS.doStat(FS.stat, path, buf);
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_statfs64(path, size, buf) {
- try {
-
- path = SYSCALLS.getStr(path);
- assert(size === 64);
- // NOTE: None of the constants here are true. We're just returning safe and
- // sane values.
- HEAP32[(((buf)+(4))>>2)] = 4096;
- HEAP32[(((buf)+(40))>>2)] = 4096;
- HEAP32[(((buf)+(8))>>2)] = 1000000;
- HEAP32[(((buf)+(12))>>2)] = 500000;
- HEAP32[(((buf)+(16))>>2)] = 500000;
- HEAP32[(((buf)+(20))>>2)] = FS.nextInode;
- HEAP32[(((buf)+(24))>>2)] = 1000000;
- HEAP32[(((buf)+(28))>>2)] = 42;
- HEAP32[(((buf)+(44))>>2)] = 2; // ST_NOSUID
- HEAP32[(((buf)+(36))>>2)] = 255;
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_symlink(target, linkpath) {
- try {
-
- target = SYSCALLS.getStr(target);
- linkpath = SYSCALLS.getStr(linkpath);
- FS.symlink(target, linkpath);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- function ___syscall_unlinkat(dirfd, path, flags) {
- try {
-
- path = SYSCALLS.getStr(path);
- path = SYSCALLS.calculateAt(dirfd, path);
- if (flags === 0) {
- FS.unlink(path);
- } else if (flags === 512) {
- FS.rmdir(path);
- } else {
- abort('Invalid flags passed to unlinkat');
- }
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- var readI53FromI64 = (ptr) => {
- return HEAPU32[((ptr)>>2)] + HEAP32[(((ptr)+(4))>>2)] * 4294967296;
- };
-
- function ___syscall_utimensat(dirfd, path, times, flags) {
- try {
-
- path = SYSCALLS.getStr(path);
- assert(flags === 0);
- path = SYSCALLS.calculateAt(dirfd, path, true);
- if (!times) {
- var atime = Date.now();
- var mtime = atime;
- } else {
- var seconds = readI53FromI64(times);
- var nanoseconds = HEAP32[(((times)+(8))>>2)];
- atime = (seconds*1000) + (nanoseconds/(1000*1000));
- times += 16;
- seconds = readI53FromI64(times);
- nanoseconds = HEAP32[(((times)+(8))>>2)];
- mtime = (seconds*1000) + (nanoseconds/(1000*1000));
- }
- FS.utime(path, atime, mtime);
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- }
-
- var nowIsMonotonic = true;;
- var __emscripten_get_now_is_monotonic = () => nowIsMonotonic;
-
- var __emscripten_throw_longjmp = () => {
- throw Infinity;
- };
-
- function __gmtime_js(time_low, time_high,tmPtr) {
- var time = convertI32PairToI53Checked(time_low, time_high);;
-
-
- var date = new Date(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 isLeapYear = (year) => {
- return 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; // -1 since it's days since Jan 1
-
- return yday;
- };
-
- function __localtime_js(time_low, time_high,tmPtr) {
- var time = convertI32PairToI53Checked(time_low, time_high);;
-
-
- var date = new Date(time*1000);
- 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.getFullYear()-1900;
- HEAP32[(((tmPtr)+(24))>>2)] = date.getDay();
-
- var yday = ydayFromDate(date)|0;
- HEAP32[(((tmPtr)+(28))>>2)] = yday;
- HEAP32[(((tmPtr)+(36))>>2)] = -(date.getTimezoneOffset() * 60);
-
- // Attention: DST is in December in South, and some regions don't have DST at all.
- var start = new Date(date.getFullYear(), 0, 1);
- var summerOffset = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
- var winterOffset = start.getTimezoneOffset();
- var dst = (summerOffset != winterOffset && date.getTimezoneOffset() == Math.min(winterOffset, summerOffset))|0;
- HEAP32[(((tmPtr)+(32))>>2)] = dst;
- ;
- }
-
-
-
- var __mktime_js = function(tmPtr) {
-
- var ret = (() => {
- 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 = ydayFromDate(date)|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;
- })();
- return (setTempRet0((tempDouble=ret,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)), ret>>>0);
- };
-
-
-
-
-
-
- function __mmap_js(len,prot,flags,fd,offset_low, offset_high,allocated,addr) {
- var offset = convertI32PairToI53Checked(offset_low, offset_high);;
-
-
- try {
-
- if (isNaN(offset)) return 61;
- var stream = SYSCALLS.getStreamFromFD(fd);
- var res = FS.mmap(stream, len, offset, prot, flags);
- var ptr = res.ptr;
- HEAP32[((allocated)>>2)] = res.allocated;
- HEAPU32[((addr)>>2)] = ptr;
- return 0;
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- ;
- }
-
-
-
-
- function __munmap_js(addr,len,prot,flags,fd,offset_low, offset_high) {
- var offset = convertI32PairToI53Checked(offset_low, offset_high);;
-
-
- try {
-
- if (isNaN(offset)) return 61;
- var stream = SYSCALLS.getStreamFromFD(fd);
- if (prot & 2) {
- SYSCALLS.doMsync(addr, stream, len, flags, offset);
- }
- FS.munmap(stream);
- // implicitly return 0
- } catch (e) {
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
- return -e.errno;
- }
- ;
- }
-
- var timers = {
- };
-
- var handleException = (e) => {
- // Certain exception types we do not treat as errors since they are used for
- // internal control flow.
- // 1. ExitStatus, which is thrown by exit()
- // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
- // that wish to return to JS event loop.
- if (e instanceof ExitStatus || e == 'unwind') {
- return EXITSTATUS;
- }
- checkStackCookie();
- if (e instanceof WebAssembly.RuntimeError) {
- if (_emscripten_stack_get_current() <= 0) {
- err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)');
- }
- }
- quit_(1, e);
- };
-
-
- var _proc_exit = (code) => {
- EXITSTATUS = code;
- if (!keepRuntimeAlive()) {
- if (Module['onExit']) Module['onExit'](code);
- ABORT = true;
- }
- quit_(code, new ExitStatus(code));
- };
- /** @suppress {duplicate } */
- /** @param {boolean|number=} implicit */
- var exitJS = (status, implicit) => {
- EXITSTATUS = status;
-
- checkUnflushedContent();
-
- // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
- if (keepRuntimeAlive() && !implicit) {
- var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`;
- readyPromiseReject(msg);
- err(msg);
- }
-
- _proc_exit(status);
- };
- var _exit = exitJS;
-
- var maybeExit = () => {
- if (!keepRuntimeAlive()) {
- try {
- _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_get_now;
- // Modern environment where performance.now() is supported:
- // N.B. a shorter form "_emscripten_get_now = performance.now;" is
- // unfortunately not allowed even in current browsers (e.g. FF Nightly 75).
- _emscripten_get_now = () => performance.now();
- ;
- var __setitimer_js = (which, timeout_ms) => {
- // First, clear any existing timer.
- if (timers[which]) {
- clearTimeout(timers[which].id);
- delete timers[which];
- }
-
- // A timeout of zero simply cancels the current timeout so we have nothing
- // more to do.
- if (!timeout_ms) return 0;
-
- var id = setTimeout(() => {
- assert(which in timers);
- delete timers[which];
- callUserCallback(() => __emscripten_timeout(which, _emscripten_get_now()));
- }, timeout_ms);
- timers[which] = { id, timeout_ms };
- return 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) => {
- // TODO: Use (malleable) environment variables instead of system settings.
- 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
- HEAPU32[((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 = stringToNewUTF8(winterName);
- var summerNamePtr = stringToNewUTF8(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;
- }
- };
-
- var _abort = () => {
- abort('native code called abort()');
- };
-
- var _emscripten_date_now = () => Date.now();
-
- var _emscripten_err = (str) => err(UTF8ToString(str));
-
- var getHeapMax = () =>
- HEAPU8.length;
- var _emscripten_get_heap_max = () => getHeapMax();
-
-
- var _emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num);
-
-
- var abortOnCannotGrowMemory = (requestedSize) => {
- abort(`Cannot enlarge memory arrays to size ${requestedSize} bytes (OOM). Either (1) compile with -sINITIAL_MEMORY=X with X higher than the current value ${HEAP8.length}, (2) compile with -sALLOW_MEMORY_GROWTH which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -sABORTING_MALLOC=0`);
- };
- var _emscripten_resize_heap = (requestedSize) => {
- var oldSize = HEAPU8.length;
- // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
- requestedSize >>>= 0;
- abortOnCannotGrowMemory(requestedSize);
- };
-
- var ENV = {
- };
-
- var getExecutableName = () => {
- return thisProgram || './this.program';
- };
- var 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;
- };
-
- var stringToAscii = (str, buffer) => {
- 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 string
- HEAP8[((buffer)>>0)] = 0;
- };
-
- var _environ_get = (__environ, environ_buf) => {
- var bufSize = 0;
- getEnvStrings().forEach((string, i) => {
- var ptr = environ_buf + bufSize;
- HEAPU32[(((__environ)+(i*4))>>2)] = ptr;
- stringToAscii(string, ptr);
- bufSize += string.length + 1;
- });
- return 0;
- };
-
-
- var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
- var strings = getEnvStrings();
- HEAPU32[((penviron_count)>>2)] = strings.length;
- var bufSize = 0;
- strings.forEach((string) => bufSize += string.length + 1);
- HEAPU32[((penviron_buf_size)>>2)] = bufSize;
- return 0;
- };
-
-
- function _fd_close(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;
- }
- }
-
- function _fd_fdstat_get(fd, pbuf) {
- try {
-
- var rightsBase = 0;
- var rightsInheriting = 0;
- var flags = 0;
- {
- var stream = SYSCALLS.getStreamFromFD(fd);
- // All character devices are terminals (other things a Linux system would
- // assume is a character device, like the mouse, we have special APIs for).
- var type = stream.tty ? 2 :
- FS.isDir(stream.mode) ? 3 :
- FS.isLink(stream.mode) ? 7 :
- 4;
- }
- HEAP8[((pbuf)>>0)] = type;
- HEAP16[(((pbuf)+(2))>>1)] = flags;
- (tempI64 = [rightsBase>>>0,(tempDouble=rightsBase,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[(((pbuf)+(8))>>2)] = tempI64[0],HEAP32[(((pbuf)+(12))>>2)] = tempI64[1]);
- (tempI64 = [rightsInheriting>>>0,(tempDouble=rightsInheriting,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[(((pbuf)+(16))>>2)] = tempI64[0],HEAP32[(((pbuf)+(20))>>2)] = tempI64[1]);
- 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 = 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
- if (typeof offset !== 'undefined') {
- offset += curr;
- }
- }
- 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.name === 'ErrnoError')) throw e;
- return e.errno;
- }
- }
-
-
- function _fd_seek(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.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.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.name === 'ErrnoError')) throw e;
- return e.errno;
- }
- ;
- }
-
- function _fd_sync(fd) {
- try {
-
- var stream = SYSCALLS.getStreamFromFD(fd);
- if (stream.stream_ops && stream.stream_ops.fsync) {
- return stream.stream_ops.fsync(stream);
- }
- return 0; // we can't do anything synchronously; the in-memory FS is already synced to
- } 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 = 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;
- if (typeof offset !== 'undefined') {
- offset += 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.name === 'ErrnoError')) throw e;
- return e.errno;
- }
- }
-
-
-
-
-
-
-
-
-
-
- var _getaddrinfo = (node, service, hint, out) => {
- // Note getaddrinfo currently only returns a single addrinfo with ai_next defaulting to NULL. When NULL
- // hints are specified or ai_family set to AF_UNSPEC or ai_socktype or ai_protocol set to 0 then we
- // really should provide a linked list of suitable addrinfo values.
- var addrs = [];
- var canon = null;
- var addr = 0;
- var port = 0;
- var flags = 0;
- var family = 0;
- var type = 0;
- var proto = 0;
- var ai, last;
-
- function allocaddrinfo(family, type, proto, canon, addr, port) {
- var sa, salen, ai;
- var errno;
-
- salen = family === 10 ?
- 28 :
- 16;
- addr = family === 10 ?
- inetNtop6(addr) :
- inetNtop4(addr);
- sa = _malloc(salen);
- errno = writeSockaddr(sa, family, addr, port);
- assert(!errno);
-
- ai = _malloc(32);
- HEAP32[(((ai)+(4))>>2)] = family;
- HEAP32[(((ai)+(8))>>2)] = type;
- HEAP32[(((ai)+(12))>>2)] = proto;
- HEAPU32[(((ai)+(24))>>2)] = canon;
- HEAPU32[(((ai)+(20))>>2)] = sa;
- if (family === 10) {
- HEAP32[(((ai)+(16))>>2)] = 28;
- } else {
- HEAP32[(((ai)+(16))>>2)] = 16;
- }
- HEAP32[(((ai)+(28))>>2)] = 0;
-
- return ai;
- }
-
- if (hint) {
- flags = HEAP32[((hint)>>2)];
- family = HEAP32[(((hint)+(4))>>2)];
- type = HEAP32[(((hint)+(8))>>2)];
- proto = HEAP32[(((hint)+(12))>>2)];
- }
- if (type && !proto) {
- proto = type === 2 ? 17 : 6;
- }
- if (!type && proto) {
- type = proto === 17 ? 2 : 1;
- }
-
- // If type or proto are set to zero in hints we should really be returning multiple addrinfo values, but for
- // now default to a TCP STREAM socket so we can at least return a sensible addrinfo given NULL hints.
- if (proto === 0) {
- proto = 6;
- }
- if (type === 0) {
- type = 1;
- }
-
- if (!node && !service) {
- return -2;
- }
- if (flags & ~(1|2|4|
- 1024|8|16|32)) {
- return -1;
- }
- if (hint !== 0 && (HEAP32[((hint)>>2)] & 2) && !node) {
- return -1;
- }
- if (flags & 32) {
- // TODO
- return -2;
- }
- if (type !== 0 && type !== 1 && type !== 2) {
- return -7;
- }
- if (family !== 0 && family !== 2 && family !== 10) {
- return -6;
- }
-
- if (service) {
- service = UTF8ToString(service);
- port = parseInt(service, 10);
-
- if (isNaN(port)) {
- if (flags & 1024) {
- return -2;
- }
- // TODO support resolving well-known service names from:
- // http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
- return -8;
- }
- }
-
- if (!node) {
- if (family === 0) {
- family = 2;
- }
- if ((flags & 1) === 0) {
- if (family === 2) {
- addr = _htonl(2130706433);
- } else {
- addr = [0, 0, 0, 1];
- }
- }
- ai = allocaddrinfo(family, type, proto, null, addr, port);
- HEAPU32[((out)>>2)] = ai;
- return 0;
- }
-
- //
- // try as a numeric address
- //
- node = UTF8ToString(node);
- addr = inetPton4(node);
- if (addr !== null) {
- // incoming node is a valid ipv4 address
- if (family === 0 || family === 2) {
- family = 2;
- }
- else if (family === 10 && (flags & 8)) {
- addr = [0, 0, _htonl(0xffff), addr];
- family = 10;
- } else {
- return -2;
- }
- } else {
- addr = inetPton6(node);
- if (addr !== null) {
- // incoming node is a valid ipv6 address
- if (family === 0 || family === 10) {
- family = 10;
- } else {
- return -2;
- }
- }
- }
- if (addr != null) {
- ai = allocaddrinfo(family, type, proto, node, addr, port);
- HEAPU32[((out)>>2)] = ai;
- return 0;
- }
- if (flags & 4) {
- return -2;
- }
-
- //
- // try as a hostname
- //
- // resolve the hostname to a temporary fake address
- node = DNS.lookup_name(node);
- addr = inetPton4(node);
- if (family === 0) {
- family = 2;
- } else if (family === 10) {
- addr = [0, 0, _htonl(0xffff), addr];
- }
- ai = allocaddrinfo(family, type, proto, null, addr, port);
- HEAPU32[((out)>>2)] = ai;
- return 0;
- };
-
- /** @type {function(...*):?} */
- function _getcontext(
- ) {
- abort('missing function: getcontext');
- }
- _getcontext.stub = true;
-
- /** @type {function(...*):?} */
- function _getdtablesize(
- ) {
- abort('missing function: getdtablesize');
- }
- _getdtablesize.stub = true;
-
-
-
-
- var getHostByName = (name) => {
- // generate hostent
- var ret = _malloc(20); // XXX possibly leaked, as are others here
- var nameBuf = stringToNewUTF8(name);
- HEAPU32[((ret)>>2)] = nameBuf;
- var aliasesBuf = _malloc(4);
- HEAPU32[((aliasesBuf)>>2)] = 0;
- HEAPU32[(((ret)+(4))>>2)] = aliasesBuf;
- var afinet = 2;
- HEAP32[(((ret)+(8))>>2)] = afinet;
- HEAP32[(((ret)+(12))>>2)] = 4;
- var addrListBuf = _malloc(12);
- HEAPU32[((addrListBuf)>>2)] = addrListBuf+8;
- HEAPU32[(((addrListBuf)+(4))>>2)] = 0;
- HEAP32[(((addrListBuf)+(8))>>2)] = inetPton4(DNS.lookup_name(name));
- HEAPU32[(((ret)+(16))>>2)] = addrListBuf;
- return ret;
- };
-
- var _gethostbyname = (name) => {
- return getHostByName(UTF8ToString(name));
- };
-
-
- var _gethostbyname_r = (name, ret, buf, buflen, out, err) => {
- var data = _gethostbyname(name);
- _memcpy(ret, data, 20);
- _free(data);
- HEAP32[((err)>>2)] = 0;
- HEAPU32[((out)>>2)] = ret;
- return 0;
- };
-
-
-
-
- var _getnameinfo = (sa, salen, node, nodelen, serv, servlen, flags) => {
- var info = readSockaddr(sa, salen);
- if (info.errno) {
- return -6;
- }
- var port = info.port;
- var addr = info.addr;
-
- var overflowed = false;
-
- if (node && nodelen) {
- var lookup;
- if ((flags & 1) || !(lookup = DNS.lookup_addr(addr))) {
- if (flags & 8) {
- return -2;
- }
- } else {
- addr = lookup;
- }
- var numBytesWrittenExclNull = stringToUTF8(addr, node, nodelen);
-
- if (numBytesWrittenExclNull+1 >= nodelen) {
- overflowed = true;
- }
- }
-
- if (serv && servlen) {
- port = '' + port;
- var numBytesWrittenExclNull = stringToUTF8(port, serv, servlen);
-
- if (numBytesWrittenExclNull+1 >= servlen) {
- overflowed = true;
- }
- }
-
- if (overflowed) {
- // Note: even when we overflow, getnameinfo() is specced to write out the truncated results.
- return -12;
- }
-
- return 0;
- };
-
- var Protocols = {
- list:[],
- map:{
- },
- };
-
-
- var _setprotoent = (stayopen) => {
- // void setprotoent(int stayopen);
-
- // Allocate and populate a protoent structure given a name, protocol number and array of aliases
- function allocprotoent(name, proto, aliases) {
- // write name into buffer
- var nameBuf = _malloc(name.length + 1);
- stringToAscii(name, nameBuf);
-
- // write aliases into buffer
- var j = 0;
- var length = aliases.length;
- var aliasListBuf = _malloc((length + 1) * 4); // Use length + 1 so we have space for the terminating NULL ptr.
-
- for (var i = 0; i < length; i++, j += 4) {
- var alias = aliases[i];
- var aliasBuf = _malloc(alias.length + 1);
- stringToAscii(alias, aliasBuf);
- HEAPU32[(((aliasListBuf)+(j))>>2)] = aliasBuf;
- }
- HEAPU32[(((aliasListBuf)+(j))>>2)] = 0; // Terminating NULL pointer.
-
- // generate protoent
- var pe = _malloc(12);
- HEAPU32[((pe)>>2)] = nameBuf;
- HEAPU32[(((pe)+(4))>>2)] = aliasListBuf;
- HEAP32[(((pe)+(8))>>2)] = proto;
- return pe;
- };
-
- // Populate the protocol 'database'. The entries are limited to tcp and udp, though it is fairly trivial
- // to add extra entries from /etc/protocols if desired - though not sure if that'd actually be useful.
- var list = Protocols.list;
- var map = Protocols.map;
- if (list.length === 0) {
- var entry = allocprotoent('tcp', 6, ['TCP']);
- list.push(entry);
- map['tcp'] = map['6'] = entry;
- entry = allocprotoent('udp', 17, ['UDP']);
- list.push(entry);
- map['udp'] = map['17'] = entry;
- }
-
- _setprotoent.index = 0;
- };
-
-
- var _getprotobyname = (name) => {
- // struct protoent *getprotobyname(const char *);
- name = UTF8ToString(name);
- _setprotoent(true);
- var result = Protocols.map[name];
- return result;
- };
-
-
- var _getprotobynumber = (number) => {
- // struct protoent *getprotobynumber(int proto);
- _setprotoent(true);
- var result = Protocols.map[number];
- return result;
- };
-
- /** @type {function(...*):?} */
- function _makecontext(
- ) {
- abort('missing function: makecontext');
- }
- _makecontext.stub = true;
-
-
-
- var 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];
- 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()) {
- // 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;
- };
-
-
-
-
- var writeArrayToMemory = (array, buffer) => {
- assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
- HEAP8.set(array, buffer);
- };
-
- var _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 = HEAPU32[(((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 <space> characters.
- '%Oe': '%e', // Replaced by the day of the month, using the locale's alternative numeric symbols, filled as needed with leading <space> 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': (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) => {
- // %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': (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) => {
- // 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': (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) => {
- // 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': (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) => {
- // 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);
- },
- // Replaced by the year as a decimal number (for example, 1997). [ tm_year]
- '%Y': (date) => date.tm_year+1900,
- '%z': (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': (date) => date.tm_zone,
- '%%': () => '%'
- };
-
- // 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;
- };
-
-
-
-
-
-
-
-
- var _strptime = (buf, format, tm) => {
- // char *strptime(const char *restrict buf, const char *restrict format, struct tm *restrict tm);
- // http://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
- var pattern = UTF8ToString(format);
-
- // escape special characters
- // TODO: not sure we really need to escape all of these in JS regexps
- var SPECIAL_CHARS = '\\!@#$^&*()+=-[]/{}|:<>?,.';
- for (var i=0, ii=SPECIAL_CHARS.length; i<ii; ++i) {
- pattern = pattern.replace(new RegExp('\\'+SPECIAL_CHARS[i], 'g'), '\\'+SPECIAL_CHARS[i]);
- }
-
- // reduce number of matchers
- var EQUIVALENT_MATCHERS = {
- '%A': '%a',
- '%B': '%b',
- '%c': '%a %b %d %H:%M:%S %Y',
- '%D': '%m\\/%d\\/%y',
- '%e': '%d',
- '%F': '%Y-%m-%d',
- '%h': '%b',
- '%R': '%H\\:%M',
- '%r': '%I\\:%M\\:%S\\s%p',
- '%T': '%H\\:%M\\:%S',
- '%x': '%m\\/%d\\/(?:%y|%Y)',
- '%X': '%H\\:%M\\:%S'
- };
- for (var matcher in EQUIVALENT_MATCHERS) {
- pattern = pattern.replace(matcher, EQUIVALENT_MATCHERS[matcher]);
- }
-
- // TODO: take care of locale
-
- var DATE_PATTERNS = {
- /* weeday name */ '%a': '(?:Sun(?:day)?)|(?:Mon(?:day)?)|(?:Tue(?:sday)?)|(?:Wed(?:nesday)?)|(?:Thu(?:rsday)?)|(?:Fri(?:day)?)|(?:Sat(?:urday)?)',
- /* month name */ '%b': '(?:Jan(?:uary)?)|(?:Feb(?:ruary)?)|(?:Mar(?:ch)?)|(?:Apr(?:il)?)|May|(?:Jun(?:e)?)|(?:Jul(?:y)?)|(?:Aug(?:ust)?)|(?:Sep(?:tember)?)|(?:Oct(?:ober)?)|(?:Nov(?:ember)?)|(?:Dec(?:ember)?)',
- /* century */ '%C': '\\d\\d',
- /* day of month */ '%d': '0[1-9]|[1-9](?!\\d)|1\\d|2\\d|30|31',
- /* hour (24hr) */ '%H': '\\d(?!\\d)|[0,1]\\d|20|21|22|23',
- /* hour (12hr) */ '%I': '\\d(?!\\d)|0\\d|10|11|12',
- /* day of year */ '%j': '00[1-9]|0?[1-9](?!\\d)|0?[1-9]\\d(?!\\d)|[1,2]\\d\\d|3[0-6]\\d',
- /* month */ '%m': '0[1-9]|[1-9](?!\\d)|10|11|12',
- /* minutes */ '%M': '0\\d|\\d(?!\\d)|[1-5]\\d',
- /* whitespace */ '%n': '\\s',
- /* AM/PM */ '%p': 'AM|am|PM|pm|A\\.M\\.|a\\.m\\.|P\\.M\\.|p\\.m\\.',
- /* seconds */ '%S': '0\\d|\\d(?!\\d)|[1-5]\\d|60',
- /* week number */ '%U': '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53',
- /* week number */ '%W': '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53',
- /* weekday number */ '%w': '[0-6]',
- /* 2-digit year */ '%y': '\\d\\d',
- /* 4-digit year */ '%Y': '\\d\\d\\d\\d',
- /* % */ '%%': '%',
- /* whitespace */ '%t': '\\s',
- };
-
- var MONTH_NUMBERS = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};
- var DAY_NUMBERS_SUN_FIRST = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};
- var DAY_NUMBERS_MON_FIRST = {MON: 0, TUE: 1, WED: 2, THU: 3, FRI: 4, SAT: 5, SUN: 6};
-
- for (var datePattern in DATE_PATTERNS) {
- pattern = pattern.replace(datePattern, '('+datePattern+DATE_PATTERNS[datePattern]+')');
- }
-
- // take care of capturing groups
- var capture = [];
- for (var i=pattern.indexOf('%'); i>=0; i=pattern.indexOf('%')) {
- capture.push(pattern[i+1]);
- pattern = pattern.replace(new RegExp('\\%'+pattern[i+1], 'g'), '');
- }
-
- var matches = new RegExp('^'+pattern, "i").exec(UTF8ToString(buf))
- // out(UTF8ToString(buf)+ ' is matched by '+((new RegExp('^'+pattern)).source)+' into: '+JSON.stringify(matches));
-
- function initDate() {
- function fixup(value, min, max) {
- return (typeof value != 'number' || isNaN(value)) ? min : (value>=min ? (value<=max ? value: max): min);
- };
- return {
- year: fixup(HEAP32[(((tm)+(20))>>2)] + 1900 , 1970, 9999),
- month: fixup(HEAP32[(((tm)+(16))>>2)], 0, 11),
- day: fixup(HEAP32[(((tm)+(12))>>2)], 1, 31),
- hour: fixup(HEAP32[(((tm)+(8))>>2)], 0, 23),
- min: fixup(HEAP32[(((tm)+(4))>>2)], 0, 59),
- sec: fixup(HEAP32[((tm)>>2)], 0, 59)
- };
- };
-
- if (matches) {
- var date = initDate();
- var value;
-
- var getMatch = (symbol) => {
- var pos = capture.indexOf(symbol);
- // check if symbol appears in regexp
- if (pos >= 0) {
- // return matched value or null (falsy!) for non-matches
- return matches[pos+1];
- }
- return;
- };
-
- // seconds
- if ((value=getMatch('S'))) {
- date.sec = jstoi_q(value);
- }
-
- // minutes
- if ((value=getMatch('M'))) {
- date.min = jstoi_q(value);
- }
-
- // hours
- if ((value=getMatch('H'))) {
- // 24h clock
- date.hour = jstoi_q(value);
- } else if ((value = getMatch('I'))) {
- // AM/PM clock
- var hour = jstoi_q(value);
- if ((value=getMatch('p'))) {
- hour += value.toUpperCase()[0] === 'P' ? 12 : 0;
- }
- date.hour = hour;
- }
-
- // year
- if ((value=getMatch('Y'))) {
- // parse from four-digit year
- date.year = jstoi_q(value);
- } else if ((value=getMatch('y'))) {
- // parse from two-digit year...
- var year = jstoi_q(value);
- if ((value=getMatch('C'))) {
- // ...and century
- year += jstoi_q(value)*100;
- } else {
- // ...and rule-of-thumb
- year += year<69 ? 2000 : 1900;
- }
- date.year = year;
- }
-
- // month
- if ((value=getMatch('m'))) {
- // parse from month number
- date.month = jstoi_q(value)-1;
- } else if ((value=getMatch('b'))) {
- // parse from month name
- date.month = MONTH_NUMBERS[value.substring(0,3).toUpperCase()] || 0;
- // TODO: derive month from day in year+year, week number+day of week+year
- }
-
- // day
- if ((value=getMatch('d'))) {
- // get day of month directly
- date.day = jstoi_q(value);
- } else if ((value=getMatch('j'))) {
- // get day of month from day of year ...
- var day = jstoi_q(value);
- var leapYear = isLeapYear(date.year);
- for (var month=0; month<12; ++month) {
- var daysUntilMonth = arraySum(leapYear ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR, month-1);
- if (day<=daysUntilMonth+(leapYear ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR)[month]) {
- date.day = day-daysUntilMonth;
- }
- }
- } else if ((value=getMatch('a'))) {
- // get day of month from weekday ...
- var weekDay = value.substring(0,3).toUpperCase();
- if ((value=getMatch('U'))) {
- // ... and week number (Sunday being first day of week)
- // Week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
- // All days in a new year preceding the first Sunday are considered to be in week 0.
- var weekDayNumber = DAY_NUMBERS_SUN_FIRST[weekDay];
- var weekNumber = jstoi_q(value);
-
- // January 1st
- var janFirst = new Date(date.year, 0, 1);
- var endDate;
- if (janFirst.getDay() === 0) {
- // Jan 1st is a Sunday, and, hence in the 1st CW
- endDate = addDays(janFirst, weekDayNumber+7*(weekNumber-1));
- } else {
- // Jan 1st is not a Sunday, and, hence still in the 0th CW
- endDate = addDays(janFirst, 7-janFirst.getDay()+weekDayNumber+7*(weekNumber-1));
- }
- date.day = endDate.getDate();
- date.month = endDate.getMonth();
- } else if ((value=getMatch('W'))) {
- // ... and week number (Monday being first day of week)
- // Week number of the year (Monday as the first day of the week) as a decimal number [00,53].
- // All days in a new year preceding the first Monday are considered to be in week 0.
- var weekDayNumber = DAY_NUMBERS_MON_FIRST[weekDay];
- var weekNumber = jstoi_q(value);
-
- // January 1st
- var janFirst = new Date(date.year, 0, 1);
- var endDate;
- if (janFirst.getDay()===1) {
- // Jan 1st is a Monday, and, hence in the 1st CW
- endDate = addDays(janFirst, weekDayNumber+7*(weekNumber-1));
- } else {
- // Jan 1st is not a Monday, and, hence still in the 0th CW
- endDate = addDays(janFirst, 7-janFirst.getDay()+1+weekDayNumber+7*(weekNumber-1));
- }
-
- date.day = endDate.getDate();
- date.month = endDate.getMonth();
- }
- }
-
- /*
- tm_sec int seconds after the minute 0-61*
- tm_min int minutes after the hour 0-59
- tm_hour int hours since midnight 0-23
- tm_mday int day of the month 1-31
- tm_mon int months since January 0-11
- tm_year int years since 1900
- tm_wday int days since Sunday 0-6
- tm_yday int days since January 1 0-365
- tm_isdst int Daylight Saving Time flag
- */
-
- var fullDate = new Date(date.year, date.month, date.day, date.hour, date.min, date.sec, 0);
- HEAP32[((tm)>>2)] = fullDate.getSeconds();
- HEAP32[(((tm)+(4))>>2)] = fullDate.getMinutes();
- HEAP32[(((tm)+(8))>>2)] = fullDate.getHours();
- HEAP32[(((tm)+(12))>>2)] = fullDate.getDate();
- HEAP32[(((tm)+(16))>>2)] = fullDate.getMonth();
- HEAP32[(((tm)+(20))>>2)] = fullDate.getFullYear()-1900;
- HEAP32[(((tm)+(24))>>2)] = fullDate.getDay();
- HEAP32[(((tm)+(28))>>2)] = arraySum(isLeapYear(fullDate.getFullYear()) ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1;
- HEAP32[(((tm)+(32))>>2)] = 0;
-
- // we need to convert the matched sequence into an integer array to take care of UTF-8 characters > 0x7F
- // TODO: not sure that intArrayFromString handles all unicode characters correctly
- return buf+intArrayFromString(matches[0]).length-1;
- }
-
- return 0;
- };
-
- /** @type {function(...*):?} */
- function _swapcontext(
- ) {
- abort('missing function: swapcontext');
- }
- _swapcontext.stub = true;
-
-
- var getCFunc = (ident) => {
- var func = Module['_' + ident]; // closure exported function
- assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
- return func;
- };
-
-
-
- var stringToUTF8OnStack = (str) => {
- var size = lengthBytesUTF8(str) + 1;
- var ret = stackAlloc(size);
- stringToUTF8(str, ret, size);
- return ret;
- };
-
-
- /**
- * @param {string|null=} returnType
- * @param {Array=} argTypes
- * @param {Arguments|Array=} args
- * @param {Object=} opts
- */
- var ccall = (ident, returnType, argTypes, args, opts) => {
- // For fast lookup of conversion functions
- var toC = {
- 'string': (str) => {
- var ret = 0;
- if (str !== null && str !== undefined && str !== 0) { // null string
- // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
- ret = stringToUTF8OnStack(str);
- }
- return ret;
- },
- 'array': (arr) => {
- var ret = stackAlloc(arr.length);
- writeArrayToMemory(arr, ret);
- return ret;
- }
- };
-
- function convertReturnValue(ret) {
- if (returnType === 'string') {
-
- return UTF8ToString(ret);
- }
- if (returnType === 'boolean') return Boolean(ret);
- return ret;
- }
-
- var func = getCFunc(ident);
- var cArgs = [];
- var stack = 0;
- assert(returnType !== 'array', 'Return type should not be "array".');
- if (args) {
- for (var i = 0; i < args.length; i++) {
- var converter = toC[argTypes[i]];
- if (converter) {
- if (stack === 0) stack = stackSave();
- cArgs[i] = converter(args[i]);
- } else {
- cArgs[i] = args[i];
- }
- }
- }
- var ret = func.apply(null, cArgs);
- function onDone(ret) {
- if (stack !== 0) stackRestore(stack);
- return convertReturnValue(ret);
- }
-
- ret = onDone(ret);
- return ret;
- };
-
- 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.createPreloadedFile = FS_createPreloadedFile;
- 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,
- };;
-function checkIncomingModuleAPI() {
- ignoredModuleProp('fetchSettings');
-}
-var wasmImports = {
- /** @export */
- __assert_fail: ___assert_fail,
- /** @export */
- __call_sighandler: ___call_sighandler,
- /** @export */
- __syscall__newselect: ___syscall__newselect,
- /** @export */
- __syscall_accept4: ___syscall_accept4,
- /** @export */
- __syscall_bind: ___syscall_bind,
- /** @export */
- __syscall_chdir: ___syscall_chdir,
- /** @export */
- __syscall_chmod: ___syscall_chmod,
- /** @export */
- __syscall_connect: ___syscall_connect,
- /** @export */
- __syscall_dup: ___syscall_dup,
- /** @export */
- __syscall_dup3: ___syscall_dup3,
- /** @export */
- __syscall_faccessat: ___syscall_faccessat,
- /** @export */
- __syscall_fchownat: ___syscall_fchownat,
- /** @export */
- __syscall_fcntl64: ___syscall_fcntl64,
- /** @export */
- __syscall_fdatasync: ___syscall_fdatasync,
- /** @export */
- __syscall_fstat64: ___syscall_fstat64,
- /** @export */
- __syscall_ftruncate64: ___syscall_ftruncate64,
- /** @export */
- __syscall_getcwd: ___syscall_getcwd,
- /** @export */
- __syscall_getdents64: ___syscall_getdents64,
- /** @export */
- __syscall_getpeername: ___syscall_getpeername,
- /** @export */
- __syscall_getsockname: ___syscall_getsockname,
- /** @export */
- __syscall_getsockopt: ___syscall_getsockopt,
- /** @export */
- __syscall_ioctl: ___syscall_ioctl,
- /** @export */
- __syscall_listen: ___syscall_listen,
- /** @export */
- __syscall_lstat64: ___syscall_lstat64,
- /** @export */
- __syscall_mkdirat: ___syscall_mkdirat,
- /** @export */
- __syscall_newfstatat: ___syscall_newfstatat,
- /** @export */
- __syscall_openat: ___syscall_openat,
- /** @export */
- __syscall_pipe: ___syscall_pipe,
- /** @export */
- __syscall_poll: ___syscall_poll,
- /** @export */
- __syscall_readlinkat: ___syscall_readlinkat,
- /** @export */
- __syscall_recvfrom: ___syscall_recvfrom,
- /** @export */
- __syscall_renameat: ___syscall_renameat,
- /** @export */
- __syscall_rmdir: ___syscall_rmdir,
- /** @export */
- __syscall_sendto: ___syscall_sendto,
- /** @export */
- __syscall_socket: ___syscall_socket,
- /** @export */
- __syscall_stat64: ___syscall_stat64,
- /** @export */
- __syscall_statfs64: ___syscall_statfs64,
- /** @export */
- __syscall_symlink: ___syscall_symlink,
- /** @export */
- __syscall_unlinkat: ___syscall_unlinkat,
- /** @export */
- __syscall_utimensat: ___syscall_utimensat,
- /** @export */
- _emscripten_get_now_is_monotonic: __emscripten_get_now_is_monotonic,
- /** @export */
- _emscripten_throw_longjmp: __emscripten_throw_longjmp,
- /** @export */
- _gmtime_js: __gmtime_js,
- /** @export */
- _localtime_js: __localtime_js,
- /** @export */
- _mktime_js: __mktime_js,
- /** @export */
- _mmap_js: __mmap_js,
- /** @export */
- _munmap_js: __munmap_js,
- /** @export */
- _setitimer_js: __setitimer_js,
- /** @export */
- _tzset_js: __tzset_js,
- /** @export */
- abort: _abort,
- /** @export */
- emscripten_date_now: _emscripten_date_now,
- /** @export */
- emscripten_err: _emscripten_err,
- /** @export */
- emscripten_get_heap_max: _emscripten_get_heap_max,
- /** @export */
- emscripten_get_now: _emscripten_get_now,
- /** @export */
- emscripten_memcpy_js: _emscripten_memcpy_js,
- /** @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_fdstat_get: _fd_fdstat_get,
- /** @export */
- fd_read: _fd_read,
- /** @export */
- fd_seek: _fd_seek,
- /** @export */
- fd_sync: _fd_sync,
- /** @export */
- fd_write: _fd_write,
- /** @export */
- getaddrinfo: _getaddrinfo,
- /** @export */
- getcontext: _getcontext,
- /** @export */
- getdtablesize: _getdtablesize,
- /** @export */
- gethostbyname_r: _gethostbyname_r,
- /** @export */
- getnameinfo: _getnameinfo,
- /** @export */
- getprotobyname: _getprotobyname,
- /** @export */
- getprotobynumber: _getprotobynumber,
- /** @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_iiiiiiiiii: invoke_iiiiiiiiii,
- /** @export */
- invoke_v: invoke_v,
- /** @export */
- invoke_vi: invoke_vi,
- /** @export */
- invoke_vii: invoke_vii,
- /** @export */
- invoke_viidii: invoke_viidii,
- /** @export */
- invoke_viii: invoke_viii,
- /** @export */
- invoke_viiii: invoke_viiii,
- /** @export */
- invoke_viiiii: invoke_viiiii,
- /** @export */
- invoke_viiiiii: invoke_viiiiii,
- /** @export */
- makecontext: _makecontext,
- /** @export */
- proc_exit: _proc_exit,
- /** @export */
- strftime: _strftime,
- /** @export */
- strptime: _strptime,
- /** @export */
- swapcontext: _swapcontext
-};
-var wasmExports = createWasm();
-var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors');
-var _php_wasm_run = Module['_php_wasm_run'] = createExportWrapper('php_wasm_run');
-var _malloc = createExportWrapper('malloc');
-var setTempRet0 = createExportWrapper('setTempRet0');
-var _fflush = Module['_fflush'] = createExportWrapper('fflush');
-var _free = createExportWrapper('free');
-var ___errno_location = createExportWrapper('__errno_location');
-var _memcpy = createExportWrapper('memcpy');
-var _htons = createExportWrapper('htons');
-var _ntohs = createExportWrapper('ntohs');
-var _htonl = createExportWrapper('htonl');
-var _emscripten_builtin_memalign = createExportWrapper('emscripten_builtin_memalign');
-var __emscripten_timeout = createExportWrapper('_emscripten_timeout');
-var _setThrew = createExportWrapper('setThrew');
-var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports['emscripten_stack_init'])();
-var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'])();
-var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'])();
-var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'])();
-var stackSave = createExportWrapper('stackSave');
-var stackRestore = createExportWrapper('stackRestore');
-var stackAlloc = createExportWrapper('stackAlloc');
-var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])();
-var dynCall_vij = Module['dynCall_vij'] = createExportWrapper('dynCall_vij');
-var dynCall_ji = Module['dynCall_ji'] = createExportWrapper('dynCall_ji');
-var dynCall_jiji = Module['dynCall_jiji'] = createExportWrapper('dynCall_jiji');
-
-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_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_v(index) {
- var sp = stackSave();
- try {
- getWasmTableEntry(index)();
- } 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 !== 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 !== 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 !== 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 !== 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 !== e+0) 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);
- }
-}
-
-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_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_viiiii(index,a1,a2,a3,a4,a5) {
- var sp = stackSave();
- try {
- 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 !== e+0) throw e;
- _setThrew(1, 0);
- }
-}
-
-function invoke_iiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9) {
- var sp = stackSave();
- try {
- return getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9);
- } 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 !== e+0) throw e;
- _setThrew(1, 0);
- }
-}
-
-function invoke_viidii(index,a1,a2,a3,a4,a5) {
- var sp = stackSave();
- try {
- getWasmTableEntry(index)(a1,a2,a3,a4,a5);
- } catch(e) {
- stackRestore(sp);
- if (e !== e+0) throw e;
- _setThrew(1, 0);
- }
-}
-
-
-// include: postamble.js
-// === Auto-generated postamble setup entry stuff ===
-
-Module['ccall'] = ccall;
-var missingLibrarySymbols = [
- 'writeI53ToI64',
- 'writeI53ToI64Clamped',
- 'writeI53ToI64Signaling',
- 'writeI53ToU64Clamped',
- 'writeI53ToU64Signaling',
- 'readI53FromU64',
- 'convertI32PairToI53',
- 'convertU32PairToI53',
- 'growMemory',
- 'getCallstack',
- 'emscriptenLog',
- 'convertPCtoSourceLocation',
- 'readEmAsmArgs',
- 'jstoi_s',
- 'listenOnce',
- 'autoResumeAudioContext',
- 'dynCallLegacy',
- 'getDynCaller',
- 'dynCall',
- 'runtimeKeepalivePush',
- 'runtimeKeepalivePop',
- 'safeSetTimeout',
- 'asmjsMangle',
- 'handleAllocatorInit',
- 'HandleAllocator',
- 'getNativeTypeSize',
- 'STACK_SIZE',
- 'STACK_ALIGN',
- 'POINTER_SIZE',
- 'ASSERTIONS',
- 'cwrap',
- 'uleb128Encode',
- 'sigToWasmTypes',
- 'generateFuncType',
- 'convertJsFunctionToWasm',
- 'getEmptyTableSlot',
- 'updateTableMap',
- 'getFunctionAddress',
- 'addFunction',
- 'removeFunction',
- 'reallyNegative',
- 'unSign',
- 'strLen',
- 'reSign',
- 'formatString',
- 'intArrayToString',
- 'AsciiToString',
- 'UTF16ToString',
- 'stringToUTF16',
- 'lengthBytesUTF16',
- 'UTF32ToString',
- 'stringToUTF32',
- 'lengthBytesUTF32',
- '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',
- 'jsStackTrace',
- 'stackTrace',
- 'checkWasiClock',
- 'wasiRightsToMuslOFlags',
- 'wasiOFlagsToMuslOFlags',
- 'createDyncallWrapper',
- 'setImmediateWrapped',
- 'clearImmediateWrapped',
- 'polyfillSetImmediate',
- 'getPromise',
- 'makePromise',
- 'idsToPromises',
- 'makePromiseCallback',
- 'ExceptionInfo',
- 'findMatchingCatch',
- 'setMainLoop',
- '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',
- 'registerWebGlEventCallback',
- 'runAndAbortIfError',
- 'SDL_unicode',
- 'SDL_ttfContext',
- 'SDL_audio',
- 'ALLOC_NORMAL',
- 'ALLOC_STACK',
- 'allocate',
- 'writeStringToMemory',
- 'writeAsciiToMemory',
-];
-missingLibrarySymbols.forEach(missingLibrarySymbol)
-
-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',
- 'keepRuntimeAlive',
- 'wasmMemory',
- 'wasmExports',
- 'stackAlloc',
- 'stackSave',
- 'stackRestore',
- 'getTempRet0',
- 'setTempRet0',
- 'writeStackCookie',
- 'checkStackCookie',
- 'readI53FromI64',
- 'convertI32PairToI53Checked',
- 'ptrToString',
- 'zeroMemory',
- 'exitJS',
- 'getHeapMax',
- 'abortOnCannotGrowMemory',
- 'ENV',
- 'MONTH_DAYS_REGULAR',
- 'MONTH_DAYS_LEAP',
- 'MONTH_DAYS_REGULAR_CUMULATIVE',
- 'MONTH_DAYS_LEAP_CUMULATIVE',
- 'isLeapYear',
- 'ydayFromDate',
- 'arraySum',
- 'addDays',
- 'ERRNO_CODES',
- 'ERRNO_MESSAGES',
- 'setErrNo',
- 'inetPton4',
- 'inetNtop4',
- 'inetPton6',
- 'inetNtop6',
- 'readSockaddr',
- 'writeSockaddr',
- 'DNS',
- 'getHostByName',
- 'Protocols',
- 'Sockets',
- 'initRandomFill',
- 'randomFill',
- 'timers',
- 'warnOnce',
- 'UNWIND_CACHE',
- 'readEmAsmArgsArray',
- 'jstoi_q',
- 'getExecutableName',
- 'handleException',
- 'callUserCallback',
- 'maybeExit',
- 'asyncLoad',
- 'alignMemory',
- 'mmapAlloc',
- 'wasmTable',
- 'getCFunc',
- 'freeTableIndexes',
- 'functionsInTableMap',
- 'setValue',
- 'getValue',
- 'PATH',
- 'PATH_FS',
- 'UTF8Decoder',
- 'UTF8ArrayToString',
- 'UTF8ToString',
- 'stringToUTF8Array',
- 'stringToUTF8',
- 'lengthBytesUTF8',
- 'intArrayFromString',
- 'stringToAscii',
- 'UTF16Decoder',
- 'stringToNewUTF8',
- 'stringToUTF8OnStack',
- 'writeArrayToMemory',
- 'JSEvents',
- 'specialHTMLTargets',
- 'currentFullscreenStrategy',
- 'restoreOldWindowedStyle',
- 'demangle',
- 'demangleAll',
- 'ExitStatus',
- 'getEnvStrings',
- 'doReadv',
- 'doWritev',
- 'promiseMap',
- 'uncaughtExceptionCount',
- 'exceptionLast',
- 'exceptionCaught',
- 'Browser',
- 'wget',
- 'SYSCALLS',
- 'getSocketFromFD',
- 'getSocketAddress',
- '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',
-];
-unexportedSymbols.forEach(unexportedRuntimeSymbol);
-
-
-
-var calledRun;
-
-dependenciesFulfilled = function runCaller() {
- // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
- if (!calledRun) run();
- if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
-};
-
-function stackCheckInit() {
- // This is normally called automatically during __wasm_call_ctors but need to
- // get these values before even running any of the ctors so we call it redundantly
- // here.
- _emscripten_stack_init();
- // TODO(sbc): Move writeStackCookie to native to to avoid this.
- writeStackCookie();
-}
-
-function run() {
-
- if (runDependencies > 0) {
- return;
- }
-
- stackCheckInit();
-
- preRun();
-
- // a preRun added a dependency, run will be called later
- if (runDependencies > 0) {
- return;
- }
-
- function doRun() {
- // run may have just been called through dependencies being fulfilled just in this very frame,
- // or while the async setStatus time below was happening
- if (calledRun) return;
- calledRun = true;
- Module['calledRun'] = true;
-
- if (ABORT) return;
-
- initRuntime();
-
- readyPromiseResolve(Module);
- if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
-
- assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');
-
- postRun();
- }
-
- if (Module['setStatus']) {
- Module['setStatus']('Running...');
- setTimeout(function() {
- setTimeout(function() {
- Module['setStatus']('');
- }, 1);
- doRun();
- }, 1);
- } else
- {
- doRun();
- }
- checkStackCookie();
-}
-
-function checkUnflushedContent() {
- // Compiler settings do not allow exiting the runtime, so flushing
- // the streams is not possible. but in ASSERTIONS mode we check
- // if there was something to flush, and if so tell the user they
- // should request that the runtime be exitable.
- // Normally we would not even include flush() at all, but in ASSERTIONS
- // builds we do so just for this check, and here we see if there is any
- // content to flush, that is, we check if there would have been
- // something a non-ASSERTIONS build would have not seen.
- // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
- // mode (which has its own special function for this; otherwise, all
- // the code is inside libc)
- var oldOut = out;
- var oldErr = err;
- var has = false;
- out = err = (x) => {
- has = true;
- }
- try { // it doesn't matter if it fails
- _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 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()();
- }
-}
-
-run();
-
-
-// end include: postamble.js
-
-
- return moduleArg.ready
-}
-
-);
-})();
-export default Module; \ No newline at end of file
diff --git a/examples/php-on-wasm/php-wasm.php b/examples/php-on-wasm/php-wasm.php
index 809af69..96625b8 100644
--- a/examples/php-on-wasm/php-wasm.php
+++ b/examples/php-on-wasm/php-wasm.php
@@ -35,7 +35,6 @@ $hostFuncs = [
makeHostFunc('(i32, i32, i32) -> (i32)', hostFunc__env__invoke_iii(...)),
makeHostFunc('(i32, i32, i32, i32, i32) -> (i32)', hostFunc__env__invoke_iiiii(...)),
makeHostFunc('(i32) -> ()', hostFunc__env__invoke_v(...)),
- makeHostFunc('(i32, i32, i32, i32) -> (i32)', hostFunc__env__invoke_iiii(...)),
makeHostFunc('(i32, i32) -> (i32)', hostFunc__env__invoke_ii(...)),
makeHostFunc('() -> ()', hostFunc__env__abort(...)),
makeHostFunc('(i32) -> ()', hostFunc__env__exit(...)),
@@ -44,6 +43,7 @@ $hostFuncs = [
makeHostFunc('(i32, i32) -> ()', hostFunc__env__invoke_vi(...)),
makeHostFunc('(i32) -> (i32)', hostFunc__env__invoke_i(...)),
makeHostFunc('(i32, i32, i32, i32, i32, i32, i32) -> (i32)', hostFunc__env__invoke_iiiiiii(...)),
+ makeHostFunc('(i32, i32, i32, i32) -> (i32)', hostFunc__env__invoke_iiii(...)),
makeHostFunc('(i32, i32, i32, i32) -> ()', hostFunc__env____assert_fail(...)),
makeHostFunc('(i32, i32, i32, i32, i32) -> ()', hostFunc__env__invoke_viiii(...)),
makeHostFunc('(i32, i32, i32, i32, i32, i32) -> ()', hostFunc__env__invoke_viiiii(...)),
diff --git a/examples/php-on-wasm/php-wasm.wasm b/examples/php-on-wasm/php-wasm.wasm
index 8e91021..4f254d7 100755..120000
--- a/examples/php-on-wasm/php-wasm.wasm
+++ b/examples/php-on-wasm/php-wasm.wasm
Binary files differ