| /** |
| * @license |
| * Copyright 2020 The Emscripten Authors |
| * SPDX-License-Identifier: MIT |
| */ |
| |
| #if ASSERTIONS |
| |
| // Endianness check |
| #if !SUPPORT_BIG_ENDIAN |
| (() => { |
| 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)'; |
| })(); |
| #endif |
| |
| 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)'); |
| } |
| |
| function legacyModuleProp(prop, newName, incoming=true) { |
| if (!Object.getOwnPropertyDescriptor(Module, prop)) { |
| Object.defineProperty(Module, prop, { |
| configurable: true, |
| get() { |
| let extra = incoming ? ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' : ''; |
| abort(`\`Module.${prop}\` has been replaced by \`${newName}\`` + extra); |
| |
| } |
| }); |
| } |
| } |
| |
| function consumedModuleProp(prop) { |
| if (!Object.getOwnPropertyDescriptor(Module, prop)) { |
| Object.defineProperty(Module, prop, { |
| configurable: true, |
| set() { |
| abort(`Attempt to set \`Module.${prop}\` after it has already been processed. This can happen, for example, when code is injected via '--post-js' rather than '--pre-js'`); |
| |
| } |
| }); |
| } |
| } |
| |
| 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' || |
| #if !WASMFS |
| // The old FS has some functionality that WasmFS lacks. |
| name === 'FS_createLazyFile' || |
| name === 'FS_createDevice' || |
| #endif |
| name === 'removeRunDependency'; |
| } |
| |
| /** |
| * Intercept access to a global symbol. This enables us to give informative |
| * warnings/errors when folks attempt to use symbols they did not include in |
| * their build, or no symbols that no longer exist. |
| */ |
| function hookGlobalSymbolAccess(sym, func) { |
| #if MODULARIZE && !EXPORT_ES6 |
| // In MODULARIZE mode the generated code runs inside a function scope and not |
| // the global scope, and JavaScript does not provide access to function scopes |
| // so we cannot dynamically modify the scrope using `defineProperty` in this |
| // case. |
| // |
| // In this mode we simply ignore requests for `hookGlobalSymbolAccess`. Since |
| // this is a debug-only feature, skipping it is not major issue. |
| #else |
| if (typeof globalThis != 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) { |
| Object.defineProperty(globalThis, sym, { |
| configurable: true, |
| get() { |
| func(); |
| return undefined; |
| } |
| }); |
| } |
| #endif |
| } |
| |
| function missingGlobal(sym, msg) { |
| hookGlobalSymbolAccess(sym, () => { |
| warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`); |
| }); |
| } |
| |
| missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer'); |
| missingGlobal('asm', 'Please use wasmExports instead'); |
| |
| function missingLibrarySymbol(sym) { |
| hookGlobalSymbolAccess(sym, () => { |
| // 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); |
| }); |
| |
| // Any symbol that is not included from the JS library is also (by definition) |
| // not exported on the Module object. |
| unexportedRuntimeSymbol(sym); |
| } |
| |
| function unexportedRuntimeSymbol(sym) { |
| #if PTHREADS |
| if (ENVIRONMENT_IS_PTHREAD) { |
| return; |
| } |
| #endif |
| 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); |
| } |
| }); |
| } |
| } |
| |
| #if ASSERTIONS == 2 |
| |
| var MAX_UINT8 = (2 ** 8) - 1; |
| var MAX_UINT16 = (2 ** 16) - 1; |
| var MAX_UINT32 = (2 ** 32) - 1; |
| var MAX_UINT53 = (2 ** 53) - 1; |
| var MAX_UINT64 = (2 ** 64) - 1; |
| |
| var MIN_INT8 = - (2 ** ( 8 - 1)); |
| var MIN_INT16 = - (2 ** (16 - 1)); |
| var MIN_INT32 = - (2 ** (32 - 1)); |
| var MIN_INT53 = - (2 ** (53 - 1)); |
| var MIN_INT64 = - (2 ** (64 - 1)); |
| |
| function checkInt(value, bits, min, max) { |
| assert(Number.isInteger(Number(value)), `attempt to write non-integer (${value}) into integer heap`); |
| assert(value <= max, `value (${value}) too large to write as ${bits}-bit value`); |
| assert(value >= min, `value (${value}) too small to write as ${bits}-bit value`); |
| } |
| |
| var checkInt1 = (value) => checkInt(value, 1, 1); |
| var checkInt8 = (value) => checkInt(value, 8, MIN_INT8, MAX_UINT8); |
| var checkInt16 = (value) => checkInt(value, 16, MIN_INT16, MAX_UINT16); |
| var checkInt32 = (value) => checkInt(value, 32, MIN_INT32, MAX_UINT32); |
| var checkInt53 = (value) => checkInt(value, 53, MIN_INT53, MAX_UINT53); |
| var checkInt64 = (value) => checkInt(value, 64, MIN_INT64, MAX_UINT64); |
| |
| #endif // ASSERTIONS == 2 |
| |
| #endif // ASSERTIONS |
| |
| #if RUNTIME_DEBUG |
| var runtimeDebug = true; // Switch to false at runtime to disable logging at the right times |
| |
| var printObjectList = []; |
| |
| function prettyPrint(arg) { |
| if (typeof arg == 'undefined') return 'undefined'; |
| if (typeof arg == 'boolean') arg = arg + 0; |
| if (!arg) return arg; |
| var index = printObjectList.indexOf(arg); |
| if (index >= 0) return '<' + arg + '|' + index + '>'; |
| if (arg.toString() == '[object HTMLImageElement]') { |
| return arg + '\n\n'; |
| } |
| if (arg.byteLength) { |
| return '{' + Array.prototype.slice.call(arg, 0, Math.min(arg.length, 400)) + '}'; |
| } |
| if (typeof arg == 'function') { |
| return '<function>'; |
| } else if (typeof arg == 'object') { |
| printObjectList.push(arg); |
| return '<' + arg + '|' + (printObjectList.length-1) + '>'; |
| } else if (typeof arg == 'number') { |
| if (arg > 0) return ptrToString(arg) + ' (' + arg + ')'; |
| } |
| return arg; |
| } |
| #endif |
| |
| #if ASSERTIONS || RUNTIME_DEBUG || AUTODEBUG |
| // Used by XXXXX_DEBUG settings to output debug messages. |
| function dbg(...args) { |
| #if ENVIRONMENT_MAY_BE_NODE && PTHREADS |
| // Avoid using the console for debugging in multi-threaded node applications |
| // See https://github.com/emscripten-core/emscripten/issues/14804 |
| if (ENVIRONMENT_IS_NODE && fs) { |
| fs.writeSync(2, args.join(' ') + '\n'); |
| } else |
| #endif |
| // TODO(sbc): Make this configurable somehow. Its not always convenient for |
| // logging to show up as warnings. |
| console.warn(...args); |
| } |
| #endif |