diff --git a/index.html b/index.html index bbb70f1..8f06920 100644 --- a/index.html +++ b/index.html @@ -26,7 +26,6 @@ -ms-interpolation-mode: nearest-neighbor; } - @@ -64,5 +63,3 @@ - - diff --git a/index.js b/index.js index 2acaaac..6ac4c51 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,4 @@ - - +// 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 @@ -15,11 +14,9 @@ // can continue to use Module afterwards as well. var Module = typeof Module != 'undefined' ? Module : {}; -// See https://caniuse.com/mdn-javascript_builtins_object_assign - // --pre-jses are emitted after the Module integration code, so that they can // refer to Module (if they choose; they can also define Module) -// {{PRE_JSES}} + // Sometimes an existing Module object exists with properties // meant to overwrite the default module functionality. Here @@ -64,50 +61,37 @@ var read_, readBinary, setWindowTitle; -// Normally we don't log exceptions but instead let them bubble out the top -// level where the embedding environment (e.g. the browser) can handle -// them. -// However under v8 and node we sometimes exit the process direcly in which case -// its up to use us to log the exception before exiting. -// If we fix https://github.com/emscripten-core/emscripten/issues/15080 -// this may no longer be needed under node. -function logExceptionOnExit(e) { - if (e instanceof ExitStatus) return; - let toLog = e; - if (e && typeof e == 'object' && e.stack) { - toLog = [e, e.stack]; +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 + ')'); } - err('exiting due to exception: ' + toLog); -} -var fs; -var nodePath; -var requireNodeFS; + // `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_NODE) { - if (!(typeof process == 'object' && typeof require == 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = require('path').dirname(scriptDirectory) + '/'; + scriptDirectory = nodePath.dirname(scriptDirectory) + '/'; } else { scriptDirectory = __dirname + '/'; } // include: node_shell_read.js - - -requireNodeFS = () => { - // Use nodePath as the indicator for these not being initialized, - // since in some environments a global fs may have already been - // created. - if (!nodePath) { - fs = require('fs'); - nodePath = require('path'); - } -}; - -read_ = function shell_read(filename, binary) { - requireNodeFS(); - filename = nodePath['normalize'](filename); +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'); }; @@ -120,50 +104,38 @@ readBinary = (filename) => { return ret; }; -readAsync = (filename, onload, onerror) => { - requireNodeFS(); - filename = nodePath['normalize'](filename); - fs.readFile(filename, function(err, data) { +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(data.buffer); + else onload(binary ? data.buffer : data); }); }; - // end include: node_shell_read.js - if (process['argv'].length > 1) { - thisProgram = process['argv'][1].replace(/\\/g, '/'); + if (!Module['thisProgram'] && process.argv.length > 1) { + thisProgram = process.argv[1].replace(/\\/g, '/'); } - arguments_ = process['argv'].slice(2); + arguments_ = process.argv.slice(2); if (typeof module != 'undefined') { module['exports'] = Module; } - process['on']('uncaughtException', function(ex) { + process.on('uncaughtException', (ex) => { // suppress ExitStatus exceptions from showing an error - if (!(ex instanceof ExitStatus)) { + if (ex !== 'unwind' && !(ex instanceof ExitStatus) && !(ex.context instanceof ExitStatus)) { throw ex; } }); - // Without this older versions of node (< v15) will log unhandled rejections - // but return 0, which is not normally the desired behaviour. This is - // not be needed with node v15 and about because it is now the default - // behaviour: - // See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode - process['on']('unhandledRejection', function(reason) { throw reason; }); - quit_ = (status, toThrow) => { - if (keepRuntimeAlive()) { - process['exitCode'] = status; - throw toThrow; - } - logExceptionOnExit(toThrow); - process['exit'](status); + process.exitCode = status; + throw toThrow; }; - Module['inspect'] = function () { return '[Emscripten Module object]'; }; + Module['inspect'] = () => '[Emscripten Module object]'; } else if (ENVIRONMENT_IS_SHELL) { @@ -171,25 +143,31 @@ 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_ = function shell_read(f) { - return read(f); - }; + read_ = read; } - readBinary = function readBinary(f) { - let data; + readBinary = (f) => { if (typeof readbuffer == 'function') { return new Uint8Array(readbuffer(f)); } - data = read(f, 'binary'); + let data = read(f, 'binary'); assert(typeof data == 'object'); return data; }; - readAsync = function readAsync(f, onload, onerror) { - setTimeout(() => onload(readBinary(f)), 0); + 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') { @@ -201,19 +179,23 @@ if (ENVIRONMENT_IS_SHELL) { // 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, so we need to be - // careful of whether the runtime is alive or not, which is why this code - // path looks different than node. It also has the downside that it will - // halt the entire program when no code remains to run, which means this - // is not friendly for bundling this code into a larger codebase, and for - // that reason the "shell" environment is mainly useful for testing whole - // programs by themselves, basically. - if (runtimeKeepaliveCounter) { - throw toThrow; - } - logExceptionOnExit(toThrow); - quit(status); + // 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; }; } @@ -253,22 +235,20 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { // be done differently. { // include: web_or_worker_shell_read.js - - - read_ = (url) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.send(null); - return xhr.responseText; +read_ = (url) => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.send(null); + return xhr.responseText; } if (ENVIRONMENT_IS_WORKER) { readBinary = (url) => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.responseType = 'arraybuffer'; - xhr.send(null); - return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.responseType = 'arraybuffer'; + xhr.send(null); + return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); }; } @@ -297,7 +277,7 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { } var out = Module['print'] || console.log.bind(console); -var err = Module['printErr'] || console.warn.bind(console); +var err = Module['printErr'] || console.error.bind(console); // Merge back in the overrides Object.assign(Module, moduleOverrides); @@ -328,6 +308,7 @@ assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was r assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)'); assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)'); assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY'); +legacyModuleProp('asm', 'wasmExports'); legacyModuleProp('read', 'read_'); legacyModuleProp('readAsync', 'readAsync'); legacyModuleProp('readBinary', 'readBinary'); @@ -336,274 +317,12 @@ var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js'; var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js'; var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js'; var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; -function alignMemory() { abort('`alignMemory` is now a library function and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line'); } assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable."); - - -var STACK_ALIGN = 16; -var POINTER_SIZE = 4; - -function getNativeTypeSize(type) { - switch (type) { - case 'i1': case 'i8': case 'u8': return 1; - case 'i16': case 'u16': return 2; - case 'i32': case 'u32': return 4; - case 'i64': case 'u64': return 8; - case 'float': return 4; - case 'double': return 8; - default: { - if (type[type.length - 1] === '*') { - return POINTER_SIZE; - } else if (type[0] === 'i') { - const bits = Number(type.substr(1)); - assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type); - return bits / 8; - } else { - return 0; - } - } - } -} - -function warnOnce(text) { - if (!warnOnce.shown) warnOnce.shown = {}; - if (!warnOnce.shown[text]) { - warnOnce.shown[text] = 1; - err(text); - } -} - -// include: runtime_functions.js - - -// This gives correct answers for everything less than 2^{14} = 16384 -// I hope nobody is contemplating functions with 16384 arguments... -function uleb128Encode(n) { - assert(n < 16384); - if (n < 128) { - return [n]; - } - return [(n % 128) | 128, n >> 7]; -} - -// Wraps a JS function as a wasm function with a given signature. -function convertJsFunctionToWasm(func, sig) { - - // If the type reflection proposal is available, use the new - // "WebAssembly.Function" constructor. - // Otherwise, construct a minimal wasm module importing the JS function and - // re-exporting it. - if (typeof WebAssembly.Function == "function") { - var typeNames = { - 'i': 'i32', - 'j': 'i64', - 'f': 'f32', - 'd': 'f64' - }; - var type = { - parameters: [], - results: sig[0] == 'v' ? [] : [typeNames[sig[0]]] - }; - for (var i = 1; i < sig.length; ++i) { - type.parameters.push(typeNames[sig[i]]); - } - return new WebAssembly.Function(type, func); - } - - // The module is static, with the exception of the type section, which is - // generated based on the signature passed in. - var typeSection = [ - 0x01, // count: 1 - 0x60, // form: func - ]; - var sigRet = sig.slice(0, 1); - var sigParam = sig.slice(1); - var typeCodes = { - 'i': 0x7f, // i32 - 'j': 0x7e, // i64 - 'f': 0x7d, // f32 - 'd': 0x7c, // f64 - }; - - // Parameters, length + signatures - typeSection = typeSection.concat(uleb128Encode(sigParam.length)); - for (var i = 0; i < sigParam.length; ++i) { - typeSection.push(typeCodes[sigParam[i]]); - } - - // Return values, length + signatures - // With no multi-return in MVP, either 0 (void) or 1 (anything else) - if (sigRet == 'v') { - typeSection.push(0x00); - } else { - typeSection = typeSection.concat([0x01, typeCodes[sigRet]]); - } - - // Write the section code and overall length of the type section into the - // section header - typeSection = [0x01 /* Type section code */].concat( - uleb128Encode(typeSection.length), - typeSection - ); - - // Rest of the module is static - var bytes = new Uint8Array([ - 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm") - 0x01, 0x00, 0x00, 0x00, // version: 1 - ].concat(typeSection, [ - 0x02, 0x07, // import section - // (import "e" "f" (func 0 (type 0))) - 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00, - 0x07, 0x05, // export section - // (export "f" (func 0 (type 0))) - 0x01, 0x01, 0x66, 0x00, 0x00, - ])); - - // We can compile this wasm module synchronously because it is very small. - // This accepts an import (at "e.f"), that it reroutes to an export (at "f") - var module = new WebAssembly.Module(bytes); - var instance = new WebAssembly.Instance(module, { - 'e': { - 'f': func - } - }); - var wrappedFunc = instance.exports['f']; - return wrappedFunc; -} - -var freeTableIndexes = []; - -// Weak map of functions in the table to their indexes, created on first use. -var functionsInTableMap; - -function getEmptyTableSlot() { - // Reuse a free index if there is one, otherwise grow. - if (freeTableIndexes.length) { - return freeTableIndexes.pop(); - } - // Grow the table - try { - wasmTable.grow(1); - } catch (err) { - if (!(err instanceof RangeError)) { - throw err; - } - throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.'; - } - return wasmTable.length - 1; -} - -function updateTableMap(offset, count) { - for (var i = offset; i < offset + count; i++) { - var item = getWasmTableEntry(i); - // Ignore null values. - if (item) { - functionsInTableMap.set(item, i); - } - } -} - -/** - * Add a function to the table. - * 'sig' parameter is required if the function being added is a JS function. - * @param {string=} sig - */ -function addFunction(func, sig) { - assert(typeof func != 'undefined'); - - // Check if the function is already in the table, to ensure each function - // gets a unique index. First, create the map if this is the first use. - if (!functionsInTableMap) { - functionsInTableMap = new WeakMap(); - updateTableMap(0, wasmTable.length); - } - if (functionsInTableMap.has(func)) { - return functionsInTableMap.get(func); - } - - // It's not in the table, add it now. - - var ret = getEmptyTableSlot(); - - // Set the new value. - try { - // Attempting to call this with JS function will cause of table.set() to fail - setWasmTableEntry(ret, func); - } catch (err) { - if (!(err instanceof TypeError)) { - throw err; - } - assert(typeof sig != 'undefined', 'Missing signature argument to addFunction: ' + func); - var wrapped = convertJsFunctionToWasm(func, sig); - setWasmTableEntry(ret, wrapped); - } - - functionsInTableMap.set(func, ret); - - return ret; -} - -function removeFunction(index) { - functionsInTableMap.delete(getWasmTableEntry(index)); - freeTableIndexes.push(index); -} - -// end include: runtime_functions.js -// include: runtime_debug.js - - -function legacyModuleProp(prop, newName) { - if (!Object.getOwnPropertyDescriptor(Module, prop)) { - Object.defineProperty(Module, prop, { - configurable: true, - get: function() { - abort('Module.' + prop + ' has been replaced with plain ' + newName + ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)'); - } - }); - } -} - -function ignoredModuleProp(prop) { - if (Object.getOwnPropertyDescriptor(Module, prop)) { - abort('`Module.' + prop + '` was supplied but `' + prop + '` not included in INCOMING_MODULE_JS_API'); - } -} - -function unexportedMessage(sym, isFSSybol) { - var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)"; - if (isFSSybol) { - msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you'; - } - return msg; -} - -function unexportedRuntimeSymbol(sym, isFSSybol) { - if (!Object.getOwnPropertyDescriptor(Module, sym)) { - Object.defineProperty(Module, sym, { - configurable: true, - get: function() { - abort(unexportedMessage(sym, isFSSybol)); - } - }); - } -} - -function unexportedRuntimeFunction(sym, isFSSybol) { - if (!Object.getOwnPropertyDescriptor(Module, sym)) { - Module[sym] = () => abort(unexportedMessage(sym, isFSSybol)); - } -} - -// end include: runtime_debug.js -var tempRet0 = 0; -var setTempRet0 = (value) => { tempRet0 = value; }; -var getTempRet0 = () => tempRet0; - - - +// end include: shell.js +// include: preamble.js // === Preamble library stuff === // Documentation for the public APIs defined in this file must be updated in: @@ -622,53 +341,10 @@ if (typeof WebAssembly != 'object') { abort('no native wasm support detected'); } -// include: runtime_safe_heap.js - - -// In MINIMAL_RUNTIME, setValue() and getValue() are only available when -// building with safe heap enabled, for heap safety checking. -// In traditional runtime, setValue() and getValue() are always available -// (although their use is highly discouraged due to perf penalties) - -/** @param {number} ptr - @param {number} value - @param {string} type - @param {number|boolean=} noSafe */ -function setValue(ptr, value, type = 'i8', noSafe) { - if (type.endsWith('*')) type = 'i32'; - switch (type) { - case 'i1': HEAP8[((ptr)>>0)] = value; break; - case 'i8': HEAP8[((ptr)>>0)] = value; break; - case 'i16': HEAP16[((ptr)>>1)] = value; break; - case 'i32': HEAP32[((ptr)>>2)] = value; break; - case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break; - case 'float': HEAPF32[((ptr)>>2)] = value; break; - case 'double': HEAPF64[((ptr)>>3)] = value; break; - default: abort('invalid type for setValue: ' + type); - } -} - -/** @param {number} ptr - @param {string} type - @param {number|boolean=} noSafe */ -function getValue(ptr, type = 'i8', noSafe) { - if (type.endsWith('*')) type = 'i32'; - switch (type) { - case 'i1': return HEAP8[((ptr)>>0)]; - case 'i8': return HEAP8[((ptr)>>0)]; - case 'i16': return HEAP16[((ptr)>>1)]; - case 'i32': return HEAP32[((ptr)>>2)]; - case 'i64': return HEAP32[((ptr)>>2)]; - case 'float': return HEAPF32[((ptr)>>2)]; - case 'double': return Number(HEAPF64[((ptr)>>3)]); - default: abort('invalid type for getValue: ' + type); - } -} - -// end include: runtime_safe_heap.js // Wasm globals var wasmMemory; +var wasmExports; //======================================== // Runtime essentials @@ -690,505 +366,16 @@ function assert(condition, text) { } } -// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) -function getCFunc(ident) { - var func = Module['_' + ident]; // closure exported function - assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported'); - return func; -} - -// C calling interface. -/** @param {string|null=} returnType - @param {Array=} argTypes - @param {Arguments|Array=} args - @param {Object=} opts */ -function ccall(ident, returnType, argTypes, args, opts) { - // For fast lookup of conversion functions - var toC = { - 'string': function(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' - var len = (str.length << 2) + 1; - ret = stackAlloc(len); - stringToUTF8(str, ret, len); - } - return ret; - }, - 'array': function(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; -} - -/** @param {string=} returnType - @param {Array=} argTypes - @param {Object=} opts */ -function cwrap(ident, returnType, argTypes, opts) { - return function() { - return ccall(ident, returnType, argTypes, arguments, opts); - } -} - // We used to include malloc/free by default in the past. Show a helpful error in // builds with assertions. - -// include: runtime_legacy.js - - -var ALLOC_NORMAL = 0; // Tries to use _malloc() -var ALLOC_STACK = 1; // Lives for the duration of the current function call - -/** - * allocate(): This function is no longer used by emscripten but is kept around to avoid - * breaking external users. - * You should normally not use allocate(), and instead allocate - * memory using _malloc()/stackAlloc(), initialize it with - * setValue(), and so forth. - * @param {(Uint8Array|Array)} slab: An array of data. - * @param {number=} allocator : How to allocate memory, see ALLOC_* - */ -function allocate(slab, allocator) { - var ret; - assert(typeof allocator == 'number', 'allocate no longer takes a type argument') - assert(typeof slab != 'number', 'allocate no longer takes a number as arg0') - - if (allocator == ALLOC_STACK) { - ret = stackAlloc(slab.length); - } else { - ret = _malloc(slab.length); - } - - if (!slab.subarray && !slab.slice) { - slab = new Uint8Array(slab); - } - HEAPU8.set(slab, ret); - return ret; -} - -// end include: runtime_legacy.js -// include: runtime_strings.js - - -// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime. - -var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf8') : undefined; - -// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns -// a copy of that string as a Javascript String object. -/** - * heapOrArray is either a regular array, or a JavaScript typed array view. - * @param {number} idx - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) { - var endIdx = idx + maxBytesToRead; - var endPtr = idx; - // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself. - // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage. - // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity) - while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr; - - if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) { - return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr)); - } else { - var str = ''; - // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that - while (idx < endPtr) { - // For UTF8 byte structure, see: - // http://en.wikipedia.org/wiki/UTF-8#Description - // https://www.ietf.org/rfc/rfc2279.txt - // https://tools.ietf.org/html/rfc3629 - var u0 = heapOrArray[idx++]; - if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } - var u1 = heapOrArray[idx++] & 63; - if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } - var u2 = heapOrArray[idx++] & 63; - if ((u0 & 0xF0) == 0xE0) { - u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; - } else { - if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!'); - u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63); - } - - if (u0 < 0x10000) { - str += String.fromCharCode(u0); - } else { - var ch = u0 - 0x10000; - str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); - } - } - } - return str; -} - -// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a -// copy of that string as a Javascript String object. -// maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit -// this parameter to scan the string until the first \0 byte. If maxBytesToRead is -// passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the -// middle, then the string will cut short at that byte index (i.e. maxBytesToRead will -// not produce a string of exact length [ptr, ptr+maxBytesToRead[) -// N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may -// throw JS JIT optimizations off, so it is worth to consider consistently using one -// style or the other. -/** - * @param {number} ptr - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ToString(ptr, maxBytesToRead) { - ; - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; -} - -// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', -// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element. -// outIdx: The starting offset in the array to begin the copying. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. -// This count should include the null terminator, -// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else. -// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes. - return 0; - - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629 - var u = str.charCodeAt(i); // possibly a lead surrogate - if (u >= 0xD800 && u <= 0xDFFF) { - var u1 = str.charCodeAt(++i); - u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); - } - if (u <= 0x7F) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u; - } else if (u <= 0x7FF) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 0xC0 | (u >> 6); - heap[outIdx++] = 0x80 | (u & 63); - } else if (u <= 0xFFFF) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 0xE0 | (u >> 12); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } else { - if (outIdx + 3 >= endIdx) break; - if (u > 0x10FFFF) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).'); - heap[outIdx++] = 0xF0 | (u >> 18); - heap[outIdx++] = 0x80 | ((u >> 12) & 63); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } - } - // Null-terminate the pointer to the buffer. - heap[outIdx] = 0; - return outIdx - startIdx; +function _free() { + // Show a helpful error since we used to include free by default in the past. + abort("free() called but not included in the build - add '_free' to EXPORTED_FUNCTIONS"); } -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF8(str, outPtr, maxBytesToWrite) { - assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite); -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte. -function lengthBytesUTF8(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var u = str.charCodeAt(i); // possibly a lead surrogate - if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - if (u <= 0x7F) ++len; - else if (u <= 0x7FF) len += 2; - else if (u <= 0xFFFF) len += 3; - else len += 4; - } - return len; -} - -// end include: runtime_strings.js -// include: runtime_strings_extra.js - - -// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime. - -// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns -// a copy of that string as a Javascript String object. - -function AsciiToString(ptr) { - var str = ''; - while (1) { - var ch = HEAPU8[((ptr++)>>0)]; - if (!ch) return str; - str += String.fromCharCode(ch); - } -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP. - -function stringToAscii(str, outPtr) { - return writeAsciiToMemory(str, outPtr, false); -} - -// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns -// a copy of that string as a Javascript String object. - -var UTF16Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder('utf-16le') : undefined; - -function UTF16ToString(ptr, maxBytesToRead) { - assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!'); - var endPtr = ptr; - // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself. - // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage. - var idx = endPtr >> 1; - var maxIdx = idx + maxBytesToRead / 2; - // If maxBytesToRead is not passed explicitly, it will be undefined, and this - // will always evaluate to true. This saves on code size. - while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; - endPtr = idx << 1; - - if (endPtr - ptr > 32 && UTF16Decoder) { - return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); - } else { - var str = ''; - - // If maxBytesToRead is not passed explicitly, it will be undefined, and the for-loop's condition - // will always evaluate to true. The loop is then terminated on the first null char. - for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { - var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; - if (codeUnit == 0) break; - // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. - str += String.fromCharCode(codeUnit); - } - - return str; - } -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP. -// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// outPtr: Byte address in Emscripten HEAP where to write the string to. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null -// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else. -// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF16(str, outPtr, maxBytesToWrite) { - assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 0x7FFFFFFF; - } - if (maxBytesToWrite < 2) return 0; - maxBytesToWrite -= 2; // Null terminator. - var startPtr = outPtr; - var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length; - for (var i = 0; i < numCharsToWrite; ++i) { - // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. - var codeUnit = str.charCodeAt(i); // possibly a lead surrogate - HEAP16[((outPtr)>>1)] = codeUnit; - outPtr += 2; - } - // Null-terminate the pointer to the HEAP. - HEAP16[((outPtr)>>1)] = 0; - return outPtr - startPtr; -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. - -function lengthBytesUTF16(str) { - return str.length*2; -} - -function UTF32ToString(ptr, maxBytesToRead) { - assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); - var i = 0; - - var str = ''; - // If maxBytesToRead is not passed explicitly, it will be undefined, and this - // will always evaluate to true. This saves on code size. - while (!(i >= maxBytesToRead / 4)) { - var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; - if (utf32 == 0) break; - ++i; - // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - if (utf32 >= 0x10000) { - var ch = utf32 - 0x10000; - str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); - } else { - str += String.fromCharCode(utf32); - } - } - return str; -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP. -// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// outPtr: Byte address in Emscripten HEAP where to write the string to. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null -// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else. -// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF32(str, outPtr, maxBytesToWrite) { - assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 0x7FFFFFFF; - } - if (maxBytesToWrite < 4) return 0; - var startPtr = outPtr; - var endPtr = startPtr + maxBytesToWrite - 4; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var codeUnit = str.charCodeAt(i); // possibly a lead surrogate - if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { - var trailSurrogate = str.charCodeAt(++i); - codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); - } - HEAP32[((outPtr)>>2)] = codeUnit; - outPtr += 4; - if (outPtr + 4 > endPtr) break; - } - // Null-terminate the pointer to the HEAP. - HEAP32[((outPtr)>>2)] = 0; - return outPtr - startPtr; -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. - -function lengthBytesUTF32(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var codeUnit = str.charCodeAt(i); - if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate. - len += 4; - } - - return len; -} - -// Allocate heap space for a JS string, and write it there. -// It is the responsibility of the caller to free() that memory. -function allocateUTF8(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = _malloc(size); - if (ret) stringToUTF8Array(str, HEAP8, ret, size); - return ret; -} - -// Allocate stack space for a JS string, and write it there. -function allocateUTF8OnStack(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = stackAlloc(size); - stringToUTF8Array(str, HEAP8, ret, size); - return ret; -} - -// Deprecated: This function should not be called because it is unsafe and does not provide -// a maximum length limit of how many bytes it is allowed to write. Prefer calling the -// function stringToUTF8Array() instead, which takes in a maximum length that can be used -// to be secure from out of bounds writes. -/** @deprecated - @param {boolean=} dontAddNull */ -function writeStringToMemory(string, buffer, dontAddNull) { - warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!'); - - var /** @type {number} */ lastChar, /** @type {number} */ end; - if (dontAddNull) { - // stringToUTF8Array always appends null. If we don't want to do that, remember the - // character that existed at the location where the null will be placed, and restore - // that after the write (below). - end = buffer + lengthBytesUTF8(string); - lastChar = HEAP8[end]; - } - stringToUTF8(string, buffer, Infinity); - if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character. -} - -function writeArrayToMemory(array, buffer) { - assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)') - HEAP8.set(array, buffer); -} - -/** @param {boolean=} dontAddNull */ -function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff)); - HEAP8[((buffer++)>>0)] = str.charCodeAt(i); - } - // Null-terminate the pointer to the HEAP. - if (!dontAddNull) HEAP8[((buffer)>>0)] = 0; -} - -// end include: runtime_strings_extra.js // Memory management var HEAP, -/** @type {!ArrayBuffer} */ - buffer, /** @type {!Int8Array} */ HEAP8, /** @type {!Uint8Array} */ @@ -1206,72 +393,72 @@ var HEAP, /** @type {!Float64Array} */ HEAPF64; -function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module['HEAP8'] = HEAP8 = new Int8Array(buf); - Module['HEAP16'] = HEAP16 = new Int16Array(buf); - Module['HEAP32'] = HEAP32 = new Int32Array(buf); - Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf); - Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf); - Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf); - Module['HEAPF32'] = HEAPF32 = new Float32Array(buf); - Module['HEAPF64'] = HEAPF64 = new Float64Array(buf); +function updateMemoryViews() { + var b = wasmMemory.buffer; + Module['HEAP8'] = HEAP8 = new Int8Array(b); + Module['HEAP16'] = HEAP16 = new Int16Array(b); + Module['HEAP32'] = HEAP32 = new Int32Array(b); + Module['HEAPU8'] = HEAPU8 = new Uint8Array(b); + Module['HEAPU16'] = HEAPU16 = new Uint16Array(b); + Module['HEAPU32'] = HEAPU32 = new Uint32Array(b); + Module['HEAPF32'] = HEAPF32 = new Float32Array(b); + Module['HEAPF64'] = HEAPF64 = new Float64Array(b); } -var TOTAL_STACK = 5242880; -if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime') - -var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;legacyModuleProp('INITIAL_MEMORY', 'INITIAL_MEMORY'); - -assert(INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')'); +assert(!Module['STACK_SIZE'], 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time') -// check for full engine support (use string 'subarray' to avoid closure compiler confusion) assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined, 'JS engine does not provide full typed array support'); -// If memory is defined in wasm, the user can't provide it. +// 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(INITIAL_MEMORY == 16777216, 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically'); +assert(!Module['INITIAL_MEMORY'], 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically'); // include: runtime_init_table.js // In regular non-RELOCATABLE mode the table is exported // from the wasm module and this will be assigned once // the exports are available. var wasmTable; - // end include: runtime_init_table.js // include: runtime_stack_check.js - - // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. function writeStackCookie() { var max = _emscripten_stack_get_end(); assert((max & 3) == 0); + // 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. - HEAP32[((max)>>2)] = 0x2135467; - HEAP32[(((max)+(4))>>2)] = 0x89BACDFE; + HEAPU32[((max)>>2)] = 0x02135467; + HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE; // Also test the global address 0 for integrity. - HEAPU32[0] = 0x63736d65; /* 'emsc' */ + 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 != 0x2135467 || cookie2 != 0x89BACDFE) { - abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' 0x' + cookie1.toString(16)); + 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] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!'); + 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); @@ -1290,6 +477,7 @@ var __ATPOSTRUN__ = []; // functions called after the main() is called var runtimeInitialized = false; var runtimeExited = false; + var runtimeKeepaliveCounter = 0; function keepRuntimeAlive() { @@ -1297,22 +485,21 @@ function keepRuntimeAlive() { } 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() { - checkStackCookie(); assert(!runtimeInitialized); runtimeInitialized = true; + checkStackCookie(); + callRuntimeCallbacks(__ATINIT__); } @@ -1324,6 +511,7 @@ function preMain() { } function exitRuntime() { + assert(!runtimeExited); checkStackCookie(); ___funcs_on_exit(); // Native atexit() functions callRuntimeCallbacks(__ATEXIT__); @@ -1365,8 +553,6 @@ function addOnPostRun(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 @@ -1379,7 +565,6 @@ assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_ 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 @@ -1413,7 +598,7 @@ function addRunDependency(id) { runDependencyTracking[id] = 1; if (runDependencyWatcher === null && typeof setInterval != 'undefined') { // Check for missing dependencies every few seconds - runDependencyWatcher = setInterval(function() { + runDependencyWatcher = setInterval(() => { if (ABORT) { clearInterval(runDependencyWatcher); runDependencyWatcher = null; @@ -1465,10 +650,8 @@ function removeRunDependency(id) { /** @param {string|number=} what */ function abort(what) { - { - if (Module['onAbort']) { - Module['onAbort'](what); - } + if (Module['onAbort']) { + Module['onAbort'](what); } what = 'Aborted(' + what + ')'; @@ -1482,12 +665,16 @@ function abort(what) { // 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); @@ -1497,35 +684,28 @@ function abort(what) { throw e; } -// {{MEM_INITIALIZER}} - // include: memoryprofiler.js - - // end include: memoryprofiler.js // show errors on likely calls to FS when it was not included var FS = { - error: function() { + error() { abort('Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -sFORCE_FILESYSTEM'); }, - init: function() { FS.error() }, - createDataFile: function() { FS.error() }, - createPreloadedFile: function() { FS.error() }, - createLazyFile: function() { FS.error() }, - open: function() { FS.error() }, - mkdev: function() { FS.error() }, - registerDevice: function() { FS.error() }, - analyzePath: function() { FS.error() }, - loadFilesFromDB: function() { FS.error() }, - - ErrnoError: function ErrnoError() { FS.error() }, + init() { FS.error() }, + createDataFile() { FS.error() }, + createPreloadedFile() { FS.error() }, + createLazyFile() { FS.error() }, + open() { FS.error() }, + mkdev() { FS.error() }, + registerDevice() { FS.error() }, + analyzePath() { FS.error() }, + + ErrnoError() { FS.error() }, }; Module['FS_createDataFile'] = FS.createDataFile; Module['FS_createPreloadedFile'] = FS.createPreloadedFile; // include: URIUtils.js - - // Prefix of data URIs emitted by SINGLE_FILE and related options. var dataURIPrefix = 'data:application/octet-stream;base64,'; @@ -1539,78 +719,115 @@ function isDataURI(filename) { function isFileURI(filename) { return filename.startsWith('file://'); } - // end include: URIUtils.js -/** @param {boolean=} fixedasm */ -function createExportWrapper(name, fixedasm) { +function createExportWrapper(name) { return function() { - var displayName = name; - var asm = fixedasm; - if (!fixedasm) { - asm = Module['asm']; - } - assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization'); - assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); - if (!asm[name]) { - assert(asm[name], 'exported native function `' + displayName + '` not found'); - } - return asm[name].apply(null, arguments); + assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`); + assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`); + 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; wasmBinaryFile = 'index.wasm'; if (!isDataURI(wasmBinaryFile)) { wasmBinaryFile = locateFile(wasmBinaryFile); } -function getBinary(file) { - try { - if (file == wasmBinaryFile && wasmBinary) { - return new Uint8Array(wasmBinary); - } - if (readBinary) { - return readBinary(file); - } else { - throw "both async and sync fetching of the wasm failed"; - } +function getBinarySync(file) { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); } - catch (err) { - abort(err); + if (readBinary) { + return readBinary(file); } + throw "both async and sync fetching of the wasm failed"; } -function getBinaryPromise() { - // If we don't have the binary yet, try to to load it asynchronously. +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 (!wasmBinary + && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { if (typeof fetch == 'function' - && !isFileURI(wasmBinaryFile) + && !isFileURI(binaryFile) ) { - return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { + return fetch(binaryFile, { credentials: 'same-origin' }).then((response) => { if (!response['ok']) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; + throw "failed to load wasm binary file at '" + binaryFile + "'"; } return response['arrayBuffer'](); - }).catch(function () { - return getBinary(wasmBinaryFile); - }); + }).catch(() => getBinarySync(binaryFile)); } - else { - if (readAsync) { - // fetch is not available or url is file => try XHR (readAsync uses XHR internally) - return new Promise(function(resolve, reject) { - readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject) - }); - } + else if (readAsync) { + // fetch is not available or url is file => try XHR (readAsync uses XHR internally) + return new Promise((resolve, reject) => { + readAsync(binaryFile, (response) => resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))), reject) + }); } } - // Otherwise, getBinary should be able to get it synchronously - return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); }); + // 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) && + // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. + !isFileURI(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 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. @@ -1618,8 +835,8 @@ function getBinaryPromise() { function createWasm() { // prepare imports var info = { - 'env': asmLibraryArg, - 'wasi_snapshot_preview1': asmLibraryArg, + '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 @@ -1628,25 +845,28 @@ function createWasm() { function receiveInstance(instance, module) { var exports = instance.exports; - Module['asm'] = exports; + wasmExports = exports; + - wasmMemory = Module['asm']['memory']; + 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); - updateGlobalBufferAndViews(wasmMemory.buffer); + updateMemoryViews(); - wasmTable = Module['asm']['__indirect_function_table']; + wasmTable = wasmExports['__indirect_function_table']; + assert(wasmTable, "table not found in wasm exports"); - addOnInit(Module['asm']['__wasm_call_ctors']); + addOnInit(wasmExports['__wasm_call_ctors']); removeRunDependency('wasm-instantiate'); - + return exports; } - // we can't run yet (except in a pthread, where we have a custom sync instantiator) + // wait for the pthread pool (if any) addRunDependency('wasm-instantiate'); // Prefer streaming instantiation if available. @@ -1660,71 +880,27 @@ function createWasm() { assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?'); trueModule = null; // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line. - // When the regression is fixed, can restore the above USE_PTHREADS-enabled path. + // When the regression is fixed, can restore the above PTHREADS-enabled path. receiveInstance(result['instance']); } - function instantiateArrayBuffer(receiver) { - return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info); - }).then(function (instance) { - return instance; - }).then(receiver, function(reason) { - err('failed to asynchronously prepare wasm: ' + reason); - - // Warn on some common problems. - if (isFileURI(wasmBinaryFile)) { - err('warning: Loading from a file URI (' + wasmBinaryFile + ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing'); - } - abort(reason); - }); - } - - function instantiateAsync() { - if (!wasmBinary && - typeof WebAssembly.instantiateStreaming == 'function' && - !isDataURI(wasmBinaryFile) && - // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. - !isFileURI(wasmBinaryFile) && - typeof fetch == 'function') { - return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { - // Suppress closure warning here since the upstream definition for - // instantiateStreaming only allows Promise rather than - // an actual Response. - // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed. - /** @suppress {checkTypes} */ - var result = WebAssembly.instantiateStreaming(response, info); - - return result.then( - receiveInstantiationResult, - function(reason) { - // We expect the most common failure cause to be a bad MIME type for the binary, - // in which case falling back to ArrayBuffer instantiation should work. - err('wasm streaming compile failed: ' + reason); - err('falling back to ArrayBuffer instantiation'); - return instantiateArrayBuffer(receiveInstantiationResult); - }); - }); - } else { - return instantiateArrayBuffer(receiveInstantiationResult); - } - } - // 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. + // to manually instantiate the Wasm module themselves. This allows pages to + // run the instantiation parallel to any other async startup actions they are + // performing. + // Also pthreads and wasm workers initialize the wasm instance through this + // path. if (Module['instantiateWasm']) { + try { - var exports = Module['instantiateWasm'](info, receiveInstance); - return exports; + return Module['instantiateWasm'](info, receiveInstance); } catch(e) { err('Module.instantiateWasm callback failed with error: ' + e); - return false; + return false; } } - instantiateAsync(); + instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult); return {}; // no exports yet; we'll fill them in later } @@ -1732,110 +908,175 @@ function createWasm() { 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'); + +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 === var ASM_CONSTS = { - 202063: function() {if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false;}, - 202210: function() {if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false;}, - 202444: function($0) {if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { autoResumeAudioContext(SDL2.audioContext); } } return SDL2.audioContext === undefined ? -1 : 0;}, - 202937: function() {var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate;}, - 203005: function($0, $1, $2, $3) {var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); }}, - 204657: function($0, $1, $2, $3) {var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);}, - 205067: function($0, $1) {var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } }}, - 205672: function($0, $1) {var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } }}, - 206152: function($0) {var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); SDL2.capture.mediaStreamNode = undefined; } if (SDL2.capture.silenceBuffer !== undefined) { SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); SDL2.audio.scriptProcessorNode = undefined; } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; }}, - 207324: function($0, $1, $2) {var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); return 0;}, - 208803: function($0, $1, $2, $3, $4) {var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf;}, - 209792: function($0) {if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } return 0;}, - 209885: function() {if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; }}, - 209954: function() {return window.innerWidth;}, - 209984: function() {return window.innerHeight;} + 267591: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; }, + 267738: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; }, + 267972: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { autoResumeAudioContext(SDL2.audioContext); } } return SDL2.audioContext === undefined ? -1 : 0; }, + 268465: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; }, + 268533: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } }, + 270185: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); }, + 270595: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } }, + 271200: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } } }, + 271680: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearTimeout(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); SDL2.capture.mediaStreamNode = undefined; } if (SDL2.capture.silenceBuffer !== undefined) { SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); SDL2.audio.scriptProcessorNode = undefined; } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } }, + 272852: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); }, + 274321: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels >> 2; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; }, + 275310: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } }, + 275393: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } }, + 275462: () => { return window.innerWidth; }, + 275492: () => { return window.innerHeight; } }; -function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = document.createElement('textarea'); ta.setAttribute('autocomplete', 'off'); ta.setAttribute('autocorrect', 'off'); ta.setAttribute('autocapitalize', 'off'); ta.setAttribute('spellcheck', 'false'); ta.style.left = -100 + 'px'; ta.style.top = -100 + 'px'; ta.style.height = 1; ta.style.width = 1; ta.value = str; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); } - +function sapp_js_write_clipboard(c_str) { var str = UTF8ToString(c_str); var ta = document.createElement('textarea'); ta.setAttribute('autocomplete', 'off'); ta.setAttribute('autocorrect', 'off'); ta.setAttribute('autocapitalize', 'off'); ta.setAttribute('spellcheck', 'false'); ta.style.left = -100 + 'px'; ta.style.top = -100 + 'px'; ta.style.height = 1; ta.style.width = 1; ta.value = str; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); } +// end include: preamble.js + /** @constructor */ + function ExitStatus(status) { + this.name = 'ExitStatus'; + this.message = `Program terminated with exit(${status})`; + this.status = status; + } - function listenOnce(object, event, func) { + var listenOnce = (object, event, func) => { object.addEventListener(event, func, { 'once': true }); - } + }; /** @param {Object=} elements */ - function autoResumeAudioContext(ctx, elements) { + var autoResumeAudioContext = (ctx, elements) => { if (!elements) { elements = [document, document.getElementById('canvas')]; } - ['keydown', 'mousedown', 'touchstart'].forEach(function(event) { - elements.forEach(function(element) { + ['keydown', 'mousedown', 'touchstart'].forEach((event) => { + elements.forEach((element) => { if (element) { - listenOnce(element, event, function() { + listenOnce(element, event, () => { if (ctx.state === 'suspended') ctx.resume(); }); } }); }); - } + }; - function callRuntimeCallbacks(callbacks) { + var callRuntimeCallbacks = (callbacks) => { while (callbacks.length > 0) { - var callback = callbacks.shift(); - if (typeof callback == 'function') { - callback(Module); // Pass the module as the first argument. - continue; - } - var func = callback.func; - if (typeof func == 'number') { - if (callback.arg === undefined) { - // Run the wasm function ptr with signature 'v'. If no function - // with such signature was exported, this call does not need - // to be emitted (and would confuse Closure) - getWasmTableEntry(func)(); - } else { - // If any function with signature 'vi' was exported, run - // the callback with that signature. - getWasmTableEntry(func)(callback.arg); - } - } else { - func(callback.arg === undefined ? null : callback.arg); - } + // Pass the module as the first argument. + callbacks.shift()(Module); } - } - - function withStackSave(f) { - var stack = stackSave(); - var ret = f(); - stackRestore(stack); - return ret; - } - function demangle(func) { - warnOnce('warning: build with -sDEMANGLE_SUPPORT to link in libcxxabi demangling'); - return func; - } - - function demangleAll(text) { - var regex = - /\b_Z[\w\d_]+/g; - return text.replace(regex, - function(x) { - var y = demangle(x); - return x === y ? x : (y + ' [' + x + ']'); - }); - } + }; - function dynCallLegacy(sig, ptr, args) { - assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); + var dynCallLegacy = (sig, ptr, args) => { + assert(('dynCall_' + sig) in Module, `bad function pointer type - dynCall function not found for sig '${sig}'`); if (args && args.length) { // j (64-bit integer) must be passed in as two numbers [low 32, high 32]. assert(args.length === sig.substring(1).replace(/j/g, '--').length); } else { assert(sig.length == 1); } - var f = Module["dynCall_" + sig]; + var f = Module['dynCall_' + sig]; return args && args.length ? f.apply(null, [ptr].concat(args)) : f.call(null, ptr); - } + }; var wasmTableMirror = []; - function getWasmTableEntry(funcPtr) { + var getWasmTableEntry = (funcPtr) => { var func = wasmTableMirror[funcPtr]; if (!func) { if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1; @@ -1843,71 +1084,155 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } assert(wasmTable.get(funcPtr) == func, "JavaScript-side Wasm function table mirror is out of date!"); return func; - } + }; + /** @param {Object=} args */ - function dynCall(sig, ptr, args) { + var dynCall = (sig, ptr, args) => { // Without WASM_BIGINT support we cannot directly call function with i64 as // part of thier signature, so we rely the dynCall functions generated by // wasm-emscripten-finalize if (sig.includes('j')) { return dynCallLegacy(sig, ptr, args); } - assert(getWasmTableEntry(ptr), 'missing table entry in dynCall: ' + ptr); - return getWasmTableEntry(ptr).apply(null, args) + assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`); + var rtn = getWasmTableEntry(ptr).apply(null, args); + return rtn; + + }; + + + /** + * @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'); + }; - function handleException(e) { - // Certain exception types we do not treat as errors since they are used for - // internal control flow. - // 1. ExitStatus, which is thrown by exit() - // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others - // that wish to return to JS event loop. - if (e instanceof ExitStatus || e == 'unwind') { - return EXITSTATUS; - } - quit_(1, e); + + /** + * @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}`); } + } - function jsStackTrace() { - var error = new Error(); - if (!error.stack) { - // IE10+ special cases: It does have callstack info, but it is only - // populated if an Error object is thrown, so try that as a special-case. - try { - throw new Error(); - } catch(e) { - error = e; + 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 (!error.stack) { - return '(no stack trace available)'; + + if (u0 < 0x10000) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); } } - return error.stack.toString(); - } - - function setWasmTableEntry(idx, func) { - wasmTable.set(idx, func); - // With ABORT_ON_WASM_EXCEPTIONS wasmTable.get is overriden to return wrapped - // functions so we need to call it here to retrieve the potential wrapper correctly - // instead of just storing 'func' directly into wasmTableMirror - wasmTableMirror[idx] = wasmTable.get(idx); - } - - function stackTrace() { - var js = jsStackTrace(); - if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); - return demangleAll(js); - } - - function ___assert_fail(condition, filename, line, func) { - abort('Assertion failed: ' + UTF8ToString(condition) + ', at: ' + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']); - } - - function ___cxa_allocate_exception(size) { - // Thrown object is prepended by exception metadata block - return _malloc(size + 24) + 24; - } + 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']); + }; /** @constructor */ function ExceptionInfo(excPtr) { @@ -1930,10 +1255,6 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return HEAPU32[(((this.ptr)+(8))>>2)]; }; - this.set_refcount = function(refcount) { - HEAP32[((this.ptr)>>2)] = refcount; - }; - this.set_caught = function (caught) { caught = caught ? 1 : 0; HEAP8[(((this.ptr)+(12))>>0)] = caught; @@ -1957,24 +1278,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = this.set_adjusted_ptr(0); this.set_type(type); this.set_destructor(destructor); - this.set_refcount(0); - this.set_caught(false); - this.set_rethrown(false); } - this.add_ref = function() { - var value = HEAP32[((this.ptr)>>2)]; - HEAP32[((this.ptr)>>2)] = value + 1; - }; - - // Returns true if last reference released. - this.release_ref = function() { - var prev = HEAP32[((this.ptr)>>2)]; - HEAP32[((this.ptr)>>2)] = prev - 1; - assert(prev > 0); - return prev === 1; - }; - this.set_adjusted_ptr = function(adjustedPtr) { HEAPU32[(((this.ptr)+(16))>>2)] = adjustedPtr; }; @@ -2009,23 +1314,27 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = info.init(type, destructor); exceptionLast = ptr; uncaughtExceptionCount++; - throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -sNO_DISABLE_EXCEPTION_CATCHING or -sEXCEPTION_CATCHING_ALLOWED=[..] to catch."; + assert(false, 'Exception thrown, but exception catching is not enabled. Compile with -sNO_DISABLE_EXCEPTION_CATCHING or -sEXCEPTION_CATCHING_ALLOWED=[..] to catch.'); } - function setErrNo(value) { + var setErrNo = (value) => { HEAP32[((___errno_location())>>2)] = value; return value; - } + }; - var SYSCALLS = {varargs:undefined,get:function() { + var SYSCALLS = { + varargs:undefined, + get() { assert(SYSCALLS.varargs != undefined); SYSCALLS.varargs += 4; var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)]; return ret; - },getStr:function(ptr) { + }, + getStr(ptr) { var ret = UTF8ToString(ptr); return ret; - }}; + }, + }; function ___syscall_fcntl64(fd, cmd, varargs) { SYSCALLS.varargs = varargs; @@ -2044,19 +1353,17 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = abort('it should not be possible to operate on streams when !SYSCALLS_REQUIRE_FILESYSTEM'); } - function __emscripten_date_now() { - return Date.now(); - } - var nowIsMonotonic = true;; - function __emscripten_get_now_is_monotonic() { - return nowIsMonotonic; - } + var __emscripten_get_now_is_monotonic = () => nowIsMonotonic; - function _abort() { + var _abort = () => { abort('native code called abort()'); - } + }; + + var runtimeKeepalivePush = () => { + runtimeKeepaliveCounter += 1; + }; function _emscripten_set_main_loop_timing(mode, value) { Browser.mainLoop.timingMode = mode; Browser.mainLoop.timingValue = value; @@ -2070,30 +1377,31 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = runtimeKeepalivePush(); Browser.mainLoop.running = true; } - if (mode == 0 /*EM_TIMING_SETTIMEOUT*/) { + if (mode == 0) { Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_setTimeout() { var timeUntilNextTick = Math.max(0, Browser.mainLoop.tickStartTime + value - _emscripten_get_now())|0; setTimeout(Browser.mainLoop.runner, timeUntilNextTick); // doing this each time means that on exception, we stop }; Browser.mainLoop.method = 'timeout'; - } else if (mode == 1 /*EM_TIMING_RAF*/) { + } else if (mode == 1) { Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler_rAF() { Browser.requestAnimationFrame(Browser.mainLoop.runner); }; Browser.mainLoop.method = 'rAF'; - } else if (mode == 2 /*EM_TIMING_SETIMMEDIATE*/) { + } else if (mode == 2) { if (typeof setImmediate == 'undefined') { // Emulate setImmediate. (note: not a complete polyfill, we don't emulate clearImmediate() to keep code size to minimum, since not needed) var setImmediates = []; var emscriptenMainLoopMessageId = 'setimmediate'; - var Browser_setImmediate_messageHandler = function(/** @type {Event} */ event) { + /** @param {Event} event */ + var Browser_setImmediate_messageHandler = (event) => { // When called in current thread or Worker, the main loop ID is structured slightly different to accommodate for --proxy-to-worker runtime listening to Worker events, // so check for both cases. if (event.data === emscriptenMainLoopMessageId || event.data.target === emscriptenMainLoopMessageId) { event.stopPropagation(); setImmediates.shift()(); } - } + }; addEventListener("message", Browser_setImmediate_messageHandler, true); setImmediate = /** @type{function(function(): ?, ...?): number} */(function Browser_emulated_setImmediate(func) { setImmediates.push(func); @@ -2112,24 +1420,62 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 0; } - var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) { - _emscripten_get_now = () => { - var t = process['hrtime'](); - return t[0] * 1e3 + t[1] / 1e6; - }; - } else _emscripten_get_now = () => performance.now(); + 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(); ; - function runtimeKeepalivePush() { - runtimeKeepaliveCounter += 1; - } - function _exit(status) { - // void _exit(int status); - // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html - exit(status); - } - function maybeExit() { + 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; + + if (!keepRuntimeAlive()) { + exitRuntime(); + } + + // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down + if (keepRuntimeAlive() && !implicit) { + var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`; + err(msg); + } + + _proc_exit(status); + }; + var _exit = exitJS; + + 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 maybeExit = () => { + if (runtimeExited) { + return; + } if (!keepRuntimeAlive()) { try { _exit(EXITSTATUS); @@ -2137,7 +1483,13 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = handleException(e); } } - } + }; + + + var runtimeKeepalivePop = () => { + assert(runtimeKeepaliveCounter > 0); + runtimeKeepaliveCounter -= 1; + }; /** * @param {number=} arg @@ -2197,11 +1549,11 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = // Implement very basic swap interval control Browser.mainLoop.currentFrameNumber = Browser.mainLoop.currentFrameNumber + 1 | 0; - if (Browser.mainLoop.timingMode == 1/*EM_TIMING_RAF*/ && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) { + if (Browser.mainLoop.timingMode == 1 && Browser.mainLoop.timingValue > 1 && Browser.mainLoop.currentFrameNumber % Browser.mainLoop.timingValue != 0) { // Not the scheduled time to render this frame - skip. Browser.mainLoop.scheduler(); return; - } else if (Browser.mainLoop.timingMode == 0/*EM_TIMING_SETTIMEOUT*/) { + } else if (Browser.mainLoop.timingMode == 0) { Browser.mainLoop.tickStartTime = _emscripten_get_now(); } @@ -2230,8 +1582,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } if (!noSetTiming) { - if (fps && fps > 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 1000.0 / fps); - else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, 1); // Do rAF by rendering each frame (no decimating) + if (fps && fps > 0) { + _emscripten_set_main_loop_timing(0, 1000.0 / fps); + } else { + // Do rAF by rendering each frame (no decimating) + _emscripten_set_main_loop_timing(1, 1); + } Browser.mainLoop.scheduler(); } @@ -2241,42 +1597,53 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } - /** @param {boolean=} synchronous */ - function callUserCallback(func, synchronous) { + + var callUserCallback = (func) => { if (runtimeExited || ABORT) { err('user callback triggered after runtime exited or application aborted. Ignoring.'); return; } - // For synchronous calls, let any exceptions propagate, and don't let the runtime exit. - if (synchronous) { - func(); - return; - } try { func(); - maybeExit(); + maybeExit(); } catch (e) { handleException(e); } - } + }; + + - function runtimeKeepalivePop() { - assert(runtimeKeepaliveCounter > 0); - runtimeKeepaliveCounter -= 1; - } /** @param {number=} timeout */ - function safeSetTimeout(func, timeout) { + var safeSetTimeout = (func, timeout) => { runtimeKeepalivePush(); - return setTimeout(function() { + return setTimeout(() => { runtimeKeepalivePop(); callUserCallback(func); }, timeout); - } - var Browser = {mainLoop:{running:false,scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function() { + }; + + + + + + var Browser = { + mainLoop:{ + running:false, + scheduler:null, + method:"", + currentlyRunningMainloop:0, + func:null, + arg:0, + timingMode:0, + timingValue:0, + currentFrameNumber:0, + queue:[], + pause:function() { Browser.mainLoop.scheduler = null; // Incrementing this signals the previous main loop that it's now become old, and it must return. Browser.mainLoop.currentlyRunningMainloop++; - },resume:function() { + }, + resume:function() { Browser.mainLoop.currentlyRunningMainloop++; var timingMode = Browser.mainLoop.timingMode; var timingValue = Browser.mainLoop.timingValue; @@ -2286,7 +1653,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = setMainLoop(func, 0, false, Browser.mainLoop.arg, true); _emscripten_set_main_loop_timing(timingMode, timingValue); Browser.mainLoop.scheduler(); - },updateStatus:function() { + }, + updateStatus:function() { if (Module['setStatus']) { var message = Module['statusMessage'] || 'Please wait...'; var remaining = Browser.mainLoop.remainingBlockers; @@ -2301,7 +1669,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = Module['setStatus'](''); } } - },runIter:function(func) { + }, + runIter:function(func) { if (ABORT) return; if (Module['preMainLoop']) { var preRet = Module['preMainLoop'](); @@ -2311,147 +1680,16 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } callUserCallback(func); if (Module['postMainLoop']) Module['postMainLoop'](); - }},isFullscreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function() { - if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers - - if (Browser.initted) return; + }, + }, + isFullscreen:false, + pointerLock:false, + moduleContextCreatedCallbacks:[], + workers:[], + init:function() { + if (Browser.initted) return; Browser.initted = true; - try { - new Blob(); - Browser.hasBlobConstructor = true; - } catch(e) { - Browser.hasBlobConstructor = false; - out("warning: no blob constructor, cannot create blobs with mimetypes"); - } - Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? out("warning: no BlobBuilder") : null)); - Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined; - if (!Module.noImageDecoding && typeof Browser.URLObject == 'undefined') { - out("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available."); - Module.noImageDecoding = true; - } - - // Support for plugins that can process preloaded files. You can add more of these to - // your app by creating and appending to Module.preloadPlugins. - // - // Each plugin is asked if it can handle a file based on the file's name. If it can, - // it is given the file's raw data. When it is done, it calls a callback with the file's - // (possibly modified) data. For example, a plugin might decompress a file, or it - // might create some side data structure for use later (like an Image element, etc.). - - var imagePlugin = {}; - imagePlugin['canHandle'] = function imagePlugin_canHandle(name) { - return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name); - }; - imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) { - var b = null; - if (Browser.hasBlobConstructor) { - try { - b = new Blob([byteArray], { type: Browser.getMimetype(name) }); - if (b.size !== byteArray.length) { // Safari bug #118630 - // Safari's Blob can only take an ArrayBuffer - b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) }); - } - } catch(e) { - warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder'); - } - } - if (!b) { - var bb = new Browser.BlobBuilder(); - bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range - b = bb.getBlob(); - } - var url = Browser.URLObject.createObjectURL(b); - assert(typeof url == 'string', 'createObjectURL must return a url as a string'); - var img = new Image(); - img.onload = () => { - assert(img.complete, 'Image ' + name + ' could not be decoded'); - var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement('canvas')); - canvas.width = img.width; - canvas.height = img.height; - var ctx = canvas.getContext('2d'); - ctx.drawImage(img, 0, 0); - preloadedImages[name] = canvas; - Browser.URLObject.revokeObjectURL(url); - if (onload) onload(byteArray); - }; - img.onerror = (event) => { - out('Image ' + url + ' could not be decoded'); - if (onerror) onerror(); - }; - img.src = url; - }; - Module['preloadPlugins'].push(imagePlugin); - - var audioPlugin = {}; - audioPlugin['canHandle'] = function audioPlugin_canHandle(name) { - return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 }; - }; - audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) { - var done = false; - function finish(audio) { - if (done) return; - done = true; - preloadedAudios[name] = audio; - if (onload) onload(byteArray); - } - function fail() { - if (done) return; - done = true; - preloadedAudios[name] = new Audio(); // empty shim - if (onerror) onerror(); - } - if (Browser.hasBlobConstructor) { - try { - var b = new Blob([byteArray], { type: Browser.getMimetype(name) }); - } catch(e) { - return fail(); - } - var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this! - assert(typeof url == 'string', 'createObjectURL must return a url as a string'); - var audio = new Audio(); - audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926 - audio.onerror = function audio_onerror(event) { - if (done) return; - out('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach'); - function encode64(data) { - var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - var PAD = '='; - var ret = ''; - var leftchar = 0; - var leftbits = 0; - for (var i = 0; i < data.length; i++) { - leftchar = (leftchar << 8) | data[i]; - leftbits += 8; - while (leftbits >= 6) { - var curr = (leftchar >> (leftbits-6)) & 0x3f; - leftbits -= 6; - ret += BASE[curr]; - } - } - if (leftbits == 2) { - ret += BASE[(leftchar&3) << 4]; - ret += PAD + PAD; - } else if (leftbits == 4) { - ret += BASE[(leftchar&0xf) << 2]; - ret += PAD; - } - return ret; - } - audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray); - finish(audio); // we don't wait for confirmation this worked - but it's worth trying - }; - audio.src = url; - // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror - safeSetTimeout(function() { - finish(audio); // try to use it even though it is not necessarily ready to play - }, 10000); - } else { - return fail(); - } - }; - Module['preloadPlugins'].push(audioPlugin); - // Canvas event setup function pointerLockChange() { @@ -2469,12 +1707,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = canvas['mozRequestPointerLock'] || canvas['webkitRequestPointerLock'] || canvas['msRequestPointerLock'] || - function(){}; + (() => {}); canvas.exitPointerLock = document['exitPointerLock'] || document['mozExitPointerLock'] || document['webkitExitPointerLock'] || document['msExitPointerLock'] || - function(){}; // no-op if function does not exist + (() => {}); // no-op if function does not exist canvas.exitPointerLock = canvas.exitPointerLock.bind(document); document.addEventListener('pointerlockchange', pointerLockChange, false); @@ -2483,7 +1721,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = document.addEventListener('mspointerlockchange', pointerLockChange, false); if (Module['elementPointerLock']) { - canvas.addEventListener("click", function(ev) { + canvas.addEventListener("click", (ev) => { if (!Browser.pointerLock && Module['canvas'].requestPointerLock) { Module['canvas'].requestPointerLock(); ev.preventDefault(); @@ -2491,20 +1729,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }, false); } } - },handledByPreloadPlugin:function(byteArray, fullname, finish, onerror) { - // Ensure plugins are ready. - Browser.init(); - - var handled = false; - Module['preloadPlugins'].forEach(function(plugin) { - if (handled) return; - if (plugin['canHandle'](fullname)) { - plugin['handle'](byteArray, fullname, finish, onerror); - handled = true; - } - }); - return handled; - },createContext:function(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) { + }, + createContext:function(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) { if (useWebGL && Module.ctx && canvas == Module.canvas) return Module.ctx; // no need to recreate GL context if it's already been created for this canvas. var ctx; @@ -2544,11 +1770,16 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = Module.ctx = ctx; if (useWebGL) GL.makeContextCurrent(contextHandle); Module.useWebGL = useWebGL; - Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() }); + Browser.moduleContextCreatedCallbacks.forEach((callback) => callback()); Browser.init(); } return ctx; - },destroyContext:function(canvas, useWebGL, setInModule) {},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen:function(lockPointer, resizeCanvas) { + }, + destroyContext:function(canvas, useWebGL, setInModule) {}, + fullscreenHandlersInstalled:false, + lockPointer:undefined, + resizeCanvas:undefined, + requestFullscreen:function(lockPointer, resizeCanvas) { Browser.lockPointer = lockPointer; Browser.resizeCanvas = resizeCanvas; if (typeof Browser.lockPointer == 'undefined') Browser.lockPointer = true; @@ -2601,13 +1832,15 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = canvasContainer.requestFullscreen = canvasContainer['requestFullscreen'] || canvasContainer['mozRequestFullScreen'] || canvasContainer['msRequestFullscreen'] || - (canvasContainer['webkitRequestFullscreen'] ? function() { canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null) || - (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null); + (canvasContainer['webkitRequestFullscreen'] ? () => canvasContainer['webkitRequestFullscreen'](Element['ALLOW_KEYBOARD_INPUT']) : null) || + (canvasContainer['webkitRequestFullScreen'] ? () => canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) : null); canvasContainer.requestFullscreen(); - },requestFullScreen:function() { + }, + requestFullScreen:function() { abort('Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)'); - },exitFullscreen:function() { + }, + exitFullscreen:function() { // This is workaround for chrome. Trying to exit from fullscreen // not in fullscreen state will cause "TypeError: Document not active" // in chrome. See https://github.com/emscripten-core/emscripten/pull/8236 @@ -2620,10 +1853,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = document['mozCancelFullScreen'] || document['msExitFullscreen'] || document['webkitCancelFullScreen'] || - (function() {}); + (() => {}); CFS.apply(document, []); return true; - },nextRAF:0,fakeRequestAnimationFrame:function(func) { + }, + nextRAF:0, + fakeRequestAnimationFrame:function(func) { // try to keep 60fps between calls to here var now = Date.now(); if (Browser.nextRAF === 0) { @@ -2635,24 +1870,29 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } var delay = Math.max(Browser.nextRAF - now, 0); setTimeout(func, delay); - },requestAnimationFrame:function(func) { + }, + requestAnimationFrame:function(func) { if (typeof requestAnimationFrame == 'function') { requestAnimationFrame(func); return; } var RAF = Browser.fakeRequestAnimationFrame; RAF(func); - },safeSetTimeout:function(func) { + }, + safeSetTimeout:function(func, timeout) { // Legacy function, this is used by the SDL2 port so we need to keep it // around at least until that is updated. - return safeSetTimeout(func); - },safeRequestAnimationFrame:function(func) { + // See https://github.com/libsdl-org/SDL/pull/6304 + return safeSetTimeout(func, timeout); + }, + safeRequestAnimationFrame:function(func) { runtimeKeepalivePush(); - return Browser.requestAnimationFrame(function() { + return Browser.requestAnimationFrame(() => { runtimeKeepalivePop(); callUserCallback(func); }); - },getMimetype:function(name) { + }, + getMimetype:function(name) { return { 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', @@ -2662,23 +1902,27 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = 'wav': 'audio/wav', 'mp3': 'audio/mpeg' }[name.substr(name.lastIndexOf('.')+1)]; - },getUserMedia:function(func) { + }, + getUserMedia:function(func) { if (!window.getUserMedia) { window.getUserMedia = navigator['getUserMedia'] || navigator['mozGetUserMedia']; } window.getUserMedia(func); - },getMovementX:function(event) { + }, + getMovementX:function(event) { return event['movementX'] || event['mozMovementX'] || event['webkitMovementX'] || 0; - },getMovementY:function(event) { + }, + getMovementY:function(event) { return event['movementY'] || event['mozMovementY'] || event['webkitMovementY'] || 0; - },getMouseWheelDelta:function(event) { + }, + getMouseWheelDelta:function(event) { var delta = 0; switch (event.type) { case 'DOMMouseScroll': @@ -2712,7 +1956,16 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = throw 'unrecognized mouse wheel event: ' + event.type; } return delta; - },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(event) { // event should be mousemove, mousedown or mouseup + }, + mouseX:0, + mouseY:0, + mouseMovementX:0, + mouseMovementY:0, + touches:{ + }, + lastTouches:{ + }, + calculateMouseEvent:function(event) { // event should be mousemove, mousedown or mouseup if (Browser.pointerLock) { // When the pointer is locked, calculate the coordinates // based on the movement of the mouse. @@ -2791,16 +2044,20 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = Browser.mouseX = x; Browser.mouseY = y; } - },resizeListeners:[],updateResizeListeners:function() { + }, + resizeListeners:[], + updateResizeListeners:function() { var canvas = Module['canvas']; - Browser.resizeListeners.forEach(function(listener) { - listener(canvas.width, canvas.height); - }); - },setCanvasSize:function(width, height, noUpdates) { + Browser.resizeListeners.forEach((listener) => listener(canvas.width, canvas.height)); + }, + setCanvasSize:function(width, height, noUpdates) { var canvas = Module['canvas']; Browser.updateCanvasDimensions(canvas, width, height); if (!noUpdates) Browser.updateResizeListeners(); - },windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function() { + }, + windowedWidth:0, + windowedHeight:0, + setFullscreenCanvasSize:function() { // check if SDL is available if (typeof SDL != "undefined") { var flags = HEAPU32[((SDL.screen)>>2)]; @@ -2809,7 +2066,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } Browser.updateCanvasDimensions(Module['canvas']); Browser.updateResizeListeners(); - },setWindowedCanvasSize:function() { + }, + setWindowedCanvasSize:function() { // check if SDL is available if (typeof SDL != "undefined") { var flags = HEAPU32[((SDL.screen)>>2)]; @@ -2818,7 +2076,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } Browser.updateCanvasDimensions(Module['canvas']); Browser.updateResizeListeners(); - },updateCanvasDimensions:function(canvas, wNative, hNative) { + }, + updateCanvasDimensions:function(canvas, wNative, hNative) { if (wNative && hNative) { canvas.widthNative = wNative; canvas.heightNative = hNative; @@ -2862,10 +2121,27 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } } - }}; - var EGL = {errorCode:12288,defaultDisplayInitialized:false,currentContext:0,currentReadSurface:0,currentDrawSurface:0,contextAttributes:{alpha:false,depth:false,stencil:false,antialias:false},stringCache:{},setErrorCode:function(code) { + }, + }; + + var EGL = { + errorCode:12288, + defaultDisplayInitialized:false, + currentContext:0, + currentReadSurface:0, + currentDrawSurface:0, + contextAttributes:{ + alpha:false, + depth:false, + stencil:false, + antialias:false, + }, + stringCache:{ + }, + setErrorCode:function(code) { EGL.errorCode = code; - },chooseConfig:function(display, attribList, config, config_size, numConfigs) { + }, + chooseConfig:function(display, attribList, config, config_size, numConfigs) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; @@ -2913,22 +2189,23 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; - }}; + }, + }; function _eglBindAPI(api) { if (api == 0x30A0 /* EGL_OPENGL_ES_API */) { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; - } else { // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) { - EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); - return 0; } + // if (api == 0x30A1 /* EGL_OPENVG_API */ || api == 0x30A2 /* EGL_OPENGL_API */) { + EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); + return 0; } function _eglChooseConfig(display, attrib_list, configs, config_size, numConfigs) { return EGL.chooseConfig(display, attrib_list, configs, config_size, numConfigs); } - function __webgl_enable_ANGLE_instanced_arrays(ctx) { + function webgl_enable_ANGLE_instanced_arrays(ctx) { // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2. var ext = ctx.getExtension('ANGLE_instanced_arrays'); if (ext) { @@ -2939,7 +2216,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } - function __webgl_enable_OES_vertex_array_object(ctx) { + function webgl_enable_OES_vertex_array_object(ctx) { // Extension available in WebGL 1 from Firefox 25 and WebKit 536.28/desktop Safari 6.0.3 onwards. Core feature in WebGL 2. var ext = ctx.getExtension('OES_vertex_array_object'); if (ext) { @@ -2951,7 +2228,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } - function __webgl_enable_WEBGL_draw_buffers(ctx) { + function webgl_enable_WEBGL_draw_buffers(ctx) { // Extension available in WebGL 1 from Firefox 28 onwards. Core feature in WebGL 2. var ext = ctx.getExtension('WEBGL_draw_buffers'); if (ext) { @@ -2960,28 +2237,49 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } - function __webgl_enable_WEBGL_multi_draw(ctx) { + function webgl_enable_WEBGL_multi_draw(ctx) { // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted. return !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw')); } - var GL = {counter:1,buffers:[],programs:[],framebuffers:[],renderbuffers:[],textures:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},queries:[],stringCache:{},unpackAlignment:4,recordError:function recordError(errorCode) { + + + var GL = { + counter:1, + buffers:[], + programs:[], + framebuffers:[], + renderbuffers:[], + textures:[], + shaders:[], + vaos:[], + contexts:[], + offscreenCanvases:{ + }, + queries:[], + stringCache:{ + }, + unpackAlignment:4, + recordError:function recordError(errorCode) { if (!GL.lastError) { GL.lastError = errorCode; } - },getNewId:function(table) { + }, + getNewId:function(table) { var ret = GL.counter++; for (var i = table.length; i < ret; i++) { table[i] = null; } return ret; - },getSource:function(shader, count, string, length) { + }, + getSource:function(shader, count, string, length) { var source = ''; for (var i = 0; i < count; ++i) { var len = length ? HEAP32[(((length)+(i*4))>>2)] : -1; source += UTF8ToString(HEAP32[(((string)+(i*4))>>2)], len < 0 ? undefined : len); } return source; - },createContext:function(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) { + }, + createContext:function(/** @type {HTMLCanvasElement} */ canvas, webGLContextAttributes) { // BUG: Workaround Safari WebGL issue: After successfully acquiring WebGL context on a canvas, // calling .getContext() will always return that context independent of which 'webgl' or 'webgl2' @@ -2998,7 +2296,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = canvas.getContext = fixedGetContext; } - var ctx = + var ctx = (canvas.getContext("webgl", webGLContextAttributes) // https://caniuse.com/#feat=webgl ); @@ -3008,12 +2306,13 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = var handle = GL.registerContext(ctx, webGLContextAttributes); return handle; - },registerContext:function(ctx, webGLContextAttributes) { + }, + registerContext:function(ctx, webGLContextAttributes) { // without pthreads a context is just an integer ID var handle = GL.getNewId(GL.contexts); var context = { - handle: handle, + handle, attributes: webGLContextAttributes, version: webGLContextAttributes.majorVersion, GLctx: ctx @@ -3027,19 +2326,23 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } return handle; - },makeContextCurrent:function(contextHandle) { + }, + makeContextCurrent:function(contextHandle) { GL.currentContext = GL.contexts[contextHandle]; // Active Emscripten GL layer context object. Module.ctx = GLctx = GL.currentContext && GL.currentContext.GLctx; // Active WebGL context object. return !(contextHandle && !GLctx); - },getContext:function(contextHandle) { + }, + getContext:function(contextHandle) { return GL.contexts[contextHandle]; - },deleteContext:function(contextHandle) { + }, + deleteContext:function(contextHandle) { if (GL.currentContext === GL.contexts[contextHandle]) GL.currentContext = null; if (typeof JSEvents == 'object') JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas); // Release all JS event handlers on the DOM element that the GL context is associated with since the context is now deleted. if (GL.contexts[contextHandle] && GL.contexts[contextHandle].GLctx.canvas) GL.contexts[contextHandle].GLctx.canvas.GLctxObject = undefined; // Make sure the canvas object no longer refers to the context object so there are no GC surprises. GL.contexts[contextHandle] = null; - },initExtensions:function(context) { + }, + initExtensions:function(context) { // If this function is called without a specific context object, init the extensions of the currently active context. if (!context) context = GL.currentContext; @@ -3051,15 +2354,15 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = // Detect the presence of a few extensions manually, this GL interop layer itself will need to know if they exist. // Extensions that are only available in WebGL 1 (the calls will be no-ops if called on a WebGL 2 context active) - __webgl_enable_ANGLE_instanced_arrays(GLctx); - __webgl_enable_OES_vertex_array_object(GLctx); - __webgl_enable_WEBGL_draw_buffers(GLctx); + webgl_enable_ANGLE_instanced_arrays(GLctx); + webgl_enable_OES_vertex_array_object(GLctx); + webgl_enable_WEBGL_draw_buffers(GLctx); { GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query"); } - __webgl_enable_WEBGL_multi_draw(GLctx); + webgl_enable_WEBGL_multi_draw(GLctx); // .getSupportedExtensions() can return null if context is lost, so coerce to empty array. var exts = GLctx.getSupportedExtensions() || []; @@ -3070,7 +2373,9 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GLctx.getExtension(ext); } }); - }}; + }, + }; + function _eglCreateContext(display, config, hmm, contextAttribs) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); @@ -3137,6 +2442,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 62006; /* Magic ID for Emscripten 'default surface' */ } + function _eglDestroyContext(display, context) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); @@ -3310,23 +2616,22 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } function _eglInitialize(display, majorVersion, minorVersion) { - if (display == 62000 /* Magic ID for Emscripten 'default display' */) { - if (majorVersion) { - HEAP32[((majorVersion)>>2)] = 1; // Advertise EGL Major version: '1' - } - if (minorVersion) { - HEAP32[((minorVersion)>>2)] = 4; // Advertise EGL Minor version: '4' - } - EGL.defaultDisplayInitialized = true; - EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); - return 1; - } - else { + if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } + if (majorVersion) { + HEAP32[((majorVersion)>>2)] = 1; // Advertise EGL Major version: '1' + } + if (minorVersion) { + HEAP32[((minorVersion)>>2)] = 4; // Advertise EGL Minor version: '4' + } + EGL.defaultDisplayInitialized = true; + EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); + return 1; } + function _eglMakeCurrent(display, draw, read, context) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); @@ -3351,6 +2656,86 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 1 /* EGL_TRUE */; } + 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; + }; + var stringToUTF8 = (str, outPtr, maxBytesToWrite) => { + assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite); + }; + + var stringToNewUTF8 = (str) => { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8(str, ret, size); + return ret; + }; + function _eglQueryString(display, name) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); @@ -3361,10 +2746,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = if (EGL.stringCache[name]) return EGL.stringCache[name]; var ret; switch (name) { - case 0x3053 /* EGL_VENDOR */: ret = allocateUTF8("Emscripten"); break; - case 0x3054 /* EGL_VERSION */: ret = allocateUTF8("1.4 Emscripten EGL"); break; - case 0x3055 /* EGL_EXTENSIONS */: ret = allocateUTF8(""); break; // Currently not supporting any EGL extensions. - case 0x308D /* EGL_CLIENT_APIS */: ret = allocateUTF8("OpenGL_ES"); break; + case 0x3053 /* EGL_VENDOR */: ret = stringToNewUTF8("Emscripten"); break; + case 0x3054 /* EGL_VERSION */: ret = stringToNewUTF8("1.4 Emscripten EGL"); break; + case 0x3055 /* EGL_EXTENSIONS */: ret = stringToNewUTF8(""); break; // Currently not supporting any EGL extensions. + case 0x308D /* EGL_CLIENT_APIS */: ret = stringToNewUTF8("OpenGL_ES"); break; default: EGL.setErrorCode(0x300C /* EGL_BAD_PARAMETER */); return 0; @@ -3373,7 +2758,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return ret; } - function _eglSwapBuffers() { + function _eglSwapBuffers(dpy, surface) { if (!EGL.defaultDisplayInitialized) { EGL.setErrorCode(0x3001 /* EGL_NOT_INITIALIZED */); @@ -3392,13 +2777,14 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 0 /* EGL_FALSE */; } + function _eglSwapInterval(display, interval) { if (display != 62000 /* Magic ID for Emscripten 'default display' */) { EGL.setErrorCode(0x3008 /* EGL_BAD_DISPLAY */); return 0; } - if (interval == 0) _emscripten_set_main_loop_timing(0/*EM_TIMING_SETTIMEOUT*/, 0); - else _emscripten_set_main_loop_timing(1/*EM_TIMING_RAF*/, interval); + if (interval == 0) _emscripten_set_main_loop_timing(0, 0); + else _emscripten_set_main_loop_timing(1, interval); EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; @@ -3417,64 +2803,90 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 1; } + + /** @suppress {duplicate } */ function _eglWaitClient() { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; } - function _eglWaitGL( - ) { - return _eglWaitClient(); - } + var _eglWaitGL = _eglWaitClient; function _eglWaitNative(nativeEngineId) { EGL.setErrorCode(0x3000 /* EGL_SUCCESS */); return 1; } - var readAsmConstArgsArray = []; - function readAsmConstArgs(sigPtr, buf) { - ; - // Nobody should have mutated _readAsmConstArgsArray underneath us to be something else than an array. - assert(Array.isArray(readAsmConstArgsArray)); + var readEmAsmArgsArray = []; + var readEmAsmArgs = (sigPtr, buf) => { + // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array. + assert(Array.isArray(readEmAsmArgsArray)); // The input buffer is allocated on the stack, so it must be stack-aligned. assert(buf % 16 == 0); - readAsmConstArgsArray.length = 0; + readEmAsmArgsArray.length = 0; var ch; // Most arguments are i32s, so shift the buffer pointer so it is a plain // index into HEAP32. buf >>= 2; while (ch = HEAPU8[sigPtr++]) { - assert(ch === 100/*'d'*/ || ch === 102/*'f'*/ || ch === 105 /*'i'*/ || ch === 106 /*'j'*/, 'Invalid character ' + ch + '("' + String.fromCharCode(ch) + '") in readAsmConstArgs! Use only "d", "f" or "i", and do not specify "v" for void return argument.'); - assert(ch !== 106/*'j'*/, "i64 arguments to ASM_JS function are not available without WASM_BIGINT"); + var chr = String.fromCharCode(ch); + var validChars = ['d', 'f', 'i']; + assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`); // Floats are always passed as doubles, and doubles and int64s take up 8 // bytes (two 32-bit slots) in memory, align reads to these: - buf += (ch != 105) & buf; - readAsmConstArgsArray.push( + buf += (ch != 105/*i*/) & buf; + readEmAsmArgsArray.push( ch == 105/*i*/ ? HEAP32[buf] : HEAPF64[buf++ >> 1] ); ++buf; } - return readAsmConstArgsArray; - } - function _emscripten_asm_const_int(code, sigPtr, argbuf) { - var args = readAsmConstArgs(sigPtr, argbuf); - if (!ASM_CONSTS.hasOwnProperty(code)) abort('No EM_ASM constant found at address ' + code); + return readEmAsmArgsArray; + }; + var runEmAsmFunction = (code, sigPtr, argbuf) => { + var args = readEmAsmArgs(sigPtr, argbuf); + if (!ASM_CONSTS.hasOwnProperty(code)) abort(`No EM_ASM constant found at address ${code}`); + return ASM_CONSTS[code].apply(null, args); + }; + var _emscripten_asm_const_int = (code, sigPtr, argbuf) => { + return runEmAsmFunction(code, sigPtr, argbuf); + }; + + var runMainThreadEmAsm = (code, sigPtr, argbuf, sync) => { + var args = readEmAsmArgs(sigPtr, argbuf); + if (!ASM_CONSTS.hasOwnProperty(code)) abort(`No EM_ASM constant found at address ${code}`); return ASM_CONSTS[code].apply(null, args); + }; + var _emscripten_asm_const_int_sync_on_main_thread = (code, sigPtr, argbuf) => { + return runMainThreadEmAsm(code, sigPtr, argbuf, 1); + }; + + function _emscripten_date_now() { + return Date.now(); } - var JSEvents = {inEventHandler:0,removeAllEventListeners:function() { + var withStackSave = (f) => { + var stack = stackSave(); + var ret = f(); + stackRestore(stack); + return ret; + }; + var JSEvents = { + inEventHandler:0, + removeAllEventListeners:function() { for (var i = JSEvents.eventHandlers.length-1; i >= 0; --i) { JSEvents._removeHandler(i); } JSEvents.eventHandlers = []; JSEvents.deferredCalls = []; - },registerRemoveEventListeners:function() { + }, + registerRemoveEventListeners:function() { if (!JSEvents.removeEventListenersRegistered) { __ATEXIT__.push(JSEvents.removeAllEventListeners); JSEvents.removeEventListenersRegistered = true; } - },deferredCalls:[],deferCall:function(targetFunction, precedence, argsList) { + }, + deferredCalls:[], + deferCall:function(targetFunction, precedence, argsList) { function arraysHaveEqualContent(arrA, arrB) { if (arrA.length != arrB.length) return false; @@ -3491,22 +2903,33 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } JSEvents.deferredCalls.push({ - targetFunction: targetFunction, - precedence: precedence, - argsList: argsList + targetFunction, + precedence, + argsList }); JSEvents.deferredCalls.sort(function(x,y) { return x.precedence < y.precedence; }); - },removeDeferredCalls:function(targetFunction) { + }, + removeDeferredCalls:function(targetFunction) { for (var i = 0; i < JSEvents.deferredCalls.length; ++i) { if (JSEvents.deferredCalls[i].targetFunction == targetFunction) { JSEvents.deferredCalls.splice(i, 1); --i; } } - },canPerformEventHandlerRequests:function() { + }, + canPerformEventHandlerRequests:function() { + if (navigator.userActivation) { + // Verify against transient activation status from UserActivation API + // whether it is possible to perform a request here without needing to defer. See + // https://developer.mozilla.org/en-US/docs/Web/Security/User_activation#transient_activation + // and https://caniuse.com/mdn-api_useractivation + // At the time of writing, Firefox does not support this API: https://bugzilla.mozilla.org/show_bug.cgi?id=1791079 + return navigator.userActivation.isActive; + } return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls; - },runDeferredCalls:function() { + }, + runDeferredCalls:function() { if (!JSEvents.canPerformEventHandlerRequests()) { return; } @@ -3516,18 +2939,27 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = --i; call.targetFunction.apply(null, call.argsList); } - },eventHandlers:[],removeAllHandlersOnTarget:function(target, eventTypeString) { + }, + eventHandlers:[], + removeAllHandlersOnTarget:function(target, eventTypeString) { for (var i = 0; i < JSEvents.eventHandlers.length; ++i) { if (JSEvents.eventHandlers[i].target == target && (!eventTypeString || eventTypeString == JSEvents.eventHandlers[i].eventTypeString)) { JSEvents._removeHandler(i--); } } - },_removeHandler:function(i) { + }, + _removeHandler:function(i) { var h = JSEvents.eventHandlers[i]; h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture); JSEvents.eventHandlers.splice(i, 1); - },registerOrRemoveHandler:function(eventHandler) { + }, + registerOrRemoveHandler:function(eventHandler) { + if (!eventHandler.target) { + err('registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:'); + console.dir(eventHandler); + return -4; + } var jsEventHandler = function jsEventHandler(event) { // Increment nesting count for the event handler. ++JSEvents.inEventHandler; @@ -3555,20 +2987,28 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } } - },getNodeNameForTarget:function(target) { + return 0; + }, + getNodeNameForTarget:function(target) { if (!target) return ''; if (target == window) return '#window'; if (target == screen) return '#screen'; return (target && target.nodeName) ? target.nodeName : ''; - },fullscreenEnabled:function() { + }, + fullscreenEnabled:function() { return document.fullscreenEnabled // Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitFullscreenEnabled. // TODO: If Safari at some point ships with unprefixed version, update the version check above. || document.webkitFullscreenEnabled ; - }}; + }, + }; + + var currentFullscreenStrategy = { + }; + + - var currentFullscreenStrategy = {}; function maybeCStringToJsString(cString) { // "cString > 2" checks if the input is a number, and isn't of the special @@ -3591,18 +3031,25 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[((width)>>2)] = canvas.width; HEAP32[((height)>>2)] = canvas.height; } - function getCanvasElementSize(target) { - return withStackSave(function() { - var w = stackAlloc(8); - var h = w + 4; - var targetInt = stackAlloc(target.id.length+1); - stringToUTF8(target.id, targetInt, target.id.length+1); - var ret = _emscripten_get_canvas_element_size(targetInt, w, h); - var size = [HEAP32[((w)>>2)], HEAP32[((h)>>2)]]; - return size; - }); - } + + + var stringToUTF8OnStack = (str) => { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8(str, ret, size); + return ret; + }; + var getCanvasElementSize = (target) => withStackSave(() => { + var w = stackAlloc(8); + var h = w + 4; + + var targetInt = stringToUTF8OnStack(target.id); + var ret = _emscripten_get_canvas_element_size(targetInt, w, h); + var size = [HEAP32[((w)>>2)], HEAP32[((h)>>2)]]; + return size; + }); + function _emscripten_set_canvas_element_size(target, width, height) { var canvas = findCanvasEventTarget(target); @@ -3611,6 +3058,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = canvas.height = height; return 0; } + + function setCanvasElementSize(target, width, height) { if (!target.controlTransferredOffscreen) { target.width = width; @@ -3619,12 +3068,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = // This function is being called from high-level JavaScript code instead of asm.js/Wasm, // and it needs to synchronously proxy over to another thread, so marshal the string onto the heap to do the call. withStackSave(function() { - var targetInt = stackAlloc(target.id.length+1); - stringToUTF8(target.id, targetInt, target.id.length+1); + var targetInt = stringToUTF8OnStack(target.id); _emscripten_set_canvas_element_size(targetInt, width, height); }); } } + function registerRestoreOldStyle(canvas) { var canvasSize = getCanvasElementSize(canvas); var oldWidth = canvasSize[0]; @@ -3650,7 +3099,6 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = function restoreOldStyle() { var fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement - || document.msFullscreenElement ; if (!fullscreenElement) { document.removeEventListener('fullscreenchange', restoreOldStyle); @@ -3695,16 +3143,18 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return restoreOldStyle; } + function setLetterbox(element, topBottom, leftRight) { // Cannot use margin to specify letterboxes in FF or Chrome, since those ignore margins in fullscreen mode. element.style.paddingLeft = element.style.paddingRight = leftRight + 'px'; element.style.paddingTop = element.style.paddingBottom = topBottom + 'px'; } + function getBoundingClientRect(e) { return specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0}; } - function _JSEvents_resizeCanvasForFullscreen(target, strategy) { + function JSEvents_resizeCanvasForFullscreen(target, strategy) { var restoreOldStyle = registerRestoreOldStyle(target); var cssWidth = strategy.softFullscreen ? innerWidth : screen.width; var cssHeight = strategy.softFullscreen ? innerHeight : screen.height; @@ -3760,10 +3210,11 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } return restoreOldStyle; } - function _JSEvents_requestFullscreen(target, strategy) { + + function JSEvents_requestFullscreen(target, strategy) { // EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT + EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE is a mode where no extra logic is performed to the DOM elements. if (strategy.scaleMode != 0 || strategy.canvasResolutionScaleMode != 0) { - _JSEvents_resizeCanvasForFullscreen(target, strategy); + JSEvents_resizeCanvasForFullscreen(target, strategy); } if (target.requestFullscreen) { @@ -3782,10 +3233,11 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 0; } + function _emscripten_exit_fullscreen() { if (!JSEvents.fullscreenEnabled()) return -1; // Make sure no queued up calls will fire after this. - JSEvents.removeDeferredCalls(_JSEvents_requestFullscreen); + JSEvents.removeDeferredCalls(JSEvents_requestFullscreen); var d = specialHTMLTargets[1]; if (d.exitFullscreen) { @@ -3799,21 +3251,18 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 0; } + function requestPointerLock(target) { if (target.requestPointerLock) { target.requestPointerLock(); - } else if (target.msRequestPointerLock) { - target.msRequestPointerLock(); } else { // document.body is known to accept pointer lock, so use that to differentiate if the user passed a bad element, // or if the whole browser just doesn't support the feature. if (document.body.requestPointerLock - || document.body.msRequestPointerLock ) { return -3; - } else { - return -1; } + return -1; } return 0; } @@ -3823,8 +3272,6 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = if (document.exitPointerLock) { document.exitPointerLock(); - } else if (document.msExitPointerLock) { - document.msExitPointerLock(); } else { return -1; } @@ -3835,6 +3282,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0; } + + function _emscripten_get_element_css_size(target, width, height) { target = findEventTarget(target); if (!target) return -4; @@ -3846,6 +3295,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return 0; } + function fillGamepadEventData(eventStruct, e) { HEAPF64[((eventStruct)>>3)] = e.timestamp; for (var i = 0; i < e.axes.length; ++i) { @@ -3903,95 +3353,154 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[((height)>>2)] = screen.height; } - function _emscripten_glActiveTexture(x0) { GLctx['activeTexture'](x0) } + /** @suppress {duplicate } */ + function _glActiveTexture(x0) { GLctx.activeTexture(x0) } + var _emscripten_glActiveTexture = _glActiveTexture; - function _emscripten_glAttachShader(program, shader) { + /** @suppress {duplicate } */ + function _glAttachShader(program, shader) { GLctx.attachShader(GL.programs[program], GL.shaders[shader]); } + var _emscripten_glAttachShader = _glAttachShader; - function _emscripten_glBeginQueryEXT(target, id) { + /** @suppress {duplicate } */ + function _glBeginQueryEXT(target, id) { GLctx.disjointTimerQueryExt['beginQueryEXT'](target, GL.queries[id]); } + var _emscripten_glBeginQueryEXT = _glBeginQueryEXT; - function _emscripten_glBindAttribLocation(program, index, name) { + + /** @suppress {duplicate } */ + function _glBindAttribLocation(program, index, name) { GLctx.bindAttribLocation(GL.programs[program], index, UTF8ToString(name)); } + var _emscripten_glBindAttribLocation = _glBindAttribLocation; - function _emscripten_glBindBuffer(target, buffer) { + /** @suppress {duplicate } */ + function _glBindBuffer(target, buffer) { GLctx.bindBuffer(target, GL.buffers[buffer]); } + var _emscripten_glBindBuffer = _glBindBuffer; - function _emscripten_glBindFramebuffer(target, framebuffer) { + /** @suppress {duplicate } */ + function _glBindFramebuffer(target, framebuffer) { GLctx.bindFramebuffer(target, GL.framebuffers[framebuffer]); } + var _emscripten_glBindFramebuffer = _glBindFramebuffer; - function _emscripten_glBindRenderbuffer(target, renderbuffer) { + /** @suppress {duplicate } */ + function _glBindRenderbuffer(target, renderbuffer) { GLctx.bindRenderbuffer(target, GL.renderbuffers[renderbuffer]); } + var _emscripten_glBindRenderbuffer = _glBindRenderbuffer; - function _emscripten_glBindTexture(target, texture) { + /** @suppress {duplicate } */ + function _glBindTexture(target, texture) { GLctx.bindTexture(target, GL.textures[texture]); } + var _emscripten_glBindTexture = _glBindTexture; - function _emscripten_glBindVertexArrayOES(vao) { - GLctx['bindVertexArray'](GL.vaos[vao]); + + /** @suppress {duplicate } */ + function _glBindVertexArray(vao) { + GLctx.bindVertexArray(GL.vaos[vao]); } + /** @suppress {duplicate } */ + var _glBindVertexArrayOES = _glBindVertexArray; + var _emscripten_glBindVertexArrayOES = _glBindVertexArrayOES; - function _emscripten_glBlendColor(x0, x1, x2, x3) { GLctx['blendColor'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glBlendColor(x0, x1, x2, x3) { GLctx.blendColor(x0, x1, x2, x3) } + var _emscripten_glBlendColor = _glBlendColor; - function _emscripten_glBlendEquation(x0) { GLctx['blendEquation'](x0) } + /** @suppress {duplicate } */ + function _glBlendEquation(x0) { GLctx.blendEquation(x0) } + var _emscripten_glBlendEquation = _glBlendEquation; - function _emscripten_glBlendEquationSeparate(x0, x1) { GLctx['blendEquationSeparate'](x0, x1) } + /** @suppress {duplicate } */ + function _glBlendEquationSeparate(x0, x1) { GLctx.blendEquationSeparate(x0, x1) } + var _emscripten_glBlendEquationSeparate = _glBlendEquationSeparate; - function _emscripten_glBlendFunc(x0, x1) { GLctx['blendFunc'](x0, x1) } + /** @suppress {duplicate } */ + function _glBlendFunc(x0, x1) { GLctx.blendFunc(x0, x1) } + var _emscripten_glBlendFunc = _glBlendFunc; - function _emscripten_glBlendFuncSeparate(x0, x1, x2, x3) { GLctx['blendFuncSeparate'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glBlendFuncSeparate(x0, x1, x2, x3) { GLctx.blendFuncSeparate(x0, x1, x2, x3) } + var _emscripten_glBlendFuncSeparate = _glBlendFuncSeparate; - function _emscripten_glBufferData(target, size, data, usage) { + /** @suppress {duplicate } */ + function _glBufferData(target, size, data, usage) { // N.b. here first form specifies a heap subarray, second form an integer size, so the ?: code here is polymorphic. It is advised to avoid // randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues. GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage); } + var _emscripten_glBufferData = _glBufferData; - function _emscripten_glBufferSubData(target, offset, size, data) { + /** @suppress {duplicate } */ + function _glBufferSubData(target, offset, size, data) { GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size)); } + var _emscripten_glBufferSubData = _glBufferSubData; - function _emscripten_glCheckFramebufferStatus(x0) { return GLctx['checkFramebufferStatus'](x0) } + /** @suppress {duplicate } */ + function _glCheckFramebufferStatus(x0) { return GLctx.checkFramebufferStatus(x0) } + var _emscripten_glCheckFramebufferStatus = _glCheckFramebufferStatus; - function _emscripten_glClear(x0) { GLctx['clear'](x0) } + /** @suppress {duplicate } */ + function _glClear(x0) { GLctx.clear(x0) } + var _emscripten_glClear = _glClear; - function _emscripten_glClearColor(x0, x1, x2, x3) { GLctx['clearColor'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glClearColor(x0, x1, x2, x3) { GLctx.clearColor(x0, x1, x2, x3) } + var _emscripten_glClearColor = _glClearColor; - function _emscripten_glClearDepthf(x0) { GLctx['clearDepth'](x0) } + /** @suppress {duplicate } */ + function _glClearDepthf(x0) { GLctx.clearDepth(x0) } + var _emscripten_glClearDepthf = _glClearDepthf; - function _emscripten_glClearStencil(x0) { GLctx['clearStencil'](x0) } + /** @suppress {duplicate } */ + function _glClearStencil(x0) { GLctx.clearStencil(x0) } + var _emscripten_glClearStencil = _glClearStencil; - function _emscripten_glColorMask(red, green, blue, alpha) { + /** @suppress {duplicate } */ + function _glColorMask(red, green, blue, alpha) { GLctx.colorMask(!!red, !!green, !!blue, !!alpha); } + var _emscripten_glColorMask = _glColorMask; - function _emscripten_glCompileShader(shader) { + /** @suppress {duplicate } */ + function _glCompileShader(shader) { GLctx.compileShader(GL.shaders[shader]); } + var _emscripten_glCompileShader = _glCompileShader; - function _emscripten_glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data) { - GLctx['compressedTexImage2D'](target, level, internalFormat, width, height, border, data ? HEAPU8.subarray((data), (data+imageSize)) : null); + /** @suppress {duplicate } */ + function _glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data) { + GLctx.compressedTexImage2D(target, level, internalFormat, width, height, border, data ? HEAPU8.subarray((data), (data+imageSize)) : null); } + var _emscripten_glCompressedTexImage2D = _glCompressedTexImage2D; - function _emscripten_glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data) { - GLctx['compressedTexSubImage2D'](target, level, xoffset, yoffset, width, height, format, data ? HEAPU8.subarray((data), (data+imageSize)) : null); + /** @suppress {duplicate } */ + function _glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data) { + GLctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, data ? HEAPU8.subarray((data), (data+imageSize)) : null); } + var _emscripten_glCompressedTexSubImage2D = _glCompressedTexSubImage2D; - function _emscripten_glCopyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx['copyTexImage2D'](x0, x1, x2, x3, x4, x5, x6, x7) } + /** @suppress {duplicate } */ + function _glCopyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx.copyTexImage2D(x0, x1, x2, x3, x4, x5, x6, x7) } + var _emscripten_glCopyTexImage2D = _glCopyTexImage2D; - function _emscripten_glCopyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx['copyTexSubImage2D'](x0, x1, x2, x3, x4, x5, x6, x7) } + /** @suppress {duplicate } */ + function _glCopyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7) { GLctx.copyTexSubImage2D(x0, x1, x2, x3, x4, x5, x6, x7) } + var _emscripten_glCopyTexSubImage2D = _glCopyTexSubImage2D; - function _emscripten_glCreateProgram() { + /** @suppress {duplicate } */ + function _glCreateProgram() { var id = GL.getNewId(GL.programs); var program = GLctx.createProgram(); // Store additional information needed for each shader program: @@ -4002,17 +3511,23 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GL.programs[id] = program; return id; } + var _emscripten_glCreateProgram = _glCreateProgram; - function _emscripten_glCreateShader(shaderType) { + /** @suppress {duplicate } */ + function _glCreateShader(shaderType) { var id = GL.getNewId(GL.shaders); GL.shaders[id] = GLctx.createShader(shaderType); return id; } + var _emscripten_glCreateShader = _glCreateShader; - function _emscripten_glCullFace(x0) { GLctx['cullFace'](x0) } + /** @suppress {duplicate } */ + function _glCullFace(x0) { GLctx.cullFace(x0) } + var _emscripten_glCullFace = _glCullFace; - function _emscripten_glDeleteBuffers(n, buffers) { + /** @suppress {duplicate } */ + function _glDeleteBuffers(n, buffers) { for (var i = 0; i < n; i++) { var id = HEAP32[(((buffers)+(i*4))>>2)]; var buffer = GL.buffers[id]; @@ -4027,8 +3542,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } + var _emscripten_glDeleteBuffers = _glDeleteBuffers; - function _emscripten_glDeleteFramebuffers(n, framebuffers) { + /** @suppress {duplicate } */ + function _glDeleteFramebuffers(n, framebuffers) { for (var i = 0; i < n; ++i) { var id = HEAP32[(((framebuffers)+(i*4))>>2)]; var framebuffer = GL.framebuffers[id]; @@ -4038,8 +3555,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GL.framebuffers[id] = null; } } + var _emscripten_glDeleteFramebuffers = _glDeleteFramebuffers; - function _emscripten_glDeleteProgram(id) { + /** @suppress {duplicate } */ + function _glDeleteProgram(id) { if (!id) return; var program = GL.programs[id]; if (!program) { // glDeleteProgram actually signals an error when deleting a nonexisting object, unlike some other GL delete functions. @@ -4050,8 +3569,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = program.name = 0; GL.programs[id] = null; } + var _emscripten_glDeleteProgram = _glDeleteProgram; - function _emscripten_glDeleteQueriesEXT(n, ids) { + /** @suppress {duplicate } */ + function _glDeleteQueriesEXT(n, ids) { for (var i = 0; i < n; i++) { var id = HEAP32[(((ids)+(i*4))>>2)]; var query = GL.queries[id]; @@ -4060,8 +3581,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GL.queries[id] = null; } } + var _emscripten_glDeleteQueriesEXT = _glDeleteQueriesEXT; - function _emscripten_glDeleteRenderbuffers(n, renderbuffers) { + /** @suppress {duplicate } */ + function _glDeleteRenderbuffers(n, renderbuffers) { for (var i = 0; i < n; i++) { var id = HEAP32[(((renderbuffers)+(i*4))>>2)]; var renderbuffer = GL.renderbuffers[id]; @@ -4071,8 +3594,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GL.renderbuffers[id] = null; } } + var _emscripten_glDeleteRenderbuffers = _glDeleteRenderbuffers; - function _emscripten_glDeleteShader(id) { + /** @suppress {duplicate } */ + function _glDeleteShader(id) { if (!id) return; var shader = GL.shaders[id]; if (!shader) { // glDeleteShader actually signals an error when deleting a nonexisting object, unlike some other GL delete functions. @@ -4082,8 +3607,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GLctx.deleteShader(shader); GL.shaders[id] = null; } + var _emscripten_glDeleteShader = _glDeleteShader; - function _emscripten_glDeleteTextures(n, textures) { + /** @suppress {duplicate } */ + function _glDeleteTextures(n, textures) { for (var i = 0; i < n; i++) { var id = HEAP32[(((textures)+(i*4))>>2)]; var texture = GL.textures[id]; @@ -4093,89 +3620,143 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GL.textures[id] = null; } } + var _emscripten_glDeleteTextures = _glDeleteTextures; - function _emscripten_glDeleteVertexArraysOES(n, vaos) { + + /** @suppress {duplicate } */ + function _glDeleteVertexArrays(n, vaos) { for (var i = 0; i < n; i++) { var id = HEAP32[(((vaos)+(i*4))>>2)]; - GLctx['deleteVertexArray'](GL.vaos[id]); + GLctx.deleteVertexArray(GL.vaos[id]); GL.vaos[id] = null; } } + /** @suppress {duplicate } */ + var _glDeleteVertexArraysOES = _glDeleteVertexArrays; + var _emscripten_glDeleteVertexArraysOES = _glDeleteVertexArraysOES; - function _emscripten_glDepthFunc(x0) { GLctx['depthFunc'](x0) } + /** @suppress {duplicate } */ + function _glDepthFunc(x0) { GLctx.depthFunc(x0) } + var _emscripten_glDepthFunc = _glDepthFunc; - function _emscripten_glDepthMask(flag) { + /** @suppress {duplicate } */ + function _glDepthMask(flag) { GLctx.depthMask(!!flag); } + var _emscripten_glDepthMask = _glDepthMask; - function _emscripten_glDepthRangef(x0, x1) { GLctx['depthRange'](x0, x1) } + /** @suppress {duplicate } */ + function _glDepthRangef(x0, x1) { GLctx.depthRange(x0, x1) } + var _emscripten_glDepthRangef = _glDepthRangef; - function _emscripten_glDetachShader(program, shader) { + /** @suppress {duplicate } */ + function _glDetachShader(program, shader) { GLctx.detachShader(GL.programs[program], GL.shaders[shader]); } + var _emscripten_glDetachShader = _glDetachShader; - function _emscripten_glDisable(x0) { GLctx['disable'](x0) } + /** @suppress {duplicate } */ + function _glDisable(x0) { GLctx.disable(x0) } + var _emscripten_glDisable = _glDisable; - function _emscripten_glDisableVertexAttribArray(index) { + /** @suppress {duplicate } */ + function _glDisableVertexAttribArray(index) { GLctx.disableVertexAttribArray(index); } + var _emscripten_glDisableVertexAttribArray = _glDisableVertexAttribArray; - function _emscripten_glDrawArrays(mode, first, count) { + /** @suppress {duplicate } */ + function _glDrawArrays(mode, first, count) { GLctx.drawArrays(mode, first, count); } + var _emscripten_glDrawArrays = _glDrawArrays; - function _emscripten_glDrawArraysInstancedANGLE(mode, first, count, primcount) { - GLctx['drawArraysInstanced'](mode, first, count, primcount); + + /** @suppress {duplicate } */ + function _glDrawArraysInstanced(mode, first, count, primcount) { + GLctx.drawArraysInstanced(mode, first, count, primcount); } + /** @suppress {duplicate } */ + var _glDrawArraysInstancedANGLE = _glDrawArraysInstanced; + var _emscripten_glDrawArraysInstancedANGLE = _glDrawArraysInstancedANGLE; + var tempFixedLengthArray = []; - function _emscripten_glDrawBuffersWEBGL(n, bufs) { + + /** @suppress {duplicate } */ + function _glDrawBuffers(n, bufs) { var bufArray = tempFixedLengthArray[n]; for (var i = 0; i < n; i++) { bufArray[i] = HEAP32[(((bufs)+(i*4))>>2)]; } - GLctx['drawBuffers'](bufArray); + GLctx.drawBuffers(bufArray); } + /** @suppress {duplicate } */ + var _glDrawBuffersWEBGL = _glDrawBuffers; + var _emscripten_glDrawBuffersWEBGL = _glDrawBuffersWEBGL; - function _emscripten_glDrawElements(mode, count, type, indices) { + /** @suppress {duplicate } */ + function _glDrawElements(mode, count, type, indices) { GLctx.drawElements(mode, count, type, indices); } + var _emscripten_glDrawElements = _glDrawElements; - function _emscripten_glDrawElementsInstancedANGLE(mode, count, type, indices, primcount) { - GLctx['drawElementsInstanced'](mode, count, type, indices, primcount); + + /** @suppress {duplicate } */ + function _glDrawElementsInstanced(mode, count, type, indices, primcount) { + GLctx.drawElementsInstanced(mode, count, type, indices, primcount); } + /** @suppress {duplicate } */ + var _glDrawElementsInstancedANGLE = _glDrawElementsInstanced; + var _emscripten_glDrawElementsInstancedANGLE = _glDrawElementsInstancedANGLE; - function _emscripten_glEnable(x0) { GLctx['enable'](x0) } + /** @suppress {duplicate } */ + function _glEnable(x0) { GLctx.enable(x0) } + var _emscripten_glEnable = _glEnable; - function _emscripten_glEnableVertexAttribArray(index) { + /** @suppress {duplicate } */ + function _glEnableVertexAttribArray(index) { GLctx.enableVertexAttribArray(index); } + var _emscripten_glEnableVertexAttribArray = _glEnableVertexAttribArray; - function _emscripten_glEndQueryEXT(target) { + /** @suppress {duplicate } */ + function _glEndQueryEXT(target) { GLctx.disjointTimerQueryExt['endQueryEXT'](target); } + var _emscripten_glEndQueryEXT = _glEndQueryEXT; - function _emscripten_glFinish() { GLctx['finish']() } + /** @suppress {duplicate } */ + function _glFinish() { GLctx.finish() } + var _emscripten_glFinish = _glFinish; - function _emscripten_glFlush() { GLctx['flush']() } + /** @suppress {duplicate } */ + function _glFlush() { GLctx.flush() } + var _emscripten_glFlush = _glFlush; - function _emscripten_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) { + /** @suppress {duplicate } */ + function _glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) { GLctx.framebufferRenderbuffer(target, attachment, renderbuffertarget, GL.renderbuffers[renderbuffer]); } + var _emscripten_glFramebufferRenderbuffer = _glFramebufferRenderbuffer; - function _emscripten_glFramebufferTexture2D(target, attachment, textarget, texture, level) { + /** @suppress {duplicate } */ + function _glFramebufferTexture2D(target, attachment, textarget, texture, level) { GLctx.framebufferTexture2D(target, attachment, textarget, GL.textures[texture], level); } + var _emscripten_glFramebufferTexture2D = _glFramebufferTexture2D; - function _emscripten_glFrontFace(x0) { GLctx['frontFace'](x0) } + /** @suppress {duplicate } */ + function _glFrontFace(x0) { GLctx.frontFace(x0) } + var _emscripten_glFrontFace = _glFrontFace; function __glGenObject(n, buffers, createFunction, objectTable ) { @@ -4191,17 +3772,24 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[(((buffers)+(i*4))>>2)] = id; } } - function _emscripten_glGenBuffers(n, buffers) { + + /** @suppress {duplicate } */ + function _glGenBuffers(n, buffers) { __glGenObject(n, buffers, 'createBuffer', GL.buffers ); } + var _emscripten_glGenBuffers = _glGenBuffers; - function _emscripten_glGenFramebuffers(n, ids) { + + /** @suppress {duplicate } */ + function _glGenFramebuffers(n, ids) { __glGenObject(n, ids, 'createFramebuffer', GL.framebuffers ); } + var _emscripten_glGenFramebuffers = _glGenFramebuffers; - function _emscripten_glGenQueriesEXT(n, ids) { + /** @suppress {duplicate } */ + function _glGenQueriesEXT(n, ids) { for (var i = 0; i < n; i++) { var query = GLctx.disjointTimerQueryExt['createQueryEXT'](); if (!query) { @@ -4215,24 +3803,40 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[(((ids)+(i*4))>>2)] = id; } } + var _emscripten_glGenQueriesEXT = _glGenQueriesEXT; - function _emscripten_glGenRenderbuffers(n, renderbuffers) { + + /** @suppress {duplicate } */ + function _glGenRenderbuffers(n, renderbuffers) { __glGenObject(n, renderbuffers, 'createRenderbuffer', GL.renderbuffers ); } + var _emscripten_glGenRenderbuffers = _glGenRenderbuffers; - function _emscripten_glGenTextures(n, textures) { + + /** @suppress {duplicate } */ + function _glGenTextures(n, textures) { __glGenObject(n, textures, 'createTexture', GL.textures ); } + var _emscripten_glGenTextures = _glGenTextures; - function _emscripten_glGenVertexArraysOES(n, arrays) { + + + /** @suppress {duplicate } */ + function _glGenVertexArrays(n, arrays) { __glGenObject(n, arrays, 'createVertexArray', GL.vaos ); } + /** @suppress {duplicate } */ + var _glGenVertexArraysOES = _glGenVertexArrays; + var _emscripten_glGenVertexArraysOES = _glGenVertexArraysOES; - function _emscripten_glGenerateMipmap(x0) { GLctx['generateMipmap'](x0) } + /** @suppress {duplicate } */ + function _glGenerateMipmap(x0) { GLctx.generateMipmap(x0) } + var _emscripten_glGenerateMipmap = _glGenerateMipmap; + function __glGetActiveAttribOrUniform(funcName, program, index, bufSize, length, size, type, name) { program = GL.programs[program]; var info = GLctx[funcName](program, index); @@ -4243,15 +3847,22 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = if (type) HEAP32[((type)>>2)] = info.type; } } - function _emscripten_glGetActiveAttrib(program, index, bufSize, length, size, type, name) { + + /** @suppress {duplicate } */ + function _glGetActiveAttrib(program, index, bufSize, length, size, type, name) { __glGetActiveAttribOrUniform('getActiveAttrib', program, index, bufSize, length, size, type, name); } + var _emscripten_glGetActiveAttrib = _glGetActiveAttrib; - function _emscripten_glGetActiveUniform(program, index, bufSize, length, size, type, name) { + + /** @suppress {duplicate } */ + function _glGetActiveUniform(program, index, bufSize, length, size, type, name) { __glGetActiveAttribOrUniform('getActiveUniform', program, index, bufSize, length, size, type, name); } + var _emscripten_glGetActiveUniform = _glGetActiveUniform; - function _emscripten_glGetAttachedShaders(program, maxCount, count, shaders) { + /** @suppress {duplicate } */ + function _glGetAttachedShaders(program, maxCount, count, shaders) { var result = GLctx.getAttachedShaders(GL.programs[program]); var len = result.length; if (len > maxCount) { @@ -4263,10 +3874,14 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[(((shaders)+(i*4))>>2)] = id; } } + var _emscripten_glGetAttachedShaders = _glGetAttachedShaders; - function _emscripten_glGetAttribLocation(program, name) { + + /** @suppress {duplicate } */ + function _glGetAttribLocation(program, name) { return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name)); } + var _emscripten_glGetAttribLocation = _glGetAttribLocation; function readI53FromI64(ptr) { return HEAPU32[ptr>>2] + HEAP32[ptr+4>>2] * 4294967296; @@ -4279,8 +3894,9 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAPU32[ptr>>2] = num; HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296; var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr); - if (deserialized != num) warnOnce('writeI53ToI64() out of range: serialized JS Number ' + num + ' to Wasm heap as bytes lo=0x' + HEAPU32[ptr>>2].toString(16) + ', hi=0x' + HEAPU32[ptr+4>>2].toString(16) + ', which deserializes back to ' + deserialized + ' instead!'); + if (deserialized != num) warnOnce('writeI53ToI64() out of range: serialized JS Number ' + num + ' to Wasm heap as bytes lo=' + ptrToString(HEAPU32[ptr>>2]) + ', hi=' + ptrToString(HEAPU32[ptr+4>>2]) + ', which deserializes back to ' + deserialized + ' instead!'); } + function emscriptenWebGLGet(name_, p, type) { // Guard against user passing a null pointer. // Note that GLES2 spec does not say anything about how passing a null pointer should be treated. @@ -4381,11 +3997,15 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = case 4: HEAP8[((p)>>0)] = ret ? 1 : 0; break; } } - function _emscripten_glGetBooleanv(name_, p) { + + /** @suppress {duplicate } */ + function _glGetBooleanv(name_, p) { emscriptenWebGLGet(name_, p, 4); } + var _emscripten_glGetBooleanv = _glGetBooleanv; - function _emscripten_glGetBufferParameteriv(target, value, data) { + /** @suppress {duplicate } */ + function _glGetBufferParameteriv(target, value, data) { if (!data) { // GLES2 specification does not specify how to behave if data is a null pointer. Since calling this function does not make sense // if data == null, issue a GL error to notify user about it. @@ -4394,18 +4014,25 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAP32[((data)>>2)] = GLctx.getBufferParameter(target, value); } + var _emscripten_glGetBufferParameteriv = _glGetBufferParameteriv; - function _emscripten_glGetError() { + /** @suppress {duplicate } */ + function _glGetError() { var error = GLctx.getError() || GL.lastError; GL.lastError = 0/*GL_NO_ERROR*/; return error; } + var _emscripten_glGetError = _glGetError; - function _emscripten_glGetFloatv(name_, p) { + + /** @suppress {duplicate } */ + function _glGetFloatv(name_, p) { emscriptenWebGLGet(name_, p, 2); } + var _emscripten_glGetFloatv = _glGetFloatv; - function _emscripten_glGetFramebufferAttachmentParameteriv(target, attachment, pname, params) { + /** @suppress {duplicate } */ + function _glGetFramebufferAttachmentParameteriv(target, attachment, pname, params) { var result = GLctx.getFramebufferAttachmentParameter(target, attachment, pname); if (result instanceof WebGLRenderbuffer || result instanceof WebGLTexture) { @@ -4413,19 +4040,26 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAP32[((params)>>2)] = result; } + var _emscripten_glGetFramebufferAttachmentParameteriv = _glGetFramebufferAttachmentParameteriv; - function _emscripten_glGetIntegerv(name_, p) { + + /** @suppress {duplicate } */ + function _glGetIntegerv(name_, p) { emscriptenWebGLGet(name_, p, 0); } + var _emscripten_glGetIntegerv = _glGetIntegerv; - function _emscripten_glGetProgramInfoLog(program, maxLength, length, infoLog) { + /** @suppress {duplicate } */ + function _glGetProgramInfoLog(program, maxLength, length, infoLog) { var log = GLctx.getProgramInfoLog(GL.programs[program]); if (log === null) log = '(unknown error)'; var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0; if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull; } + var _emscripten_glGetProgramInfoLog = _glGetProgramInfoLog; - function _emscripten_glGetProgramiv(program, pname, p) { + /** @suppress {duplicate } */ + function _glGetProgramiv(program, pname, p) { if (!p) { // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense // if p == null, issue a GL error to notify user about it. @@ -4469,8 +4103,11 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname); } } + var _emscripten_glGetProgramiv = _glGetProgramiv; - function _emscripten_glGetQueryObjecti64vEXT(id, pname, params) { + + /** @suppress {duplicate } */ + function _glGetQueryObjecti64vEXT(id, pname, params) { if (!params) { // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense // if p == null, issue a GL error to notify user about it. @@ -4490,8 +4127,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } writeI53ToI64(params, ret); } + var _emscripten_glGetQueryObjecti64vEXT = _glGetQueryObjecti64vEXT; - function _emscripten_glGetQueryObjectivEXT(id, pname, params) { + /** @suppress {duplicate } */ + function _glGetQueryObjectivEXT(id, pname, params) { if (!params) { // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense // if p == null, issue a GL error to notify user about it. @@ -4508,47 +4147,20 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAP32[((params)>>2)] = ret; } + var _emscripten_glGetQueryObjectivEXT = _glGetQueryObjectivEXT; - function _emscripten_glGetQueryObjectui64vEXT(id, pname, params) { - if (!params) { - // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense - // if p == null, issue a GL error to notify user about it. - GL.recordError(0x501 /* GL_INVALID_VALUE */); - return; - } - var query = GL.queries[id]; - var param; - { - param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname); - } - var ret; - if (typeof param == 'boolean') { - ret = param ? 1 : 0; - } else { - ret = param; - } - writeI53ToI64(params, ret); - } + + /** @suppress {duplicate } */ + var _glGetQueryObjectui64vEXT = _glGetQueryObjecti64vEXT; + var _emscripten_glGetQueryObjectui64vEXT = _glGetQueryObjectui64vEXT; - function _emscripten_glGetQueryObjectuivEXT(id, pname, params) { - if (!params) { - // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense - // if p == null, issue a GL error to notify user about it. - GL.recordError(0x501 /* GL_INVALID_VALUE */); - return; - } - var query = GL.queries[id]; - var param = GLctx.disjointTimerQueryExt['getQueryObjectEXT'](query, pname); - var ret; - if (typeof param == 'boolean') { - ret = param ? 1 : 0; - } else { - ret = param; - } - HEAP32[((params)>>2)] = ret; - } + + /** @suppress {duplicate } */ + var _glGetQueryObjectuivEXT = _glGetQueryObjectivEXT; + var _emscripten_glGetQueryObjectuivEXT = _glGetQueryObjectuivEXT; - function _emscripten_glGetQueryivEXT(target, pname, params) { + /** @suppress {duplicate } */ + function _glGetQueryivEXT(target, pname, params) { if (!params) { // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense // if p == null, issue a GL error to notify user about it. @@ -4557,8 +4169,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAP32[((params)>>2)] = GLctx.disjointTimerQueryExt['getQueryEXT'](target, pname); } + var _emscripten_glGetQueryivEXT = _glGetQueryivEXT; - function _emscripten_glGetRenderbufferParameteriv(target, pname, params) { + /** @suppress {duplicate } */ + function _glGetRenderbufferParameteriv(target, pname, params) { if (!params) { // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense // if params == null, issue a GL error to notify user about it. @@ -4567,29 +4181,38 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAP32[((params)>>2)] = GLctx.getRenderbufferParameter(target, pname); } + var _emscripten_glGetRenderbufferParameteriv = _glGetRenderbufferParameteriv; - function _emscripten_glGetShaderInfoLog(shader, maxLength, length, infoLog) { + + /** @suppress {duplicate } */ + function _glGetShaderInfoLog(shader, maxLength, length, infoLog) { var log = GLctx.getShaderInfoLog(GL.shaders[shader]); if (log === null) log = '(unknown error)'; var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0; if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull; } + var _emscripten_glGetShaderInfoLog = _glGetShaderInfoLog; - function _emscripten_glGetShaderPrecisionFormat(shaderType, precisionType, range, precision) { + /** @suppress {duplicate } */ + function _glGetShaderPrecisionFormat(shaderType, precisionType, range, precision) { var result = GLctx.getShaderPrecisionFormat(shaderType, precisionType); HEAP32[((range)>>2)] = result.rangeMin; HEAP32[(((range)+(4))>>2)] = result.rangeMax; HEAP32[((precision)>>2)] = result.precision; } + var _emscripten_glGetShaderPrecisionFormat = _glGetShaderPrecisionFormat; - function _emscripten_glGetShaderSource(shader, bufSize, length, source) { + /** @suppress {duplicate } */ + function _glGetShaderSource(shader, bufSize, length, source) { var result = GLctx.getShaderSource(GL.shaders[shader]); if (!result) return; // If an error occurs, nothing will be written to length or source. var numBytesWrittenExclNull = (bufSize > 0 && source) ? stringToUTF8(result, source, bufSize) : 0; if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull; } + var _emscripten_glGetShaderSource = _glGetShaderSource; - function _emscripten_glGetShaderiv(shader, pname, p) { + /** @suppress {duplicate } */ + function _glGetShaderiv(shader, pname, p) { if (!p) { // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense // if p == null, issue a GL error to notify user about it. @@ -4615,14 +4238,11 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname); } } + var _emscripten_glGetShaderiv = _glGetShaderiv; - function stringToNewUTF8(jsString) { - var length = lengthBytesUTF8(jsString)+1; - var cString = _malloc(length); - stringToUTF8(jsString, cString, length); - return cString; - } - function _emscripten_glGetString(name_) { + + /** @suppress {duplicate } */ + function _glGetString(name_) { var ret = GL.stringCache[name_]; if (!ret) { switch (name_) { @@ -4669,8 +4289,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } return ret; } + var _emscripten_glGetString = _glGetString; - function _emscripten_glGetTexParameterfv(target, pname, params) { + /** @suppress {duplicate } */ + function _glGetTexParameterfv(target, pname, params) { if (!params) { // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense // if p == null, issue a GL error to notify user about it. @@ -4679,8 +4301,10 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAPF32[((params)>>2)] = GLctx.getTexParameter(target, pname); } + var _emscripten_glGetTexParameterfv = _glGetTexParameterfv; - function _emscripten_glGetTexParameteriv(target, pname, params) { + /** @suppress {duplicate } */ + function _glGetTexParameteriv(target, pname, params) { if (!params) { // GLES2 specification does not specify how to behave if params is a null pointer. Since calling this function does not make sense // if p == null, issue a GL error to notify user about it. @@ -4689,16 +4313,16 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAP32[((params)>>2)] = GLctx.getTexParameter(target, pname); } + var _emscripten_glGetTexParameteriv = _glGetTexParameteriv; /** @suppress {checkTypes} */ - function jstoi_q(str) { - return parseInt(str); - } + var jstoi_q = (str) => parseInt(str); /** @noinline */ function webglGetLeftBracePos(name) { return name.slice(-1) == ']' && name.lastIndexOf('['); } + function webglPrepareUniformLocationsBeforeFirstUse(program) { var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint] @@ -4738,7 +4362,11 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } } - function _emscripten_glGetUniformLocation(program, name) { + + + + /** @suppress {duplicate } */ + function _glGetUniformLocation(program, name) { name = UTF8ToString(name); @@ -4780,6 +4408,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } return -1; } + var _emscripten_glGetUniformLocation = _glGetUniformLocation; function webglGetUniformLocation(location) { var p = GLctx.currentProgram; @@ -4799,6 +4428,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = GL.recordError(0x502/*GL_INVALID_OPERATION*/); } } + + /** @suppress{checkTypes} */ function emscriptenWebGLGetUniform(program, location, params, type) { if (!params) { @@ -4824,15 +4455,22 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } } - function _emscripten_glGetUniformfv(program, location, params) { + + /** @suppress {duplicate } */ + function _glGetUniformfv(program, location, params) { emscriptenWebGLGetUniform(program, location, params, 2); } + var _emscripten_glGetUniformfv = _glGetUniformfv; - function _emscripten_glGetUniformiv(program, location, params) { + + /** @suppress {duplicate } */ + function _glGetUniformiv(program, location, params) { emscriptenWebGLGetUniform(program, location, params, 0); } + var _emscripten_glGetUniformiv = _glGetUniformiv; - function _emscripten_glGetVertexAttribPointerv(index, pname, pointer) { + /** @suppress {duplicate } */ + function _glGetVertexAttribPointerv(index, pname, pointer) { if (!pointer) { // GLES2 specification does not specify how to behave if pointer is a null pointer. Since calling this function does not make sense // if pointer == null, issue a GL error to notify user about it. @@ -4841,6 +4479,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } HEAP32[((pointer)>>2)] = GLctx.getVertexAttribOffset(index, pname); } + var _emscripten_glGetVertexAttribPointerv = _glGetVertexAttribPointerv; /** @suppress{checkTypes} */ function emscriptenWebGLGetVertexAttrib(index, pname, params, type) { @@ -4869,74 +4508,106 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } } } - function _emscripten_glGetVertexAttribfv(index, pname, params) { + + /** @suppress {duplicate } */ + function _glGetVertexAttribfv(index, pname, params) { // N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(), // otherwise the results are undefined. (GLES3 spec 6.1.12) emscriptenWebGLGetVertexAttrib(index, pname, params, 2); } + var _emscripten_glGetVertexAttribfv = _glGetVertexAttribfv; - function _emscripten_glGetVertexAttribiv(index, pname, params) { + + /** @suppress {duplicate } */ + function _glGetVertexAttribiv(index, pname, params) { // N.B. This function may only be called if the vertex attribute was specified using the function glVertexAttrib*f(), // otherwise the results are undefined. (GLES3 spec 6.1.12) emscriptenWebGLGetVertexAttrib(index, pname, params, 5); } + var _emscripten_glGetVertexAttribiv = _glGetVertexAttribiv; - function _emscripten_glHint(x0, x1) { GLctx['hint'](x0, x1) } + /** @suppress {duplicate } */ + function _glHint(x0, x1) { GLctx.hint(x0, x1) } + var _emscripten_glHint = _glHint; - function _emscripten_glIsBuffer(buffer) { + /** @suppress {duplicate } */ + function _glIsBuffer(buffer) { var b = GL.buffers[buffer]; if (!b) return 0; return GLctx.isBuffer(b); } + var _emscripten_glIsBuffer = _glIsBuffer; - function _emscripten_glIsEnabled(x0) { return GLctx['isEnabled'](x0) } + /** @suppress {duplicate } */ + function _glIsEnabled(x0) { return GLctx.isEnabled(x0) } + var _emscripten_glIsEnabled = _glIsEnabled; - function _emscripten_glIsFramebuffer(framebuffer) { + /** @suppress {duplicate } */ + function _glIsFramebuffer(framebuffer) { var fb = GL.framebuffers[framebuffer]; if (!fb) return 0; return GLctx.isFramebuffer(fb); } + var _emscripten_glIsFramebuffer = _glIsFramebuffer; - function _emscripten_glIsProgram(program) { + /** @suppress {duplicate } */ + function _glIsProgram(program) { program = GL.programs[program]; if (!program) return 0; return GLctx.isProgram(program); } + var _emscripten_glIsProgram = _glIsProgram; - function _emscripten_glIsQueryEXT(id) { + /** @suppress {duplicate } */ + function _glIsQueryEXT(id) { var query = GL.queries[id]; if (!query) return 0; return GLctx.disjointTimerQueryExt['isQueryEXT'](query); } + var _emscripten_glIsQueryEXT = _glIsQueryEXT; - function _emscripten_glIsRenderbuffer(renderbuffer) { + /** @suppress {duplicate } */ + function _glIsRenderbuffer(renderbuffer) { var rb = GL.renderbuffers[renderbuffer]; if (!rb) return 0; return GLctx.isRenderbuffer(rb); } + var _emscripten_glIsRenderbuffer = _glIsRenderbuffer; - function _emscripten_glIsShader(shader) { + /** @suppress {duplicate } */ + function _glIsShader(shader) { var s = GL.shaders[shader]; if (!s) return 0; return GLctx.isShader(s); } + var _emscripten_glIsShader = _glIsShader; - function _emscripten_glIsTexture(id) { + /** @suppress {duplicate } */ + function _glIsTexture(id) { var texture = GL.textures[id]; if (!texture) return 0; return GLctx.isTexture(texture); } + var _emscripten_glIsTexture = _glIsTexture; - function _emscripten_glIsVertexArrayOES(array) { + + /** @suppress {duplicate } */ + function _glIsVertexArray(array) { var vao = GL.vaos[array]; if (!vao) return 0; - return GLctx['isVertexArray'](vao); + return GLctx.isVertexArray(vao); } + /** @suppress {duplicate } */ + var _glIsVertexArrayOES = _glIsVertexArray; + var _emscripten_glIsVertexArrayOES = _glIsVertexArrayOES; - function _emscripten_glLineWidth(x0) { GLctx['lineWidth'](x0) } + /** @suppress {duplicate } */ + function _glLineWidth(x0) { GLctx.lineWidth(x0) } + var _emscripten_glLineWidth = _glLineWidth; - function _emscripten_glLinkProgram(program) { + /** @suppress {duplicate } */ + function _glLinkProgram(program) { program = GL.programs[program]; GLctx.linkProgram(program); // Invalidate earlier computed uniform->ID mappings, those have now become stale @@ -4944,19 +4615,26 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = program.uniformSizeAndIdsByName = {}; } + var _emscripten_glLinkProgram = _glLinkProgram; - function _emscripten_glPixelStorei(pname, param) { + /** @suppress {duplicate } */ + function _glPixelStorei(pname, param) { if (pname == 0xCF5 /* GL_UNPACK_ALIGNMENT */) { GL.unpackAlignment = param; } GLctx.pixelStorei(pname, param); } + var _emscripten_glPixelStorei = _glPixelStorei; - function _emscripten_glPolygonOffset(x0, x1) { GLctx['polygonOffset'](x0, x1) } + /** @suppress {duplicate } */ + function _glPolygonOffset(x0, x1) { GLctx.polygonOffset(x0, x1) } + var _emscripten_glPolygonOffset = _glPolygonOffset; - function _emscripten_glQueryCounterEXT(id, target) { + /** @suppress {duplicate } */ + function _glQueryCounterEXT(id, target) { GLctx.disjointTimerQueryExt['queryCounterEXT'](GL.queries[id], target); } + var _emscripten_glQueryCounterEXT = _glQueryCounterEXT; function computeUnpackAlignedImageSize(width, height, sizePerPixel, alignment) { function roundedToNextMultipleOf(x, y) { @@ -4967,7 +4645,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return height * alignedRowSize; } - function __colorChannelsInGlTextureFormat(format) { + function colorChannelsInGlTextureFormat(format) { // Micro-optimizations for size: map format to size by subtracting smallest enum value (0x1902) from all values first. // Also omit the most common size value (1) from the list, which is assumed by formats not on the list. var colorChannels = { @@ -5007,15 +4685,18 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = function heapAccessShiftForWebGLHeap(heap) { return 31 - Math.clz32(heap.BYTES_PER_ELEMENT); } + function emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) { var heap = heapObjectForWebGLType(type); var shift = heapAccessShiftForWebGLHeap(heap); var byteSize = 1<> shift, pixels + bytes >> shift); } - function _emscripten_glReadPixels(x, y, width, height, format, type, pixels) { + + /** @suppress {duplicate } */ + function _glReadPixels(x, y, width, height, format, type, pixels) { var pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, format); if (!pixelData) { GL.recordError(0x500/*GL_INVALID_ENUM*/); @@ -5023,71 +4704,116 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.readPixels(x, y, width, height, format, type, pixelData); } + var _emscripten_glReadPixels = _glReadPixels; - function _emscripten_glReleaseShaderCompiler() { + /** @suppress {duplicate } */ + function _glReleaseShaderCompiler() { // NOP (as allowed by GLES 2.0 spec) } + var _emscripten_glReleaseShaderCompiler = _glReleaseShaderCompiler; - function _emscripten_glRenderbufferStorage(x0, x1, x2, x3) { GLctx['renderbufferStorage'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glRenderbufferStorage(x0, x1, x2, x3) { GLctx.renderbufferStorage(x0, x1, x2, x3) } + var _emscripten_glRenderbufferStorage = _glRenderbufferStorage; - function _emscripten_glSampleCoverage(value, invert) { + /** @suppress {duplicate } */ + function _glSampleCoverage(value, invert) { GLctx.sampleCoverage(value, !!invert); } + var _emscripten_glSampleCoverage = _glSampleCoverage; - function _emscripten_glScissor(x0, x1, x2, x3) { GLctx['scissor'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glScissor(x0, x1, x2, x3) { GLctx.scissor(x0, x1, x2, x3) } + var _emscripten_glScissor = _glScissor; - function _emscripten_glShaderBinary() { + /** @suppress {duplicate } */ + function _glShaderBinary(count, shaders, binaryformat, binary, length) { GL.recordError(0x500/*GL_INVALID_ENUM*/); } + var _emscripten_glShaderBinary = _glShaderBinary; - function _emscripten_glShaderSource(shader, count, string, length) { + /** @suppress {duplicate } */ + function _glShaderSource(shader, count, string, length) { var source = GL.getSource(shader, count, string, length); GLctx.shaderSource(GL.shaders[shader], source); } + var _emscripten_glShaderSource = _glShaderSource; - function _emscripten_glStencilFunc(x0, x1, x2) { GLctx['stencilFunc'](x0, x1, x2) } + /** @suppress {duplicate } */ + function _glStencilFunc(x0, x1, x2) { GLctx.stencilFunc(x0, x1, x2) } + var _emscripten_glStencilFunc = _glStencilFunc; - function _emscripten_glStencilFuncSeparate(x0, x1, x2, x3) { GLctx['stencilFuncSeparate'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glStencilFuncSeparate(x0, x1, x2, x3) { GLctx.stencilFuncSeparate(x0, x1, x2, x3) } + var _emscripten_glStencilFuncSeparate = _glStencilFuncSeparate; - function _emscripten_glStencilMask(x0) { GLctx['stencilMask'](x0) } + /** @suppress {duplicate } */ + function _glStencilMask(x0) { GLctx.stencilMask(x0) } + var _emscripten_glStencilMask = _glStencilMask; - function _emscripten_glStencilMaskSeparate(x0, x1) { GLctx['stencilMaskSeparate'](x0, x1) } + /** @suppress {duplicate } */ + function _glStencilMaskSeparate(x0, x1) { GLctx.stencilMaskSeparate(x0, x1) } + var _emscripten_glStencilMaskSeparate = _glStencilMaskSeparate; - function _emscripten_glStencilOp(x0, x1, x2) { GLctx['stencilOp'](x0, x1, x2) } + /** @suppress {duplicate } */ + function _glStencilOp(x0, x1, x2) { GLctx.stencilOp(x0, x1, x2) } + var _emscripten_glStencilOp = _glStencilOp; - function _emscripten_glStencilOpSeparate(x0, x1, x2, x3) { GLctx['stencilOpSeparate'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glStencilOpSeparate(x0, x1, x2, x3) { GLctx.stencilOpSeparate(x0, x1, x2, x3) } + var _emscripten_glStencilOpSeparate = _glStencilOpSeparate; - function _emscripten_glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) { + + /** @suppress {duplicate } */ + function _glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) { GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null); } + var _emscripten_glTexImage2D = _glTexImage2D; - function _emscripten_glTexParameterf(x0, x1, x2) { GLctx['texParameterf'](x0, x1, x2) } + /** @suppress {duplicate } */ + function _glTexParameterf(x0, x1, x2) { GLctx.texParameterf(x0, x1, x2) } + var _emscripten_glTexParameterf = _glTexParameterf; - function _emscripten_glTexParameterfv(target, pname, params) { + /** @suppress {duplicate } */ + function _glTexParameterfv(target, pname, params) { var param = HEAPF32[((params)>>2)]; GLctx.texParameterf(target, pname, param); } + var _emscripten_glTexParameterfv = _glTexParameterfv; - function _emscripten_glTexParameteri(x0, x1, x2) { GLctx['texParameteri'](x0, x1, x2) } + /** @suppress {duplicate } */ + function _glTexParameteri(x0, x1, x2) { GLctx.texParameteri(x0, x1, x2) } + var _emscripten_glTexParameteri = _glTexParameteri; - function _emscripten_glTexParameteriv(target, pname, params) { + /** @suppress {duplicate } */ + function _glTexParameteriv(target, pname, params) { var param = HEAP32[((params)>>2)]; GLctx.texParameteri(target, pname, param); } + var _emscripten_glTexParameteriv = _glTexParameteriv; - function _emscripten_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) { + + /** @suppress {duplicate } */ + function _glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) { var pixelData = null; if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0); GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData); } + var _emscripten_glTexSubImage2D = _glTexSubImage2D; - function _emscripten_glUniform1f(location, v0) { + + /** @suppress {duplicate } */ + function _glUniform1f(location, v0) { GLctx.uniform1f(webglGetUniformLocation(location), v0); } + var _emscripten_glUniform1f = _glUniform1f; + var miniTempWebGLFloatBuffers = []; - function _emscripten_glUniform1fv(location, count, value) { + + /** @suppress {duplicate } */ + function _glUniform1fv(location, count, value) { if (count <= 288) { // avoid allocation when uploading few enough uniforms @@ -5101,17 +4827,24 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform1fv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform1fv = _glUniform1fv; - function _emscripten_glUniform1i(location, v0) { + + /** @suppress {duplicate } */ + function _glUniform1i(location, v0) { GLctx.uniform1i(webglGetUniformLocation(location), v0); } + var _emscripten_glUniform1i = _glUniform1i; - var __miniTempWebGLIntBuffers = []; - function _emscripten_glUniform1iv(location, count, value) { + + var miniTempWebGLIntBuffers = []; + + /** @suppress {duplicate } */ + function _glUniform1iv(location, count, value) { if (count <= 288) { // avoid allocation when uploading few enough uniforms - var view = __miniTempWebGLIntBuffers[count-1]; + var view = miniTempWebGLIntBuffers[count-1]; for (var i = 0; i < count; ++i) { view[i] = HEAP32[(((value)+(4*i))>>2)]; } @@ -5121,12 +4854,19 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform1iv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform1iv = _glUniform1iv; - function _emscripten_glUniform2f(location, v0, v1) { + + /** @suppress {duplicate } */ + function _glUniform2f(location, v0, v1) { GLctx.uniform2f(webglGetUniformLocation(location), v0, v1); } + var _emscripten_glUniform2f = _glUniform2f; - function _emscripten_glUniform2fv(location, count, value) { + + + /** @suppress {duplicate } */ + function _glUniform2fv(location, count, value) { if (count <= 144) { // avoid allocation when uploading few enough uniforms @@ -5141,16 +4881,23 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform2fv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform2fv = _glUniform2fv; - function _emscripten_glUniform2i(location, v0, v1) { + + /** @suppress {duplicate } */ + function _glUniform2i(location, v0, v1) { GLctx.uniform2i(webglGetUniformLocation(location), v0, v1); } + var _emscripten_glUniform2i = _glUniform2i; - function _emscripten_glUniform2iv(location, count, value) { + + + /** @suppress {duplicate } */ + function _glUniform2iv(location, count, value) { if (count <= 144) { // avoid allocation when uploading few enough uniforms - var view = __miniTempWebGLIntBuffers[2*count-1]; + var view = miniTempWebGLIntBuffers[2*count-1]; for (var i = 0; i < 2*count; i += 2) { view[i] = HEAP32[(((value)+(4*i))>>2)]; view[i+1] = HEAP32[(((value)+(4*i+4))>>2)]; @@ -5161,12 +4908,19 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform2iv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform2iv = _glUniform2iv; - function _emscripten_glUniform3f(location, v0, v1, v2) { + + /** @suppress {duplicate } */ + function _glUniform3f(location, v0, v1, v2) { GLctx.uniform3f(webglGetUniformLocation(location), v0, v1, v2); } + var _emscripten_glUniform3f = _glUniform3f; - function _emscripten_glUniform3fv(location, count, value) { + + + /** @suppress {duplicate } */ + function _glUniform3fv(location, count, value) { if (count <= 96) { // avoid allocation when uploading few enough uniforms @@ -5182,16 +4936,23 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform3fv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform3fv = _glUniform3fv; - function _emscripten_glUniform3i(location, v0, v1, v2) { + + /** @suppress {duplicate } */ + function _glUniform3i(location, v0, v1, v2) { GLctx.uniform3i(webglGetUniformLocation(location), v0, v1, v2); } + var _emscripten_glUniform3i = _glUniform3i; - function _emscripten_glUniform3iv(location, count, value) { + + + /** @suppress {duplicate } */ + function _glUniform3iv(location, count, value) { if (count <= 96) { // avoid allocation when uploading few enough uniforms - var view = __miniTempWebGLIntBuffers[3*count-1]; + var view = miniTempWebGLIntBuffers[3*count-1]; for (var i = 0; i < 3*count; i += 3) { view[i] = HEAP32[(((value)+(4*i))>>2)]; view[i+1] = HEAP32[(((value)+(4*i+4))>>2)]; @@ -5203,12 +4964,19 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform3iv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform3iv = _glUniform3iv; - function _emscripten_glUniform4f(location, v0, v1, v2, v3) { + + /** @suppress {duplicate } */ + function _glUniform4f(location, v0, v1, v2, v3) { GLctx.uniform4f(webglGetUniformLocation(location), v0, v1, v2, v3); } + var _emscripten_glUniform4f = _glUniform4f; - function _emscripten_glUniform4fv(location, count, value) { + + + /** @suppress {duplicate } */ + function _glUniform4fv(location, count, value) { if (count <= 72) { // avoid allocation when uploading few enough uniforms @@ -5229,16 +4997,23 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform4fv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform4fv = _glUniform4fv; - function _emscripten_glUniform4i(location, v0, v1, v2, v3) { + + /** @suppress {duplicate } */ + function _glUniform4i(location, v0, v1, v2, v3) { GLctx.uniform4i(webglGetUniformLocation(location), v0, v1, v2, v3); } + var _emscripten_glUniform4i = _glUniform4i; - function _emscripten_glUniform4iv(location, count, value) { + + + /** @suppress {duplicate } */ + function _glUniform4iv(location, count, value) { if (count <= 72) { // avoid allocation when uploading few enough uniforms - var view = __miniTempWebGLIntBuffers[4*count-1]; + var view = miniTempWebGLIntBuffers[4*count-1]; for (var i = 0; i < 4*count; i += 4) { view[i] = HEAP32[(((value)+(4*i))>>2)]; view[i+1] = HEAP32[(((value)+(4*i+4))>>2)]; @@ -5251,8 +5026,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniform4iv(webglGetUniformLocation(location), view); } + var _emscripten_glUniform4iv = _glUniform4iv; - function _emscripten_glUniformMatrix2fv(location, count, transpose, value) { + + + /** @suppress {duplicate } */ + function _glUniformMatrix2fv(location, count, transpose, value) { if (count <= 72) { // avoid allocation when uploading few enough uniforms @@ -5269,8 +5048,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniformMatrix2fv(webglGetUniformLocation(location), !!transpose, view); } + var _emscripten_glUniformMatrix2fv = _glUniformMatrix2fv; - function _emscripten_glUniformMatrix3fv(location, count, transpose, value) { + + + /** @suppress {duplicate } */ + function _glUniformMatrix3fv(location, count, transpose, value) { if (count <= 32) { // avoid allocation when uploading few enough uniforms @@ -5292,11 +5075,15 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniformMatrix3fv(webglGetUniformLocation(location), !!transpose, view); } + var _emscripten_glUniformMatrix3fv = _glUniformMatrix3fv; - function _emscripten_glUniformMatrix4fv(location, count, transpose, value) { - if (count <= 18) { - // avoid allocation when uploading few enough uniforms + + /** @suppress {duplicate } */ + function _glUniformMatrix4fv(location, count, transpose, value) { + + if (count <= 18) { + // avoid allocation when uploading few enough uniforms var view = miniTempWebGLFloatBuffers[16*count-1]; // hoist the heap out of the loop for size and for pthreads+growth. var heap = HEAPF32; @@ -5326,65 +5113,98 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view); } + var _emscripten_glUniformMatrix4fv = _glUniformMatrix4fv; - function _emscripten_glUseProgram(program) { + /** @suppress {duplicate } */ + function _glUseProgram(program) { program = GL.programs[program]; GLctx.useProgram(program); // Record the currently active program so that we can access the uniform // mapping table of that program. GLctx.currentProgram = program; } + var _emscripten_glUseProgram = _glUseProgram; - function _emscripten_glValidateProgram(program) { + /** @suppress {duplicate } */ + function _glValidateProgram(program) { GLctx.validateProgram(GL.programs[program]); } + var _emscripten_glValidateProgram = _glValidateProgram; - function _emscripten_glVertexAttrib1f(x0, x1) { GLctx['vertexAttrib1f'](x0, x1) } + /** @suppress {duplicate } */ + function _glVertexAttrib1f(x0, x1) { GLctx.vertexAttrib1f(x0, x1) } + var _emscripten_glVertexAttrib1f = _glVertexAttrib1f; - function _emscripten_glVertexAttrib1fv(index, v) { + /** @suppress {duplicate } */ + function _glVertexAttrib1fv(index, v) { GLctx.vertexAttrib1f(index, HEAPF32[v>>2]); } + var _emscripten_glVertexAttrib1fv = _glVertexAttrib1fv; - function _emscripten_glVertexAttrib2f(x0, x1, x2) { GLctx['vertexAttrib2f'](x0, x1, x2) } + /** @suppress {duplicate } */ + function _glVertexAttrib2f(x0, x1, x2) { GLctx.vertexAttrib2f(x0, x1, x2) } + var _emscripten_glVertexAttrib2f = _glVertexAttrib2f; - function _emscripten_glVertexAttrib2fv(index, v) { + /** @suppress {duplicate } */ + function _glVertexAttrib2fv(index, v) { GLctx.vertexAttrib2f(index, HEAPF32[v>>2], HEAPF32[v+4>>2]); } + var _emscripten_glVertexAttrib2fv = _glVertexAttrib2fv; - function _emscripten_glVertexAttrib3f(x0, x1, x2, x3) { GLctx['vertexAttrib3f'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glVertexAttrib3f(x0, x1, x2, x3) { GLctx.vertexAttrib3f(x0, x1, x2, x3) } + var _emscripten_glVertexAttrib3f = _glVertexAttrib3f; - function _emscripten_glVertexAttrib3fv(index, v) { + /** @suppress {duplicate } */ + function _glVertexAttrib3fv(index, v) { GLctx.vertexAttrib3f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2]); } + var _emscripten_glVertexAttrib3fv = _glVertexAttrib3fv; - function _emscripten_glVertexAttrib4f(x0, x1, x2, x3, x4) { GLctx['vertexAttrib4f'](x0, x1, x2, x3, x4) } + /** @suppress {duplicate } */ + function _glVertexAttrib4f(x0, x1, x2, x3, x4) { GLctx.vertexAttrib4f(x0, x1, x2, x3, x4) } + var _emscripten_glVertexAttrib4f = _glVertexAttrib4f; - function _emscripten_glVertexAttrib4fv(index, v) { + /** @suppress {duplicate } */ + function _glVertexAttrib4fv(index, v) { GLctx.vertexAttrib4f(index, HEAPF32[v>>2], HEAPF32[v+4>>2], HEAPF32[v+8>>2], HEAPF32[v+12>>2]); } + var _emscripten_glVertexAttrib4fv = _glVertexAttrib4fv; - function _emscripten_glVertexAttribDivisorANGLE(index, divisor) { - GLctx['vertexAttribDivisor'](index, divisor); + + /** @suppress {duplicate } */ + function _glVertexAttribDivisor(index, divisor) { + GLctx.vertexAttribDivisor(index, divisor); } + /** @suppress {duplicate } */ + var _glVertexAttribDivisorANGLE = _glVertexAttribDivisor; + var _emscripten_glVertexAttribDivisorANGLE = _glVertexAttribDivisorANGLE; - function _emscripten_glVertexAttribPointer(index, size, type, normalized, stride, ptr) { + /** @suppress {duplicate } */ + function _glVertexAttribPointer(index, size, type, normalized, stride, ptr) { GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); } + var _emscripten_glVertexAttribPointer = _glVertexAttribPointer; - function _emscripten_glViewport(x0, x1, x2, x3) { GLctx['viewport'](x0, x1, x2, x3) } + /** @suppress {duplicate } */ + function _glViewport(x0, x1, x2, x3) { GLctx.viewport(x0, x1, x2, x3) } + var _emscripten_glViewport = _glViewport; - function _emscripten_has_asyncify() { - return false; - } + var _emscripten_has_asyncify = () => 0; - function _emscripten_memcpy_big(dest, src, num) { - HEAPU8.copyWithin(dest, src, src + num); - } + var _emscripten_memcpy_big = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num); + + + + + + + function doRequestFullscreen(target, strategy) { if (!JSEvents.fullscreenEnabled()) return -1; target = findEventTarget(target); @@ -5401,21 +5221,22 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = // Queue this function call if we're not currently in an event handler and the user saw it appropriate to do so. if (!canPerformRequests) { if (strategy.deferUntilInEventHandler) { - JSEvents.deferCall(_JSEvents_requestFullscreen, 1 /* priority over pointer lock */, [target, strategy]); + JSEvents.deferCall(JSEvents_requestFullscreen, 1 /* priority over pointer lock */, [target, strategy]); return 1; - } else { - return -2; } + return -2; } - return _JSEvents_requestFullscreen(target, strategy); + return JSEvents_requestFullscreen(target, strategy); } + + function _emscripten_request_fullscreen_strategy(target, deferUntilInEventHandler, fullscreenStrategy) { var strategy = { scaleMode: HEAP32[((fullscreenStrategy)>>2)], canvasResolutionScaleMode: HEAP32[(((fullscreenStrategy)+(4))>>2)], filteringMode: HEAP32[(((fullscreenStrategy)+(8))>>2)], - deferUntilInEventHandler: deferUntilInEventHandler, + deferUntilInEventHandler, canvasResizedCallback: HEAP32[(((fullscreenStrategy)+(12))>>2)], canvasResizedCallbackUserData: HEAP32[(((fullscreenStrategy)+(16))>>2)] }; @@ -5423,11 +5244,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return doRequestFullscreen(target, strategy); } + + function _emscripten_request_pointerlock(target, deferUntilInEventHandler) { target = findEventTarget(target); if (!target) return -4; if (!target.requestPointerLock - && !target.msRequestPointerLock ) { return -1; } @@ -5439,37 +5261,38 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = if (deferUntilInEventHandler) { JSEvents.deferCall(requestPointerLock, 2 /* priority below fullscreen */, [target]); return 1; - } else { - return -2; } + return -2; } return requestPointerLock(target); } - function _emscripten_get_heap_max() { + var getHeapMax = () => // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side // for any code that deals with heap sizes, which would require special // casing all heap size related code to treat 0 specially. - return 2147483648; - } + 2147483648; - function emscripten_realloc_buffer(size) { + var growMemory = (size) => { + var b = wasmMemory.buffer; + var pages = (size - b.byteLength + 65535) >>> 16; try { // round size grow request up to wasm page size (fixed 64KB per spec) - wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size - updateGlobalBufferAndViews(wasmMemory.buffer); + wasmMemory.grow(pages); // .grow() takes a delta compared to the previous size + updateMemoryViews(); return 1 /*success*/; } catch(e) { - err('emscripten_realloc_buffer: Attempted to grow heap from ' + buffer.byteLength + ' bytes to ' + size + ' bytes, but got error: ' + e); + err(`growMemory: Attempted to grow heap from ${b.byteLength} bytes to ${size} bytes, but got error: ${e}`); } // implicit 0 return to save code size (caller will cast "undefined" into 0 // anyhow) - } - function _emscripten_resize_heap(requestedSize) { + }; + var _emscripten_resize_heap = (requestedSize) => { var oldSize = HEAPU8.length; - requestedSize = requestedSize >>> 0; + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; // With multithreaded builds, races can happen (another thread might increase the size // in between), so return a failure, and let the caller retry. assert(requestedSize > oldSize); @@ -5493,13 +5316,13 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = // A limit is set for how much we can grow. We should not exceed that // (the wasm binary specifies it, so if we tried, we'd fail anyhow). - var maxHeapSize = _emscripten_get_heap_max(); + var maxHeapSize = getHeapMax(); if (requestedSize > maxHeapSize) { - err('Cannot enlarge memory, asked to go up to ' + requestedSize + ' bytes, but the limit is ' + maxHeapSize + ' bytes!'); + err(`Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`); return false; } - let alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple; + var alignUp = (x, multiple) => x + (multiple - x % multiple) % multiple; // Loop through potential heap size increases. If we attempt a too eager // reservation that fails, cut down on the attempted size and reserve a @@ -5511,29 +5334,30 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); - var replacement = emscripten_realloc_buffer(newSize); + var replacement = growMemory(newSize); if (replacement) { return true; } } - err('Failed to grow the heap from ' + oldSize + ' bytes to ' + newSize + ' bytes, not enough memory!'); + err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`); return false; - } + }; - function _emscripten_run_script(ptr) { + var _emscripten_run_script = (ptr) => { eval(UTF8ToString(ptr)); - } + }; function _emscripten_sample_gamepad_data() { return (JSEvents.lastGamepadState = (navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : null))) ? 0 : -1; } - function registerBeforeUnloadEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) { - var beforeUnloadEventHandlerFunc = function(ev) { - var e = ev || event; + + + function registerBeforeUnloadEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString) { + var beforeUnloadEventHandlerFunc = function(e = event) { // Note: This is always called on the main browser thread, since it needs synchronously return a value! var confirmationMessage = getWasmTableEntry(callbackfunc)(eventTypeId, 0, userData); @@ -5549,28 +5373,29 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = var eventHandler = { target: findEventTarget(target), - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + eventTypeString, + callbackfunc, handlerFunc: beforeUnloadEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } function _emscripten_set_beforeunload_callback_on_thread(userData, callbackfunc, targetThread) { if (typeof onbeforeunload == 'undefined') return -1; // beforeunload callback can only be registered on the main browser thread, because the page will go away immediately after returning from the handler, // and there is no time to start proxying it anywhere. if (targetThread !== 1) return -5; - registerBeforeUnloadEventCallback(2, userData, true, callbackfunc, 28, "beforeunload"); - return 0; + return registerBeforeUnloadEventCallback(2, userData, true, callbackfunc, 28, "beforeunload"); } + + + + function registerFocusEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.focusEvent) JSEvents.focusEvent = _malloc( 256 ); - var focusEventHandlerFunc = function(ev) { - var e = ev || event; - + var focusEventHandlerFunc = function(e = event) { var nodeName = JSEvents.getNodeNameForTarget(e.target); var id = e.target.id ? e.target.id : ''; @@ -5583,19 +5408,19 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = var eventHandler = { target: findEventTarget(target), - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + eventTypeString, + callbackfunc, handlerFunc: focusEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } function _emscripten_set_blur_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerFocusEventCallback(target, userData, useCapture, callbackfunc, 12, "blur", targetThread); - return 0; + return registerFocusEventCallback(target, userData, useCapture, callbackfunc, 12, "blur", targetThread); } + function _emscripten_set_element_css_size(target, width, height) { target = findEventTarget(target); if (!target) return -4; @@ -5607,10 +5432,12 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } function _emscripten_set_focus_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerFocusEventCallback(target, userData, useCapture, callbackfunc, 13, "focus", targetThread); - return 0; + return registerFocusEventCallback(target, userData, useCapture, callbackfunc, 13, "focus", targetThread); } + + + function fillFullscreenChangeEventData(eventStruct) { var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; var isFullscreen = !!fullscreenElement; @@ -5633,12 +5460,13 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = JSEvents.previousFullscreenElement = fullscreenElement; } } + + + function registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.fullscreenChangeEvent) JSEvents.fullscreenChangeEvent = _malloc( 280 ); - var fullscreenChangeEventhandlerFunc = function(ev) { - var e = ev || event; - + var fullscreenChangeEventhandlerFunc = function(e = event) { var fullscreenChangeEvent = JSEvents.fullscreenChangeEvent; fillFullscreenChangeEventData(fullscreenChangeEvent); @@ -5647,33 +5475,36 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }; var eventHandler = { - target: target, - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + target, + eventTypeString, + callbackfunc, handlerFunc: fullscreenChangeEventhandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } + + function _emscripten_set_fullscreenchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { if (!JSEvents.fullscreenEnabled()) return -1; target = findEventTarget(target); if (!target) return -4; - registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread); // Unprefixed Fullscreen API shipped in Chromium 71 (https://bugs.chromium.org/p/chromium/issues/detail?id=383813) // As of Safari 13.0.3 on macOS Catalina 10.15.1 still ships with prefixed webkitfullscreenchange. TODO: revisit this check once Safari ships unprefixed version. registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "webkitfullscreenchange", targetThread); - return 0; + return registerFullscreenChangeEventCallback(target, userData, useCapture, callbackfunc, 19, "fullscreenchange", targetThread); } + + + + function registerGamepadEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.gamepadEvent) JSEvents.gamepadEvent = _malloc( 1432 ); - var gamepadEventHandlerFunc = function(ev) { - var e = ev || event; - + var gamepadEventHandlerFunc = function(e = event) { var gamepadEvent = JSEvents.gamepadEvent; fillGamepadEventData(gamepadEvent, e["gamepad"]); @@ -5683,25 +5514,27 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = var eventHandler = { target: findEventTarget(target), allowsDeferredCalls: true, - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + eventTypeString, + callbackfunc, handlerFunc: gamepadEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } function _emscripten_set_gamepadconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) { if (!navigator.getGamepads && !navigator.webkitGetGamepads) return -1; - registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread); - return 0; + return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 26, "gamepadconnected", targetThread); } function _emscripten_set_gamepaddisconnected_callback_on_thread(userData, useCapture, callbackfunc, targetThread) { if (!navigator.getGamepads && !navigator.webkitGetGamepads) return -1; - registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread); - return 0; + return registerGamepadEventCallback(2, userData, useCapture, callbackfunc, 27, "gamepaddisconnected", targetThread); } + + + + function registerKeyEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.keyEvent) JSEvents.keyEvent = _malloc( 176 ); @@ -5733,33 +5566,35 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = var eventHandler = { target: findEventTarget(target), allowsDeferredCalls: true, - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + eventTypeString, + callbackfunc, handlerFunc: keyEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } function _emscripten_set_keydown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread); - return 0; + return registerKeyEventCallback(target, userData, useCapture, callbackfunc, 2, "keydown", targetThread); } function _emscripten_set_keypress_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread); - return 0; + return registerKeyEventCallback(target, userData, useCapture, callbackfunc, 1, "keypress", targetThread); } function _emscripten_set_keyup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread); - return 0; + return registerKeyEventCallback(target, userData, useCapture, callbackfunc, 3, "keyup", targetThread); } - function _emscripten_set_main_loop_arg(func, arg, fps, simulateInfiniteLoop) { - var browserIterationFunc = function() { getWasmTableEntry(func)(arg); }; + + + var _emscripten_set_main_loop_arg = function(func, arg, fps, simulateInfiniteLoop) { + var browserIterationFunc = () => getWasmTableEntry(func)(arg); setMainLoop(browserIterationFunc, fps, simulateInfiniteLoop, arg); - } + }; + + + function fillMouseEventData(eventStruct, e, target) { assert(eventStruct % 4 == 0); HEAPF64[((eventStruct)>>3)] = e.timeStamp; @@ -5786,13 +5621,14 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[idx + 14] = e.clientY - rect.top; } + + + function registerMouseEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc( 72 ); target = findEventTarget(target); - var mouseEventHandlerFunc = function(ev) { - var e = ev || event; - + var mouseEventHandlerFunc = function(e = event) { // TODO: Make this access thread safe, or this could update live while app is reading it. fillMouseEventData(JSEvents.mouseEvent, e, target); @@ -5800,40 +5636,38 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }; var eventHandler = { - target: target, + target, allowsDeferredCalls: eventTypeString != 'mousemove' && eventTypeString != 'mouseenter' && eventTypeString != 'mouseleave', // Mouse move events do not allow fullscreen/pointer lock requests to be handled in them! - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + eventTypeString, + callbackfunc, handlerFunc: mouseEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } function _emscripten_set_mousedown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread); - return 0; + return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread); } function _emscripten_set_mouseenter_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread); - return 0; + return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 33, "mouseenter", targetThread); } function _emscripten_set_mouseleave_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread); - return 0; + return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 34, "mouseleave", targetThread); } function _emscripten_set_mousemove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread); - return 0; + return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread); } function _emscripten_set_mouseup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread); - return 0; + return registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread); } + + + function fillPointerlockChangeEventData(eventStruct) { var pointerLockElement = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement || document.msPointerLockElement; var isPointerlocked = !!pointerLockElement; @@ -5845,12 +5679,13 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = stringToUTF8(nodeName, eventStruct + 4, 128); stringToUTF8(id, eventStruct + 132, 128); } + + + function registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.pointerlockChangeEvent) JSEvents.pointerlockChangeEvent = _malloc( 260 ); - var pointerlockChangeEventHandlerFunc = function(ev) { - var e = ev || event; - + var pointerlockChangeEventHandlerFunc = function(e = event) { var pointerlockChangeEvent = JSEvents.pointerlockChangeEvent; fillPointerlockChangeEventData(pointerlockChangeEvent); @@ -5858,14 +5693,16 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }; var eventHandler = { - target: target, - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + target, + eventTypeString, + callbackfunc, handlerFunc: pointerlockChangeEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } + + /** @suppress {missingProperties} */ function _emscripten_set_pointerlockchange_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { // TODO: Currently not supported in pthreads or in --proxy-to-worker mode. (In pthreads mode, document object is not defined) @@ -5875,20 +5712,21 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = target = findEventTarget(target); if (!target) return -4; - registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread); registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mozpointerlockchange", targetThread); registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "webkitpointerlockchange", targetThread); registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "mspointerlockchange", targetThread); - return 0; + return registerPointerlockChangeEventCallback(target, userData, useCapture, callbackfunc, 20, "pointerlockchange", targetThread); } + + + function registerUiEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.uiEvent) JSEvents.uiEvent = _malloc( 36 ); target = findEventTarget(target); - var uiEventHandlerFunc = function(ev) { - var e = ev || event; + var uiEventHandlerFunc = function(e = event) { if (e.target != target) { // Never take ui events such as scroll via a 'bubbled' route, but always from the direct element that // was targeted. Otherwise e.g. if app logs a message in response to a page scroll, the Emscripten log @@ -5915,19 +5753,22 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }; var eventHandler = { - target: target, - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + target, + eventTypeString, + callbackfunc, handlerFunc: uiEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } function _emscripten_set_resize_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread); - return 0; + return registerUiEventCallback(target, userData, useCapture, callbackfunc, 10, "resize", targetThread); } + + + + function registerTouchEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.touchEvent) JSEvents.touchEvent = _malloc( 1696 ); @@ -5994,35 +5835,32 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }; var eventHandler = { - target: target, + target, allowsDeferredCalls: eventTypeString == 'touchstart' || eventTypeString == 'touchend', - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + eventTypeString, + callbackfunc, handlerFunc: touchEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } function _emscripten_set_touchcancel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread); - return 0; + return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 25, "touchcancel", targetThread); } function _emscripten_set_touchend_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread); - return 0; + return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 23, "touchend", targetThread); } function _emscripten_set_touchmove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread); - return 0; + return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 24, "touchmove", targetThread); } function _emscripten_set_touchstart_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { - registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread); - return 0; + return registerTouchEventCallback(target, userData, useCapture, callbackfunc, 22, "touchstart", targetThread); } + function fillVisibilityChangeEventData(eventStruct) { var visibilityStates = [ "hidden", "visible", "prerender", "unloaded" ]; var visibilityState = visibilityStates.indexOf(document.visibilityState); @@ -6032,12 +5870,13 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = HEAP32[((eventStruct)>>2)] = document.hidden; HEAP32[(((eventStruct)+(4))>>2)] = visibilityState; } + + + function registerVisibilityChangeEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.visibilityChangeEvent) JSEvents.visibilityChangeEvent = _malloc( 8 ); - var visibilityChangeEventHandlerFunc = function(ev) { - var e = ev || event; - + var visibilityChangeEventHandlerFunc = function(e = event) { var visibilityChangeEvent = JSEvents.visibilityChangeEvent; fillVisibilityChangeEventData(visibilityChangeEvent); @@ -6046,28 +5885,32 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }; var eventHandler = { - target: target, - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + target, + eventTypeString, + callbackfunc, handlerFunc: visibilityChangeEventHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } + function _emscripten_set_visibilitychange_callback_on_thread(userData, useCapture, callbackfunc, targetThread) { if (!specialHTMLTargets[1]) { return -4; } - registerVisibilityChangeEventCallback(specialHTMLTargets[1], userData, useCapture, callbackfunc, 21, "visibilitychange", targetThread); - return 0; + return registerVisibilityChangeEventCallback(specialHTMLTargets[1], userData, useCapture, callbackfunc, 21, "visibilitychange", targetThread); } + + + + + function registerWheelEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { if (!JSEvents.wheelEvent) JSEvents.wheelEvent = _malloc( 104 ); // The DOM Level 3 events spec event 'wheel' - var wheelHandlerFunc = function(ev) { - var e = ev || event; + var wheelHandlerFunc = function(e = event) { var wheelEvent = JSEvents.wheelEvent; fillMouseEventData(wheelEvent, e, target); HEAPF64[(((wheelEvent)+(72))>>3)] = e["deltaX"]; @@ -6078,25 +5921,27 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = }; var eventHandler = { - target: target, + target, allowsDeferredCalls: true, - eventTypeString: eventTypeString, - callbackfunc: callbackfunc, + eventTypeString, + callbackfunc, handlerFunc: wheelHandlerFunc, - useCapture: useCapture + useCapture }; - JSEvents.registerOrRemoveHandler(eventHandler); + return JSEvents.registerOrRemoveHandler(eventHandler); } + function _emscripten_set_wheel_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) { target = findEventTarget(target); + if (!target) return -4; if (typeof target.onwheel != 'undefined') { - registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread); - return 0; + return registerWheelEventCallback(target, userData, useCapture, callbackfunc, 9, "wheel", targetThread); } else { return -1; } } + function _emscripten_set_window_title(title) { setWindowTitle(UTF8ToString(title)); } @@ -6105,12 +5950,13 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = throw 'Please compile your program with async support in order to use asynchronous operations like emscripten_sleep'; } - var ENV = {}; + var ENV = { + }; - function getExecutableName() { + var getExecutableName = () => { return thisProgram || './this.program'; - } - function getEnvStrings() { + }; + var getEnvStrings = () => { if (!getEnvStrings.strings) { // Default values. // Browser language detection #8751 @@ -6134,434 +5980,169 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } var strings = []; for (var x in env) { - strings.push(x + '=' + env[x]); + strings.push(`${x}=${env[x]}`); } getEnvStrings.strings = strings; } return getEnvStrings.strings; - } - function _environ_get(__environ, environ_buf) { + }; + + 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(function(string, i) { var ptr = environ_buf + bufSize; - HEAP32[(((__environ)+(i * 4))>>2)] = ptr; - writeAsciiToMemory(string, ptr); + HEAPU32[(((__environ)+(i*4))>>2)] = ptr; + stringToAscii(string, ptr); bufSize += string.length + 1; }); return 0; - } + }; - function _environ_sizes_get(penviron_count, penviron_buf_size) { + + var _environ_sizes_get = (penviron_count, penviron_buf_size) => { var strings = getEnvStrings(); - HEAP32[((penviron_count)>>2)] = strings.length; + HEAPU32[((penviron_count)>>2)] = strings.length; var bufSize = 0; strings.forEach(function(string) { bufSize += string.length + 1; }); - HEAP32[((penviron_buf_size)>>2)] = bufSize; + HEAPU32[((penviron_buf_size)>>2)] = bufSize; return 0; - } + }; - function _fd_close(fd) { + var _fd_close = (fd) => { abort('fd_close called without SYSCALLS_REQUIRE_FILESYSTEM'); - } + }; - function _fd_read(fd, iov, iovcnt, pnum) { + var _fd_read = (fd, iov, iovcnt, pnum) => { abort('fd_read called without SYSCALLS_REQUIRE_FILESYSTEM'); - } - - function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { - return 70; - } - - var printCharBuffers = [null,[],[]]; - function printChar(stream, curr) { - var buffer = printCharBuffers[stream]; - assert(buffer); - if (curr === 0 || curr === 10) { - (stream === 1 ? out : err)(UTF8ArrayToString(buffer, 0)); - buffer.length = 0; - } else { - buffer.push(curr); - } - } - function flush_NO_FILESYSTEM() { - // flush anything remaining in the buffers during shutdown - ___stdio_exit(); - if (printCharBuffers[1].length) printChar(1, 10); - if (printCharBuffers[2].length) printChar(2, 10); - } - function _fd_write(fd, iov, iovcnt, pnum) { - ; - // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0 - var num = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAPU32[((iov)>>2)]; - var len = HEAPU32[(((iov)+(4))>>2)]; - iov += 8; - for (var j = 0; j < len; j++) { - printChar(fd, HEAPU8[ptr+j]); - } - num += len; - } - HEAP32[((pnum)>>2)] = num; - return 0; - } - - function _glActiveTexture(x0) { GLctx['activeTexture'](x0) } - - function _glAttachShader(program, shader) { - GLctx.attachShader(GL.programs[program], GL.shaders[shader]); - } - - function _glBindBuffer(target, buffer) { - - GLctx.bindBuffer(target, GL.buffers[buffer]); - } - - function _glBindTexture(target, texture) { - GLctx.bindTexture(target, GL.textures[texture]); - } - - function _glBindVertexArrayOES(vao) { - GLctx['bindVertexArray'](GL.vaos[vao]); - } - - function _glBlendEquation(x0) { GLctx['blendEquation'](x0) } - - function _glBlendEquationSeparate(x0, x1) { GLctx['blendEquationSeparate'](x0, x1) } - - function _glBlendFuncSeparate(x0, x1, x2, x3) { GLctx['blendFuncSeparate'](x0, x1, x2, x3) } - - function _glBufferData(target, size, data, usage) { - - // N.b. here first form specifies a heap subarray, second form an integer size, so the ?: code here is polymorphic. It is advised to avoid - // randomly mixing both uses in calling code, to avoid any potential JS engine JIT issues. - GLctx.bufferData(target, data ? HEAPU8.subarray(data, data+size) : size, usage); - } - - function _glBufferSubData(target, offset, size, data) { - GLctx.bufferSubData(target, offset, HEAPU8.subarray(data, data+size)); - } - - function _glClear(x0) { GLctx['clear'](x0) } - - function _glClearColor(x0, x1, x2, x3) { GLctx['clearColor'](x0, x1, x2, x3) } - - function _glCompileShader(shader) { - GLctx.compileShader(GL.shaders[shader]); - } - - function _glCreateProgram() { - var id = GL.getNewId(GL.programs); - var program = GLctx.createProgram(); - // Store additional information needed for each shader program: - program.name = id; - // Lazy cache results of glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH) - program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0; - program.uniformIdCounter = 1; - GL.programs[id] = program; - return id; - } - - function _glCreateShader(shaderType) { - var id = GL.getNewId(GL.shaders); - GL.shaders[id] = GLctx.createShader(shaderType); - - return id; - } - - function _glDeleteShader(id) { - if (!id) return; - var shader = GL.shaders[id]; - if (!shader) { // glDeleteShader actually signals an error when deleting a nonexisting object, unlike some other GL delete functions. - GL.recordError(0x501 /* GL_INVALID_VALUE */); - return; - } - GLctx.deleteShader(shader); - GL.shaders[id] = null; - } - - function _glDeleteVertexArraysOES(n, vaos) { - for (var i = 0; i < n; i++) { - var id = HEAP32[(((vaos)+(i*4))>>2)]; - GLctx['deleteVertexArray'](GL.vaos[id]); - GL.vaos[id] = null; - } - } - - function _glDetachShader(program, shader) { - GLctx.detachShader(GL.programs[program], GL.shaders[shader]); - } - - function _glDisable(x0) { GLctx['disable'](x0) } - - function _glDrawElements(mode, count, type, indices) { - - GLctx.drawElements(mode, count, type, indices); - - } - - function _glEnable(x0) { GLctx['enable'](x0) } - - function _glEnableVertexAttribArray(index) { - GLctx.enableVertexAttribArray(index); - } - - function _glGenBuffers(n, buffers) { - __glGenObject(n, buffers, 'createBuffer', GL.buffers - ); - } - - function _glGenTextures(n, textures) { - __glGenObject(n, textures, 'createTexture', GL.textures - ); - } - - function _glGenVertexArraysOES(n, arrays) { - __glGenObject(n, arrays, 'createVertexArray', GL.vaos - ); - } - - function _glGetAttribLocation(program, name) { - return GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name)); - } - - function _glGetIntegerv(name_, p) { - emscriptenWebGLGet(name_, p, 0); - } - - function _glGetProgramInfoLog(program, maxLength, length, infoLog) { - var log = GLctx.getProgramInfoLog(GL.programs[program]); - if (log === null) log = '(unknown error)'; - var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0; - if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull; - } + }; - function _glGetProgramiv(program, pname, p) { - if (!p) { - // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense - // if p == null, issue a GL error to notify user about it. - GL.recordError(0x501 /* GL_INVALID_VALUE */); - return; - } - - if (program >= GL.counter) { - GL.recordError(0x501 /* GL_INVALID_VALUE */); - return; - } - - program = GL.programs[program]; - if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH - var log = GLctx.getProgramInfoLog(program); - if (log === null) log = '(unknown error)'; - HEAP32[((p)>>2)] = log.length + 1; - } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) { - if (!program.maxUniformLength) { - for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); ++i) { - program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1); - } - } - HEAP32[((p)>>2)] = program.maxUniformLength; - } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) { - if (!program.maxAttributeLength) { - for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/); ++i) { - program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1); - } - } - HEAP32[((p)>>2)] = program.maxAttributeLength; - } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) { - if (!program.maxUniformBlockNameLength) { - for (var i = 0; i < GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/); ++i) { - program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1); - } - } - HEAP32[((p)>>2)] = program.maxUniformBlockNameLength; - } else { - HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname); - } - } - - function _glGetShaderInfoLog(shader, maxLength, length, infoLog) { - var log = GLctx.getShaderInfoLog(GL.shaders[shader]); - if (log === null) log = '(unknown error)'; - var numBytesWrittenExclNull = (maxLength > 0 && infoLog) ? stringToUTF8(log, infoLog, maxLength) : 0; - if (length) HEAP32[((length)>>2)] = numBytesWrittenExclNull; - } - - function _glGetShaderiv(shader, pname, p) { - if (!p) { - // GLES2 specification does not specify how to behave if p is a null pointer. Since calling this function does not make sense - // if p == null, issue a GL error to notify user about it. - GL.recordError(0x501 /* GL_INVALID_VALUE */); - return; - } - if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH - var log = GLctx.getShaderInfoLog(GL.shaders[shader]); - if (log === null) log = '(unknown error)'; - // The GLES2 specification says that if the shader has an empty info log, - // a value of 0 is returned. Otherwise the log has a null char appended. - // (An empty string is falsey, so we can just check that instead of - // looking at log.length.) - var logLength = log ? log.length + 1 : 0; - HEAP32[((p)>>2)] = logLength; - } else if (pname == 0x8B88) { // GL_SHADER_SOURCE_LENGTH - var source = GLctx.getShaderSource(GL.shaders[shader]); - // source may be a null, or the empty string, both of which are falsey - // values that we report a 0 length for. - var sourceLength = source ? source.length + 1 : 0; - HEAP32[((p)>>2)] = sourceLength; - } else { - HEAP32[((p)>>2)] = GLctx.getShaderParameter(GL.shaders[shader], pname); - } + function convertI32PairToI53Checked(lo, hi) { + assert(lo == (lo >>> 0) || lo == (lo|0)); // lo should either be a i32 or a u32 + assert(hi === (hi|0)); // hi should be a i32 + return ((hi + 0x200000) >>> 0 < 0x400001 - !!lo) ? (lo >>> 0) + hi * 4294967296 : NaN; } - - function _glGetUniformLocation(program, name) { - - name = UTF8ToString(name); + function _fd_seek(fd,offset_low, offset_high,whence,newOffset) { + var offset = convertI32PairToI53Checked(offset_low, offset_high);; - if (program = GL.programs[program]) { - webglPrepareUniformLocationsBeforeFirstUse(program); - var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation - var arrayIndex = 0; - var uniformBaseName = name; + + return 70; + ; + } + + var printCharBuffers = [null,[],[]]; - // Invariant: when populating integer IDs for uniform locations, we must maintain the precondition that - // arrays reside in contiguous addresses, i.e. for a 'vec4 colors[10];', colors[4] must be at location colors[0]+4. - // However, user might call glGetUniformLocation(program, "colors") for an array, so we cannot discover based on the user - // input arguments whether the uniform we are dealing with is an array. The only way to discover which uniforms are arrays - // is to enumerate over all the active uniforms in the program. - var leftBrace = webglGetLeftBracePos(name); + var printChar = (stream, curr) => { + var buffer = printCharBuffers[stream]; + assert(buffer); + if (curr === 0 || curr === 10) { + (stream === 1 ? out : err)(UTF8ArrayToString(buffer, 0)); + buffer.length = 0; + } else { + buffer.push(curr); + } + }; - // If user passed an array accessor "[index]", parse the array index off the accessor. - if (leftBrace > 0) { - arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0; // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds. - uniformBaseName = name.slice(0, leftBrace); - } + var flush_NO_FILESYSTEM = () => { + // flush anything remaining in the buffers during shutdown + _fflush(0); + if (printCharBuffers[1].length) printChar(1, 10); + if (printCharBuffers[2].length) printChar(2, 10); + }; - // Have we cached the location of this uniform before? - var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName]; // A pair [array length, GLint of the uniform location] - // If an uniform with this name exists, and if its index is within the array limits (if it's even an array), - // query the WebGLlocation, or return an existing cached location. - if (sizeAndId && arrayIndex < sizeAndId[0]) { - arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset. - if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) { - return arrayIndex; - } + var _fd_write = (fd, iov, iovcnt, pnum) => { + // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0 + var num = 0; + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAPU32[((iov)>>2)]; + var len = HEAPU32[(((iov)+(4))>>2)]; + iov += 8; + for (var j = 0; j < len; j++) { + printChar(fd, HEAPU8[ptr+j]); } + num += len; } - else { - // N.b. we are currently unable to distinguish between GL program IDs that never existed vs GL program IDs that have been deleted, - // so report GL_INVALID_VALUE in both cases. - GL.recordError(0x501 /* GL_INVALID_VALUE */); - } - return -1; - } + HEAPU32[((pnum)>>2)] = num; + return 0; + }; + + + + + + + + + + - function _glIsEnabled(x0) { return GLctx['isEnabled'](x0) } - function _glLinkProgram(program) { - program = GL.programs[program]; - GLctx.linkProgram(program); - // Invalidate earlier computed uniform->ID mappings, those have now become stale - program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again. - program.uniformSizeAndIdsByName = {}; - - } - function _glScissor(x0, x1, x2, x3) { GLctx['scissor'](x0, x1, x2, x3) } - function _glShaderSource(shader, count, string, length) { - var source = GL.getSource(shader, count, string, length); - - GLctx.shaderSource(GL.shaders[shader], source); - } - function _glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) { - GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null); - } - function _glTexParameteri(x0, x1, x2) { GLctx['texParameteri'](x0, x1, x2) } - function _glUniform1i(location, v0) { - GLctx.uniform1i(webglGetUniformLocation(location), v0); - } - function _glUniformMatrix4fv(location, count, transpose, value) { - - if (count <= 18) { - // avoid allocation when uploading few enough uniforms - var view = miniTempWebGLFloatBuffers[16*count-1]; - // hoist the heap out of the loop for size and for pthreads+growth. - var heap = HEAPF32; - value >>= 2; - for (var i = 0; i < 16 * count; i += 16) { - var dst = value + i; - view[i] = heap[dst]; - view[i + 1] = heap[dst + 1]; - view[i + 2] = heap[dst + 2]; - view[i + 3] = heap[dst + 3]; - view[i + 4] = heap[dst + 4]; - view[i + 5] = heap[dst + 5]; - view[i + 6] = heap[dst + 6]; - view[i + 7] = heap[dst + 7]; - view[i + 8] = heap[dst + 8]; - view[i + 9] = heap[dst + 9]; - view[i + 10] = heap[dst + 10]; - view[i + 11] = heap[dst + 11]; - view[i + 12] = heap[dst + 12]; - view[i + 13] = heap[dst + 13]; - view[i + 14] = heap[dst + 14]; - view[i + 15] = heap[dst + 15]; - } - } else - { - var view = HEAPF32.subarray((value)>>2, (value+count*64)>>2); - } - GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view); - } - function _glUseProgram(program) { - program = GL.programs[program]; - GLctx.useProgram(program); - // Record the currently active program so that we can access the uniform - // mapping table of that program. - GLctx.currentProgram = program; - } - function _glVertexAttribPointer(index, size, type, normalized, stride, ptr) { - GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); - } - function _glViewport(x0, x1, x2, x3) { GLctx['viewport'](x0, x1, x2, x3) } - function _setTempRet0(val) { - setTempRet0(val); - } - function __isLeapYear(year) { + + + + + + + + + + + + + + + + + + + + + + var isLeapYear = (year) => { return year%4 === 0 && (year%100 !== 0 || year%400 === 0); - } + }; - function __arraySum(array, index) { + 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_LEAP = [31,29,31,30,31,30,31,31,30,31,30,31]; - var __MONTH_DAYS_REGULAR = [31,28,31,30,31,30,31,31,30,31,30,31]; - function __addDays(date, days) { + var 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 leap = isLeapYear(newDate.getFullYear()); var currentMonth = newDate.getMonth(); - var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth]; + var daysInCurrentMonth = (leap ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR)[currentMonth]; if (days > daysInCurrentMonth-newDate.getDate()) { // we spill over to next month @@ -6581,8 +6162,26 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } return newDate; - } - function _strftime(s, maxsize, format, tm) { + }; + + + + + /** @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 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 @@ -6689,7 +6288,7 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = } function getWeekBasedYear(date) { - var thisDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday); + 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); @@ -6701,38 +6300,24 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = // this date is after the start of the first week of this year if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { return thisDate.getFullYear()+1; - } else { - return thisDate.getFullYear(); } - } else { - return thisDate.getFullYear()-1; + return thisDate.getFullYear(); } + return thisDate.getFullYear()-1; } var EXPANSION_RULES_2 = { - '%a': function(date) { - return WEEKDAYS[date.tm_wday].substring(0,3); - }, - '%A': function(date) { - return WEEKDAYS[date.tm_wday]; - }, - '%b': function(date) { - return MONTHS[date.tm_mon].substring(0,3); - }, - '%B': function(date) { - return MONTHS[date.tm_mon]; - }, - '%C': function(date) { + '%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': function(date) { - return leadingNulls(date.tm_mday, 2); - }, - '%e': function(date) { - return leadingSomething(date.tm_mday, 2, ' '); - }, - '%g': function(date) { + '%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 @@ -6745,52 +6330,35 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = return getWeekBasedYear(date).toString().substring(2); }, - '%G': function(date) { - return getWeekBasedYear(date); - }, - '%H': function(date) { - return leadingNulls(date.tm_hour, 2); - }, - '%I': function(date) { + '%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': function(date) { + '%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': function(date) { - return leadingNulls(date.tm_mon+1, 2); - }, - '%M': function(date) { - return leadingNulls(date.tm_min, 2); + return leadingNulls(date.tm_mday + arraySum(isLeapYear(date.tm_year+1900) ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR, date.tm_mon-1), 3); }, - '%n': function() { - return '\n'; - }, - '%p': function(date) { + '%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'; - } else { - return 'PM'; } + return 'PM'; }, - '%S': function(date) { - return leadingNulls(date.tm_sec, 2); - }, - '%t': function() { - return '\t'; - }, - '%u': function(date) { - return date.tm_wday || 7; - }, - '%U': function(date) { + '%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': function(date) { + '%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. @@ -6807,34 +6375,30 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = // 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))) { + 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))) + if (jan1 != 4 && (jan1 != 3 || !isLeapYear(date.tm_year))) val = 1; } return leadingNulls(val, 2); }, - '%w': function(date) { - return date.tm_wday; - }, - '%W': function(date) { + '%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': function(date) { + '%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); }, - '%Y': function(date) { - // Replaced by the year as a decimal number (for example, 1997). [ tm_year] - return date.tm_year+1900; - }, - '%z': function(date) { + // Replaced by the 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; @@ -6844,12 +6408,8 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = off = (off / 60)*100 + (off % 60); return (ahead ? '+' : '-') + String("0000" + off).slice(-4); }, - '%Z': function(date) { - return date.tm_zone; - }, - '%%': function() { - return '%'; - } + '%Z': (date) => date.tm_zone, + '%%': () => '%' }; // Replace %% with a pair of NULLs (which cannot occur in a C string), then @@ -6869,21 +6429,25 @@ function sapp_js_write_clipboard(c_str){ var str = UTF8ToString(c_str); var ta = writeArrayToMemory(bytes, s); return bytes.length-1; - } - function _strftime_l(s, maxsize, format, tm) { + }; + var _strftime_l = (s, maxsize, format, tm, loc) => { return _strftime(s, maxsize, format, tm); // no locale support yet - } -Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas) { Browser.requestFullscreen(lockPointer, resizeCanvas) }; - Module["requestFullScreen"] = function Module_requestFullScreen() { Browser.requestFullScreen() }; - Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) }; - Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) }; - Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() }; - Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() }; - Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }; - Module["createContext"] = function Module_createContext(canvas, useWebGL, setInModule, webGLContextAttributes) { return Browser.createContext(canvas, useWebGL, setInModule, webGLContextAttributes) }; - var preloadedImages = {}; - var preloadedAudios = {}; - ; + }; + + + + + // exports + Module["requestFullscreen"] = function Module_requestFullscreen(lockPointer, resizeCanvas) { Browser.requestFullscreen(lockPointer, resizeCanvas) }; + Module["requestFullScreen"] = function Module_requestFullScreen() { Browser.requestFullScreen() }; + Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) }; + Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) }; + Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() }; + Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() }; + Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }; + Module["createContext"] = function Module_createContext(canvas, useWebGL, setInModule, webGLContextAttributes) { return Browser.createContext(canvas, useWebGL, setInModule, webGLContextAttributes) }; + var preloadedImages = {}; + var preloadedAudios = {};; var GLctx;; for (var i = 0; i < 32; ++i) tempFixedLengthArray.push(new Array(i));; var miniTempWebGLFloatBuffersStorage = new Float32Array(288); @@ -6891,639 +6455,597 @@ var miniTempWebGLFloatBuffersStorage = new Float32Array(288); miniTempWebGLFloatBuffers[i] = miniTempWebGLFloatBuffersStorage.subarray(0, i+1); } ; -var __miniTempWebGLIntBuffersStorage = new Int32Array(288); +var miniTempWebGLIntBuffersStorage = new Int32Array(288); for (/**@suppress{duplicate}*/var i = 0; i < 288; ++i) { - __miniTempWebGLIntBuffers[i] = __miniTempWebGLIntBuffersStorage.subarray(0, i+1); + miniTempWebGLIntBuffers[i] = miniTempWebGLIntBuffersStorage.subarray(0, i+1); } ; -var ASSERTIONS = true; - - - -/** @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; -} - -function intArrayToString(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - var chr = array[i]; - if (chr > 0xFF) { - if (ASSERTIONS) { - assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); - } - chr &= 0xFF; - } - ret.push(String.fromCharCode(chr)); - } - return ret.join(''); -} - - function checkIncomingModuleAPI() { ignoredModuleProp('fetchSettings'); } -var asmLibraryArg = { - "__assert_fail": ___assert_fail, - "__cxa_allocate_exception": ___cxa_allocate_exception, - "__cxa_throw": ___cxa_throw, - "__syscall_fcntl64": ___syscall_fcntl64, - "__syscall_ioctl": ___syscall_ioctl, - "__syscall_openat": ___syscall_openat, - "_emscripten_date_now": __emscripten_date_now, - "_emscripten_get_now_is_monotonic": __emscripten_get_now_is_monotonic, - "abort": _abort, - "eglBindAPI": _eglBindAPI, - "eglChooseConfig": _eglChooseConfig, - "eglCreateContext": _eglCreateContext, - "eglCreateWindowSurface": _eglCreateWindowSurface, - "eglDestroyContext": _eglDestroyContext, - "eglDestroySurface": _eglDestroySurface, - "eglGetConfigAttrib": _eglGetConfigAttrib, - "eglGetDisplay": _eglGetDisplay, - "eglGetError": _eglGetError, - "eglInitialize": _eglInitialize, - "eglMakeCurrent": _eglMakeCurrent, - "eglQueryString": _eglQueryString, - "eglSwapBuffers": _eglSwapBuffers, - "eglSwapInterval": _eglSwapInterval, - "eglTerminate": _eglTerminate, - "eglWaitGL": _eglWaitGL, - "eglWaitNative": _eglWaitNative, - "emscripten_asm_const_int": _emscripten_asm_const_int, - "emscripten_exit_fullscreen": _emscripten_exit_fullscreen, - "emscripten_exit_pointerlock": _emscripten_exit_pointerlock, - "emscripten_get_device_pixel_ratio": _emscripten_get_device_pixel_ratio, - "emscripten_get_element_css_size": _emscripten_get_element_css_size, - "emscripten_get_gamepad_status": _emscripten_get_gamepad_status, - "emscripten_get_now": _emscripten_get_now, - "emscripten_get_num_gamepads": _emscripten_get_num_gamepads, - "emscripten_get_screen_size": _emscripten_get_screen_size, - "emscripten_glActiveTexture": _emscripten_glActiveTexture, - "emscripten_glAttachShader": _emscripten_glAttachShader, - "emscripten_glBeginQueryEXT": _emscripten_glBeginQueryEXT, - "emscripten_glBindAttribLocation": _emscripten_glBindAttribLocation, - "emscripten_glBindBuffer": _emscripten_glBindBuffer, - "emscripten_glBindFramebuffer": _emscripten_glBindFramebuffer, - "emscripten_glBindRenderbuffer": _emscripten_glBindRenderbuffer, - "emscripten_glBindTexture": _emscripten_glBindTexture, - "emscripten_glBindVertexArrayOES": _emscripten_glBindVertexArrayOES, - "emscripten_glBlendColor": _emscripten_glBlendColor, - "emscripten_glBlendEquation": _emscripten_glBlendEquation, - "emscripten_glBlendEquationSeparate": _emscripten_glBlendEquationSeparate, - "emscripten_glBlendFunc": _emscripten_glBlendFunc, - "emscripten_glBlendFuncSeparate": _emscripten_glBlendFuncSeparate, - "emscripten_glBufferData": _emscripten_glBufferData, - "emscripten_glBufferSubData": _emscripten_glBufferSubData, - "emscripten_glCheckFramebufferStatus": _emscripten_glCheckFramebufferStatus, - "emscripten_glClear": _emscripten_glClear, - "emscripten_glClearColor": _emscripten_glClearColor, - "emscripten_glClearDepthf": _emscripten_glClearDepthf, - "emscripten_glClearStencil": _emscripten_glClearStencil, - "emscripten_glColorMask": _emscripten_glColorMask, - "emscripten_glCompileShader": _emscripten_glCompileShader, - "emscripten_glCompressedTexImage2D": _emscripten_glCompressedTexImage2D, - "emscripten_glCompressedTexSubImage2D": _emscripten_glCompressedTexSubImage2D, - "emscripten_glCopyTexImage2D": _emscripten_glCopyTexImage2D, - "emscripten_glCopyTexSubImage2D": _emscripten_glCopyTexSubImage2D, - "emscripten_glCreateProgram": _emscripten_glCreateProgram, - "emscripten_glCreateShader": _emscripten_glCreateShader, - "emscripten_glCullFace": _emscripten_glCullFace, - "emscripten_glDeleteBuffers": _emscripten_glDeleteBuffers, - "emscripten_glDeleteFramebuffers": _emscripten_glDeleteFramebuffers, - "emscripten_glDeleteProgram": _emscripten_glDeleteProgram, - "emscripten_glDeleteQueriesEXT": _emscripten_glDeleteQueriesEXT, - "emscripten_glDeleteRenderbuffers": _emscripten_glDeleteRenderbuffers, - "emscripten_glDeleteShader": _emscripten_glDeleteShader, - "emscripten_glDeleteTextures": _emscripten_glDeleteTextures, - "emscripten_glDeleteVertexArraysOES": _emscripten_glDeleteVertexArraysOES, - "emscripten_glDepthFunc": _emscripten_glDepthFunc, - "emscripten_glDepthMask": _emscripten_glDepthMask, - "emscripten_glDepthRangef": _emscripten_glDepthRangef, - "emscripten_glDetachShader": _emscripten_glDetachShader, - "emscripten_glDisable": _emscripten_glDisable, - "emscripten_glDisableVertexAttribArray": _emscripten_glDisableVertexAttribArray, - "emscripten_glDrawArrays": _emscripten_glDrawArrays, - "emscripten_glDrawArraysInstancedANGLE": _emscripten_glDrawArraysInstancedANGLE, - "emscripten_glDrawBuffersWEBGL": _emscripten_glDrawBuffersWEBGL, - "emscripten_glDrawElements": _emscripten_glDrawElements, - "emscripten_glDrawElementsInstancedANGLE": _emscripten_glDrawElementsInstancedANGLE, - "emscripten_glEnable": _emscripten_glEnable, - "emscripten_glEnableVertexAttribArray": _emscripten_glEnableVertexAttribArray, - "emscripten_glEndQueryEXT": _emscripten_glEndQueryEXT, - "emscripten_glFinish": _emscripten_glFinish, - "emscripten_glFlush": _emscripten_glFlush, - "emscripten_glFramebufferRenderbuffer": _emscripten_glFramebufferRenderbuffer, - "emscripten_glFramebufferTexture2D": _emscripten_glFramebufferTexture2D, - "emscripten_glFrontFace": _emscripten_glFrontFace, - "emscripten_glGenBuffers": _emscripten_glGenBuffers, - "emscripten_glGenFramebuffers": _emscripten_glGenFramebuffers, - "emscripten_glGenQueriesEXT": _emscripten_glGenQueriesEXT, - "emscripten_glGenRenderbuffers": _emscripten_glGenRenderbuffers, - "emscripten_glGenTextures": _emscripten_glGenTextures, - "emscripten_glGenVertexArraysOES": _emscripten_glGenVertexArraysOES, - "emscripten_glGenerateMipmap": _emscripten_glGenerateMipmap, - "emscripten_glGetActiveAttrib": _emscripten_glGetActiveAttrib, - "emscripten_glGetActiveUniform": _emscripten_glGetActiveUniform, - "emscripten_glGetAttachedShaders": _emscripten_glGetAttachedShaders, - "emscripten_glGetAttribLocation": _emscripten_glGetAttribLocation, - "emscripten_glGetBooleanv": _emscripten_glGetBooleanv, - "emscripten_glGetBufferParameteriv": _emscripten_glGetBufferParameteriv, - "emscripten_glGetError": _emscripten_glGetError, - "emscripten_glGetFloatv": _emscripten_glGetFloatv, - "emscripten_glGetFramebufferAttachmentParameteriv": _emscripten_glGetFramebufferAttachmentParameteriv, - "emscripten_glGetIntegerv": _emscripten_glGetIntegerv, - "emscripten_glGetProgramInfoLog": _emscripten_glGetProgramInfoLog, - "emscripten_glGetProgramiv": _emscripten_glGetProgramiv, - "emscripten_glGetQueryObjecti64vEXT": _emscripten_glGetQueryObjecti64vEXT, - "emscripten_glGetQueryObjectivEXT": _emscripten_glGetQueryObjectivEXT, - "emscripten_glGetQueryObjectui64vEXT": _emscripten_glGetQueryObjectui64vEXT, - "emscripten_glGetQueryObjectuivEXT": _emscripten_glGetQueryObjectuivEXT, - "emscripten_glGetQueryivEXT": _emscripten_glGetQueryivEXT, - "emscripten_glGetRenderbufferParameteriv": _emscripten_glGetRenderbufferParameteriv, - "emscripten_glGetShaderInfoLog": _emscripten_glGetShaderInfoLog, - "emscripten_glGetShaderPrecisionFormat": _emscripten_glGetShaderPrecisionFormat, - "emscripten_glGetShaderSource": _emscripten_glGetShaderSource, - "emscripten_glGetShaderiv": _emscripten_glGetShaderiv, - "emscripten_glGetString": _emscripten_glGetString, - "emscripten_glGetTexParameterfv": _emscripten_glGetTexParameterfv, - "emscripten_glGetTexParameteriv": _emscripten_glGetTexParameteriv, - "emscripten_glGetUniformLocation": _emscripten_glGetUniformLocation, - "emscripten_glGetUniformfv": _emscripten_glGetUniformfv, - "emscripten_glGetUniformiv": _emscripten_glGetUniformiv, - "emscripten_glGetVertexAttribPointerv": _emscripten_glGetVertexAttribPointerv, - "emscripten_glGetVertexAttribfv": _emscripten_glGetVertexAttribfv, - "emscripten_glGetVertexAttribiv": _emscripten_glGetVertexAttribiv, - "emscripten_glHint": _emscripten_glHint, - "emscripten_glIsBuffer": _emscripten_glIsBuffer, - "emscripten_glIsEnabled": _emscripten_glIsEnabled, - "emscripten_glIsFramebuffer": _emscripten_glIsFramebuffer, - "emscripten_glIsProgram": _emscripten_glIsProgram, - "emscripten_glIsQueryEXT": _emscripten_glIsQueryEXT, - "emscripten_glIsRenderbuffer": _emscripten_glIsRenderbuffer, - "emscripten_glIsShader": _emscripten_glIsShader, - "emscripten_glIsTexture": _emscripten_glIsTexture, - "emscripten_glIsVertexArrayOES": _emscripten_glIsVertexArrayOES, - "emscripten_glLineWidth": _emscripten_glLineWidth, - "emscripten_glLinkProgram": _emscripten_glLinkProgram, - "emscripten_glPixelStorei": _emscripten_glPixelStorei, - "emscripten_glPolygonOffset": _emscripten_glPolygonOffset, - "emscripten_glQueryCounterEXT": _emscripten_glQueryCounterEXT, - "emscripten_glReadPixels": _emscripten_glReadPixels, - "emscripten_glReleaseShaderCompiler": _emscripten_glReleaseShaderCompiler, - "emscripten_glRenderbufferStorage": _emscripten_glRenderbufferStorage, - "emscripten_glSampleCoverage": _emscripten_glSampleCoverage, - "emscripten_glScissor": _emscripten_glScissor, - "emscripten_glShaderBinary": _emscripten_glShaderBinary, - "emscripten_glShaderSource": _emscripten_glShaderSource, - "emscripten_glStencilFunc": _emscripten_glStencilFunc, - "emscripten_glStencilFuncSeparate": _emscripten_glStencilFuncSeparate, - "emscripten_glStencilMask": _emscripten_glStencilMask, - "emscripten_glStencilMaskSeparate": _emscripten_glStencilMaskSeparate, - "emscripten_glStencilOp": _emscripten_glStencilOp, - "emscripten_glStencilOpSeparate": _emscripten_glStencilOpSeparate, - "emscripten_glTexImage2D": _emscripten_glTexImage2D, - "emscripten_glTexParameterf": _emscripten_glTexParameterf, - "emscripten_glTexParameterfv": _emscripten_glTexParameterfv, - "emscripten_glTexParameteri": _emscripten_glTexParameteri, - "emscripten_glTexParameteriv": _emscripten_glTexParameteriv, - "emscripten_glTexSubImage2D": _emscripten_glTexSubImage2D, - "emscripten_glUniform1f": _emscripten_glUniform1f, - "emscripten_glUniform1fv": _emscripten_glUniform1fv, - "emscripten_glUniform1i": _emscripten_glUniform1i, - "emscripten_glUniform1iv": _emscripten_glUniform1iv, - "emscripten_glUniform2f": _emscripten_glUniform2f, - "emscripten_glUniform2fv": _emscripten_glUniform2fv, - "emscripten_glUniform2i": _emscripten_glUniform2i, - "emscripten_glUniform2iv": _emscripten_glUniform2iv, - "emscripten_glUniform3f": _emscripten_glUniform3f, - "emscripten_glUniform3fv": _emscripten_glUniform3fv, - "emscripten_glUniform3i": _emscripten_glUniform3i, - "emscripten_glUniform3iv": _emscripten_glUniform3iv, - "emscripten_glUniform4f": _emscripten_glUniform4f, - "emscripten_glUniform4fv": _emscripten_glUniform4fv, - "emscripten_glUniform4i": _emscripten_glUniform4i, - "emscripten_glUniform4iv": _emscripten_glUniform4iv, - "emscripten_glUniformMatrix2fv": _emscripten_glUniformMatrix2fv, - "emscripten_glUniformMatrix3fv": _emscripten_glUniformMatrix3fv, - "emscripten_glUniformMatrix4fv": _emscripten_glUniformMatrix4fv, - "emscripten_glUseProgram": _emscripten_glUseProgram, - "emscripten_glValidateProgram": _emscripten_glValidateProgram, - "emscripten_glVertexAttrib1f": _emscripten_glVertexAttrib1f, - "emscripten_glVertexAttrib1fv": _emscripten_glVertexAttrib1fv, - "emscripten_glVertexAttrib2f": _emscripten_glVertexAttrib2f, - "emscripten_glVertexAttrib2fv": _emscripten_glVertexAttrib2fv, - "emscripten_glVertexAttrib3f": _emscripten_glVertexAttrib3f, - "emscripten_glVertexAttrib3fv": _emscripten_glVertexAttrib3fv, - "emscripten_glVertexAttrib4f": _emscripten_glVertexAttrib4f, - "emscripten_glVertexAttrib4fv": _emscripten_glVertexAttrib4fv, - "emscripten_glVertexAttribDivisorANGLE": _emscripten_glVertexAttribDivisorANGLE, - "emscripten_glVertexAttribPointer": _emscripten_glVertexAttribPointer, - "emscripten_glViewport": _emscripten_glViewport, - "emscripten_has_asyncify": _emscripten_has_asyncify, - "emscripten_memcpy_big": _emscripten_memcpy_big, - "emscripten_request_fullscreen_strategy": _emscripten_request_fullscreen_strategy, - "emscripten_request_pointerlock": _emscripten_request_pointerlock, - "emscripten_resize_heap": _emscripten_resize_heap, - "emscripten_run_script": _emscripten_run_script, - "emscripten_sample_gamepad_data": _emscripten_sample_gamepad_data, - "emscripten_set_beforeunload_callback_on_thread": _emscripten_set_beforeunload_callback_on_thread, - "emscripten_set_blur_callback_on_thread": _emscripten_set_blur_callback_on_thread, - "emscripten_set_canvas_element_size": _emscripten_set_canvas_element_size, - "emscripten_set_element_css_size": _emscripten_set_element_css_size, - "emscripten_set_focus_callback_on_thread": _emscripten_set_focus_callback_on_thread, - "emscripten_set_fullscreenchange_callback_on_thread": _emscripten_set_fullscreenchange_callback_on_thread, - "emscripten_set_gamepadconnected_callback_on_thread": _emscripten_set_gamepadconnected_callback_on_thread, - "emscripten_set_gamepaddisconnected_callback_on_thread": _emscripten_set_gamepaddisconnected_callback_on_thread, - "emscripten_set_keydown_callback_on_thread": _emscripten_set_keydown_callback_on_thread, - "emscripten_set_keypress_callback_on_thread": _emscripten_set_keypress_callback_on_thread, - "emscripten_set_keyup_callback_on_thread": _emscripten_set_keyup_callback_on_thread, - "emscripten_set_main_loop_arg": _emscripten_set_main_loop_arg, - "emscripten_set_mousedown_callback_on_thread": _emscripten_set_mousedown_callback_on_thread, - "emscripten_set_mouseenter_callback_on_thread": _emscripten_set_mouseenter_callback_on_thread, - "emscripten_set_mouseleave_callback_on_thread": _emscripten_set_mouseleave_callback_on_thread, - "emscripten_set_mousemove_callback_on_thread": _emscripten_set_mousemove_callback_on_thread, - "emscripten_set_mouseup_callback_on_thread": _emscripten_set_mouseup_callback_on_thread, - "emscripten_set_pointerlockchange_callback_on_thread": _emscripten_set_pointerlockchange_callback_on_thread, - "emscripten_set_resize_callback_on_thread": _emscripten_set_resize_callback_on_thread, - "emscripten_set_touchcancel_callback_on_thread": _emscripten_set_touchcancel_callback_on_thread, - "emscripten_set_touchend_callback_on_thread": _emscripten_set_touchend_callback_on_thread, - "emscripten_set_touchmove_callback_on_thread": _emscripten_set_touchmove_callback_on_thread, - "emscripten_set_touchstart_callback_on_thread": _emscripten_set_touchstart_callback_on_thread, - "emscripten_set_visibilitychange_callback_on_thread": _emscripten_set_visibilitychange_callback_on_thread, - "emscripten_set_wheel_callback_on_thread": _emscripten_set_wheel_callback_on_thread, - "emscripten_set_window_title": _emscripten_set_window_title, - "emscripten_sleep": _emscripten_sleep, - "environ_get": _environ_get, - "environ_sizes_get": _environ_sizes_get, - "fd_close": _fd_close, - "fd_read": _fd_read, - "fd_seek": _fd_seek, - "fd_write": _fd_write, - "glActiveTexture": _glActiveTexture, - "glAttachShader": _glAttachShader, - "glBindBuffer": _glBindBuffer, - "glBindTexture": _glBindTexture, - "glBindVertexArrayOES": _glBindVertexArrayOES, - "glBlendEquation": _glBlendEquation, - "glBlendEquationSeparate": _glBlendEquationSeparate, - "glBlendFuncSeparate": _glBlendFuncSeparate, - "glBufferData": _glBufferData, - "glBufferSubData": _glBufferSubData, - "glClear": _glClear, - "glClearColor": _glClearColor, - "glCompileShader": _glCompileShader, - "glCreateProgram": _glCreateProgram, - "glCreateShader": _glCreateShader, - "glDeleteShader": _glDeleteShader, - "glDeleteVertexArraysOES": _glDeleteVertexArraysOES, - "glDetachShader": _glDetachShader, - "glDisable": _glDisable, - "glDrawElements": _glDrawElements, - "glEnable": _glEnable, - "glEnableVertexAttribArray": _glEnableVertexAttribArray, - "glGenBuffers": _glGenBuffers, - "glGenTextures": _glGenTextures, - "glGenVertexArraysOES": _glGenVertexArraysOES, - "glGetAttribLocation": _glGetAttribLocation, - "glGetIntegerv": _glGetIntegerv, - "glGetProgramInfoLog": _glGetProgramInfoLog, - "glGetProgramiv": _glGetProgramiv, - "glGetShaderInfoLog": _glGetShaderInfoLog, - "glGetShaderiv": _glGetShaderiv, - "glGetUniformLocation": _glGetUniformLocation, - "glIsEnabled": _glIsEnabled, - "glLinkProgram": _glLinkProgram, - "glScissor": _glScissor, - "glShaderSource": _glShaderSource, - "glTexImage2D": _glTexImage2D, - "glTexParameteri": _glTexParameteri, - "glUniform1i": _glUniform1i, - "glUniformMatrix4fv": _glUniformMatrix4fv, - "glUseProgram": _glUseProgram, - "glVertexAttribPointer": _glVertexAttribPointer, - "glViewport": _glViewport, - "sapp_js_write_clipboard": sapp_js_write_clipboard, - "setTempRet0": _setTempRet0, - "strftime_l": _strftime_l +var wasmImports = { + __assert_fail: ___assert_fail, + __cxa_throw: ___cxa_throw, + __syscall_fcntl64: ___syscall_fcntl64, + __syscall_ioctl: ___syscall_ioctl, + __syscall_openat: ___syscall_openat, + _emscripten_get_now_is_monotonic: __emscripten_get_now_is_monotonic, + abort: _abort, + eglBindAPI: _eglBindAPI, + eglChooseConfig: _eglChooseConfig, + eglCreateContext: _eglCreateContext, + eglCreateWindowSurface: _eglCreateWindowSurface, + eglDestroyContext: _eglDestroyContext, + eglDestroySurface: _eglDestroySurface, + eglGetConfigAttrib: _eglGetConfigAttrib, + eglGetDisplay: _eglGetDisplay, + eglGetError: _eglGetError, + eglInitialize: _eglInitialize, + eglMakeCurrent: _eglMakeCurrent, + eglQueryString: _eglQueryString, + eglSwapBuffers: _eglSwapBuffers, + eglSwapInterval: _eglSwapInterval, + eglTerminate: _eglTerminate, + eglWaitGL: _eglWaitGL, + eglWaitNative: _eglWaitNative, + emscripten_asm_const_int: _emscripten_asm_const_int, + emscripten_asm_const_int_sync_on_main_thread: _emscripten_asm_const_int_sync_on_main_thread, + emscripten_date_now: _emscripten_date_now, + emscripten_exit_fullscreen: _emscripten_exit_fullscreen, + emscripten_exit_pointerlock: _emscripten_exit_pointerlock, + emscripten_get_device_pixel_ratio: _emscripten_get_device_pixel_ratio, + emscripten_get_element_css_size: _emscripten_get_element_css_size, + emscripten_get_gamepad_status: _emscripten_get_gamepad_status, + emscripten_get_now: _emscripten_get_now, + emscripten_get_num_gamepads: _emscripten_get_num_gamepads, + emscripten_get_screen_size: _emscripten_get_screen_size, + emscripten_glActiveTexture: _emscripten_glActiveTexture, + emscripten_glAttachShader: _emscripten_glAttachShader, + emscripten_glBeginQueryEXT: _emscripten_glBeginQueryEXT, + emscripten_glBindAttribLocation: _emscripten_glBindAttribLocation, + emscripten_glBindBuffer: _emscripten_glBindBuffer, + emscripten_glBindFramebuffer: _emscripten_glBindFramebuffer, + emscripten_glBindRenderbuffer: _emscripten_glBindRenderbuffer, + emscripten_glBindTexture: _emscripten_glBindTexture, + emscripten_glBindVertexArrayOES: _emscripten_glBindVertexArrayOES, + emscripten_glBlendColor: _emscripten_glBlendColor, + emscripten_glBlendEquation: _emscripten_glBlendEquation, + emscripten_glBlendEquationSeparate: _emscripten_glBlendEquationSeparate, + emscripten_glBlendFunc: _emscripten_glBlendFunc, + emscripten_glBlendFuncSeparate: _emscripten_glBlendFuncSeparate, + emscripten_glBufferData: _emscripten_glBufferData, + emscripten_glBufferSubData: _emscripten_glBufferSubData, + emscripten_glCheckFramebufferStatus: _emscripten_glCheckFramebufferStatus, + emscripten_glClear: _emscripten_glClear, + emscripten_glClearColor: _emscripten_glClearColor, + emscripten_glClearDepthf: _emscripten_glClearDepthf, + emscripten_glClearStencil: _emscripten_glClearStencil, + emscripten_glColorMask: _emscripten_glColorMask, + emscripten_glCompileShader: _emscripten_glCompileShader, + emscripten_glCompressedTexImage2D: _emscripten_glCompressedTexImage2D, + emscripten_glCompressedTexSubImage2D: _emscripten_glCompressedTexSubImage2D, + emscripten_glCopyTexImage2D: _emscripten_glCopyTexImage2D, + emscripten_glCopyTexSubImage2D: _emscripten_glCopyTexSubImage2D, + emscripten_glCreateProgram: _emscripten_glCreateProgram, + emscripten_glCreateShader: _emscripten_glCreateShader, + emscripten_glCullFace: _emscripten_glCullFace, + emscripten_glDeleteBuffers: _emscripten_glDeleteBuffers, + emscripten_glDeleteFramebuffers: _emscripten_glDeleteFramebuffers, + emscripten_glDeleteProgram: _emscripten_glDeleteProgram, + emscripten_glDeleteQueriesEXT: _emscripten_glDeleteQueriesEXT, + emscripten_glDeleteRenderbuffers: _emscripten_glDeleteRenderbuffers, + emscripten_glDeleteShader: _emscripten_glDeleteShader, + emscripten_glDeleteTextures: _emscripten_glDeleteTextures, + emscripten_glDeleteVertexArraysOES: _emscripten_glDeleteVertexArraysOES, + emscripten_glDepthFunc: _emscripten_glDepthFunc, + emscripten_glDepthMask: _emscripten_glDepthMask, + emscripten_glDepthRangef: _emscripten_glDepthRangef, + emscripten_glDetachShader: _emscripten_glDetachShader, + emscripten_glDisable: _emscripten_glDisable, + emscripten_glDisableVertexAttribArray: _emscripten_glDisableVertexAttribArray, + emscripten_glDrawArrays: _emscripten_glDrawArrays, + emscripten_glDrawArraysInstancedANGLE: _emscripten_glDrawArraysInstancedANGLE, + emscripten_glDrawBuffersWEBGL: _emscripten_glDrawBuffersWEBGL, + emscripten_glDrawElements: _emscripten_glDrawElements, + emscripten_glDrawElementsInstancedANGLE: _emscripten_glDrawElementsInstancedANGLE, + emscripten_glEnable: _emscripten_glEnable, + emscripten_glEnableVertexAttribArray: _emscripten_glEnableVertexAttribArray, + emscripten_glEndQueryEXT: _emscripten_glEndQueryEXT, + emscripten_glFinish: _emscripten_glFinish, + emscripten_glFlush: _emscripten_glFlush, + emscripten_glFramebufferRenderbuffer: _emscripten_glFramebufferRenderbuffer, + emscripten_glFramebufferTexture2D: _emscripten_glFramebufferTexture2D, + emscripten_glFrontFace: _emscripten_glFrontFace, + emscripten_glGenBuffers: _emscripten_glGenBuffers, + emscripten_glGenFramebuffers: _emscripten_glGenFramebuffers, + emscripten_glGenQueriesEXT: _emscripten_glGenQueriesEXT, + emscripten_glGenRenderbuffers: _emscripten_glGenRenderbuffers, + emscripten_glGenTextures: _emscripten_glGenTextures, + emscripten_glGenVertexArraysOES: _emscripten_glGenVertexArraysOES, + emscripten_glGenerateMipmap: _emscripten_glGenerateMipmap, + emscripten_glGetActiveAttrib: _emscripten_glGetActiveAttrib, + emscripten_glGetActiveUniform: _emscripten_glGetActiveUniform, + emscripten_glGetAttachedShaders: _emscripten_glGetAttachedShaders, + emscripten_glGetAttribLocation: _emscripten_glGetAttribLocation, + emscripten_glGetBooleanv: _emscripten_glGetBooleanv, + emscripten_glGetBufferParameteriv: _emscripten_glGetBufferParameteriv, + emscripten_glGetError: _emscripten_glGetError, + emscripten_glGetFloatv: _emscripten_glGetFloatv, + emscripten_glGetFramebufferAttachmentParameteriv: _emscripten_glGetFramebufferAttachmentParameteriv, + emscripten_glGetIntegerv: _emscripten_glGetIntegerv, + emscripten_glGetProgramInfoLog: _emscripten_glGetProgramInfoLog, + emscripten_glGetProgramiv: _emscripten_glGetProgramiv, + emscripten_glGetQueryObjecti64vEXT: _emscripten_glGetQueryObjecti64vEXT, + emscripten_glGetQueryObjectivEXT: _emscripten_glGetQueryObjectivEXT, + emscripten_glGetQueryObjectui64vEXT: _emscripten_glGetQueryObjectui64vEXT, + emscripten_glGetQueryObjectuivEXT: _emscripten_glGetQueryObjectuivEXT, + emscripten_glGetQueryivEXT: _emscripten_glGetQueryivEXT, + emscripten_glGetRenderbufferParameteriv: _emscripten_glGetRenderbufferParameteriv, + emscripten_glGetShaderInfoLog: _emscripten_glGetShaderInfoLog, + emscripten_glGetShaderPrecisionFormat: _emscripten_glGetShaderPrecisionFormat, + emscripten_glGetShaderSource: _emscripten_glGetShaderSource, + emscripten_glGetShaderiv: _emscripten_glGetShaderiv, + emscripten_glGetString: _emscripten_glGetString, + emscripten_glGetTexParameterfv: _emscripten_glGetTexParameterfv, + emscripten_glGetTexParameteriv: _emscripten_glGetTexParameteriv, + emscripten_glGetUniformLocation: _emscripten_glGetUniformLocation, + emscripten_glGetUniformfv: _emscripten_glGetUniformfv, + emscripten_glGetUniformiv: _emscripten_glGetUniformiv, + emscripten_glGetVertexAttribPointerv: _emscripten_glGetVertexAttribPointerv, + emscripten_glGetVertexAttribfv: _emscripten_glGetVertexAttribfv, + emscripten_glGetVertexAttribiv: _emscripten_glGetVertexAttribiv, + emscripten_glHint: _emscripten_glHint, + emscripten_glIsBuffer: _emscripten_glIsBuffer, + emscripten_glIsEnabled: _emscripten_glIsEnabled, + emscripten_glIsFramebuffer: _emscripten_glIsFramebuffer, + emscripten_glIsProgram: _emscripten_glIsProgram, + emscripten_glIsQueryEXT: _emscripten_glIsQueryEXT, + emscripten_glIsRenderbuffer: _emscripten_glIsRenderbuffer, + emscripten_glIsShader: _emscripten_glIsShader, + emscripten_glIsTexture: _emscripten_glIsTexture, + emscripten_glIsVertexArrayOES: _emscripten_glIsVertexArrayOES, + emscripten_glLineWidth: _emscripten_glLineWidth, + emscripten_glLinkProgram: _emscripten_glLinkProgram, + emscripten_glPixelStorei: _emscripten_glPixelStorei, + emscripten_glPolygonOffset: _emscripten_glPolygonOffset, + emscripten_glQueryCounterEXT: _emscripten_glQueryCounterEXT, + emscripten_glReadPixels: _emscripten_glReadPixels, + emscripten_glReleaseShaderCompiler: _emscripten_glReleaseShaderCompiler, + emscripten_glRenderbufferStorage: _emscripten_glRenderbufferStorage, + emscripten_glSampleCoverage: _emscripten_glSampleCoverage, + emscripten_glScissor: _emscripten_glScissor, + emscripten_glShaderBinary: _emscripten_glShaderBinary, + emscripten_glShaderSource: _emscripten_glShaderSource, + emscripten_glStencilFunc: _emscripten_glStencilFunc, + emscripten_glStencilFuncSeparate: _emscripten_glStencilFuncSeparate, + emscripten_glStencilMask: _emscripten_glStencilMask, + emscripten_glStencilMaskSeparate: _emscripten_glStencilMaskSeparate, + emscripten_glStencilOp: _emscripten_glStencilOp, + emscripten_glStencilOpSeparate: _emscripten_glStencilOpSeparate, + emscripten_glTexImage2D: _emscripten_glTexImage2D, + emscripten_glTexParameterf: _emscripten_glTexParameterf, + emscripten_glTexParameterfv: _emscripten_glTexParameterfv, + emscripten_glTexParameteri: _emscripten_glTexParameteri, + emscripten_glTexParameteriv: _emscripten_glTexParameteriv, + emscripten_glTexSubImage2D: _emscripten_glTexSubImage2D, + emscripten_glUniform1f: _emscripten_glUniform1f, + emscripten_glUniform1fv: _emscripten_glUniform1fv, + emscripten_glUniform1i: _emscripten_glUniform1i, + emscripten_glUniform1iv: _emscripten_glUniform1iv, + emscripten_glUniform2f: _emscripten_glUniform2f, + emscripten_glUniform2fv: _emscripten_glUniform2fv, + emscripten_glUniform2i: _emscripten_glUniform2i, + emscripten_glUniform2iv: _emscripten_glUniform2iv, + emscripten_glUniform3f: _emscripten_glUniform3f, + emscripten_glUniform3fv: _emscripten_glUniform3fv, + emscripten_glUniform3i: _emscripten_glUniform3i, + emscripten_glUniform3iv: _emscripten_glUniform3iv, + emscripten_glUniform4f: _emscripten_glUniform4f, + emscripten_glUniform4fv: _emscripten_glUniform4fv, + emscripten_glUniform4i: _emscripten_glUniform4i, + emscripten_glUniform4iv: _emscripten_glUniform4iv, + emscripten_glUniformMatrix2fv: _emscripten_glUniformMatrix2fv, + emscripten_glUniformMatrix3fv: _emscripten_glUniformMatrix3fv, + emscripten_glUniformMatrix4fv: _emscripten_glUniformMatrix4fv, + emscripten_glUseProgram: _emscripten_glUseProgram, + emscripten_glValidateProgram: _emscripten_glValidateProgram, + emscripten_glVertexAttrib1f: _emscripten_glVertexAttrib1f, + emscripten_glVertexAttrib1fv: _emscripten_glVertexAttrib1fv, + emscripten_glVertexAttrib2f: _emscripten_glVertexAttrib2f, + emscripten_glVertexAttrib2fv: _emscripten_glVertexAttrib2fv, + emscripten_glVertexAttrib3f: _emscripten_glVertexAttrib3f, + emscripten_glVertexAttrib3fv: _emscripten_glVertexAttrib3fv, + emscripten_glVertexAttrib4f: _emscripten_glVertexAttrib4f, + emscripten_glVertexAttrib4fv: _emscripten_glVertexAttrib4fv, + emscripten_glVertexAttribDivisorANGLE: _emscripten_glVertexAttribDivisorANGLE, + emscripten_glVertexAttribPointer: _emscripten_glVertexAttribPointer, + emscripten_glViewport: _emscripten_glViewport, + emscripten_has_asyncify: _emscripten_has_asyncify, + emscripten_memcpy_big: _emscripten_memcpy_big, + emscripten_request_fullscreen_strategy: _emscripten_request_fullscreen_strategy, + emscripten_request_pointerlock: _emscripten_request_pointerlock, + emscripten_resize_heap: _emscripten_resize_heap, + emscripten_run_script: _emscripten_run_script, + emscripten_sample_gamepad_data: _emscripten_sample_gamepad_data, + emscripten_set_beforeunload_callback_on_thread: _emscripten_set_beforeunload_callback_on_thread, + emscripten_set_blur_callback_on_thread: _emscripten_set_blur_callback_on_thread, + emscripten_set_canvas_element_size: _emscripten_set_canvas_element_size, + emscripten_set_element_css_size: _emscripten_set_element_css_size, + emscripten_set_focus_callback_on_thread: _emscripten_set_focus_callback_on_thread, + emscripten_set_fullscreenchange_callback_on_thread: _emscripten_set_fullscreenchange_callback_on_thread, + emscripten_set_gamepadconnected_callback_on_thread: _emscripten_set_gamepadconnected_callback_on_thread, + emscripten_set_gamepaddisconnected_callback_on_thread: _emscripten_set_gamepaddisconnected_callback_on_thread, + emscripten_set_keydown_callback_on_thread: _emscripten_set_keydown_callback_on_thread, + emscripten_set_keypress_callback_on_thread: _emscripten_set_keypress_callback_on_thread, + emscripten_set_keyup_callback_on_thread: _emscripten_set_keyup_callback_on_thread, + emscripten_set_main_loop_arg: _emscripten_set_main_loop_arg, + emscripten_set_mousedown_callback_on_thread: _emscripten_set_mousedown_callback_on_thread, + emscripten_set_mouseenter_callback_on_thread: _emscripten_set_mouseenter_callback_on_thread, + emscripten_set_mouseleave_callback_on_thread: _emscripten_set_mouseleave_callback_on_thread, + emscripten_set_mousemove_callback_on_thread: _emscripten_set_mousemove_callback_on_thread, + emscripten_set_mouseup_callback_on_thread: _emscripten_set_mouseup_callback_on_thread, + emscripten_set_pointerlockchange_callback_on_thread: _emscripten_set_pointerlockchange_callback_on_thread, + emscripten_set_resize_callback_on_thread: _emscripten_set_resize_callback_on_thread, + emscripten_set_touchcancel_callback_on_thread: _emscripten_set_touchcancel_callback_on_thread, + emscripten_set_touchend_callback_on_thread: _emscripten_set_touchend_callback_on_thread, + emscripten_set_touchmove_callback_on_thread: _emscripten_set_touchmove_callback_on_thread, + emscripten_set_touchstart_callback_on_thread: _emscripten_set_touchstart_callback_on_thread, + emscripten_set_visibilitychange_callback_on_thread: _emscripten_set_visibilitychange_callback_on_thread, + emscripten_set_wheel_callback_on_thread: _emscripten_set_wheel_callback_on_thread, + emscripten_set_window_title: _emscripten_set_window_title, + emscripten_sleep: _emscripten_sleep, + environ_get: _environ_get, + environ_sizes_get: _environ_sizes_get, + fd_close: _fd_close, + fd_read: _fd_read, + fd_seek: _fd_seek, + fd_write: _fd_write, + glActiveTexture: _glActiveTexture, + glAttachShader: _glAttachShader, + glBindBuffer: _glBindBuffer, + glBindTexture: _glBindTexture, + glBindVertexArrayOES: _glBindVertexArrayOES, + glBlendEquation: _glBlendEquation, + glBlendEquationSeparate: _glBlendEquationSeparate, + glBlendFuncSeparate: _glBlendFuncSeparate, + glBufferData: _glBufferData, + glBufferSubData: _glBufferSubData, + glClear: _glClear, + glClearColor: _glClearColor, + glCompileShader: _glCompileShader, + glCreateProgram: _glCreateProgram, + glCreateShader: _glCreateShader, + glDeleteShader: _glDeleteShader, + glDeleteVertexArraysOES: _glDeleteVertexArraysOES, + glDetachShader: _glDetachShader, + glDisable: _glDisable, + glDrawElements: _glDrawElements, + glEnable: _glEnable, + glEnableVertexAttribArray: _glEnableVertexAttribArray, + glGenBuffers: _glGenBuffers, + glGenTextures: _glGenTextures, + glGenVertexArraysOES: _glGenVertexArraysOES, + glGetAttribLocation: _glGetAttribLocation, + glGetIntegerv: _glGetIntegerv, + glGetProgramInfoLog: _glGetProgramInfoLog, + glGetProgramiv: _glGetProgramiv, + glGetShaderInfoLog: _glGetShaderInfoLog, + glGetShaderiv: _glGetShaderiv, + glGetUniformLocation: _glGetUniformLocation, + glIsEnabled: _glIsEnabled, + glLinkProgram: _glLinkProgram, + glScissor: _glScissor, + glShaderSource: _glShaderSource, + glTexImage2D: _glTexImage2D, + glTexParameteri: _glTexParameteri, + glUniform1i: _glUniform1i, + glUniformMatrix4fv: _glUniformMatrix4fv, + glUseProgram: _glUseProgram, + glVertexAttribPointer: _glVertexAttribPointer, + glViewport: _glViewport, + sapp_js_write_clipboard: sapp_js_write_clipboard, + strftime_l: _strftime_l }; var asm = createWasm(); -/** @type {function(...*):?} */ -var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors"); - -/** @type {function(...*):?} */ -var _memcpy = Module["_memcpy"] = createExportWrapper("memcpy"); - -/** @type {function(...*):?} */ -var _malloc = Module["_malloc"] = createExportWrapper("malloc"); - -/** @type {function(...*):?} */ -var _free = Module["_free"] = createExportWrapper("free"); - -/** @type {function(...*):?} */ -var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location"); - -/** @type {function(...*):?} */ -var _main = Module["_main"] = createExportWrapper("main"); - -/** @type {function(...*):?} */ -var ___stdio_exit = Module["___stdio_exit"] = createExportWrapper("__stdio_exit"); - -/** @type {function(...*):?} */ -var ___funcs_on_exit = Module["___funcs_on_exit"] = createExportWrapper("__funcs_on_exit"); - -/** @type {function(...*):?} */ -var ___dl_seterr = Module["___dl_seterr"] = createExportWrapper("__dl_seterr"); - -/** @type {function(...*):?} */ -var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() { - return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var _emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = function() { - return (_emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() { - return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() { - return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var stackSave = Module["stackSave"] = createExportWrapper("stackSave"); - -/** @type {function(...*):?} */ -var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore"); - -/** @type {function(...*):?} */ -var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc"); - -/** @type {function(...*):?} */ -var ___cxa_is_pointer_type = Module["___cxa_is_pointer_type"] = createExportWrapper("__cxa_is_pointer_type"); - -/** @type {function(...*):?} */ -var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji"); - -/** @type {function(...*):?} */ -var dynCall_ji = Module["dynCall_ji"] = createExportWrapper("dynCall_ji"); - -/** @type {function(...*):?} */ -var dynCall_iiiiij = Module["dynCall_iiiiij"] = createExportWrapper("dynCall_iiiiij"); - -/** @type {function(...*):?} */ -var dynCall_iiiiijj = Module["dynCall_iiiiijj"] = createExportWrapper("dynCall_iiiiijj"); - -/** @type {function(...*):?} */ -var dynCall_iiiiiijj = Module["dynCall_iiiiiijj"] = createExportWrapper("dynCall_iiiiiijj"); - - - - - +var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors'); +var _malloc = createExportWrapper('malloc'); +var ___errno_location = createExportWrapper('__errno_location'); +var _main = Module['_main'] = createExportWrapper('__main_argc_argv'); +var ___funcs_on_exit = createExportWrapper('__funcs_on_exit'); +var _fflush = Module['_fflush'] = createExportWrapper('fflush'); +var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports['emscripten_stack_init'])(); +var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'])(); +var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'])(); +var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'])(); +var stackSave = createExportWrapper('stackSave'); +var stackRestore = createExportWrapper('stackRestore'); +var stackAlloc = createExportWrapper('stackAlloc'); +var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])(); +var ___cxa_is_pointer_type = createExportWrapper('__cxa_is_pointer_type'); +var dynCall_jiji = Module['dynCall_jiji'] = createExportWrapper('dynCall_jiji'); +var dynCall_ji = Module['dynCall_ji'] = createExportWrapper('dynCall_ji'); +var dynCall_iiiiij = Module['dynCall_iiiiij'] = createExportWrapper('dynCall_iiiiij'); +var dynCall_iiiiijj = Module['dynCall_iiiiijj'] = createExportWrapper('dynCall_iiiiijj'); +var dynCall_iiiiiijj = Module['dynCall_iiiiiijj'] = createExportWrapper('dynCall_iiiiiijj'); +var ___start_em_js = Module['___start_em_js'] = 267108; +var ___stop_em_js = Module['___stop_em_js'] = 267591; + +// include: postamble.js // === Auto-generated postamble setup entry stuff === -unexportedRuntimeFunction('ccall', false); -unexportedRuntimeFunction('cwrap', false); -unexportedRuntimeFunction('setValue', false); -unexportedRuntimeFunction('getValue', false); -unexportedRuntimeFunction('allocate', false); -unexportedRuntimeFunction('UTF8ArrayToString', false); -unexportedRuntimeFunction('UTF8ToString', false); -unexportedRuntimeFunction('stringToUTF8Array', false); -unexportedRuntimeFunction('stringToUTF8', false); -unexportedRuntimeFunction('lengthBytesUTF8', false); -unexportedRuntimeFunction('addOnPreRun', false); -unexportedRuntimeFunction('addOnInit', false); -unexportedRuntimeFunction('addOnPreMain', false); -unexportedRuntimeFunction('addOnExit', false); -unexportedRuntimeFunction('addOnPostRun', false); -unexportedRuntimeFunction('addRunDependency', true); -unexportedRuntimeFunction('removeRunDependency', true); -unexportedRuntimeFunction('FS_createFolder', false); -unexportedRuntimeFunction('FS_createPath', true); -unexportedRuntimeFunction('FS_createDataFile', true); -unexportedRuntimeFunction('FS_createPreloadedFile', true); -unexportedRuntimeFunction('FS_createLazyFile', true); -unexportedRuntimeFunction('FS_createLink', false); -unexportedRuntimeFunction('FS_createDevice', true); -unexportedRuntimeFunction('FS_unlink', true); -unexportedRuntimeFunction('getLEB', false); -unexportedRuntimeFunction('getFunctionTables', false); -unexportedRuntimeFunction('alignFunctionTables', false); -unexportedRuntimeFunction('registerFunctions', false); -unexportedRuntimeFunction('addFunction', false); -unexportedRuntimeFunction('removeFunction', false); -unexportedRuntimeFunction('prettyPrint', false); -unexportedRuntimeFunction('getCompilerSetting', false); -unexportedRuntimeFunction('print', false); -unexportedRuntimeFunction('printErr', false); -unexportedRuntimeFunction('getTempRet0', false); -unexportedRuntimeFunction('setTempRet0', false); -unexportedRuntimeFunction('callMain', false); -unexportedRuntimeFunction('abort', false); -unexportedRuntimeFunction('keepRuntimeAlive', false); -unexportedRuntimeFunction('wasmMemory', false); -unexportedRuntimeFunction('warnOnce', false); -unexportedRuntimeFunction('stackSave', false); -unexportedRuntimeFunction('stackRestore', false); -unexportedRuntimeFunction('stackAlloc', false); -unexportedRuntimeFunction('AsciiToString', false); -unexportedRuntimeFunction('stringToAscii', false); -unexportedRuntimeFunction('UTF16ToString', false); -unexportedRuntimeFunction('stringToUTF16', false); -unexportedRuntimeFunction('lengthBytesUTF16', false); -unexportedRuntimeFunction('UTF32ToString', false); -unexportedRuntimeFunction('stringToUTF32', false); -unexportedRuntimeFunction('lengthBytesUTF32', false); -unexportedRuntimeFunction('allocateUTF8', false); -unexportedRuntimeFunction('allocateUTF8OnStack', false); -unexportedRuntimeFunction('ExitStatus', false); -unexportedRuntimeFunction('intArrayFromString', false); -unexportedRuntimeFunction('intArrayToString', false); -unexportedRuntimeFunction('writeStringToMemory', false); -unexportedRuntimeFunction('writeArrayToMemory', false); -unexportedRuntimeFunction('writeAsciiToMemory', false); -Module["writeStackCookie"] = writeStackCookie; -Module["checkStackCookie"] = checkStackCookie; -unexportedRuntimeFunction('ptrToString', false); -unexportedRuntimeFunction('zeroMemory', false); -unexportedRuntimeFunction('stringToNewUTF8', false); -unexportedRuntimeFunction('emscripten_realloc_buffer', false); -unexportedRuntimeFunction('ENV', false); -unexportedRuntimeFunction('ERRNO_CODES', false); -unexportedRuntimeFunction('ERRNO_MESSAGES', false); -unexportedRuntimeFunction('setErrNo', false); -unexportedRuntimeFunction('inetPton4', false); -unexportedRuntimeFunction('inetNtop4', false); -unexportedRuntimeFunction('inetPton6', false); -unexportedRuntimeFunction('inetNtop6', false); -unexportedRuntimeFunction('readSockaddr', false); -unexportedRuntimeFunction('writeSockaddr', false); -unexportedRuntimeFunction('DNS', false); -unexportedRuntimeFunction('getHostByName', false); -unexportedRuntimeFunction('Protocols', false); -unexportedRuntimeFunction('Sockets', false); -unexportedRuntimeFunction('getRandomDevice', false); -unexportedRuntimeFunction('traverseStack', false); -unexportedRuntimeFunction('UNWIND_CACHE', false); -unexportedRuntimeFunction('convertPCtoSourceLocation', false); -unexportedRuntimeFunction('readAsmConstArgsArray', false); -unexportedRuntimeFunction('readAsmConstArgs', false); -unexportedRuntimeFunction('mainThreadEM_ASM', false); -unexportedRuntimeFunction('jstoi_q', false); -unexportedRuntimeFunction('jstoi_s', false); -unexportedRuntimeFunction('getExecutableName', false); -unexportedRuntimeFunction('listenOnce', false); -unexportedRuntimeFunction('autoResumeAudioContext', false); -unexportedRuntimeFunction('dynCallLegacy', false); -unexportedRuntimeFunction('getDynCaller', false); -unexportedRuntimeFunction('dynCall', false); -unexportedRuntimeFunction('handleException', false); -unexportedRuntimeFunction('runtimeKeepalivePush', false); -unexportedRuntimeFunction('runtimeKeepalivePop', false); -unexportedRuntimeFunction('callUserCallback', false); -unexportedRuntimeFunction('maybeExit', false); -unexportedRuntimeFunction('safeSetTimeout', false); -unexportedRuntimeFunction('asmjsMangle', false); -unexportedRuntimeFunction('asyncLoad', false); -unexportedRuntimeFunction('alignMemory', false); -unexportedRuntimeFunction('mmapAlloc', false); -unexportedRuntimeFunction('reallyNegative', false); -unexportedRuntimeFunction('unSign', false); -unexportedRuntimeFunction('reSign', false); -unexportedRuntimeFunction('formatString', false); -unexportedRuntimeFunction('PATH', false); -unexportedRuntimeFunction('PATH_FS', false); -unexportedRuntimeFunction('SYSCALLS', false); -unexportedRuntimeFunction('getSocketFromFD', false); -unexportedRuntimeFunction('getSocketAddress', false); -unexportedRuntimeFunction('JSEvents', false); -unexportedRuntimeFunction('registerKeyEventCallback', false); -unexportedRuntimeFunction('specialHTMLTargets', false); -unexportedRuntimeFunction('maybeCStringToJsString', false); -unexportedRuntimeFunction('findEventTarget', false); -unexportedRuntimeFunction('findCanvasEventTarget', false); -unexportedRuntimeFunction('getBoundingClientRect', false); -unexportedRuntimeFunction('fillMouseEventData', false); -unexportedRuntimeFunction('registerMouseEventCallback', false); -unexportedRuntimeFunction('registerWheelEventCallback', false); -unexportedRuntimeFunction('registerUiEventCallback', false); -unexportedRuntimeFunction('registerFocusEventCallback', false); -unexportedRuntimeFunction('fillDeviceOrientationEventData', false); -unexportedRuntimeFunction('registerDeviceOrientationEventCallback', false); -unexportedRuntimeFunction('fillDeviceMotionEventData', false); -unexportedRuntimeFunction('registerDeviceMotionEventCallback', false); -unexportedRuntimeFunction('screenOrientation', false); -unexportedRuntimeFunction('fillOrientationChangeEventData', false); -unexportedRuntimeFunction('registerOrientationChangeEventCallback', false); -unexportedRuntimeFunction('fillFullscreenChangeEventData', false); -unexportedRuntimeFunction('registerFullscreenChangeEventCallback', false); -unexportedRuntimeFunction('registerRestoreOldStyle', false); -unexportedRuntimeFunction('hideEverythingExceptGivenElement', false); -unexportedRuntimeFunction('restoreHiddenElements', false); -unexportedRuntimeFunction('setLetterbox', false); -unexportedRuntimeFunction('currentFullscreenStrategy', false); -unexportedRuntimeFunction('restoreOldWindowedStyle', false); -unexportedRuntimeFunction('softFullscreenResizeWebGLRenderTarget', false); -unexportedRuntimeFunction('doRequestFullscreen', false); -unexportedRuntimeFunction('fillPointerlockChangeEventData', false); -unexportedRuntimeFunction('registerPointerlockChangeEventCallback', false); -unexportedRuntimeFunction('registerPointerlockErrorEventCallback', false); -unexportedRuntimeFunction('requestPointerLock', false); -unexportedRuntimeFunction('fillVisibilityChangeEventData', false); -unexportedRuntimeFunction('registerVisibilityChangeEventCallback', false); -unexportedRuntimeFunction('registerTouchEventCallback', false); -unexportedRuntimeFunction('fillGamepadEventData', false); -unexportedRuntimeFunction('registerGamepadEventCallback', false); -unexportedRuntimeFunction('registerBeforeUnloadEventCallback', false); -unexportedRuntimeFunction('fillBatteryEventData', false); -unexportedRuntimeFunction('battery', false); -unexportedRuntimeFunction('registerBatteryEventCallback', false); -unexportedRuntimeFunction('setCanvasElementSize', false); -unexportedRuntimeFunction('getCanvasElementSize', false); -unexportedRuntimeFunction('demangle', false); -unexportedRuntimeFunction('demangleAll', false); -unexportedRuntimeFunction('jsStackTrace', false); -unexportedRuntimeFunction('stackTrace', false); -unexportedRuntimeFunction('getEnvStrings', false); -unexportedRuntimeFunction('checkWasiClock', false); -unexportedRuntimeFunction('flush_NO_FILESYSTEM', false); -unexportedRuntimeFunction('writeI53ToI64', false); -unexportedRuntimeFunction('writeI53ToI64Clamped', false); -unexportedRuntimeFunction('writeI53ToI64Signaling', false); -unexportedRuntimeFunction('writeI53ToU64Clamped', false); -unexportedRuntimeFunction('writeI53ToU64Signaling', false); -unexportedRuntimeFunction('readI53FromI64', false); -unexportedRuntimeFunction('readI53FromU64', false); -unexportedRuntimeFunction('convertI32PairToI53', false); -unexportedRuntimeFunction('convertU32PairToI53', false); -unexportedRuntimeFunction('dlopenMissingError', false); -unexportedRuntimeFunction('setImmediateWrapped', false); -unexportedRuntimeFunction('clearImmediateWrapped', false); -unexportedRuntimeFunction('polyfillSetImmediate', false); -unexportedRuntimeFunction('uncaughtExceptionCount', false); -unexportedRuntimeFunction('exceptionLast', false); -unexportedRuntimeFunction('exceptionCaught', false); -unexportedRuntimeFunction('ExceptionInfo', false); -unexportedRuntimeFunction('exception_addRef', false); -unexportedRuntimeFunction('exception_decRef', false); -unexportedRuntimeFunction('Browser', false); -unexportedRuntimeFunction('setMainLoop', false); -unexportedRuntimeFunction('wget', false); -unexportedRuntimeFunction('tempFixedLengthArray', false); -unexportedRuntimeFunction('miniTempWebGLFloatBuffers', false); -unexportedRuntimeFunction('heapObjectForWebGLType', false); -unexportedRuntimeFunction('heapAccessShiftForWebGLHeap', false); -unexportedRuntimeFunction('GL', false); -unexportedRuntimeFunction('emscriptenWebGLGet', false); -unexportedRuntimeFunction('computeUnpackAlignedImageSize', false); -unexportedRuntimeFunction('emscriptenWebGLGetTexPixelData', false); -unexportedRuntimeFunction('emscriptenWebGLGetUniform', false); -unexportedRuntimeFunction('webglGetUniformLocation', false); -unexportedRuntimeFunction('webglPrepareUniformLocationsBeforeFirstUse', false); -unexportedRuntimeFunction('webglGetLeftBracePos', false); -unexportedRuntimeFunction('emscriptenWebGLGetVertexAttrib', false); -unexportedRuntimeFunction('writeGLArray', false); -unexportedRuntimeFunction('AL', false); -unexportedRuntimeFunction('SDL_unicode', false); -unexportedRuntimeFunction('SDL_ttfContext', false); -unexportedRuntimeFunction('SDL_audio', false); -unexportedRuntimeFunction('SDL', false); -unexportedRuntimeFunction('SDL_gfx', false); -unexportedRuntimeFunction('GLUT', false); -unexportedRuntimeFunction('EGL', false); -unexportedRuntimeFunction('GLFW_Window', false); -unexportedRuntimeFunction('GLFW', false); -unexportedRuntimeFunction('GLEW', false); -unexportedRuntimeFunction('IDBStore', false); -unexportedRuntimeFunction('runAndAbortIfError', false); -unexportedRuntimeSymbol('ALLOC_NORMAL', false); -unexportedRuntimeSymbol('ALLOC_STACK', false); +var missingLibrarySymbols = [ + 'writeI53ToI64Clamped', + 'writeI53ToI64Signaling', + 'writeI53ToU64Clamped', + 'writeI53ToU64Signaling', + 'convertI32PairToI53', + 'convertU32PairToI53', + 'zeroMemory', + 'ydayFromDate', + 'inetPton4', + 'inetNtop4', + 'inetPton6', + 'inetNtop6', + 'readSockaddr', + 'writeSockaddr', + 'getHostByName', + 'initRandomFill', + 'randomFill', + 'getCallstack', + 'emscriptenLog', + 'convertPCtoSourceLocation', + 'jstoi_s', + 'getDynCaller', + 'asmjsMangle', + 'asyncLoad', + 'alignMemory', + 'mmapAlloc', + 'handleAllocatorInit', + 'HandleAllocator', + 'getNativeTypeSize', + 'STACK_SIZE', + 'STACK_ALIGN', + 'POINTER_SIZE', + 'ASSERTIONS', + 'getCFunc', + 'ccall', + 'cwrap', + 'uleb128Encode', + 'sigToWasmTypes', + 'generateFuncType', + 'convertJsFunctionToWasm', + 'getEmptyTableSlot', + 'updateTableMap', + 'getFunctionAddress', + 'addFunction', + 'removeFunction', + 'reallyNegative', + 'unSign', + 'strLen', + 'reSign', + 'formatString', + 'intArrayToString', + 'AsciiToString', + 'UTF16ToString', + 'stringToUTF16', + 'lengthBytesUTF16', + 'UTF32ToString', + 'stringToUTF32', + 'lengthBytesUTF32', + 'fillDeviceOrientationEventData', + 'registerDeviceOrientationEventCallback', + 'fillDeviceMotionEventData', + 'registerDeviceMotionEventCallback', + 'screenOrientation', + 'fillOrientationChangeEventData', + 'registerOrientationChangeEventCallback', + 'hideEverythingExceptGivenElement', + 'restoreHiddenElements', + 'softFullscreenResizeWebGLRenderTarget', + 'registerPointerlockErrorEventCallback', + 'fillBatteryEventData', + 'battery', + 'registerBatteryEventCallback', + 'demangle', + 'demangleAll', + 'jsStackTrace', + 'stackTrace', + 'checkWasiClock', + 'wasiRightsToMuslOFlags', + 'wasiOFlagsToMuslOFlags', + 'createDyncallWrapper', + 'setImmediateWrapped', + 'clearImmediateWrapped', + 'polyfillSetImmediate', + 'getPromise', + 'makePromise', + 'idsToPromises', + 'makePromiseCallback', + 'findMatchingCatch', + 'getSocketFromFD', + 'getSocketAddress', + 'writeGLArray', + 'registerWebGlEventCallback', + 'runAndAbortIfError', + 'GLFW_Window', + '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_createDataFile', + 'FS_createLazyFile', + 'FS_createLink', + 'FS_createDevice', + 'FS_unlink', + 'out', + 'err', + 'callMain', + 'abort', + 'keepRuntimeAlive', + 'wasmMemory', + 'wasmTable', + 'wasmExports', + 'stackAlloc', + 'stackSave', + 'stackRestore', + 'getTempRet0', + 'setTempRet0', + 'writeStackCookie', + 'checkStackCookie', + 'writeI53ToI64', + 'readI53FromI64', + 'readI53FromU64', + 'convertI32PairToI53Checked', + 'ptrToString', + 'exitJS', + 'getHeapMax', + 'growMemory', + 'ENV', + 'MONTH_DAYS_REGULAR', + 'MONTH_DAYS_LEAP', + 'MONTH_DAYS_REGULAR_CUMULATIVE', + 'MONTH_DAYS_LEAP_CUMULATIVE', + 'isLeapYear', + 'arraySum', + 'addDays', + 'ERRNO_CODES', + 'ERRNO_MESSAGES', + 'setErrNo', + 'DNS', + 'Protocols', + 'Sockets', + 'timers', + 'warnOnce', + 'UNWIND_CACHE', + 'readEmAsmArgsArray', + 'readEmAsmArgs', + 'runEmAsmFunction', + 'runMainThreadEmAsm', + 'jstoi_q', + 'getExecutableName', + 'listenOnce', + 'autoResumeAudioContext', + 'dynCallLegacy', + 'dynCall', + 'handleException', + 'runtimeKeepalivePush', + 'runtimeKeepalivePop', + 'callUserCallback', + 'maybeExit', + 'safeSetTimeout', + 'freeTableIndexes', + 'functionsInTableMap', + 'setValue', + 'getValue', + 'PATH', + 'PATH_FS', + 'UTF8Decoder', + 'UTF8ArrayToString', + 'UTF8ToString', + 'stringToUTF8Array', + 'stringToUTF8', + 'lengthBytesUTF8', + 'intArrayFromString', + 'stringToAscii', + 'UTF16Decoder', + 'stringToNewUTF8', + 'stringToUTF8OnStack', + 'writeArrayToMemory', + 'JSEvents', + 'registerKeyEventCallback', + 'specialHTMLTargets', + 'maybeCStringToJsString', + 'findEventTarget', + 'findCanvasEventTarget', + 'getBoundingClientRect', + 'fillMouseEventData', + 'registerMouseEventCallback', + 'registerWheelEventCallback', + 'registerUiEventCallback', + 'registerFocusEventCallback', + 'fillFullscreenChangeEventData', + 'registerFullscreenChangeEventCallback', + 'JSEvents_requestFullscreen', + 'JSEvents_resizeCanvasForFullscreen', + 'registerRestoreOldStyle', + 'setLetterbox', + 'currentFullscreenStrategy', + 'restoreOldWindowedStyle', + 'doRequestFullscreen', + 'fillPointerlockChangeEventData', + 'registerPointerlockChangeEventCallback', + 'requestPointerLock', + 'fillVisibilityChangeEventData', + 'registerVisibilityChangeEventCallback', + 'registerTouchEventCallback', + 'fillGamepadEventData', + 'registerGamepadEventCallback', + 'registerBeforeUnloadEventCallback', + 'setCanvasElementSize', + 'getCanvasElementSize', + 'ExitStatus', + 'getEnvStrings', + 'flush_NO_FILESYSTEM', + 'promiseMap', + 'uncaughtExceptionCount', + 'exceptionLast', + 'exceptionCaught', + 'ExceptionInfo', + 'Browser', + 'setMainLoop', + 'wget', + 'SYSCALLS', + 'tempFixedLengthArray', + 'miniTempWebGLFloatBuffers', + 'miniTempWebGLIntBuffers', + 'heapObjectForWebGLType', + 'heapAccessShiftForWebGLHeap', + 'webgl_enable_ANGLE_instanced_arrays', + 'webgl_enable_OES_vertex_array_object', + 'webgl_enable_WEBGL_draw_buffers', + 'webgl_enable_WEBGL_multi_draw', + 'GL', + 'emscriptenWebGLGet', + 'computeUnpackAlignedImageSize', + 'colorChannelsInGlTextureFormat', + 'emscriptenWebGLGetTexPixelData', + '__glGenObject', + 'emscriptenWebGLGetUniform', + 'webglGetUniformLocation', + 'webglPrepareUniformLocationsBeforeFirstUse', + 'webglGetLeftBracePos', + 'emscriptenWebGLGetVertexAttrib', + '__glGetActiveAttribOrUniform', + 'emscripten_webgl_power_preferences', + 'AL', + 'GLUT', + 'EGL', + 'GLEW', + 'IDBStore', + 'GLFW', + 'allocateUTF8', + 'allocateUTF8OnStack', +]; +unexportedSymbols.forEach(unexportedRuntimeSymbol); -var calledRun; -/** - * @constructor - * @this {ExitStatus} - */ -function ExitStatus(status) { - this.name = "ExitStatus"; - this.message = "Program terminated with exit(" + status + ")"; - this.status = status; -} -var calledMain = false; +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) @@ -7531,37 +7053,32 @@ dependenciesFulfilled = function runCaller() { if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled }; -function callMain(args) { +function callMain(args = []) { assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])'); assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called'); - var entryFunction = Module['_main']; + var entryFunction = _main; - args = args || []; + args.unshift(thisProgram); - var argc = args.length+1; + var argc = args.length; var argv = stackAlloc((argc + 1) * 4); - HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram); - for (var i = 1; i < argc; i++) { - HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i - 1]); - } - HEAP32[(argv >> 2) + argc] = 0; + var argv_ptr = argv >> 2; + args.forEach((arg) => { + HEAP32[argv_ptr++] = stringToUTF8OnStack(arg); + }); + HEAP32[argv_ptr] = 0; try { var ret = entryFunction(argc, argv); - // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as - // execution is asynchronously handed off to a pthread. // if we're not running an evented main loop, it's time to exit - exit(ret, /* implicit = */ true); + exitJS(ret, /* implicit = */ true); return ret; } catch (e) { return handleException(e); - } finally { - calledMain = true; - } } @@ -7569,20 +7086,18 @@ 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. - // TODO(sbc): Move writeStackCookie to native to to avoid this. _emscripten_stack_init(); + // TODO(sbc): Move writeStackCookie to native to to avoid this. writeStackCookie(); } -/** @type {function(Array=)} */ -function run(args) { - args = args || arguments_; +function run(args = arguments_) { if (runDependencies > 0) { return; } - stackCheckInit(); + stackCheckInit(); preRun(); @@ -7625,33 +7140,6 @@ function run(args) { } checkStackCookie(); } -Module['run'] = run; - -/** @param {boolean|number=} implicit */ -function exit(status, implicit) { - EXITSTATUS = status; - - if (!keepRuntimeAlive()) { - exitRuntime(); - } - - // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down - if (keepRuntimeAlive() && !implicit) { - var msg = 'program exited (with status: ' + status + '), but keepRuntimeAlive() is set (counter=' + runtimeKeepaliveCounter + ') due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)'; - err(msg); - } - - procExit(status); -} - -function procExit(code) { - EXITSTATUS = code; - if (!keepRuntimeAlive()) { - if (Module['onExit']) Module['onExit'](code); - ABORT = true; - } - quit_(code, new ExitStatus(code)); -} if (Module['preInit']) { if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; @@ -7668,6 +7156,4 @@ if (Module['noInitialRun']) shouldRunNow = false; run(); - - - +// end include: postamble.js diff --git a/index.wasm b/index.wasm index b5e2416..79ebc8e 100755 Binary files a/index.wasm and b/index.wasm differ