Skip to content

Instantly share code, notes, and snippets.

@ddgg-el
Last active August 18, 2023 01:11
Show Gist options
  • Save ddgg-el/e6819f773abbfc75385c7fa15d79b692 to your computer and use it in GitHub Desktop.
Save ddgg-el/e6819f773abbfc75385c7fa15d79b692 to your computer and use it in GitHub Desktop.
Webaudio Worklets in wasm (emscripten)
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Emscripten-Generated Code</title>
<style>
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
textarea.emscripten { font-family: monospace; width: 80%; }
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; background-color: black; }
.spinner {
height: 50px;
width: 50px;
margin: 0px auto;
-webkit-animation: rotation .8s linear infinite;
-moz-animation: rotation .8s linear infinite;
-o-animation: rotation .8s linear infinite;
animation: rotation 0.8s linear infinite;
border-left: 10px solid rgb(0,150,240);
border-right: 10px solid rgb(0,150,240);
border-bottom: 10px solid rgb(0,150,240);
border-top: 10px solid rgb(100,0,200);
border-radius: 100%;
background-color: rgb(200,100,250);
}
@-webkit-keyframes rotation {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(360deg);}
}
@-moz-keyframes rotation {
from {-moz-transform: rotate(0deg);}
to {-moz-transform: rotate(360deg);}
}
@-o-keyframes rotation {
from {-o-transform: rotate(0deg);}
to {-o-transform: rotate(360deg);}
}
@keyframes rotation {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
</style>
</head>
<body>
<hr/>
<figure style="overflow:visible;" id="spinner"><div class="spinner"></div><center style="margin-top:0.5em"><strong>emscripten</strong></center></figure>
<div class="emscripten" id="status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="progress" hidden=1></progress>
</div>
<div class="emscripten_border">
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
</div>
<hr/>
<div class="emscripten">
<input type="checkbox" id="resize">Resize canvas
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
&nbsp;&nbsp;&nbsp;
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
document.getElementById('resize').checked)">
</div>
<hr/>
<textarea class="emscripten" id="output" rows="8"></textarea>
<hr>
<script type='text/javascript'>
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
var spinnerElement = document.getElementById('spinner');
var Module = {
preRun: [],
postRun: [],
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
// These replacements are necessary if you render to raw HTML
//text = text.replace(/&/g, "&amp;");
//text = text.replace(/</g, "&lt;");
//text = text.replace(/>/g, "&gt;");
//text = text.replace('\n', '<br>', 'g');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
canvas: (() => {
var canvas = document.getElementById('canvas');
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
// application robust, you may want to override this behavior before shipping!
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
canvas.addEventListener("webglcontextlost", (e) => { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: (text) => {
if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.last.text) return;
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
Module.setStatus.last.time = now;
Module.setStatus.last.text = text;
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
spinnerElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
if (!text) spinnerElement.hidden = true;
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: (left) => {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
}
};
Module.setStatus('Downloading...');
window.onerror = () => {
Module.setStatus('Exception thrown, see JavaScript console');
spinnerElement.style.display = 'none';
Module.setStatus = (text) => {
if (text) console.error('[post-exception status] ' + text);
};
};
</script>
<script async type="text/javascript" src="NoiseGenerator.js"></script>
</body>
</html>
// include: shell.js
// The Module object: Our interface to the outside world. We import
// and export values on it. There are various ways Module can be used:
// 1. Not defined. We create it here
// 2. A function parameter, function(Module) { ..generated code.. }
// 3. pre-run appended it, var Module = {}; ..generated code..
// 4. External script tag defines var Module.
// We need to check if Module already exists (e.g. case 3 above).
// Substitution will be replaced with actual code on later stage of the build,
// this way Closure Compiler will not mangle it (e.g. case 4. above).
// Note that if you want to run closure, and also to use Module
// after the generated code, you will need to define var Module = {};
// before the code. Then that object will be used in the code, and you
// can continue to use Module afterwards as well.
var Module = globalThis.Module || (typeof Module != 'undefined' ? Module : {});
// --pre-jses are emitted after the Module integration code, so that they can
// refer to Module (if they choose; they can also define Module)
// Sometimes an existing Module object exists with properties
// meant to overwrite the default module functionality. Here
// we collect those properties and reapply _after_ we configure
// the current environment's defaults to avoid having to be so
// defensive during initialization.
var moduleOverrides = Object.assign({}, Module);
var arguments_ = [];
var thisProgram = './this.program';
var quit_ = (status, toThrow) => {
throw toThrow;
};
// Determine the runtime environment we are in. You can customize this by
// setting the ENVIRONMENT setting at compile time (see settings.js).
var ENVIRONMENT_IS_AUDIO_WORKLET = typeof AudioWorkletGlobalScope !== 'undefined';
// Attempt to auto-detect the environment
var ENVIRONMENT_IS_WEB = typeof window == 'object';
var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';
// N.b. Electron.js environment is simultaneously a NODE-environment, but
// also a web environment.
var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER && !ENVIRONMENT_IS_AUDIO_WORKLET;
if (Module['ENVIRONMENT']) {
throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
}
var ENVIRONMENT_IS_WASM_WORKER = Module['$ww'];
// In MODULARIZE mode _scriptDir needs to be captured already at the very top of the page immediately when the page is parsed, so it is generated there
// before the page load. In non-MODULARIZE modes generate it here.
var _scriptDir = (typeof document != 'undefined' && document.currentScript) ? document.currentScript.src : undefined;
if (ENVIRONMENT_IS_WORKER) {
_scriptDir = self.location.href;
}
else if (ENVIRONMENT_IS_NODE) {
_scriptDir = __filename;
}
// `/` should be present at the end if `scriptDirectory` is not empty
var scriptDirectory = '';
function locateFile(path) {
if (Module['locateFile']) {
return Module['locateFile'](path, scriptDirectory);
}
return scriptDirectory + path;
}
// Hooks that are implemented differently in different runtime environments.
var read_,
readAsync,
readBinary,
setWindowTitle;
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 = 120000;
if (numericVersion < 120000) {
throw new Error('This emscripten-generated code requires node v12.0.0 (detected v' + nodeVersion + ')');
}
// `require()` is no-op in an ESM module, use `createRequire()` to construct
// the require()` function. This is only necessary for multi-environment
// builds, `-sENVIRONMENT=node` emits a static import declaration instead.
// TODO: Swap all `require()`'s with `import()`'s?
// These modules will usually be used on Node.js. Load them eagerly to avoid
// the complexity of lazy-loading.
var fs = require('fs');
var nodePath = require('path');
if (ENVIRONMENT_IS_WORKER) {
scriptDirectory = nodePath.dirname(scriptDirectory) + '/';
} else {
scriptDirectory = __dirname + '/';
}
// include: node_shell_read.js
read_ = (filename, binary) => {
// We need to re-wrap `file://` strings to URLs. Normalizing isn't
// necessary in that case, the path should already be absolute.
filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
return fs.readFileSync(filename, binary ? undefined : 'utf8');
};
readBinary = (filename) => {
var ret = read_(filename, true);
if (!ret.buffer) {
ret = new Uint8Array(ret);
}
assert(ret.buffer);
return ret;
};
readAsync = (filename, onload, onerror, binary = true) => {
// See the comment in the `read_` function.
filename = isFileURI(filename) ? new URL(filename) : nodePath.normalize(filename);
fs.readFile(filename, binary ? undefined : 'utf8', (err, data) => {
if (err) onerror(err);
else onload(binary ? data.buffer : data);
});
};
// end include: node_shell_read.js
if (!Module['thisProgram'] && process.argv.length > 1) {
thisProgram = process.argv[1].replace(/\\/g, '/');
}
arguments_ = process.argv.slice(2);
if (typeof module != 'undefined') {
module['exports'] = Module;
}
process.on('uncaughtException', (ex) => {
// suppress ExitStatus exceptions from showing an error
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
var nodeMajor = process.versions.node.split(".")[0];
if (nodeMajor < 15) {
process.on('unhandledRejection', (reason) => { throw reason; });
}
quit_ = (status, toThrow) => {
process.exitCode = status;
throw toThrow;
};
Module['inspect'] = () => '[Emscripten Module object]';
} else
if (ENVIRONMENT_IS_SHELL) {
if ((typeof process == 'object' && typeof require === 'function') || typeof window == 'object' || typeof importScripts == 'function') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
if (typeof read != 'undefined') {
read_ = (f) => {
return read(f);
};
}
readBinary = (f) => {
let data;
if (typeof readbuffer == 'function') {
return new Uint8Array(readbuffer(f));
}
data = read(f, 'binary');
assert(typeof data == 'object');
return data;
};
readAsync = (f, onload, onerror) => {
setTimeout(() => onload(readBinary(f)), 0);
};
if (typeof clearTimeout == 'undefined') {
globalThis.clearTimeout = (id) => {};
}
if (typeof scriptArgs != 'undefined') {
arguments_ = scriptArgs;
} else if (typeof arguments != 'undefined') {
arguments_ = arguments;
}
if (typeof quit == 'function') {
quit_ = (status, toThrow) => {
// Unlike node which has process.exitCode, d8 has no such mechanism. So we
// have no way to set the exit code and then let the program exit with
// that code when it naturally stops running (say, when all setTimeouts
// have completed). For that reason, we must call `quit` - the only way to
// set the exit code - but quit also halts immediately. To increase
// consistency with node (and the web) we schedule the actual quit call
// using a setTimeout to give the current stack and any exception handlers
// a chance to run. This enables features such as addOnPostRun (which
// expected to be able to run code after main returns).
setTimeout(() => {
if (!(toThrow instanceof ExitStatus)) {
let toLog = toThrow;
if (toThrow && typeof toThrow == 'object' && toThrow.stack) {
toLog = [toThrow, toThrow.stack];
}
err('exiting due to exception: ' + toLog);
}
quit(status);
});
throw toThrow;
};
}
if (typeof print != 'undefined') {
// Prefer to use print/printErr where they exist, as they usually work better.
if (typeof console == 'undefined') console = /** @type{!Console} */({});
console.log = /** @type{!function(this:Console, ...*): undefined} */ (print);
console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr != 'undefined' ? printErr : print);
}
} else
// Note that this includes Node.js workers when relevant (pthreads is enabled).
// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
// ENVIRONMENT_IS_NODE.
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled
scriptDirectory = self.location.href;
} else if (typeof document != 'undefined' && document.currentScript) { // web
scriptDirectory = document.currentScript.src;
}
// blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
// otherwise, slice off the final part of the url to find the script directory.
// if scriptDirectory does not contain a slash, lastIndexOf will return -1,
// and scriptDirectory will correctly be replaced with an empty string.
// If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
// they are removed because they could contain a slash.
if (scriptDirectory.indexOf('blob:') !== 0) {
scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf('/')+1);
} else {
scriptDirectory = '';
}
if (!(typeof window == 'object' || typeof importScripts == 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
// Differentiate the Web Worker from the Node Worker case, as reading must
// be done differently.
{
// include: web_or_worker_shell_read.js
read_ = (url) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send(null);
return xhr.responseText;
}
if (ENVIRONMENT_IS_WORKER) {
readBinary = (url) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.responseType = 'arraybuffer';
xhr.send(null);
return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
};
}
readAsync = (url, onload, onerror) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
onload(xhr.response);
return;
}
onerror();
};
xhr.onerror = onerror;
xhr.send(null);
}
// end include: web_or_worker_shell_read.js
}
setWindowTitle = (title) => document.title = title;
} else
if (!ENVIRONMENT_IS_AUDIO_WORKLET)
{
throw new Error('environment detection error');
}
var out = Module['print'] || console.log.bind(console);
var err = Module['printErr'] || console.warn.bind(console);
// Merge back in the overrides
Object.assign(Module, moduleOverrides);
// Free the object hierarchy contained in the overrides, this lets the GC
// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
moduleOverrides = null;
checkIncomingModuleAPI();
// Emit code to handle expected values on the Module object. This applies Module.x
// to the proper local x. This has two benefits: first, we only emit it if it is
// expected to arrive, and second, by using a local everywhere else that can be
// minified.
if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
if (Module['quit']) quit_ = Module['quit'];legacyModuleProp('quit', 'quit_');
// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
// Assertions on removed incoming Module JS APIs.
assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
assert(typeof Module['read'] == 'undefined', 'Module.read option was removed (modify read_ in JS)');
assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)');
assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
legacyModuleProp('read', 'read_');
legacyModuleProp('readAsync', 'readAsync');
legacyModuleProp('readBinary', 'readBinary');
legacyModuleProp('setWindowTitle', 'setWindowTitle');
var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-sENVIRONMENT` to enable.");
// end include: shell.js
// include: preamble.js
// === Preamble library stuff ===
// Documentation for the public APIs defined in this file must be updated in:
// site/source/docs/api_reference/preamble.js.rst
// A prebuilt local version of the documentation is available at:
// site/build/text/docs/api_reference/preamble.js.txt
// You can also build docs locally as HTML or other formats in site/
// An online HTML version (which may be of a different version of Emscripten)
// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
var wasmBinary;
if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
var noExitRuntime = Module['noExitRuntime'] || true;legacyModuleProp('noExitRuntime', 'noExitRuntime');
if (typeof WebAssembly != 'object') {
abort('no native wasm support detected');
}
// Wasm globals
var wasmMemory;
// For sending to workers.
var wasmModule;
//========================================
// Runtime essentials
//========================================
// whether we are quitting the application. no code should run after this.
// set in exit() and abort()
var ABORT = false;
// set by exit() and abort(). Passed to 'onExit' handler.
// NOTE: This is also used as the process return code code in shell environments
// but only when noExitRuntime is false.
var EXITSTATUS;
/** @type {function(*, string=)} */
function assert(condition, text) {
if (!condition) {
abort('Assertion failed' + (text ? ': ' + text : ''));
}
}
// We used to include malloc/free by default in the past. Show a helpful error in
// builds with assertions.
function _free() {
// Show a helpful error since we used to include free by default in the past.
abort("free() called but not included in the build - add '_free' to EXPORTED_FUNCTIONS");
}
// Memory management
var HEAP,
/** @type {!Int8Array} */
HEAP8,
/** @type {!Uint8Array} */
HEAPU8,
/** @type {!Int16Array} */
HEAP16,
/** @type {!Uint16Array} */
HEAPU16,
/** @type {!Int32Array} */
HEAP32,
/** @type {!Uint32Array} */
HEAPU32,
/** @type {!Float32Array} */
HEAPF32,
/** @type {!Float64Array} */
HEAPF64;
function updateMemoryViews() {
var b = wasmMemory.buffer;
Module['HEAP8'] = HEAP8 = new Int8Array(b);
Module['HEAP16'] = HEAP16 = new Int16Array(b);
Module['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);
}
assert(!Module['STACK_SIZE'], 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
'JS engine does not provide full typed array support');
// In non-standalone/normal mode, we create the memory here.
// include: runtime_init_memory.js
// Create the wasm memory. (Note: this only applies if IMPORTED_MEMORY is defined)
var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216;legacyModuleProp('INITIAL_MEMORY', 'INITIAL_MEMORY');
assert(INITIAL_MEMORY >= 65536, 'INITIAL_MEMORY should be larger than STACK_SIZE, was ' + INITIAL_MEMORY + '! (STACK_SIZE=' + 65536 + ')');
// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
if (Module['wasmMemory']) {
wasmMemory = Module['wasmMemory'];
} else
{
wasmMemory = new WebAssembly.Memory({
'initial': INITIAL_MEMORY / 65536,
'maximum': INITIAL_MEMORY / 65536
,
'shared': true
});
if (!(wasmMemory.buffer instanceof SharedArrayBuffer)) {
err('requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag');
if (ENVIRONMENT_IS_NODE) {
err('(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and/or recent version)');
}
throw Error('bad memory');
}
}
updateMemoryViews();
// If the user provides an incorrect length, just use that length instead rather than providing the user to
// specifically provide the memory length with Module['INITIAL_MEMORY'].
INITIAL_MEMORY = wasmMemory.buffer.byteLength;
assert(INITIAL_MEMORY % 65536 === 0);
// end include: runtime_init_memory.js
// 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 the (separate) address-zero check
// below.
if (max == 0) {
max += 4;
}
// The stack grow downwards towards _emscripten_stack_get_end.
// We write cookies to the final two words in the stack and detect if they are
// ever overwritten.
HEAPU32[((max)>>2)] = 0x02135467;
HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
// Also test the global address 0 for integrity.
HEAPU32[0] = 0x63736d65; /* 'emsc' */
}
function checkStackCookie() {
if (ABORT) return;
var max = _emscripten_stack_get_end();
// See writeStackCookie().
if (max == 0) {
max += 4;
}
var cookie1 = HEAPU32[((max)>>2)];
var cookie2 = HEAPU32[(((max)+(4))>>2)];
if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
abort('Stack overflow! Stack cookie has been overwritten at ' + ptrToString(max) + ', expected hex dwords 0x89BACDFE and 0x2135467, but received ' + ptrToString(cookie2) + ' ' + ptrToString(cookie1));
}
// Also test the global address 0 for integrity.
if (HEAPU32[0] !== 0x63736d65 /* 'emsc' */) {
abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
}
}
// end include: runtime_stack_check.js
// include: runtime_assertions.js
// Endianness check
(function() {
var h16 = new Int16Array(1);
var h8 = new Int8Array(h16.buffer);
h16[0] = 0x6373;
if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
})();
// end include: runtime_assertions.js
var __ATPRERUN__ = []; // functions called before the runtime is initialized
var __ATINIT__ = []; // functions called during startup
var __ATMAIN__ = []; // functions called when main() is to be run
var __ATEXIT__ = []; // functions called during shutdown
var __ATPOSTRUN__ = []; // functions called after the main() is called
var runtimeInitialized = false;
var runtimeKeepaliveCounter = 0;
function keepRuntimeAlive() {
return noExitRuntime || runtimeKeepaliveCounter > 0;
}
function preRun() {
if (Module['preRun']) {
if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
while (Module['preRun'].length) {
addOnPreRun(Module['preRun'].shift());
}
}
callRuntimeCallbacks(__ATPRERUN__);
}
function initRuntime() {
assert(!runtimeInitialized);
runtimeInitialized = true;
if (ENVIRONMENT_IS_WASM_WORKER) return __wasm_worker_initializeRuntime();
checkStackCookie();
callRuntimeCallbacks(__ATINIT__);
}
function preMain() {
checkStackCookie();
callRuntimeCallbacks(__ATMAIN__);
}
function postRun() {
checkStackCookie();
if (Module['postRun']) {
if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
while (Module['postRun'].length) {
addOnPostRun(Module['postRun'].shift());
}
}
callRuntimeCallbacks(__ATPOSTRUN__);
}
function addOnPreRun(cb) {
__ATPRERUN__.unshift(cb);
}
function addOnInit(cb) {
__ATINIT__.unshift(cb);
}
function addOnPreMain(cb) {
__ATMAIN__.unshift(cb);
}
function addOnExit(cb) {
}
function addOnPostRun(cb) {
__ATPOSTRUN__.unshift(cb);
}
// include: runtime_math.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill');
// end include: runtime_math.js
// A counter of dependencies for calling run(). If we need to
// do asynchronous work before running, increment this and
// decrement it. Incrementing must happen in a place like
// Module.preRun (used by emcc to add file preloading).
// Note that you can add dependencies in preRun, even though
// it happens right before run - run will be postponed until
// the dependencies are met.
var runDependencies = 0;
var runDependencyWatcher = null;
var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
var runDependencyTracking = {};
function getUniqueRunDependency(id) {
var orig = id;
while (1) {
if (!runDependencyTracking[id]) return id;
id = orig + Math.random();
}
}
function addRunDependency(id) {
runDependencies++;
if (Module['monitorRunDependencies']) {
Module['monitorRunDependencies'](runDependencies);
}
if (id) {
assert(!runDependencyTracking[id]);
runDependencyTracking[id] = 1;
if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
// Check for missing dependencies every few seconds
runDependencyWatcher = setInterval(() => {
if (ABORT) {
clearInterval(runDependencyWatcher);
runDependencyWatcher = null;
return;
}
var shown = false;
for (var dep in runDependencyTracking) {
if (!shown) {
shown = true;
err('still waiting on run dependencies:');
}
err('dependency: ' + dep);
}
if (shown) {
err('(end of list)');
}
}, 10000);
}
} else {
err('warning: run dependency added without ID');
}
}
function removeRunDependency(id) {
runDependencies--;
if (Module['monitorRunDependencies']) {
Module['monitorRunDependencies'](runDependencies);
}
if (id) {
assert(runDependencyTracking[id]);
delete runDependencyTracking[id];
} else {
err('warning: run dependency removed without ID');
}
if (runDependencies == 0) {
if (runDependencyWatcher !== null) {
clearInterval(runDependencyWatcher);
runDependencyWatcher = null;
}
if (dependenciesFulfilled) {
var callback = dependenciesFulfilled;
dependenciesFulfilled = null;
callback(); // can add another dependenciesFulfilled
}
}
}
/** @param {string|number=} what */
function abort(what) {
if (Module['onAbort']) {
Module['onAbort'](what);
}
what = 'Aborted(' + what + ')';
// TODO(sbc): Should we remove printing and leave it up to whoever
// catches the exception?
err(what);
ABORT = true;
EXITSTATUS = 1;
// Use a wasm runtime error, because a JS error might be seen as a foreign
// exception, which means we'd run destructors on it. We need the error to
// simply make the program stop.
// FIXME This approach does not work in Wasm EH because it currently does not assume
// all RuntimeErrors are from traps; it decides whether a RuntimeError is from
// a trap or not based on a hidden field within the object. So at the moment
// we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
// allows this in the wasm spec.
// Suppress closure compiler warning here. Closure compiler's builtin extern
// defintion for WebAssembly.RuntimeError claims it takes no arguments even
// though it can.
// TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
/** @suppress {checkTypes} */
var e = new WebAssembly.RuntimeError(what);
// Throw the error whether or not MODULARIZE is set because abort is used
// in code paths apart from instantiation where an exception is expected
// to be thrown when abort is called.
throw e;
}
// include: memoryprofiler.js
// end include: memoryprofiler.js
// show errors on likely calls to FS when it was not included
var FS = {
error: function() {
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() },
ErrnoError: function 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,';
// Indicates whether filename is a base64 data URI.
function isDataURI(filename) {
// Prefix of data URIs emitted by SINGLE_FILE and related options.
return filename.startsWith(dataURIPrefix);
}
// Indicates whether filename is delivered via file protocol (as opposed to http/https)
function isFileURI(filename) {
return filename.startsWith('file://');
}
// end include: URIUtils.js
/** @param {boolean=} fixedasm */
function createExportWrapper(name, fixedasm) {
return function() {
var displayName = name;
var asm = fixedasm;
if (!fixedasm) {
asm = Module['asm'];
}
assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization');
if (!asm[name]) {
assert(asm[name], 'exported native function `' + displayName + '` not found');
}
return asm[name].apply(null, arguments);
};
}
// include: runtime_exceptions.js
// end include: runtime_exceptions.js
var wasmBinaryFile;
wasmBinaryFile = 'NoiseGenerator.wasm';
if (!isDataURI(wasmBinaryFile)) {
wasmBinaryFile = locateFile(wasmBinaryFile);
}
function getBinary(file) {
try {
if (file == wasmBinaryFile && wasmBinary) {
return new Uint8Array(wasmBinary);
}
if (readBinary) {
return readBinary(file);
}
throw "both async and sync fetching of the wasm failed";
}
catch (err) {
abort(err);
}
}
function getBinaryPromise(binaryFile) {
// If we don't have the binary yet, try to load it asynchronously.
// Fetch has some additional restrictions over XHR, like it can't be used on a file:// url.
// See https://github.com/github/fetch/pull/92#issuecomment-140665932
// Cordova or Electron apps are typically loaded from a file:// url.
// So use fetch if it is available and the url is not a file, otherwise fall back to XHR.
if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
if (typeof fetch == 'function'
&& !isFileURI(binaryFile)
) {
return fetch(binaryFile, { credentials: 'same-origin' }).then((response) => {
if (!response['ok']) {
throw "failed to load wasm binary file at '" + binaryFile + "'";
}
return response['arrayBuffer']();
}).catch(() => getBinary(binaryFile));
}
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(() => getBinary(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<Repsponse> rather than
// an actual Response.
// TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure is fixed.
/** @suppress {checkTypes} */
var result = WebAssembly.instantiateStreaming(response, imports);
return result.then(
callback,
function(reason) {
// We expect the most common failure cause to be a bad MIME type for the binary,
// in which case falling back to ArrayBuffer instantiation should work.
err('wasm streaming compile failed: ' + reason);
err('falling back to ArrayBuffer instantiation');
return instantiateArrayBuffer(binaryFile, imports, callback);
});
});
} else {
return instantiateArrayBuffer(binaryFile, imports, callback);
}
}
// Create the wasm instance.
// Receives the wasm imports, returns the exports.
function createWasm() {
// prepare imports
var info = {
'env': wasmImports,
'wasi_snapshot_preview1': wasmImports,
};
// Load the wasm module and create an instance of using native support in the JS engine.
// handle a generated wasm instance, receiving its exports and
// performing other necessary setup
/** @param {WebAssembly.Module=} module*/
function receiveInstance(instance, module) {
var exports = instance.exports;
Module['asm'] = exports;
wasmTable = Module['asm']['__indirect_function_table'];
assert(wasmTable, "table not found in wasm exports");
// If we are in the audio worklet environment, we can only access the Module object
// and not the global scope of the main JS script. Therefore we need to export
// all functions that the audio worklet scope needs onto the Module object.
Module['wasmTable'] = wasmTable;
addOnInit(Module['asm']['__wasm_call_ctors']);
// We now have the Wasm module loaded up, keep a reference to the compiled module so we can post it to the workers.
wasmModule = module;
removeRunDependency('wasm-instantiate');
return exports;
}
// wait for the pthread pool (if any)
addRunDependency('wasm-instantiate');
// Prefer streaming instantiation if available.
// Async compilation can be confusing when an error on the page overwrites Module
// (for example, if the order of elements is wrong, and the one defining Module is
// later), so we save Module and check it later.
var trueModule = Module;
function receiveInstantiationResult(result) {
// 'result' is a ResultObject object which has both the module and instance.
// receiveInstance() will swap in the exports (to Module.asm) so they can be called
assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
trueModule = null;
receiveInstance(result['instance'], result['module']);
}
// User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
// to manually instantiate the Wasm module themselves. This allows pages to
// run the instantiation parallel to any other async startup actions they are
// performing.
// Also pthreads and wasm workers initialize the wasm instance through this
// path.
if (Module['instantiateWasm']) {
try {
return Module['instantiateWasm'](info, receiveInstance);
} catch(e) {
err('Module.instantiateWasm callback failed with error: ' + e);
return false;
}
}
instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult);
return {}; // no exports yet; we'll fill them in later
}
// Globals used by JS i64 conversions (see makeSetValue)
var tempDouble;
var tempI64;
// include: runtime_debug.js
function legacyModuleProp(prop, newName) {
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');
}
}
// 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: function() {
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: function() {
// Can't `abort()` here because it would break code that does runtime
// checks. e.g. `if (typeof SDL === 'undefined')`.
var msg = '`' + sym + '` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line';
// DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
// library.js, which means $name for a JS name with no prefix, or name
// for a JS name like _name.
var librarySymbol = sym;
if (!librarySymbol.startsWith('_')) {
librarySymbol = '$' + sym;
}
msg += " (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=" + librarySymbol + ")";
if (isExportedByForceFilesystem(sym)) {
msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
}
warnOnce(msg);
return undefined;
}
});
}
// 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: function() {
var msg = "'" + sym + "' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)";
if (isExportedByForceFilesystem(sym)) {
msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
}
abort(msg);
}
});
}
}
// 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 errors.
console.error.apply(console, arguments);
}
// end include: runtime_debug.js
// === Body ===
var ASM_CONSTS = {
65736: ($0, $1) => { emscriptenGetAudioObject($0).connect(emscriptenGetAudioObject($1).destination) }
};
// end include: preamble.js
/** @constructor */
function ExitStatus(status) {
this.name = 'ExitStatus';
this.message = 'Program terminated with exit(' + status + ')';
this.status = status;
}
function callRuntimeCallbacks(callbacks) {
while (callbacks.length > 0) {
// Pass the module as the first argument.
callbacks.shift()(Module);
}
}
/**
* @param {number} ptr
* @param {string} type
*/
function getValue(ptr, type = 'i8') {
if (type.endsWith('*')) type = '*';
switch (type) {
case 'i1': return HEAP8[((ptr)>>0)];
case 'i8': return HEAP8[((ptr)>>0)];
case 'i16': return HEAP16[((ptr)>>1)];
case 'i32': return HEAP32[((ptr)>>2)];
case 'i64': return HEAP32[((ptr)>>2)];
case 'float': return HEAPF32[((ptr)>>2)];
case 'double': return HEAPF64[((ptr)>>3)];
case '*': return HEAPU32[((ptr)>>2)];
default: abort('invalid type for getValue: ' + type);
}
}
function ptrToString(ptr) {
assert(typeof ptr === 'number');
return '0x' + ptr.toString(16).padStart(8, '0');
}
/**
* @param {number} ptr
* @param {number} value
* @param {string} type
*/
function setValue(ptr, value, type = 'i8') {
if (type.endsWith('*')) type = '*';
switch (type) {
case 'i1': HEAP8[((ptr)>>0)] = value; break;
case 'i8': HEAP8[((ptr)>>0)] = value; break;
case 'i16': HEAP16[((ptr)>>1)] = value; break;
case 'i32': HEAP32[((ptr)>>2)] = value; break;
case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? (+(Math.floor((tempDouble)/4294967296.0)))>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)], HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break;
case 'float': HEAPF32[((ptr)>>2)] = value; break;
case 'double': HEAPF64[((ptr)>>3)] = value; break;
case '*': HEAPU32[((ptr)>>2)] = value; break;
default: abort('invalid type for setValue: ' + type);
}
}
function warnOnce(text) {
if (!warnOnce.shown) warnOnce.shown = {};
if (!warnOnce.shown[text]) {
warnOnce.shown[text] = 1;
if (ENVIRONMENT_IS_NODE) text = 'warning: ' + text;
err(text);
}
}
var __wasm_worker_delayedMessageQueue = [];
var wasmTableMirror = [];
function getWasmTableEntry(funcPtr) {
var func = wasmTableMirror[funcPtr];
if (!func) {
if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
}
assert(wasmTable.get(funcPtr) == func, "JavaScript-side Wasm function table mirror is out of date!");
return func;
}
function __wasm_worker_runPostMessage(e) {
let data = e.data, wasmCall = data['_wsc']; // '_wsc' is short for 'wasm call', trying to use an identifier name that will never conflict with user code
wasmCall && getWasmTableEntry(wasmCall)(...data['x']);
}
function __wasm_worker_appendToQueue(e) {
__wasm_worker_delayedMessageQueue.push(e);
}
function __wasm_worker_initializeRuntime() {
let m = Module;
assert(m['sb'] % 16 == 0);
assert(m['sz'] % 16 == 0);
// Run the C side Worker initialization for stack and TLS.
_emscripten_wasm_worker_initialize(m['sb'], m['sz']);
// Audio Worklets do not have postMessage()ing capabilities.
if (typeof AudioWorkletGlobalScope === 'undefined') {
// The Wasm Worker runtime is now up, so we can start processing
// any postMessage function calls that have been received. Drop the temp
// message handler that queued any pending incoming postMessage function calls ...
removeEventListener('message', __wasm_worker_appendToQueue);
// ... then flush whatever messages we may have already gotten in the queue,
// and clear __wasm_worker_delayedMessageQueue to undefined ...
__wasm_worker_delayedMessageQueue = __wasm_worker_delayedMessageQueue.forEach(__wasm_worker_runPostMessage);
// ... and finally register the proper postMessage handler that immediately
// dispatches incoming function calls without queueing them.
addEventListener('message', __wasm_worker_runPostMessage);
}
}
var readEmAsmArgsArray = [];
function 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);
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++]) {
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/*i*/) & buf;
readEmAsmArgsArray.push(
ch == 105/*i*/ ? HEAP32[buf] :
HEAPF64[buf++ >> 1]
);
++buf;
}
return readEmAsmArgsArray;
}
function 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);
}
function _emscripten_asm_const_int(code, sigPtr, argbuf) {
return runEmAsmFunction(code, sigPtr, argbuf);
}
function _emscripten_audio_context_state(contextHandle) {
assert(EmAudio[contextHandle], `Called emscripten_audio_context_state() on a nonexisting context handle ${contextHandle}`);
assert(EmAudio[contextHandle] instanceof (window.AudioContext || window.webkitAudioContext), `Called emscripten_audio_context_state() on a context handle ${contextHandle} that is not an AudioContext, but of type ${typeof EmAudio[contextHandle]}`);
return ['suspended', 'running', 'closed', 'interrupted'].indexOf(EmAudio[contextHandle].state);
}
var EmAudio = {};
var EmAudioCounter = 0;
function emscriptenRegisterAudioObject(object) {
assert(object, 'Called emscriptenRegisterAudioObject() with a null object handle!');
EmAudio[++EmAudioCounter] = object;
return EmAudioCounter;
}
function emscriptenGetAudioObject(objectHandle) {
return EmAudio[objectHandle];
}
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}
*/
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.buffer instanceof SharedArrayBuffer ? heapOrArray.slice(idx, endPtr) : heapOrArray.subarray(idx, endPtr));
}
var str = '';
// If building with TextDecoder, we have already computed the string length
// above, so test loop end condition against that
while (idx < endPtr) {
// For UTF8 byte structure, see:
// http://en.wikipedia.org/wiki/UTF-8#Description
// https://www.ietf.org/rfc/rfc2279.txt
// https://tools.ietf.org/html/rfc3629
var u0 = heapOrArray[idx++];
if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
var u1 = heapOrArray[idx++] & 63;
if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
var u2 = heapOrArray[idx++] & 63;
if ((u0 & 0xF0) == 0xE0) {
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
} else {
if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte ' + ptrToString(u0) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!');
u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
}
if (u0 < 0x10000) {
str += String.fromCharCode(u0);
} else {
var ch = u0 - 0x10000;
str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
}
}
return str;
}
/**
* Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
* emscripten HEAP, returns a copy of that string as a Javascript String object.
*
* @param {number} ptr
* @param {number=} maxBytesToRead - An optional length that specifies the
* maximum number of bytes to read. You can omit this parameter to scan the
* string until the first 0 byte. If maxBytesToRead is passed, and the string
* at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
* string will cut short at that byte index (i.e. maxBytesToRead will not
* produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
* frequent uses of UTF8ToString() with and without maxBytesToRead may throw
* JS JIT optimizations off, so it is worth to consider consistently using one
* @return {string}
*/
function UTF8ToString(ptr, maxBytesToRead) {
assert(typeof ptr == 'number');
return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
}
function _emscripten_create_audio_context(options) {
let ctx = window.AudioContext || window.webkitAudioContext;
if (!ctx) console.error('emscripten_create_audio_context failed! Web Audio is not supported.');
options >>= 2;
let opts = options ? {
latencyHint: HEAPU32[options] ? UTF8ToString(HEAPU32[options]) : void 0,
sampleRate: HEAP32[options+1] || void 0
} : void 0;
return ctx && emscriptenRegisterAudioObject(new ctx(opts));
}
function _emscripten_create_wasm_audio_worklet_node(contextHandle, name, options, callback, userData) {
assert(contextHandle, `Called emscripten_create_wasm_audio_worklet_node() with a null Web Audio Context handle!`);
assert(EmAudio[contextHandle], `Called emscripten_create_wasm_audio_worklet_node() with a nonexisting/already freed Web Audio Context handle ${contextHandle}!`);
assert(EmAudio[contextHandle] instanceof (window.AudioContext || window.webkitAudioContext), `Called emscripten_create_wasm_audio_worklet_node() on a context handle ${contextHandle} that is not an AudioContext, but of type ${typeof EmAudio[contextHandle]}`);
options >>= 2;
function readChannelCountArray(heapIndex, numOutputs) {
let channelCounts = [];
while(numOutputs--) channelCounts.push(HEAPU32[heapIndex++]);
return channelCounts;
}
let opts = options ? {
numberOfInputs: HEAP32[options],
numberOfOutputs: HEAP32[options+1],
outputChannelCount: HEAPU32[options+2] ? readChannelCountArray(HEAPU32[options+2]>>2, HEAP32[options+1]) : void 0,
processorOptions: { 'cb': callback, 'ud': userData }
} : void 0;
return emscriptenRegisterAudioObject(new AudioWorkletNode(EmAudio[contextHandle], UTF8ToString(name), opts));
}
function _emscripten_create_wasm_audio_worklet_processor_async(contextHandle, options, callback, userData) {
assert(contextHandle, `Called emscripten_create_wasm_audio_worklet_processor_async() with a null Web Audio Context handle!`);
assert(EmAudio[contextHandle], `Called emscripten_create_wasm_audio_worklet_processor_async() with a nonexisting/already freed Web Audio Context handle ${contextHandle}!`);
assert(EmAudio[contextHandle] instanceof (window.AudioContext || window.webkitAudioContext), `Called emscripten_create_wasm_audio_worklet_processor_async() on a context handle ${contextHandle} that is not an AudioContext, but of type ${typeof EmAudio[contextHandle]}`);
options >>= 2;
let audioParams = [],
numAudioParams = HEAPU32[options+1],
audioParamDescriptors = HEAPU32[options+2] >> 2,
i = 0;
while(numAudioParams--) {
audioParams.push({
name: i++,
defaultValue: HEAPF32[audioParamDescriptors++],
minValue: HEAPF32[audioParamDescriptors++],
maxValue: HEAPF32[audioParamDescriptors++],
automationRate: ['a','k'][HEAPU32[audioParamDescriptors++]] + '-rate',
});
}
EmAudio[contextHandle].audioWorklet.bootstrapMessage.port.postMessage({
_wpn: UTF8ToString(HEAPU32[options]), // '_wpn' == 'Worklet Processor Name', use a deliberately mangled name so that this field won't accidentally be mixed with user submitted messages.
audioParams: audioParams,
contextHandle: contextHandle,
callback: callback,
userData: userData
});
}
var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) {
_emscripten_get_now = () => {
var t = process.hrtime();
return t[0] * 1e3 + t[1] / 1e6;
};
} else if (typeof performance != 'undefined' && performance.now) {
_emscripten_get_now = () => performance.now();
} else {
_emscripten_get_now = Date.now;
}
function _emscripten_random() {
return Math.random();
}
function getHeapMax() {
return HEAPU8.length;
}
function abortOnCannotGrowMemory(requestedSize) {
abort(`Cannot enlarge memory arrays to size ${requestedSize} bytes (OOM). Either (1) compile with -sINITIAL_MEMORY=X with X higher than the current value ${HEAP8.length}, (2) compile with -sALLOW_MEMORY_GROWTH which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -sABORTING_MALLOC=0`);
}
function _emscripten_resize_heap(requestedSize) {
var oldSize = HEAPU8.length;
requestedSize = requestedSize >>> 0;
abortOnCannotGrowMemory(requestedSize);
}
function _emscripten_resume_audio_context_sync(contextHandle) {
assert(EmAudio[contextHandle], `Called emscripten_resume_audio_context_sync() on a nonexisting context handle ${contextHandle}`);
assert(EmAudio[contextHandle] instanceof (window.AudioContext || window.webkitAudioContext), `Called emscripten_resume_audio_context_sync() on a context handle ${contextHandle} that is not an AudioContext, but of type ${typeof EmAudio[contextHandle]}`);
EmAudio[contextHandle].resume();
}
function 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() {
if (!JSEvents.removeEventListenersRegistered) {
__ATEXIT__.push(JSEvents.removeAllEventListeners);
JSEvents.removeEventListenersRegistered = true;
}
},deferredCalls:[],deferCall:function(targetFunction, precedence, argsList) {
function arraysHaveEqualContent(arrA, arrB) {
if (arrA.length != arrB.length) return false;
for (var i in arrA) {
if (arrA[i] != arrB[i]) return false;
}
return true;
}
// Test if the given call was already queued, and if so, don't add it again.
for (var i in JSEvents.deferredCalls) {
var call = JSEvents.deferredCalls[i];
if (call.targetFunction == targetFunction && arraysHaveEqualContent(call.argsList, argsList)) {
return;
}
}
JSEvents.deferredCalls.push({
targetFunction: targetFunction,
precedence: precedence,
argsList: argsList
});
JSEvents.deferredCalls.sort(function(x,y) { return x.precedence < y.precedence; });
},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() {
return JSEvents.inEventHandler && JSEvents.currentEventHandler.allowsDeferredCalls;
},runDeferredCalls:function() {
if (!JSEvents.canPerformEventHandlerRequests()) {
return;
}
for (var i = 0; i < JSEvents.deferredCalls.length; ++i) {
var call = JSEvents.deferredCalls[i];
JSEvents.deferredCalls.splice(i, 1);
--i;
call.targetFunction.apply(null, call.argsList);
}
},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) {
var h = JSEvents.eventHandlers[i];
h.target.removeEventListener(h.eventTypeString, h.eventListenerFunc, h.useCapture);
JSEvents.eventHandlers.splice(i, 1);
},registerOrRemoveHandler:function(eventHandler) {
var jsEventHandler = function jsEventHandler(event) {
// Increment nesting count for the event handler.
++JSEvents.inEventHandler;
JSEvents.currentEventHandler = eventHandler;
// Process any old deferred calls the user has placed.
JSEvents.runDeferredCalls();
// Process the actual event, calls back to user C code handler.
eventHandler.handlerFunc(event);
// Process any new deferred calls that were placed right now from this event handler.
JSEvents.runDeferredCalls();
// Out of event handler - restore nesting count.
--JSEvents.inEventHandler;
};
if (eventHandler.callbackfunc) {
eventHandler.eventListenerFunc = jsEventHandler;
eventHandler.target.addEventListener(eventHandler.eventTypeString, jsEventHandler, eventHandler.useCapture);
JSEvents.eventHandlers.push(eventHandler);
JSEvents.registerRemoveEventListeners();
} else {
for (var i = 0; i < JSEvents.eventHandlers.length; ++i) {
if (JSEvents.eventHandlers[i].target == eventHandler.target
&& JSEvents.eventHandlers[i].eventTypeString == eventHandler.eventTypeString) {
JSEvents._removeHandler(i--);
}
}
}
},getNodeNameForTarget:function(target) {
if (!target) return '';
if (target == window) return '#window';
if (target == screen) return '#screen';
return (target && target.nodeName) ? target.nodeName : '';
},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 specialHTMLTargets = [0, typeof document != 'undefined' ? document : 0, typeof window != 'undefined' ? window : 0];
function getBoundingClientRect(e) {
return specialHTMLTargets.indexOf(e) < 0 ? e.getBoundingClientRect() : {'left':0,'top':0};
}
function fillMouseEventData(eventStruct, e, target) {
assert(eventStruct % 4 == 0);
HEAPF64[((eventStruct)>>3)] = e.timeStamp;
var idx = eventStruct >> 2;
HEAP32[idx + 2] = e.screenX;
HEAP32[idx + 3] = e.screenY;
HEAP32[idx + 4] = e.clientX;
HEAP32[idx + 5] = e.clientY;
HEAP32[idx + 6] = e.ctrlKey;
HEAP32[idx + 7] = e.shiftKey;
HEAP32[idx + 8] = e.altKey;
HEAP32[idx + 9] = e.metaKey;
HEAP16[idx*2 + 20] = e.button;
HEAP16[idx*2 + 21] = e.buttons;
HEAP32[idx + 11] = e["movementX"]
;
HEAP32[idx + 12] = e["movementY"]
;
var rect = getBoundingClientRect(target);
HEAP32[idx + 13] = e.clientX - rect.left;
HEAP32[idx + 14] = e.clientY - rect.top;
}
function maybeCStringToJsString(cString) {
// "cString > 2" checks if the input is a number, and isn't of the special
// values we accept here, EMSCRIPTEN_EVENT_TARGET_* (which map to 0, 1, 2).
// In other words, if cString > 2 then it's a pointer to a valid place in
// memory, and points to a C string.
return cString > 2 ? UTF8ToString(cString) : cString;
}
function findEventTarget(target) {
target = maybeCStringToJsString(target);
var domElement = specialHTMLTargets[target] || (typeof document != 'undefined' ? document.querySelector(target) : undefined);
return domElement;
}
function registerMouseEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) {
if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc( 72 );
target = findEventTarget(target);
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);
if (getWasmTableEntry(callbackfunc)(eventTypeId, JSEvents.mouseEvent, userData)) e.preventDefault();
};
var eventHandler = {
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,
handlerFunc: mouseEventHandlerFunc,
useCapture: useCapture
};
JSEvents.registerOrRemoveHandler(eventHandler);
}
function _emscripten_set_click_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
assert(!ENVIRONMENT_IS_WASM_WORKER, "Attempted to call proxied function '_emscripten_set_click_callback_on_thread' in a Wasm Worker, but in Wasm Worker enabled builds, proxied function architecture is not available!");
registerMouseEventCallback(target, userData, useCapture, callbackfunc, 4, "click", targetThread);
return 0;
}
var _wasm_workers_id = 1;
function _EmAudioDispatchProcessorCallback(e) {
let data = e.data, wasmCall = data['_wsc']; // '_wsc' is short for 'wasm call', trying to use an identifier name that will never conflict with user code
wasmCall && getWasmTableEntry(wasmCall)(...data['x']);
}
function _emscripten_start_wasm_audio_worklet_thread_async(contextHandle, stackLowestAddress, stackSize, callback, userData) {
assert(contextHandle, `Called emscripten_start_wasm_audio_worklet_thread_async() with a null Web Audio Context handle!`);
assert(EmAudio[contextHandle], `Called emscripten_start_wasm_audio_worklet_thread_async() with a nonexisting/already freed Web Audio Context handle ${contextHandle}!`);
assert(EmAudio[contextHandle] instanceof (window.AudioContext || window.webkitAudioContext), `Called emscripten_start_wasm_audio_worklet_thread_async() on a context handle ${contextHandle} that is not an AudioContext, but of type ${typeof EmAudio[contextHandle]}`);
let audioContext = EmAudio[contextHandle],
audioWorklet = audioContext.audioWorklet;
assert(stackLowestAddress != 0, 'AudioWorklets require a dedicated stack space for audio data marshalling between Wasm and JS!');
assert(stackLowestAddress % 16 == 0, `AudioWorklet stack should be aligned to 16 bytes! (was ${stackLowestAddress} == ${stackLowestAddress%16} mod 16) Use e.g. memalign(16, stackSize) to align the stack!`);
assert(stackSize != 0, 'AudioWorklets require a dedicated stack space for audio data marshalling between Wasm and JS!');
assert(stackSize % 16 == 0, `AudioWorklet stack size should be a multiple of 16 bytes! (was ${stackSize} == ${stackSize%16} mod 16)`);
assert(!audioContext.audioWorkletInitialized, 'emscripten_create_wasm_audio_worklet() was already called for AudioContext ' + contextHandle + '! Only call this function once per AudioContext!');
audioContext.audioWorkletInitialized = 1;
let audioWorkletCreationFailed = () => {
getWasmTableEntry(callback)(contextHandle, 0/*EM_FALSE*/, userData);
};
// Does browser not support AudioWorklets?
if (!audioWorklet) {
return audioWorkletCreationFailed();
}
// TODO: In MINIMAL_RUNTIME builds, read this file off of a preloaded Blob, and/or embed from a string like with WASM_WORKERS==2 mode.
audioWorklet.addModule('NoiseGenerator.aw.js').then(() => {
audioWorklet.bootstrapMessage = new AudioWorkletNode(audioContext, 'message', {
processorOptions: {
'$ww': _wasm_workers_id++, // Assign the loaded AudioWorkletGlobalScope a Wasm Worker ID so that it can utilized its own TLS slots, and it is recognized to not be the main browser thread.
'wasm': wasmModule,
'wasmMemory': wasmMemory,
'sb': stackLowestAddress, // sb = stack base
'sz': stackSize, // sz = stack size
}
});
audioWorklet.bootstrapMessage.port.onmessage = _EmAudioDispatchProcessorCallback;
// AudioWorklets do not have a importScripts() function like Web Workers do (and AudioWorkletGlobalScope does not allow dynamic import() either),
// but instead, the main thread must load all JS code into the worklet scope. Send the application main JS script to the audio worklet.
return audioWorklet.addModule(
Module['mainScriptUrlOrBlob'] || _scriptDir
);
}).then(() => {
getWasmTableEntry(callback)(contextHandle, 1/*EM_TRUE*/, userData);
}).catch(audioWorkletCreationFailed);
}
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
_fflush(0);
if (printCharBuffers[1].length) printChar(1, 10);
if (printCharBuffers[2].length) printChar(2, 10);
}
var SYSCALLS = {varargs:undefined,get:function() {
assert(SYSCALLS.varargs != undefined);
SYSCALLS.varargs += 4;
var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)];
return ret;
},getStr:function(ptr) {
var ret = UTF8ToString(ptr);
return ret;
}};
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;
}
HEAPU32[((pnum)>>2)] = num;
return 0;
}
function _proc_exit(code) {
EXITSTATUS = code;
if (!keepRuntimeAlive()) {
if (Module['onExit']) Module['onExit'](code);
ABORT = true;
}
quit_(code, new ExitStatus(code));
}
/** @param {boolean|number=} implicit */
function exitJS(status, implicit) {
EXITSTATUS = status;
checkUnflushedContent();
// if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
if (keepRuntimeAlive() && !implicit) {
var msg = `program exited (with status: ${status}), but 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);
}
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;
}
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);
}
function lengthBytesUTF8(str) {
var len = 0;
for (var i = 0; i < str.length; ++i) {
// Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
// unit, not a Unicode code point of the character! So decode
// UTF16->UTF32->UTF8.
// See http://unicode.org/faq/utf_bom.html#utf16-3
var c = str.charCodeAt(i); // possibly a lead surrogate
if (c <= 0x7F) {
len++;
} else if (c <= 0x7FF) {
len += 2;
} else if (c >= 0xD800 && c <= 0xDFFF) {
len += 4; ++i;
} else {
len += 3;
}
}
return len;
}
function 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;
}
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);
}
function stringToUTF8OnStack(str) {
var size = lengthBytesUTF8(str) + 1;
var ret = stackAlloc(size);
stringToUTF8(str, ret, size);
return ret;
}
function checkIncomingModuleAPI() {
ignoredModuleProp('fetchSettings');
}
var wasmImports = {
"emscripten_asm_const_int": _emscripten_asm_const_int,
"emscripten_audio_context_state": _emscripten_audio_context_state,
"emscripten_create_audio_context": _emscripten_create_audio_context,
"emscripten_create_wasm_audio_worklet_node": _emscripten_create_wasm_audio_worklet_node,
"emscripten_create_wasm_audio_worklet_processor_async": _emscripten_create_wasm_audio_worklet_processor_async,
"emscripten_get_now": _emscripten_get_now,
"emscripten_random": _emscripten_random,
"emscripten_resize_heap": _emscripten_resize_heap,
"emscripten_resume_audio_context_sync": _emscripten_resume_audio_context_sync,
"emscripten_set_click_callback_on_thread": _emscripten_set_click_callback_on_thread,
"emscripten_start_wasm_audio_worklet_thread_async": _emscripten_start_wasm_audio_worklet_thread_async,
"fd_write": _fd_write,
"memory": wasmMemory
};
var asm = createWasm();
/** @type {function(...*):?} */
var ___wasm_call_ctors = createExportWrapper("__wasm_call_ctors");
/** @type {function(...*):?} */
var _main = Module["_main"] = createExportWrapper("__main_argc_argv");
/** @type {function(...*):?} */
var ___errno_location = createExportWrapper("__errno_location");
/** @type {function(...*):?} */
var _fflush = Module["_fflush"] = createExportWrapper("fflush");
/** @type {function(...*):?} */
var _malloc = createExportWrapper("malloc");
/** @type {function(...*):?} */
var _emscripten_stack_init = function() {
return (_emscripten_stack_init = Module["asm"]["emscripten_stack_init"]).apply(null, arguments);
};
/** @type {function(...*):?} */
var _emscripten_stack_get_free = function() {
return (_emscripten_stack_get_free = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments);
};
/** @type {function(...*):?} */
var _emscripten_stack_get_base = function() {
return (_emscripten_stack_get_base = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments);
};
/** @type {function(...*):?} */
var _emscripten_stack_get_end = function() {
return (_emscripten_stack_get_end = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments);
};
/** @type {function(...*):?} */
var _emscripten_wasm_worker_initialize = Module["_emscripten_wasm_worker_initialize"] = createExportWrapper("emscripten_wasm_worker_initialize");
/** @type {function(...*):?} */
var stackSave = createExportWrapper("stackSave");
/** @type {function(...*):?} */
var stackRestore = createExportWrapper("stackRestore");
/** @type {function(...*):?} */
var stackAlloc = createExportWrapper("stackAlloc");
/** @type {function(...*):?} */
var _emscripten_stack_get_current = function() {
return (_emscripten_stack_get_current = Module["asm"]["emscripten_stack_get_current"]).apply(null, arguments);
};
/** @type {function(...*):?} */
var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji");
// include: postamble.js
// === Auto-generated postamble setup entry stuff ===
Module["stackAlloc"] = stackAlloc;
Module["stackSave"] = stackSave;
Module["stackRestore"] = stackRestore;
var missingLibrarySymbols = [
'zeroMemory',
'emscripten_realloc_buffer',
'isLeapYear',
'ydayFromDate',
'arraySum',
'addDays',
'setErrNo',
'inetPton4',
'inetNtop4',
'inetPton6',
'inetNtop6',
'readSockaddr',
'writeSockaddr',
'getHostByName',
'initRandomFill',
'randomFill',
'traverseStack',
'getCallstack',
'emscriptenLog',
'convertPCtoSourceLocation',
'runMainThreadEmAsm',
'jstoi_q',
'jstoi_s',
'getExecutableName',
'listenOnce',
'autoResumeAudioContext',
'dynCallLegacy',
'getDynCaller',
'dynCall',
'runtimeKeepalivePush',
'runtimeKeepalivePop',
'callUserCallback',
'maybeExit',
'safeSetTimeout',
'asmjsMangle',
'asyncLoad',
'alignMemory',
'mmapAlloc',
'HandleAllocator',
'getNativeTypeSize',
'STACK_SIZE',
'STACK_ALIGN',
'POINTER_SIZE',
'ASSERTIONS',
'writeI53ToI64',
'writeI53ToI64Clamped',
'writeI53ToI64Signaling',
'writeI53ToU64Clamped',
'writeI53ToU64Signaling',
'readI53FromI64',
'readI53FromU64',
'convertI32PairToI53',
'convertI32PairToI53Checked',
'convertU32PairToI53',
'getCFunc',
'ccall',
'cwrap',
'uleb128Encode',
'sigToWasmTypes',
'generateFuncType',
'convertJsFunctionToWasm',
'getEmptyTableSlot',
'updateTableMap',
'getFunctionAddress',
'addFunction',
'removeFunction',
'reallyNegative',
'unSign',
'strLen',
'reSign',
'formatString',
'intArrayFromString',
'intArrayToString',
'AsciiToString',
'stringToAscii',
'UTF16ToString',
'stringToUTF16',
'lengthBytesUTF16',
'UTF32ToString',
'stringToUTF32',
'lengthBytesUTF32',
'stringToNewUTF8',
'writeArrayToMemory',
'getSocketFromFD',
'getSocketAddress',
'registerKeyEventCallback',
'findCanvasEventTarget',
'registerWheelEventCallback',
'registerUiEventCallback',
'registerFocusEventCallback',
'fillDeviceOrientationEventData',
'registerDeviceOrientationEventCallback',
'fillDeviceMotionEventData',
'registerDeviceMotionEventCallback',
'screenOrientation',
'fillOrientationChangeEventData',
'registerOrientationChangeEventCallback',
'fillFullscreenChangeEventData',
'registerFullscreenChangeEventCallback',
'JSEvents_requestFullscreen',
'JSEvents_resizeCanvasForFullscreen',
'registerRestoreOldStyle',
'hideEverythingExceptGivenElement',
'restoreHiddenElements',
'setLetterbox',
'softFullscreenResizeWebGLRenderTarget',
'doRequestFullscreen',
'fillPointerlockChangeEventData',
'registerPointerlockChangeEventCallback',
'registerPointerlockErrorEventCallback',
'requestPointerLock',
'fillVisibilityChangeEventData',
'registerVisibilityChangeEventCallback',
'registerTouchEventCallback',
'fillGamepadEventData',
'registerGamepadEventCallback',
'registerBeforeUnloadEventCallback',
'fillBatteryEventData',
'battery',
'registerBatteryEventCallback',
'setCanvasElementSize',
'getCanvasElementSize',
'demangle',
'demangleAll',
'jsStackTrace',
'stackTrace',
'getEnvStrings',
'checkWasiClock',
'wasiRightsToMuslOFlags',
'wasiOFlagsToMuslOFlags',
'createDyncallWrapper',
'setImmediateWrapped',
'clearImmediateWrapped',
'polyfillSetImmediate',
'getPromise',
'makePromise',
'idsToPromises',
'makePromiseCallback',
'ExceptionInfo',
'setMainLoop',
'FS_createPreloadedFile',
'FS_modeStringToFlags',
'FS_getMode',
'_setNetworkCallback',
'heapObjectForWebGLType',
'heapAccessShiftForWebGLHeap',
'webgl_enable_ANGLE_instanced_arrays',
'webgl_enable_OES_vertex_array_object',
'webgl_enable_WEBGL_draw_buffers',
'webgl_enable_WEBGL_multi_draw',
'emscriptenWebGLGet',
'computeUnpackAlignedImageSize',
'colorChannelsInGlTextureFormat',
'emscriptenWebGLGetTexPixelData',
'__glGenObject',
'emscriptenWebGLGetUniform',
'webglGetUniformLocation',
'webglPrepareUniformLocationsBeforeFirstUse',
'webglGetLeftBracePos',
'emscriptenWebGLGetVertexAttrib',
'__glGetActiveAttribOrUniform',
'writeGLArray',
'registerWebGlEventCallback',
'runAndAbortIfError',
'SDL_unicode',
'SDL_ttfContext',
'SDL_audio',
'GLFW_Window',
'ALLOC_NORMAL',
'ALLOC_STACK',
'allocate',
'writeStringToMemory',
'writeAsciiToMemory',
'emscripten_audio_worklet_post_function_1',
'emscripten_audio_worklet_post_function_2',
'emscripten_audio_worklet_post_function_3',
];
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',
'getTempRet0',
'setTempRet0',
'writeStackCookie',
'checkStackCookie',
'ptrToString',
'exitJS',
'getHeapMax',
'abortOnCannotGrowMemory',
'ENV',
'MONTH_DAYS_REGULAR',
'MONTH_DAYS_LEAP',
'MONTH_DAYS_REGULAR_CUMULATIVE',
'MONTH_DAYS_LEAP_CUMULATIVE',
'ERRNO_CODES',
'ERRNO_MESSAGES',
'DNS',
'Protocols',
'Sockets',
'timers',
'warnOnce',
'UNWIND_CACHE',
'readEmAsmArgsArray',
'readEmAsmArgs',
'runEmAsmFunction',
'handleException',
'freeTableIndexes',
'functionsInTableMap',
'setValue',
'getValue',
'PATH',
'PATH_FS',
'UTF8Decoder',
'UTF8ArrayToString',
'UTF8ToString',
'stringToUTF8Array',
'stringToUTF8',
'lengthBytesUTF8',
'UTF16Decoder',
'stringToUTF8OnStack',
'SYSCALLS',
'JSEvents',
'specialHTMLTargets',
'maybeCStringToJsString',
'findEventTarget',
'getBoundingClientRect',
'fillMouseEventData',
'registerMouseEventCallback',
'currentFullscreenStrategy',
'restoreOldWindowedStyle',
'ExitStatus',
'flush_NO_FILESYSTEM',
'dlopenMissingError',
'promiseMap',
'uncaughtExceptionCount',
'exceptionLast',
'exceptionCaught',
'Browser',
'wget',
'preloadPlugins',
'FS',
'MEMFS',
'TTY',
'PIPEFS',
'SOCKFS',
'tempFixedLengthArray',
'miniTempWebGLFloatBuffers',
'miniTempWebGLIntBuffers',
'GL',
'emscripten_webgl_power_preferences',
'AL',
'GLUT',
'EGL',
'GLEW',
'IDBStore',
'SDL',
'SDL_gfx',
'GLFW',
'allocateUTF8',
'allocateUTF8OnStack',
'EmAudio',
'EmAudioCounter',
'emscriptenRegisterAudioObject',
'emscriptenDestroyAudioContext',
'emscriptenGetAudioObject',
'_EmAudioDispatchProcessorCallback',
];
unexportedSymbols.forEach(unexportedRuntimeSymbol);
var calledRun;
dependenciesFulfilled = function runCaller() {
// If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
if (!calledRun) run();
if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
};
function 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 = _main;
args.unshift(thisProgram);
var argc = args.length;
var argv = stackAlloc((argc + 1) * 4);
var argv_ptr = argv >> 2;
args.forEach((arg) => {
HEAP32[argv_ptr++] = stringToUTF8OnStack(arg);
});
HEAP32[argv_ptr] = 0;
try {
var ret = entryFunction(argc, argv);
// if we're not running an evented main loop, it's time to exit
exitJS(ret, /* implicit = */ true);
return ret;
}
catch (e) {
return handleException(e);
}
}
function stackCheckInit() {
// This is normally called automatically during __wasm_call_ctors but need to
// get these values before even running any of the ctors so we call it redundantly
// here.
_emscripten_stack_init();
// TODO(sbc): Move writeStackCookie to native to to avoid this.
writeStackCookie();
}
function run(args = arguments_) {
if (runDependencies > 0) {
return;
}
stackCheckInit();
if (ENVIRONMENT_IS_WASM_WORKER) {
return initRuntime();
}
preRun();
// a preRun added a dependency, run will be called later
if (runDependencies > 0) {
return;
}
function doRun() {
// run may have just been called through dependencies being fulfilled just in this very frame,
// or while the async setStatus time below was happening
if (calledRun) return;
calledRun = true;
Module['calledRun'] = true;
if (ABORT) return;
initRuntime();
preMain();
if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
if (shouldRunNow) callMain(args);
postRun();
}
if (Module['setStatus']) {
Module['setStatus']('Running...');
setTimeout(function() {
setTimeout(function() {
Module['setStatus']('');
}, 1);
doRun();
}, 1);
} else
{
doRun();
}
checkStackCookie();
}
function checkUnflushedContent() {
// Compiler settings do not allow exiting the runtime, so flushing
// the streams is not possible. but in ASSERTIONS mode we check
// if there was something to flush, and if so tell the user they
// should request that the runtime be exitable.
// Normally we would not even include flush() at all, but in ASSERTIONS
// builds we do so just for this check, and here we see if there is any
// content to flush, that is, we check if there would have been
// something a non-ASSERTIONS build would have not seen.
// How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
// mode (which has its own special function for this; otherwise, all
// the code is inside libc)
var oldOut = out;
var oldErr = err;
var has = false;
out = err = (x) => {
has = true;
}
try { // it doesn't matter if it fails
flush_NO_FILESYSTEM();
} catch(e) {}
out = oldOut;
err = oldErr;
if (has) {
warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.');
warnOnce('(this may also be due to not including full filesystem support - try building with -sFORCE_FILESYSTEM)');
}
}
if (Module['preInit']) {
if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
while (Module['preInit'].length > 0) {
Module['preInit'].pop()();
}
}
// shouldRunNow refers to calling main(), not run().
var shouldRunNow = true;
if (Module['noInitialRun']) shouldRunNow = false;
run();
// end include: postamble.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment