From 1844310dcb642a5a2469a770c6e3cf856e00f8ee Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Tue, 13 Mar 2018 13:33:10 +0100 Subject: [PATCH 1/3] Add a demo on using WebAssembly with WebAudio and WebRTC Status: Not working yet. --- .../getusermedia/wasm-volume/.gitignore | 2 + src/content/getusermedia/wasm-volume/Makefile | 3 + .../getusermedia/wasm-volume/README.md | 14 + .../getusermedia/wasm-volume/index.html | 78 + .../wasm-volume/js/js-soundmeter.js | 60 + .../getusermedia/wasm-volume/js/main.js | 79 + .../wasm-volume/js/wasm-soundmeter-wrapper.js | 54 + .../wasm-volume/js/wasm-soundmeter.cc | 42 + .../wasm-volume/js/wasm-soundmeter.js | 4378 +++++++++++++++++ .../wasm-volume/js/wasm-soundmeter.wasm | Bin 0 -> 83590 bytes src/content/getusermedia/wasm-volume/setup.sh | 18 + 11 files changed, 4728 insertions(+) create mode 100644 src/content/getusermedia/wasm-volume/.gitignore create mode 100644 src/content/getusermedia/wasm-volume/Makefile create mode 100644 src/content/getusermedia/wasm-volume/README.md create mode 100644 src/content/getusermedia/wasm-volume/index.html create mode 100644 src/content/getusermedia/wasm-volume/js/js-soundmeter.js create mode 100644 src/content/getusermedia/wasm-volume/js/main.js create mode 100644 src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js create mode 100644 src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc create mode 100644 src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js create mode 100644 src/content/getusermedia/wasm-volume/js/wasm-soundmeter.wasm create mode 100755 src/content/getusermedia/wasm-volume/setup.sh diff --git a/src/content/getusermedia/wasm-volume/.gitignore b/src/content/getusermedia/wasm-volume/.gitignore new file mode 100644 index 000000000..c0f3c52d7 --- /dev/null +++ b/src/content/getusermedia/wasm-volume/.gitignore @@ -0,0 +1,2 @@ +emsdk +*~ diff --git a/src/content/getusermedia/wasm-volume/Makefile b/src/content/getusermedia/wasm-volume/Makefile new file mode 100644 index 000000000..dd126ef17 --- /dev/null +++ b/src/content/getusermedia/wasm-volume/Makefile @@ -0,0 +1,3 @@ +js/wasm-soundmeter.js: js/wasm-soundmeter.cc + # Produces soundmeter.js, soundmeter.wasm and soundmeter.html + cd js; emcc --bind wasm-soundmeter.cc -s WASM=1 -o wasm-soundmeter.html diff --git a/src/content/getusermedia/wasm-volume/README.md b/src/content/getusermedia/wasm-volume/README.md new file mode 100644 index 000000000..d58bf56f6 --- /dev/null +++ b/src/content/getusermedia/wasm-volume/README.md @@ -0,0 +1,14 @@ +Since this demo uses WebAssembly, the structure is a bit odd. + +The WebAssembly and emscripten-produced Javascript is checked in, +and there's a script to setup and compile the source, which will +download the emscripten toolchain and install its prerequisites +if they are not present. + +This toolchain will only run on Debian-derived Linux distros, but +the resulting WASM should run independent of platform. + +To setup: Run `setup.sh`, and then `source emsdk/emsdk_env.sh` + +To compile: Run `make` + diff --git a/src/content/getusermedia/wasm-volume/index.html b/src/content/getusermedia/wasm-volume/index.html new file mode 100644 index 000000000..4cb08a206 --- /dev/null +++ b/src/content/getusermedia/wasm-volume/index.html @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + WebAssembly Audio stream volume + + + + + + + + + + +
+ +

WebRTC samples WebAssembly Audio stream volume

+ +

Measure the volume of a local media stream using WebAudio and WebAssembly.

+ +
+
+
Instant:
+ +
+
+
+
Slow:
+ +
+
+
+
Wasm:
+ +
+
+
+ +

The 'instant' volume changes approximately every 50ms; the 'slow' volume approximates the average volume over about a second. This value is computed in Javascript.

+

The 'wasm' meter computes its value using WebAssembly.

+

Note that you will not hear your own voice; use the local audio rendering demo for that.

+

The audioContext, stream and soundMeter variables are in global scope, so you can inspect them from the console.

+ + View source on GitHub + +
+ + + + + + + + + + + + + diff --git a/src/content/getusermedia/wasm-volume/js/js-soundmeter.js b/src/content/getusermedia/wasm-volume/js/js-soundmeter.js new file mode 100644 index 000000000..6ab1ed12e --- /dev/null +++ b/src/content/getusermedia/wasm-volume/js/js-soundmeter.js @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + +'use strict'; + +// Meter class that generates a number correlated to audio volume. +// The meter class itself displays nothing, but it makes the +// instantaneous and time-decaying volumes available for inspection. +// It also reports on the fraction of samples that were at or near +// the top of the measurement range. +function SoundMeter(context) { + this.context = context; + this.instant = 0.0; + this.slow = 0.0; + this.clip = 0.0; + this.script = context.createScriptProcessor(2048, 1, 1); + var that = this; + this.script.onaudioprocess = function(event) { + var input = event.inputBuffer.getChannelData(0); + var i; + var sum = 0.0; + var clipcount = 0; + for (i = 0; i < input.length; ++i) { + sum += input[i] * input[i]; + if (Math.abs(input[i]) > 0.99) { + clipcount += 1; + } + } + that.instant = Math.sqrt(sum / input.length); + that.slow = 0.95 * that.slow + 0.05 * that.instant; + that.clip = clipcount / input.length; + }; +} + +SoundMeter.prototype.connectToSource = function(stream, callback) { + console.log('SoundMeter connecting'); + try { + this.mic = this.context.createMediaStreamSource(stream); + this.mic.connect(this.script); + // necessary to make sample run, but should not be. + this.script.connect(this.context.destination); + if (typeof callback !== 'undefined') { + callback(null); + } + } catch (e) { + console.error(e); + if (typeof callback !== 'undefined') { + callback(e); + } + } +}; +SoundMeter.prototype.stop = function() { + this.mic.disconnect(); + this.script.disconnect(); +}; diff --git a/src/content/getusermedia/wasm-volume/js/main.js b/src/content/getusermedia/wasm-volume/js/main.js new file mode 100644 index 000000000..bc85d6e26 --- /dev/null +++ b/src/content/getusermedia/wasm-volume/js/main.js @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + +/* global AudioContext, SoundMeter */ + +'use strict'; + +// For WASM +var Module = { + locateFile: function(name) { + return 'js/' + name; + }, + onRuntimeInitialized: function() { + navigator.mediaDevices.getUserMedia(constraints). + then(handleSuccess).catch(handleError); + + }, +}; + +var instantMeter = document.querySelector('#instant meter'); +var slowMeter = document.querySelector('#slow meter'); +var clipMeter = document.querySelector('#clip meter'); + +var instantValueDisplay = document.querySelector('#instant .value'); +var slowValueDisplay = document.querySelector('#slow .value'); +var clipValueDisplay = document.querySelector('#clip .value'); + +try { + window.AudioContext = window.AudioContext || window.webkitAudioContext; + window.audioContext = new AudioContext(); +} catch (e) { + alert('Web Audio API not supported.'); +} + +// Put variables in global scope to make them available to the browser console. +var constraints = window.constraints = { + audio: true, + video: false +}; + +function handleSuccess(stream) { + // Put variables in global scope to make them available to the + // browser console. + window.stream = stream; + var soundMeter = window.soundMeter = new SoundMeter(window.audioContext); + soundMeter.connectToSource(stream, function(e) { + if (e) { + alert(e); + return; + } + setInterval(function() { + instantMeter.value = instantValueDisplay.innerText = + soundMeter.instant.toFixed(2); + slowMeter.value = slowValueDisplay.innerText = + soundMeter.slow.toFixed(2); + }, 200); + }); + var wasmMeter = window.wasmMeter = new WasmSoundMeter(window.audioContext); + wasmMeter.connectToSource(stream, function(e) { + if (e) { + alert(e); + return; + } + setInterval(function() { + wasmMeter.value = wasmValueDisplay.innerText = + wasmMeter.instant; + }, 200); + }); +} + +function handleError(error) { + console.log('navigator.getUserMedia error: ', error); +} + diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js new file mode 100644 index 000000000..15605a3a3 --- /dev/null +++ b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + +'use strict'; + +// Meter class that generates a number correlated to audio volume. +// The meter class itself displays nothing, but it makes the +// instantaneous and time-decaying volumes available for inspection. +// It also reports on the fraction of samples that were at or near +// the top of the measurement range. +function WasmSoundMeter(context) { + this.context = context; + this.instant = 0.0; + this.slow = 0.0; + this.clip = 0.0; + this.script = context.createScriptProcessor(2048, 1, 1); + this.measurer = new Module.SoundMeter(); + var that = this; + this.script.onaudioprocess = function(event) { + var input = event.inputBuffer.getChannelData(0); + // Waiting for how to pass Float32Array to JS + // that.measurer.load_data(input); + that.instant = that.measurer.get_fast_volume(); + that.slow = that.measurer.get_slow_volume(); + }; +} + +WasmSoundMeter.prototype.connectToSource = function(stream, callback) { + console.log('WASM SoundMeter connecting'); + try { + this.mic = this.context.createMediaStreamSource(stream); + this.mic.connect(this.script); + // necessary to make sample run, but should not be. + this.script.connect(this.context.destination); + if (typeof callback !== 'undefined') { + callback(null); + } + } catch (e) { + console.error(e); + if (typeof callback !== 'undefined') { + callback(e); + } + } +}; + +WasmSoundMeter.prototype.stop = function() { + this.mic.disconnect(); + this.script.disconnect(); +}; diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc new file mode 100644 index 000000000..fa8305aea --- /dev/null +++ b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc @@ -0,0 +1,42 @@ +// +// Demonstration file for use of C++ objects across Emscripten +// into WebAssembly. +// +// It defines a "buffer" class with an 1-kbyte buffer, and a +// "sum" function that takes a buffer as argument. +// We'll then call this from Javascript. + +// This uses the "Embind" method of defining the interface. +// http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#embind + +#include + +class SoundMeter { + public: + SoundMeter() {}; + void load_data(std::vector& data); + std::vector data() { return data_; } // pass-by-value + float get_fast_volume() { return decay_short_; } + float get_slow_volume() { return decay_long_; } + private: + float decay_long_; + float decay_short_; + std::vector data_; +}; + +void SoundMeter::load_data(std::vector& data) { + +} + +EMSCRIPTEN_BINDINGS(random_string) { + emscripten::class_("SoundMeter") + .constructor() + .function("load_data", &SoundMeter::load_data) + .function("data", &SoundMeter::data) + .function("get_fast_volume", &SoundMeter::get_fast_volume) + .function("get_slow_volume", &SoundMeter::get_slow_volume); +} + +EMSCRIPTEN_BINDINGS(stl_wrappers) { + emscripten::register_vector("VectorFloat"); +} diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js new file mode 100644 index 000000000..9c89bc800 --- /dev/null +++ b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js @@ -0,0 +1,4378 @@ +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(Module) { ..generated code.. } +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +var Module = typeof 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) +// {{PRE_JSES}} + +// 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 = {}; +var key; +for (key in Module) { + if (Module.hasOwnProperty(key)) { + moduleOverrides[key] = Module[key]; + } +} + +Module['arguments'] = []; +Module['thisProgram'] = './this.program'; +Module['quit'] = function(status, toThrow) { + throw toThrow; +}; +Module['preRun'] = []; +Module['postRun'] = []; + +// The environment setup code below is customized to use Module. +// *** Environment setup code *** +var ENVIRONMENT_IS_WEB = false; +var ENVIRONMENT_IS_WORKER = false; +var ENVIRONMENT_IS_NODE = false; +var ENVIRONMENT_IS_SHELL = false; + +// Three configurations we can be running in: +// 1) We could be the application main() thread running in the main JS UI thread. (ENVIRONMENT_IS_WORKER == false and ENVIRONMENT_IS_PTHREAD == false) +// 2) We could be the application main() thread proxied to worker. (with Emscripten -s PROXY_TO_WORKER=1) (ENVIRONMENT_IS_WORKER == true, ENVIRONMENT_IS_PTHREAD == false) +// 3) We could be an application pthread running in a worker. (ENVIRONMENT_IS_WORKER == true and ENVIRONMENT_IS_PTHREAD == true) + +if (Module['ENVIRONMENT']) { + if (Module['ENVIRONMENT'] === 'WEB') { + ENVIRONMENT_IS_WEB = true; + } else if (Module['ENVIRONMENT'] === 'WORKER') { + ENVIRONMENT_IS_WORKER = true; + } else if (Module['ENVIRONMENT'] === 'NODE') { + ENVIRONMENT_IS_NODE = true; + } else if (Module['ENVIRONMENT'] === 'SHELL') { + ENVIRONMENT_IS_SHELL = true; + } else { + throw new Error('Module[\'ENVIRONMENT\'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.'); + } +} else { + ENVIRONMENT_IS_WEB = typeof window === 'object'; + ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; + ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function' && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER; + ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; +} + + +if (ENVIRONMENT_IS_NODE) { + // Expose functionality in the same simple way that the shells work + // Note that we pollute the global namespace here, otherwise we break in node + var nodeFS; + var nodePath; + + Module['read'] = function shell_read(filename, binary) { + var ret; + if (!nodeFS) nodeFS = require('fs'); + if (!nodePath) nodePath = require('path'); + filename = nodePath['normalize'](filename); + ret = nodeFS['readFileSync'](filename); + return binary ? ret : ret.toString(); + }; + + Module['readBinary'] = function readBinary(filename) { + var ret = Module['read'](filename, true); + if (!ret.buffer) { + ret = new Uint8Array(ret); + } + assert(ret.buffer); + return ret; + }; + + if (process['argv'].length > 1) { + Module['thisProgram'] = process['argv'][1].replace(/\\/g, '/'); + } + + Module['arguments'] = process['argv'].slice(2); + + if (typeof module !== 'undefined') { + module['exports'] = Module; + } + + process['on']('uncaughtException', function(ex) { + // suppress ExitStatus exceptions from showing an error + if (!(ex instanceof ExitStatus)) { + throw ex; + } + }); + // Currently node will swallow unhandled rejections, but this behavior is + // deprecated, and in the future it will exit with error status. + process['on']('unhandledRejection', function(reason, p) { + Module['printErr']('node.js exiting due to unhandled promise rejection'); + process['exit'](1); + }); + + Module['inspect'] = function () { return '[Emscripten Module object]'; }; +} +else if (ENVIRONMENT_IS_SHELL) { + if (typeof read != 'undefined') { + Module['read'] = function shell_read(f) { + return read(f); + }; + } + + Module['readBinary'] = function readBinary(f) { + var data; + if (typeof readbuffer === 'function') { + return new Uint8Array(readbuffer(f)); + } + data = read(f, 'binary'); + assert(typeof data === 'object'); + return data; + }; + + if (typeof scriptArgs != 'undefined') { + Module['arguments'] = scriptArgs; + } else if (typeof arguments != 'undefined') { + Module['arguments'] = arguments; + } + + if (typeof quit === 'function') { + Module['quit'] = function(status, toThrow) { + quit(status); + } + } +} +else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + Module['read'] = function shell_read(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.send(null); + return xhr.responseText; + }; + + if (ENVIRONMENT_IS_WORKER) { + Module['readBinary'] = function readBinary(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.responseType = 'arraybuffer'; + xhr.send(null); + return new Uint8Array(xhr.response); + }; + } + + Module['readAsync'] = function readAsync(url, onload, onerror) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'arraybuffer'; + xhr.onload = function 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); + }; + + if (typeof arguments != 'undefined') { + Module['arguments'] = arguments; + } + + Module['setWindowTitle'] = function(title) { document.title = title }; +} +else { + // Unreachable because SHELL is dependent on the others + throw new Error('unknown runtime environment'); +} + +// console.log is checked first, as 'print' on the web will open a print dialogue +// printErr is preferable to console.warn (works better in shells) +// bind(console) is necessary to fix IE/Edge closed dev tools panel behavior. +Module['print'] = typeof console !== 'undefined' ? console.log.bind(console) : (typeof print !== 'undefined' ? print : null); +Module['printErr'] = typeof printErr !== 'undefined' ? printErr : ((typeof console !== 'undefined' && console.warn.bind(console)) || Module['print']); + +// *** Environment setup code *** + +// Closure helpers +Module.print = Module['print']; +Module.printErr = Module['printErr']; + +// Merge back in the overrides +for (key in moduleOverrides) { + if (moduleOverrides.hasOwnProperty(key)) { + Module[key] = moduleOverrides[key]; + } +} +// 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 = undefined; + + + +// {{PREAMBLE_ADDITIONS}} + +var STACK_ALIGN = 16; + +// stack management, and other functionality that is provided by the compiled code, +// should not be used before it is ready +stackSave = stackRestore = stackAlloc = setTempRet0 = getTempRet0 = function() { + abort('cannot use the stack before compiled code is ready to run, and has provided stack access'); +}; + +function staticAlloc(size) { + assert(!staticSealed); + var ret = STATICTOP; + STATICTOP = (STATICTOP + size + 15) & -16; + return ret; +} + +function dynamicAlloc(size) { + assert(DYNAMICTOP_PTR); + var ret = HEAP32[DYNAMICTOP_PTR>>2]; + var end = (ret + size + 15) & -16; + HEAP32[DYNAMICTOP_PTR>>2] = end; + if (end >= TOTAL_MEMORY) { + var success = enlargeMemory(); + if (!success) { + HEAP32[DYNAMICTOP_PTR>>2] = ret; + return 0; + } + } + return ret; +} + +function alignMemory(size, factor) { + if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default + var ret = size = Math.ceil(size / factor) * factor; + return ret; +} + +function getNativeTypeSize(type) { + switch (type) { + case 'i1': case 'i8': return 1; + case 'i16': return 2; + case 'i32': return 4; + case 'i64': return 8; + case 'float': return 4; + case 'double': return 8; + default: { + if (type[type.length-1] === '*') { + return 4; // A pointer + } else if (type[0] === 'i') { + var bits = parseInt(type.substr(1)); + assert(bits % 8 === 0); + return bits / 8; + } else { + return 0; + } + } + } +} + +function warnOnce(text) { + if (!warnOnce.shown) warnOnce.shown = {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + Module.printErr(text); + } +} + + + +var jsCallStartIndex = 1; +var functionPointers = new Array(0); + +// 'sig' parameter is only used on LLVM wasm backend +function addFunction(func, sig) { + if (typeof sig === 'undefined') { + Module.printErr('Warning: addFunction: Provide a wasm function signature ' + + 'string as a second argument'); + } + var base = 0; + for (var i = base; i < base + 0; i++) { + if (!functionPointers[i]) { + functionPointers[i] = func; + return jsCallStartIndex + i; + } + } + throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.'; +} + +function removeFunction(index) { + functionPointers[index-jsCallStartIndex] = null; +} + +var funcWrappers = {}; + +function getFuncWrapper(func, sig) { + if (!func) return; // on null pointer, return undefined + assert(sig); + if (!funcWrappers[sig]) { + funcWrappers[sig] = {}; + } + var sigCache = funcWrappers[sig]; + if (!sigCache[func]) { + // optimize away arguments usage in common cases + if (sig.length === 1) { + sigCache[func] = function dynCall_wrapper() { + return dynCall(sig, func); + }; + } else if (sig.length === 2) { + sigCache[func] = function dynCall_wrapper(arg) { + return dynCall(sig, func, [arg]); + }; + } else { + // general case + sigCache[func] = function dynCall_wrapper() { + return dynCall(sig, func, Array.prototype.slice.call(arguments)); + }; + } + } + return sigCache[func]; +} + + +function makeBigInt(low, high, unsigned) { + return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0)); +} + +function dynCall(sig, ptr, args) { + if (args && args.length) { + assert(args.length == sig.length-1); + assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); + return Module['dynCall_' + sig].apply(null, [ptr].concat(args)); + } else { + assert(sig.length == 1); + assert(('dynCall_' + sig) in Module, 'bad function pointer type - no table for sig \'' + sig + '\''); + return Module['dynCall_' + sig].call(null, ptr); + } +} + + +function getCompilerSetting(name) { + throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work'; +} + +var Runtime = { + // FIXME backwards compatibility layer for ports. Support some Runtime.* + // for now, fix it there, then remove it from here. That way we + // can minimize any period of breakage. + dynCall: dynCall, // for SDL2 port + // helpful errors + getTempRet0: function() { abort('getTempRet0() is now a top-level function, after removing the Runtime object. Remove "Runtime."') }, + staticAlloc: function() { abort('staticAlloc() is now a top-level function, after removing the Runtime object. Remove "Runtime."') }, + stackAlloc: function() { abort('stackAlloc() is now a top-level function, after removing the Runtime object. Remove "Runtime."') }, +}; + +// The address globals begin at. Very low in memory, for code size and optimization opportunities. +// Above 0 is static memory, starting with globals. +// Then the stack. +// Then 'dynamic' memory for sbrk. +var GLOBAL_BASE = 1024; + + + +// === 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 + + + +//======================================== +// Runtime essentials +//======================================== + +var ABORT = 0; // whether we are quitting the application. no code should run after this. set in exit() and abort() +var EXITSTATUS = 0; + +/** @type {function(*, string=)} */ +function assert(condition, text) { + if (!condition) { + abort('Assertion failed: ' + text); + } +} + +var globalScope = this; + +// 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; +} + +var JSfuncs = { + // Helpers for cwrap -- it can't refer to Runtime directly because it might + // be renamed by closure, instead it calls JSfuncs['stackSave'].body to find + // out what the minified function name is. + 'stackSave': function() { + stackSave() + }, + 'stackRestore': function() { + stackRestore() + }, + // type conversion from js to c + 'arrayToC' : function(arr) { + var ret = stackAlloc(arr.length); + writeArrayToMemory(arr, ret); + return ret; + }, + 'stringToC' : 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; + } +}; +// For fast lookup of conversion functions +var toC = {'string' : JSfuncs['stringToC'], 'array' : JSfuncs['arrayToC']}; + +// C calling interface. +function ccall (ident, returnType, argTypes, args, opts) { + 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); + if (returnType === 'string') ret = Pointer_stringify(ret); + if (stack !== 0) { + stackRestore(stack); + } + return ret; +} + +function cwrap (ident, returnType, argTypes) { + argTypes = argTypes || []; + var cfunc = getCFunc(ident); + // When the function takes numbers and returns a number, we can just return + // the original function + var numericArgs = argTypes.every(function(type){ return type === 'number'}); + var numericRet = returnType !== 'string'; + if (numericRet && numericArgs) { + return cfunc; + } + return function() { + return ccall(ident, returnType, argTypes, arguments); + } +} + +/** @type {function(number, number, string, boolean=)} */ +function setValue(ptr, value, type, noSafe) { + type = type || 'i8'; + if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit + 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); + } +} + +/** @type {function(number, string, boolean=)} */ +function getValue(ptr, type, noSafe) { + type = type || 'i8'; + if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit + 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)]; + default: abort('invalid type for getValue: ' + type); + } + return null; +} + +var ALLOC_NORMAL = 0; // Tries to use _malloc() +var ALLOC_STACK = 1; // Lives for the duration of the current function call +var ALLOC_STATIC = 2; // Cannot be freed +var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk +var ALLOC_NONE = 4; // Do not allocate + +// allocate(): This is for internal use. You can use it yourself as well, but the interface +// is a little tricky (see docs right below). The reason is that it is optimized +// for multiple syntaxes to save space in generated code. So you should +// normally not use allocate(), and instead allocate memory using _malloc(), +// initialize it with setValue(), and so forth. +// @slab: An array of data, or a number. If a number, then the size of the block to allocate, +// in *bytes* (note that this is sometimes confusing: the next parameter does not +// affect this!) +// @types: Either an array of types, one for each byte (or 0 if no type at that position), +// or a single type which is used for the entire block. This only matters if there +// is initial data - if @slab is a number, then this does not matter at all and is +// ignored. +// @allocator: How to allocate memory, see ALLOC_* +/** @type {function((TypedArray|Array|number), string, number, number=)} */ +function allocate(slab, types, allocator, ptr) { + var zeroinit, size; + if (typeof slab === 'number') { + zeroinit = true; + size = slab; + } else { + zeroinit = false; + size = slab.length; + } + + var singleType = typeof types === 'string' ? types : null; + + var ret; + if (allocator == ALLOC_NONE) { + ret = ptr; + } else { + ret = [typeof _malloc === 'function' ? _malloc : staticAlloc, stackAlloc, staticAlloc, dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length)); + } + + if (zeroinit) { + var stop; + ptr = ret; + assert((ret & 3) == 0); + stop = ret + (size & ~3); + for (; ptr < stop; ptr += 4) { + HEAP32[((ptr)>>2)]=0; + } + stop = ret + size; + while (ptr < stop) { + HEAP8[((ptr++)>>0)]=0; + } + return ret; + } + + if (singleType === 'i8') { + if (slab.subarray || slab.slice) { + HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret); + } else { + HEAPU8.set(new Uint8Array(slab), ret); + } + return ret; + } + + var i = 0, type, typeSize, previousType; + while (i < size) { + var curr = slab[i]; + + type = singleType || types[i]; + if (type === 0) { + i++; + continue; + } + assert(type, 'Must know what type to store in allocate!'); + + if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later + + setValue(ret+i, curr, type); + + // no need to look up size unless type changes, so cache it + if (previousType !== type) { + typeSize = getNativeTypeSize(type); + previousType = type; + } + i += typeSize; + } + + return ret; +} + +// Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready +function getMemory(size) { + if (!staticSealed) return staticAlloc(size); + if (!runtimeInitialized) return dynamicAlloc(size); + return _malloc(size); +} + +/** @type {function(number, number=)} */ +function Pointer_stringify(ptr, length) { + if (length === 0 || !ptr) return ''; + // TODO: use TextDecoder + // Find the length, and check for UTF while doing so + var hasUtf = 0; + var t; + var i = 0; + while (1) { + assert(ptr + i < TOTAL_MEMORY); + t = HEAPU8[(((ptr)+(i))>>0)]; + hasUtf |= t; + if (t == 0 && !length) break; + i++; + if (length && i == length) break; + } + if (!length) length = i; + + var ret = ''; + + if (hasUtf < 128) { + var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack + var curr; + while (length > 0) { + curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK))); + ret = ret ? ret + curr : curr; + ptr += MAX_CHUNK; + length -= MAX_CHUNK; + } + return ret; + } + return UTF8ToString(ptr); +} + +// 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 = HEAP8[((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 UTF8-encoded string in the given array that contains uint8 values, returns +// a copy of that string as a Javascript String object. + +var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined; +function UTF8ArrayToString(u8Array, idx) { + 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. + while (u8Array[endPtr]) ++endPtr; + + if (endPtr - idx > 16 && u8Array.subarray && UTF8Decoder) { + return UTF8Decoder.decode(u8Array.subarray(idx, endPtr)); + } else { + var u0, u1, u2, u3, u4, u5; + + var str = ''; + while (1) { + // 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 + u0 = u8Array[idx++]; + if (!u0) return str; + if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } + u1 = u8Array[idx++] & 63; + if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } + u2 = u8Array[idx++] & 63; + if ((u0 & 0xF0) == 0xE0) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + u3 = u8Array[idx++] & 63; + if ((u0 & 0xF8) == 0xF0) { + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | u3; + } else { + u4 = u8Array[idx++] & 63; + if ((u0 & 0xFC) == 0xF8) { + u0 = ((u0 & 3) << 24) | (u1 << 18) | (u2 << 12) | (u3 << 6) | u4; + } else { + u5 = u8Array[idx++] & 63; + u0 = ((u0 & 1) << 30) | (u1 << 24) | (u2 << 18) | (u3 << 12) | (u4 << 6) | u5; + } + } + } + if (u0 < 0x10000) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } + } + } +} + +// 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. + +function UTF8ToString(ptr) { + return UTF8ArrayToString(HEAPU8,ptr); +} + +// 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. +// outU8Array: 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, outU8Array, 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) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + if (u <= 0x7F) { + if (outIdx >= endIdx) break; + outU8Array[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) break; + outU8Array[outIdx++] = 0xC0 | (u >> 6); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) break; + outU8Array[outIdx++] = 0xE0 | (u >> 12); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0x1FFFFF) { + if (outIdx + 3 >= endIdx) break; + outU8Array[outIdx++] = 0xF0 | (u >> 18); + outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0x3FFFFFF) { + if (outIdx + 4 >= endIdx) break; + outU8Array[outIdx++] = 0xF8 | (u >> 24); + outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 5 >= endIdx) break; + outU8Array[outIdx++] = 0xFC | (u >> 30); + outU8Array[outIdx++] = 0x80 | ((u >> 24) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63); + outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63); + outU8Array[outIdx++] = 0x80 | (u & 63); + } + } + // Null-terminate the pointer to the buffer. + outU8Array[outIdx] = 0; + return outIdx - startIdx; +} + +// 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 if (u <= 0x1FFFFF) { + len += 4; + } else if (u <= 0x3FFFFFF) { + len += 5; + } else { + len += 6; + } + } + return len; +} + +// 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) { + 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; + while (HEAP16[idx]) ++idx; + endPtr = idx << 1; + + if (endPtr - ptr > 32 && UTF16Decoder) { + return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); + } else { + var i = 0; + + var str = ''; + while (1) { + var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; + if (codeUnit == 0) return str; + ++i; + // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. + str += String.fromCharCode(codeUnit); + } + } +} + +// 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) { + assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); + var i = 0; + + var str = ''; + while (1) { + var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; + if (utf32 == 0) + return str; + ++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); + } + } +} + +// 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; +} + +function demangle(func) { + warnOnce('warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling'); + return func; +} + +function demangleAll(text) { + var regex = + /__Z[\w\d_]+/g; + return text.replace(regex, + function(x) { + var y = demangle(x); + return x === y ? x : (x + ' [' + y + ']'); + }); +} + +function jsStackTrace() { + var err = new Error(); + if (!err.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(0); + } catch(e) { + err = e; + } + if (!err.stack) { + return '(no stack trace available)'; + } + } + return err.stack.toString(); +} + +function stackTrace() { + var js = jsStackTrace(); + if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); + return demangleAll(js); +} + +// Memory management + +var PAGE_SIZE = 16384; +var WASM_PAGE_SIZE = 65536; +var ASMJS_PAGE_SIZE = 16777216; +var MIN_TOTAL_MEMORY = 16777216; + +function alignUp(x, multiple) { + if (x % multiple > 0) { + x += multiple - (x % multiple); + } + return x; +} + +var HEAP, +/** @type {ArrayBuffer} */ + buffer, +/** @type {Int8Array} */ + HEAP8, +/** @type {Uint8Array} */ + HEAPU8, +/** @type {Int16Array} */ + HEAP16, +/** @type {Uint16Array} */ + HEAPU16, +/** @type {Int32Array} */ + HEAP32, +/** @type {Uint32Array} */ + HEAPU32, +/** @type {Float32Array} */ + HEAPF32, +/** @type {Float64Array} */ + HEAPF64; + +function updateGlobalBuffer(buf) { + Module['buffer'] = buffer = buf; +} + +function updateGlobalBufferViews() { + Module['HEAP8'] = HEAP8 = new Int8Array(buffer); + Module['HEAP16'] = HEAP16 = new Int16Array(buffer); + Module['HEAP32'] = HEAP32 = new Int32Array(buffer); + Module['HEAPU8'] = HEAPU8 = new Uint8Array(buffer); + Module['HEAPU16'] = HEAPU16 = new Uint16Array(buffer); + Module['HEAPU32'] = HEAPU32 = new Uint32Array(buffer); + Module['HEAPF32'] = HEAPF32 = new Float32Array(buffer); + Module['HEAPF64'] = HEAPF64 = new Float64Array(buffer); +} + +var STATIC_BASE, STATICTOP, staticSealed; // static area +var STACK_BASE, STACKTOP, STACK_MAX; // stack area +var DYNAMIC_BASE, DYNAMICTOP_PTR; // dynamic area handled by sbrk + + STATIC_BASE = STATICTOP = STACK_BASE = STACKTOP = STACK_MAX = DYNAMIC_BASE = DYNAMICTOP_PTR = 0; + staticSealed = false; + + +// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. +function writeStackCookie() { + assert((STACK_MAX & 3) == 0); + HEAPU32[(STACK_MAX >> 2)-1] = 0x02135467; + HEAPU32[(STACK_MAX >> 2)-2] = 0x89BACDFE; +} + +function checkStackCookie() { + if (HEAPU32[(STACK_MAX >> 2)-1] != 0x02135467 || HEAPU32[(STACK_MAX >> 2)-2] != 0x89BACDFE) { + abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x02135467, but received 0x' + HEAPU32[(STACK_MAX >> 2)-2].toString(16) + ' ' + HEAPU32[(STACK_MAX >> 2)-1].toString(16)); + } + // Also test the global address 0 for integrity. This check is not compatible with SAFE_SPLIT_MEMORY though, since that mode already tests all address 0 accesses on its own. + if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) throw 'Runtime error: The application has corrupted its heap memory area (address zero)!'; +} + +function abortStackOverflow(allocSize) { + abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (STACK_MAX - stackSave() + allocSize) + ' bytes available!'); +} + +function abortOnCannotGrowMemory() { + abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 '); +} + + +function enlargeMemory() { + abortOnCannotGrowMemory(); +} + + +var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880; +var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 16777216; +if (TOTAL_MEMORY < TOTAL_STACK) Module.printErr('TOTAL_MEMORY should be larger than TOTAL_STACK, was ' + TOTAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')'); + +// Initialize the runtime's memory +// 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'); + + + +// Use a provided buffer, if there is one, or else allocate a new one +if (Module['buffer']) { + buffer = Module['buffer']; + assert(buffer.byteLength === TOTAL_MEMORY, 'provided buffer should be ' + TOTAL_MEMORY + ' bytes, but it is ' + buffer.byteLength); +} else { + // Use a WebAssembly memory where available + if (typeof WebAssembly === 'object' && typeof WebAssembly.Memory === 'function') { + assert(TOTAL_MEMORY % WASM_PAGE_SIZE === 0); + Module['wasmMemory'] = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE, 'maximum': TOTAL_MEMORY / WASM_PAGE_SIZE }); + buffer = Module['wasmMemory'].buffer; + } else + { + buffer = new ArrayBuffer(TOTAL_MEMORY); + } + assert(buffer.byteLength === TOTAL_MEMORY); + Module['buffer'] = buffer; +} +updateGlobalBufferViews(); + + +function getTotalMemory() { + return TOTAL_MEMORY; +} + +// Endianness check (note: assumes compiler arch was little-endian) + HEAP32[0] = 0x63736d65; /* 'emsc' */ +HEAP16[1] = 0x6373; +if (HEAPU8[2] !== 0x73 || HEAPU8[3] !== 0x63) throw 'Runtime error: expected the system to be little-endian!'; + +function callRuntimeCallbacks(callbacks) { + while(callbacks.length > 0) { + var callback = callbacks.shift(); + if (typeof callback == 'function') { + callback(); + continue; + } + var func = callback.func; + if (typeof func === 'number') { + if (callback.arg === undefined) { + Module['dynCall_v'](func); + } else { + Module['dynCall_vi'](func, callback.arg); + } + } else { + func(callback.arg === undefined ? null : callback.arg); + } + } +} + +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 runtime has exited + +var runtimeInitialized = false; +var runtimeExited = false; + + +function preRun() { + // compatibility - merge in anything from Module['preRun'] at this time + if (Module['preRun']) { + if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; + while (Module['preRun'].length) { + addOnPreRun(Module['preRun'].shift()); + } + } + callRuntimeCallbacks(__ATPRERUN__); +} + +function ensureInitRuntime() { + checkStackCookie(); + if (runtimeInitialized) return; + runtimeInitialized = true; + callRuntimeCallbacks(__ATINIT__); +} + +function preMain() { + checkStackCookie(); + callRuntimeCallbacks(__ATMAIN__); +} + +function exitRuntime() { + checkStackCookie(); + callRuntimeCallbacks(__ATEXIT__); + runtimeExited = true; +} + +function postRun() { + checkStackCookie(); + // compatibility - merge in anything from Module['postRun'] at this time + 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) { + __ATEXIT__.unshift(cb); +} + +function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); +} + +// 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 */ +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); +} + +function writeAsciiToMemory(str, buffer, dontAddNull) { + for (var i = 0; i < str.length; ++i) { + assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff); + HEAP8[((buffer++)>>0)]=str.charCodeAt(i); + } + // Null-terminate the pointer to the HEAP. + if (!dontAddNull) HEAP8[((buffer)>>0)]=0; +} + +function unSign(value, bits, ignore) { + if (value >= 0) { + return value; + } + return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts + : Math.pow(2, bits) + value; +} +function reSign(value, bits, ignore) { + if (value <= 0) { + return value; + } + var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 + : Math.pow(2, bits-1); + if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that + // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors + // TODO: In i64 mode 1, resign the two parts separately and safely + value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts + } + return value; +} + +assert(Math['imul'] && Math['fround'] && Math['clz32'] && Math['trunc'], 'this is a legacy browser, build with LEGACY_VM_SUPPORT'); + +var Math_abs = Math.abs; +var Math_cos = Math.cos; +var Math_sin = Math.sin; +var Math_tan = Math.tan; +var Math_acos = Math.acos; +var Math_asin = Math.asin; +var Math_atan = Math.atan; +var Math_atan2 = Math.atan2; +var Math_exp = Math.exp; +var Math_log = Math.log; +var Math_sqrt = Math.sqrt; +var Math_ceil = Math.ceil; +var Math_floor = Math.floor; +var Math_pow = Math.pow; +var Math_imul = Math.imul; +var Math_fround = Math.fround; +var Math_round = Math.round; +var Math_min = Math.min; +var Math_max = Math.max; +var Math_clz32 = Math.clz32; +var Math_trunc = Math.trunc; + +// 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 +// PRE_RUN_ADDITIONS (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(); + } + return id; +} + +function addRunDependency(id) { + runDependencies++; + if (Module['monitorRunDependencies']) { + Module['monitorRunDependencies'](runDependencies); + } + if (id) { + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if (runDependencyWatcher === null && typeof setInterval !== 'undefined') { + // Check for missing dependencies every few seconds + runDependencyWatcher = setInterval(function() { + if (ABORT) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + return; + } + var shown = false; + for (var dep in runDependencyTracking) { + if (!shown) { + shown = true; + Module.printErr('still waiting on run dependencies:'); + } + Module.printErr('dependency: ' + dep); + } + if (shown) { + Module.printErr('(end of list)'); + } + }, 10000); + } + } else { + Module.printErr('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 { + Module.printErr('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 + } + } +} + +Module["preloadedImages"] = {}; // maps url to image data +Module["preloadedAudios"] = {}; // maps url to audio data + + + +var memoryInitializer = null; + + + +var /* show errors on likely calls to FS when it was not included */ 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 -s FORCE_FILESYSTEM=1'); + }, + 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() }, +}; +Module['FS_createDataFile'] = FS.createDataFile; +Module['FS_createPreloadedFile'] = FS.createPreloadedFile; + + + +// 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) { + return String.prototype.startsWith ? + filename.startsWith(dataURIPrefix) : + filename.indexOf(dataURIPrefix) === 0; +} + + + + +function integrateWasmJS() { + // wasm.js has several methods for creating the compiled code module here: + // * 'native-wasm' : use native WebAssembly support in the browser + // * 'interpret-s-expr': load s-expression code from a .wast and interpret + // * 'interpret-binary': load binary wasm and interpret + // * 'interpret-asm2wasm': load asm.js code, translate to wasm, and interpret + // * 'asmjs': no wasm, just load the asm.js code and use that (good for testing) + // The method is set at compile time (BINARYEN_METHOD) + // The method can be a comma-separated list, in which case, we will try the + // options one by one. Some of them can fail gracefully, and then we can try + // the next. + + // inputs + + var method = 'native-wasm'; + + var wasmTextFile = 'wasm-soundmeter.wast'; + var wasmBinaryFile = 'wasm-soundmeter.wasm'; + var asmjsCodeFile = 'wasm-soundmeter.temp.asm.js'; + + if (typeof Module['locateFile'] === 'function') { + if (!isDataURI(wasmTextFile)) { + wasmTextFile = Module['locateFile'](wasmTextFile); + } + if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = Module['locateFile'](wasmBinaryFile); + } + if (!isDataURI(asmjsCodeFile)) { + asmjsCodeFile = Module['locateFile'](asmjsCodeFile); + } + } + + // utilities + + var wasmPageSize = 64*1024; + + var info = { + 'global': null, + 'env': null, + 'asm2wasm': { // special asm2wasm imports + "f64-rem": function(x, y) { + return x % y; + }, + "debugger": function() { + debugger; + } + }, + 'parent': Module // Module inside wasm-js.cpp refers to wasm-js.cpp; this allows access to the outside program. + }; + + var exports = null; + + + function mergeMemory(newBuffer) { + // The wasm instance creates its memory. But static init code might have written to + // buffer already, including the mem init file, and we must copy it over in a proper merge. + // TODO: avoid this copy, by avoiding such static init writes + // TODO: in shorter term, just copy up to the last static init write + var oldBuffer = Module['buffer']; + if (newBuffer.byteLength < oldBuffer.byteLength) { + Module['printErr']('the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here'); + } + var oldView = new Int8Array(oldBuffer); + var newView = new Int8Array(newBuffer); + + + newView.set(oldView); + updateGlobalBuffer(newBuffer); + updateGlobalBufferViews(); + } + + function fixImports(imports) { + return imports; + } + + function getBinary() { + try { + if (Module['wasmBinary']) { + return new Uint8Array(Module['wasmBinary']); + } + if (Module['readBinary']) { + return Module['readBinary'](wasmBinaryFile); + } else { + throw "on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)"; + } + } + catch (err) { + abort(err); + } + } + + function getBinaryPromise() { + // if we don't have the binary yet, and have the Fetch api, use that + // in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web + if (!Module['wasmBinary'] && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function') { + return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { + if (!response['ok']) { + throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; + } + return response['arrayBuffer'](); + }).catch(function () { + return getBinary(); + }); + } + // Otherwise, getBinary should be able to get it synchronously + return new Promise(function(resolve, reject) { + resolve(getBinary()); + }); + } + + // do-method functions + + + function doNativeWasm(global, env, providedBuffer) { + if (typeof WebAssembly !== 'object') { + Module['printErr']('no native wasm support detected'); + return false; + } + // prepare memory import + if (!(Module['wasmMemory'] instanceof WebAssembly.Memory)) { + Module['printErr']('no native wasm Memory in use'); + return false; + } + env['memory'] = Module['wasmMemory']; + // Load the wasm module and create an instance of using native support in the JS engine. + info['global'] = { + 'NaN': NaN, + 'Infinity': Infinity + }; + info['global.Math'] = Math; + info['env'] = env; + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + function receiveInstance(instance, module) { + exports = instance.exports; + if (exports.memory) mergeMemory(exports.memory); + Module['asm'] = exports; + Module["usingWasm"] = true; + removeRunDependency('wasm-instantiate'); + } + addRunDependency('wasm-instantiate'); + + // 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. + if (Module['instantiateWasm']) { + try { + return Module['instantiateWasm'](info, receiveInstance); + } catch(e) { + Module['printErr']('Module.instantiateWasm callback failed with error: ' + e); + return false; + } + } + + // 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 receiveInstantiatedSource(output) { + // 'output' is a WebAssemblyInstantiatedSource 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(output['instance'], output['module']); + } + function instantiateArrayBuffer(receiver) { + getBinaryPromise().then(function(binary) { + return WebAssembly.instantiate(binary, info); + }).then(receiver).catch(function(reason) { + Module['printErr']('failed to asynchronously prepare wasm: ' + reason); + abort(reason); + }); + } + // Prefer streaming instantiation if available. + if (!Module['wasmBinary'] && + typeof WebAssembly.instantiateStreaming === 'function' && + !isDataURI(wasmBinaryFile) && + typeof fetch === 'function') { + WebAssembly.instantiateStreaming(fetch(wasmBinaryFile, { credentials: 'same-origin' }), info) + .then(receiveInstantiatedSource) + .catch(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. + Module['printErr']('wasm streaming compile failed: ' + reason); + Module['printErr']('falling back to ArrayBuffer instantiation'); + instantiateArrayBuffer(receiveInstantiatedSource); + }); + } else { + instantiateArrayBuffer(receiveInstantiatedSource); + } + return {}; // no exports yet; we'll fill them in later + } + + + // We may have a preloaded value in Module.asm, save it + Module['asmPreload'] = Module['asm']; + + // Memory growth integration code + + var asmjsReallocBuffer = Module['reallocBuffer']; + + var wasmReallocBuffer = function(size) { + var PAGE_MULTIPLE = Module["usingWasm"] ? WASM_PAGE_SIZE : ASMJS_PAGE_SIZE; // In wasm, heap size must be a multiple of 64KB. In asm.js, they need to be multiples of 16MB. + size = alignUp(size, PAGE_MULTIPLE); // round up to wasm page size + var old = Module['buffer']; + var oldSize = old.byteLength; + if (Module["usingWasm"]) { + // native wasm support + try { + var result = Module['wasmMemory'].grow((size - oldSize) / wasmPageSize); // .grow() takes a delta compared to the previous size + if (result !== (-1 | 0)) { + // success in native wasm memory growth, get the buffer from the memory + return Module['buffer'] = Module['wasmMemory'].buffer; + } else { + return null; + } + } catch(e) { + console.error('Module.reallocBuffer: Attempted to grow from ' + oldSize + ' bytes to ' + size + ' bytes, but got error: ' + e); + return null; + } + } + }; + + Module['reallocBuffer'] = function(size) { + if (finalMethod === 'asmjs') { + return asmjsReallocBuffer(size); + } else { + return wasmReallocBuffer(size); + } + }; + + // we may try more than one; this is the final one, that worked and we are using + var finalMethod = ''; + + // Provide an "asm.js function" for the application, called to "link" the asm.js module. We instantiate + // the wasm module at that time, and it receives imports and provides exports and so forth, the app + // doesn't need to care that it is wasm or olyfilled wasm or asm.js. + + Module['asm'] = function(global, env, providedBuffer) { + env = fixImports(env); + + // import table + if (!env['table']) { + var TABLE_SIZE = Module['wasmTableSize']; + if (TABLE_SIZE === undefined) TABLE_SIZE = 1024; // works in binaryen interpreter at least + var MAX_TABLE_SIZE = Module['wasmMaxTableSize']; + if (typeof WebAssembly === 'object' && typeof WebAssembly.Table === 'function') { + if (MAX_TABLE_SIZE !== undefined) { + env['table'] = new WebAssembly.Table({ 'initial': TABLE_SIZE, 'maximum': MAX_TABLE_SIZE, 'element': 'anyfunc' }); + } else { + env['table'] = new WebAssembly.Table({ 'initial': TABLE_SIZE, element: 'anyfunc' }); + } + } else { + env['table'] = new Array(TABLE_SIZE); // works in binaryen interpreter at least + } + Module['wasmTable'] = env['table']; + } + + if (!env['memoryBase']) { + env['memoryBase'] = Module['STATIC_BASE']; // tell the memory segments where to place themselves + } + if (!env['tableBase']) { + env['tableBase'] = 0; // table starts at 0 by default, in dynamic linking this will change + } + + // try the methods. each should return the exports if it succeeded + + var exports; + exports = doNativeWasm(global, env, providedBuffer); + + if (!exports) abort('no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods'); + + + return exports; + }; + + var methodHandler = Module['asm']; // note our method handler, as we may modify Module['asm'] later +} + +integrateWasmJS(); + +// === Body === + +var ASM_CONSTS = []; + + + + +STATIC_BASE = GLOBAL_BASE; + +STATICTOP = STATIC_BASE + 9152; +/* global initializers */ __ATINIT__.push({ func: function() { __GLOBAL__sub_I_wasm_soundmeter_cc() } }, { func: function() { __GLOBAL__sub_I_bind_cpp() } }); + + + + + + + +var STATIC_BUMP = 9152; +Module["STATIC_BASE"] = STATIC_BASE; +Module["STATIC_BUMP"] = STATIC_BUMP; + +/* no memory initializer */ +var tempDoublePtr = STATICTOP; STATICTOP += 16; + +assert(tempDoublePtr % 8 == 0); + +function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much + + HEAP8[tempDoublePtr] = HEAP8[ptr]; + + HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; + + HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; + + HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; + +} + +function copyTempDouble(ptr) { + + HEAP8[tempDoublePtr] = HEAP8[ptr]; + + HEAP8[tempDoublePtr+1] = HEAP8[ptr+1]; + + HEAP8[tempDoublePtr+2] = HEAP8[ptr+2]; + + HEAP8[tempDoublePtr+3] = HEAP8[ptr+3]; + + HEAP8[tempDoublePtr+4] = HEAP8[ptr+4]; + + HEAP8[tempDoublePtr+5] = HEAP8[ptr+5]; + + HEAP8[tempDoublePtr+6] = HEAP8[ptr+6]; + + HEAP8[tempDoublePtr+7] = HEAP8[ptr+7]; + +} + +// {{PRE_LIBRARY}} + + + function ___cxa_allocate_exception(size) { + return _malloc(size); + } + + + function __ZSt18uncaught_exceptionv() { // std::uncaught_exception() + return !!__ZSt18uncaught_exceptionv.uncaught_exception; + } + + var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:function (adjusted) { + if (!adjusted || EXCEPTIONS.infos[adjusted]) return adjusted; + for (var ptr in EXCEPTIONS.infos) { + var info = EXCEPTIONS.infos[ptr]; + if (info.adjusted === adjusted) { + return ptr; + } + } + return adjusted; + },addRef:function (ptr) { + if (!ptr) return; + var info = EXCEPTIONS.infos[ptr]; + info.refcount++; + },decRef:function (ptr) { + if (!ptr) return; + var info = EXCEPTIONS.infos[ptr]; + assert(info.refcount > 0); + info.refcount--; + // A rethrown exception can reach refcount 0; it must not be discarded + // Its next handler will clear the rethrown flag and addRef it, prior to + // final decRef and destruction here + if (info.refcount === 0 && !info.rethrown) { + if (info.destructor) { + Module['dynCall_vi'](info.destructor, ptr); + } + delete EXCEPTIONS.infos[ptr]; + ___cxa_free_exception(ptr); + } + },clearRef:function (ptr) { + if (!ptr) return; + var info = EXCEPTIONS.infos[ptr]; + info.refcount = 0; + }};function ___cxa_begin_catch(ptr) { + var info = EXCEPTIONS.infos[ptr]; + if (info && !info.caught) { + info.caught = true; + __ZSt18uncaught_exceptionv.uncaught_exception--; + } + if (info) info.rethrown = false; + EXCEPTIONS.caught.push(ptr); + EXCEPTIONS.addRef(EXCEPTIONS.deAdjust(ptr)); + return ptr; + } + + + function ___cxa_free_exception(ptr) { + try { + return _free(ptr); + } catch(e) { // XXX FIXME + Module.printErr('exception during cxa_free_exception: ' + e); + } + }function ___cxa_end_catch() { + // Clear state flag. + Module['setThrew'](0); + // Call destructor if one is registered then clear it. + var ptr = EXCEPTIONS.caught.pop(); + if (ptr) { + EXCEPTIONS.decRef(EXCEPTIONS.deAdjust(ptr)); + EXCEPTIONS.last = 0; // XXX in decRef? + } + } + + function ___cxa_find_matching_catch_2() { + return ___cxa_find_matching_catch.apply(null, arguments); + } + + function ___cxa_find_matching_catch_3() { + return ___cxa_find_matching_catch.apply(null, arguments); + } + + + + + function ___resumeException(ptr) { + if (!EXCEPTIONS.last) { EXCEPTIONS.last = ptr; } + throw ptr; + }function ___cxa_find_matching_catch() { + var thrown = EXCEPTIONS.last; + if (!thrown) { + // just pass through the null ptr + return ((setTempRet0(0),0)|0); + } + var info = EXCEPTIONS.infos[thrown]; + var throwntype = info.type; + if (!throwntype) { + // just pass through the thrown ptr + return ((setTempRet0(0),thrown)|0); + } + var typeArray = Array.prototype.slice.call(arguments); + + var pointer = Module['___cxa_is_pointer_type'](throwntype); + // can_catch receives a **, add indirection + if (!___cxa_find_matching_catch.buffer) ___cxa_find_matching_catch.buffer = _malloc(4); + HEAP32[((___cxa_find_matching_catch.buffer)>>2)]=thrown; + thrown = ___cxa_find_matching_catch.buffer; + // The different catch blocks are denoted by different types. + // Due to inheritance, those types may not precisely match the + // type of the thrown object. Find one which matches, and + // return the type of the catch block which should be called. + for (var i = 0; i < typeArray.length; i++) { + if (typeArray[i] && Module['___cxa_can_catch'](typeArray[i], throwntype, thrown)) { + thrown = HEAP32[((thrown)>>2)]; // undo indirection + info.adjusted = thrown; + return ((setTempRet0(typeArray[i]),thrown)|0); + } + } + // Shouldn't happen unless we have bogus data in typeArray + // or encounter a type for which emscripten doesn't have suitable + // typeinfo defined. Best-efforts match just in case. + thrown = HEAP32[((thrown)>>2)]; // undo indirection + return ((setTempRet0(throwntype),thrown)|0); + }function ___cxa_throw(ptr, type, destructor) { + EXCEPTIONS.infos[ptr] = { + ptr: ptr, + adjusted: ptr, + type: type, + destructor: destructor, + refcount: 0, + caught: false, + rethrown: false + }; + EXCEPTIONS.last = ptr; + if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) { + __ZSt18uncaught_exceptionv.uncaught_exception = 1; + } else { + __ZSt18uncaught_exceptionv.uncaught_exception++; + } + throw ptr; + } + + function ___gxx_personality_v0() { + } + + function ___lock() {} + + + + var SYSCALLS={varargs:0,get:function (varargs) { + SYSCALLS.varargs += 4; + var ret = HEAP32[(((SYSCALLS.varargs)-(4))>>2)]; + return ret; + },getStr:function () { + var ret = Pointer_stringify(SYSCALLS.get()); + return ret; + },get64:function () { + var low = SYSCALLS.get(), high = SYSCALLS.get(); + if (low >= 0) assert(high === 0); + else assert(high === -1); + return low; + },getZero:function () { + assert(SYSCALLS.get() === 0); + }};function ___syscall140(which, varargs) {SYSCALLS.varargs = varargs; + try { + // llseek + var stream = SYSCALLS.getStreamFromFD(), offset_high = SYSCALLS.get(), offset_low = SYSCALLS.get(), result = SYSCALLS.get(), whence = SYSCALLS.get(); + // NOTE: offset_high is unused - Emscripten's off_t is 32-bit + var offset = offset_low; + FS.llseek(stream, offset, whence); + HEAP32[((result)>>2)]=stream.position; + if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state + return 0; + } catch (e) { + if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e); + return -e.errno; + } + } + + + function flush_NO_FILESYSTEM() { + // flush anything remaining in the buffers during shutdown + var fflush = Module["_fflush"]; + if (fflush) fflush(0); + var printChar = ___syscall146.printChar; + if (!printChar) return; + var buffers = ___syscall146.buffers; + if (buffers[1].length) printChar(1, 10); + if (buffers[2].length) printChar(2, 10); + }function ___syscall146(which, varargs) {SYSCALLS.varargs = varargs; + try { + // writev + // hack to support printf in NO_FILESYSTEM + var stream = SYSCALLS.get(), iov = SYSCALLS.get(), iovcnt = SYSCALLS.get(); + var ret = 0; + if (!___syscall146.buffers) { + ___syscall146.buffers = [null, [], []]; // 1 => stdout, 2 => stderr + ___syscall146.printChar = function(stream, curr) { + var buffer = ___syscall146.buffers[stream]; + assert(buffer); + if (curr === 0 || curr === 10) { + (stream === 1 ? Module['print'] : Module['printErr'])(UTF8ArrayToString(buffer, 0)); + buffer.length = 0; + } else { + buffer.push(curr); + } + }; + } + for (var i = 0; i < iovcnt; i++) { + var ptr = HEAP32[(((iov)+(i*8))>>2)]; + var len = HEAP32[(((iov)+(i*8 + 4))>>2)]; + for (var j = 0; j < len; j++) { + ___syscall146.printChar(stream, HEAPU8[ptr+j]); + } + ret += len; + } + return ret; + } catch (e) { + if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e); + return -e.errno; + } + } + + function ___syscall54(which, varargs) {SYSCALLS.varargs = varargs; + try { + // ioctl + return 0; + } catch (e) { + if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e); + return -e.errno; + } + } + + function ___syscall6(which, varargs) {SYSCALLS.varargs = varargs; + try { + // close + var stream = SYSCALLS.getStreamFromFD(); + FS.close(stream); + return 0; + } catch (e) { + if (typeof FS === 'undefined' || !(e instanceof FS.ErrnoError)) abort(e); + return -e.errno; + } + } + + function ___unlock() {} + + + function getShiftFromSize(size) { + switch (size) { + case 1: return 0; + case 2: return 1; + case 4: return 2; + case 8: return 3; + default: + throw new TypeError('Unknown type size: ' + size); + } + } + + + + function embind_init_charCodes() { + var codes = new Array(256); + for (var i = 0; i < 256; ++i) { + codes[i] = String.fromCharCode(i); + } + embind_charCodes = codes; + }var embind_charCodes=undefined;function readLatin1String(ptr) { + var ret = ""; + var c = ptr; + while (HEAPU8[c]) { + ret += embind_charCodes[HEAPU8[c++]]; + } + return ret; + } + + + var awaitingDependencies={}; + + var registeredTypes={}; + + var typeDependencies={}; + + + + + + + var char_0=48; + + var char_9=57;function makeLegalFunctionName(name) { + if (undefined === name) { + return '_unknown'; + } + name = name.replace(/[^a-zA-Z0-9_]/g, '$'); + var f = name.charCodeAt(0); + if (f >= char_0 && f <= char_9) { + return '_' + name; + } else { + return name; + } + }function createNamedFunction(name, body) { + name = makeLegalFunctionName(name); + /*jshint evil:true*/ + return new Function( + "body", + "return function " + name + "() {\n" + + " \"use strict\";" + + " return body.apply(this, arguments);\n" + + "};\n" + )(body); + }function extendError(baseErrorType, errorName) { + var errorClass = createNamedFunction(errorName, function(message) { + this.name = errorName; + this.message = message; + + var stack = (new Error(message)).stack; + if (stack !== undefined) { + this.stack = this.toString() + '\n' + + stack.replace(/^Error(:[^\n]*)?\n/, ''); + } + }); + errorClass.prototype = Object.create(baseErrorType.prototype); + errorClass.prototype.constructor = errorClass; + errorClass.prototype.toString = function() { + if (this.message === undefined) { + return this.name; + } else { + return this.name + ': ' + this.message; + } + }; + + return errorClass; + }var BindingError=undefined;function throwBindingError(message) { + throw new BindingError(message); + } + + + + var InternalError=undefined;function throwInternalError(message) { + throw new InternalError(message); + }function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverters) { + myTypes.forEach(function(type) { + typeDependencies[type] = dependentTypes; + }); + + function onComplete(typeConverters) { + var myTypeConverters = getTypeConverters(typeConverters); + if (myTypeConverters.length !== myTypes.length) { + throwInternalError('Mismatched type converter count'); + } + for (var i = 0; i < myTypes.length; ++i) { + registerType(myTypes[i], myTypeConverters[i]); + } + } + + var typeConverters = new Array(dependentTypes.length); + var unregisteredTypes = []; + var registered = 0; + dependentTypes.forEach(function(dt, i) { + if (registeredTypes.hasOwnProperty(dt)) { + typeConverters[i] = registeredTypes[dt]; + } else { + unregisteredTypes.push(dt); + if (!awaitingDependencies.hasOwnProperty(dt)) { + awaitingDependencies[dt] = []; + } + awaitingDependencies[dt].push(function() { + typeConverters[i] = registeredTypes[dt]; + ++registered; + if (registered === unregisteredTypes.length) { + onComplete(typeConverters); + } + }); + } + }); + if (0 === unregisteredTypes.length) { + onComplete(typeConverters); + } + }function registerType(rawType, registeredInstance, options) { + options = options || {}; + + if (!('argPackAdvance' in registeredInstance)) { + throw new TypeError('registerType registeredInstance requires argPackAdvance'); + } + + var name = registeredInstance.name; + if (!rawType) { + throwBindingError('type "' + name + '" must have a positive integer typeid pointer'); + } + if (registeredTypes.hasOwnProperty(rawType)) { + if (options.ignoreDuplicateRegistrations) { + return; + } else { + throwBindingError("Cannot register type '" + name + "' twice"); + } + } + + registeredTypes[rawType] = registeredInstance; + delete typeDependencies[rawType]; + + if (awaitingDependencies.hasOwnProperty(rawType)) { + var callbacks = awaitingDependencies[rawType]; + delete awaitingDependencies[rawType]; + callbacks.forEach(function(cb) { + cb(); + }); + } + }function __embind_register_bool(rawType, name, size, trueValue, falseValue) { + var shift = getShiftFromSize(size); + + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': function(wt) { + // ambiguous emscripten ABI: sometimes return values are + // true or false, and sometimes integers (0 or 1) + return !!wt; + }, + 'toWireType': function(destructors, o) { + return o ? trueValue : falseValue; + }, + 'argPackAdvance': 8, + 'readValueFromPointer': function(pointer) { + // TODO: if heap is fixed (like in asm.js) this could be executed outside + var heap; + if (size === 1) { + heap = HEAP8; + } else if (size === 2) { + heap = HEAP16; + } else if (size === 4) { + heap = HEAP32; + } else { + throw new TypeError("Unknown boolean type size: " + name); + } + return this['fromWireType'](heap[pointer >> shift]); + }, + destructorFunction: null, // This type does not need a destructor + }); + } + + + + + function ClassHandle_isAliasOf(other) { + if (!(this instanceof ClassHandle)) { + return false; + } + if (!(other instanceof ClassHandle)) { + return false; + } + + var leftClass = this.$$.ptrType.registeredClass; + var left = this.$$.ptr; + var rightClass = other.$$.ptrType.registeredClass; + var right = other.$$.ptr; + + while (leftClass.baseClass) { + left = leftClass.upcast(left); + leftClass = leftClass.baseClass; + } + + while (rightClass.baseClass) { + right = rightClass.upcast(right); + rightClass = rightClass.baseClass; + } + + return leftClass === rightClass && left === right; + } + + + function shallowCopyInternalPointer(o) { + return { + count: o.count, + deleteScheduled: o.deleteScheduled, + preservePointerOnDelete: o.preservePointerOnDelete, + ptr: o.ptr, + ptrType: o.ptrType, + smartPtr: o.smartPtr, + smartPtrType: o.smartPtrType, + }; + } + + function throwInstanceAlreadyDeleted(obj) { + function getInstanceTypeName(handle) { + return handle.$$.ptrType.registeredClass.name; + } + throwBindingError(getInstanceTypeName(obj) + ' instance already deleted'); + }function ClassHandle_clone() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + + if (this.$$.preservePointerOnDelete) { + this.$$.count.value += 1; + return this; + } else { + var clone = Object.create(Object.getPrototypeOf(this), { + $$: { + value: shallowCopyInternalPointer(this.$$), + } + }); + + clone.$$.count.value += 1; + clone.$$.deleteScheduled = false; + return clone; + } + } + + + function runDestructor(handle) { + var $$ = handle.$$; + if ($$.smartPtr) { + $$.smartPtrType.rawDestructor($$.smartPtr); + } else { + $$.ptrType.registeredClass.rawDestructor($$.ptr); + } + }function ClassHandle_delete() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + + if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { + throwBindingError('Object already scheduled for deletion'); + } + + this.$$.count.value -= 1; + var toDelete = 0 === this.$$.count.value; + if (toDelete) { + runDestructor(this); + } + if (!this.$$.preservePointerOnDelete) { + this.$$.smartPtr = undefined; + this.$$.ptr = undefined; + } + } + + function ClassHandle_isDeleted() { + return !this.$$.ptr; + } + + + var delayFunction=undefined; + + var deletionQueue=[]; + + function flushPendingDeletes() { + while (deletionQueue.length) { + var obj = deletionQueue.pop(); + obj.$$.deleteScheduled = false; + obj['delete'](); + } + }function ClassHandle_deleteLater() { + if (!this.$$.ptr) { + throwInstanceAlreadyDeleted(this); + } + if (this.$$.deleteScheduled && !this.$$.preservePointerOnDelete) { + throwBindingError('Object already scheduled for deletion'); + } + deletionQueue.push(this); + if (deletionQueue.length === 1 && delayFunction) { + delayFunction(flushPendingDeletes); + } + this.$$.deleteScheduled = true; + return this; + }function init_ClassHandle() { + ClassHandle.prototype['isAliasOf'] = ClassHandle_isAliasOf; + ClassHandle.prototype['clone'] = ClassHandle_clone; + ClassHandle.prototype['delete'] = ClassHandle_delete; + ClassHandle.prototype['isDeleted'] = ClassHandle_isDeleted; + ClassHandle.prototype['deleteLater'] = ClassHandle_deleteLater; + }function ClassHandle() { + } + + var registeredPointers={}; + + + function ensureOverloadTable(proto, methodName, humanName) { + if (undefined === proto[methodName].overloadTable) { + var prevFunc = proto[methodName]; + // Inject an overload resolver function that routes to the appropriate overload based on the number of arguments. + proto[methodName] = function() { + // TODO This check can be removed in -O3 level "unsafe" optimizations. + if (!proto[methodName].overloadTable.hasOwnProperty(arguments.length)) { + throwBindingError("Function '" + humanName + "' called with an invalid number of arguments (" + arguments.length + ") - expects one of (" + proto[methodName].overloadTable + ")!"); + } + return proto[methodName].overloadTable[arguments.length].apply(this, arguments); + }; + // Move the previous function into the overload table. + proto[methodName].overloadTable = []; + proto[methodName].overloadTable[prevFunc.argCount] = prevFunc; + } + }function exposePublicSymbol(name, value, numArguments) { + if (Module.hasOwnProperty(name)) { + if (undefined === numArguments || (undefined !== Module[name].overloadTable && undefined !== Module[name].overloadTable[numArguments])) { + throwBindingError("Cannot register public name '" + name + "' twice"); + } + + // We are exposing a function with the same name as an existing function. Create an overload table and a function selector + // that routes between the two. + ensureOverloadTable(Module, name, name); + if (Module.hasOwnProperty(numArguments)) { + throwBindingError("Cannot register multiple overloads of a function with the same number of arguments (" + numArguments + ")!"); + } + // Add the new function into the overload table. + Module[name].overloadTable[numArguments] = value; + } + else { + Module[name] = value; + if (undefined !== numArguments) { + Module[name].numArguments = numArguments; + } + } + } + + function RegisteredClass( + name, + constructor, + instancePrototype, + rawDestructor, + baseClass, + getActualType, + upcast, + downcast + ) { + this.name = name; + this.constructor = constructor; + this.instancePrototype = instancePrototype; + this.rawDestructor = rawDestructor; + this.baseClass = baseClass; + this.getActualType = getActualType; + this.upcast = upcast; + this.downcast = downcast; + this.pureVirtualFunctions = []; + } + + + + function upcastPointer(ptr, ptrClass, desiredClass) { + while (ptrClass !== desiredClass) { + if (!ptrClass.upcast) { + throwBindingError("Expected null or instance of " + desiredClass.name + ", got an instance of " + ptrClass.name); + } + ptr = ptrClass.upcast(ptr); + ptrClass = ptrClass.baseClass; + } + return ptr; + }function constNoSmartPtrRawPointerToWireType(destructors, handle) { + if (handle === null) { + if (this.isReference) { + throwBindingError('null is not a valid ' + this.name); + } + return 0; + } + + if (!handle.$$) { + throwBindingError('Cannot pass "' + _embind_repr(handle) + '" as a ' + this.name); + } + if (!handle.$$.ptr) { + throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name); + } + var handleClass = handle.$$.ptrType.registeredClass; + var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass); + return ptr; + } + + function genericPointerToWireType(destructors, handle) { + var ptr; + if (handle === null) { + if (this.isReference) { + throwBindingError('null is not a valid ' + this.name); + } + + if (this.isSmartPointer) { + ptr = this.rawConstructor(); + if (destructors !== null) { + destructors.push(this.rawDestructor, ptr); + } + return ptr; + } else { + return 0; + } + } + + if (!handle.$$) { + throwBindingError('Cannot pass "' + _embind_repr(handle) + '" as a ' + this.name); + } + if (!handle.$$.ptr) { + throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name); + } + if (!this.isConst && handle.$$.ptrType.isConst) { + throwBindingError('Cannot convert argument of type ' + (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) + ' to parameter type ' + this.name); + } + var handleClass = handle.$$.ptrType.registeredClass; + ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass); + + if (this.isSmartPointer) { + // TODO: this is not strictly true + // We could support BY_EMVAL conversions from raw pointers to smart pointers + // because the smart pointer can hold a reference to the handle + if (undefined === handle.$$.smartPtr) { + throwBindingError('Passing raw pointer to smart pointer is illegal'); + } + + switch (this.sharingPolicy) { + case 0: // NONE + // no upcasting + if (handle.$$.smartPtrType === this) { + ptr = handle.$$.smartPtr; + } else { + throwBindingError('Cannot convert argument of type ' + (handle.$$.smartPtrType ? handle.$$.smartPtrType.name : handle.$$.ptrType.name) + ' to parameter type ' + this.name); + } + break; + + case 1: // INTRUSIVE + ptr = handle.$$.smartPtr; + break; + + case 2: // BY_EMVAL + if (handle.$$.smartPtrType === this) { + ptr = handle.$$.smartPtr; + } else { + var clonedHandle = handle['clone'](); + ptr = this.rawShare( + ptr, + __emval_register(function() { + clonedHandle['delete'](); + }) + ); + if (destructors !== null) { + destructors.push(this.rawDestructor, ptr); + } + } + break; + + default: + throwBindingError('Unsupporting sharing policy'); + } + } + return ptr; + } + + function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) { + if (handle === null) { + if (this.isReference) { + throwBindingError('null is not a valid ' + this.name); + } + return 0; + } + + if (!handle.$$) { + throwBindingError('Cannot pass "' + _embind_repr(handle) + '" as a ' + this.name); + } + if (!handle.$$.ptr) { + throwBindingError('Cannot pass deleted object as a pointer of type ' + this.name); + } + if (handle.$$.ptrType.isConst) { + throwBindingError('Cannot convert argument of type ' + handle.$$.ptrType.name + ' to parameter type ' + this.name); + } + var handleClass = handle.$$.ptrType.registeredClass; + var ptr = upcastPointer(handle.$$.ptr, handleClass, this.registeredClass); + return ptr; + } + + + function simpleReadValueFromPointer(pointer) { + return this['fromWireType'](HEAPU32[pointer >> 2]); + } + + function RegisteredPointer_getPointee(ptr) { + if (this.rawGetPointee) { + ptr = this.rawGetPointee(ptr); + } + return ptr; + } + + function RegisteredPointer_destructor(ptr) { + if (this.rawDestructor) { + this.rawDestructor(ptr); + } + } + + function RegisteredPointer_deleteObject(handle) { + if (handle !== null) { + handle['delete'](); + } + } + + + function downcastPointer(ptr, ptrClass, desiredClass) { + if (ptrClass === desiredClass) { + return ptr; + } + if (undefined === desiredClass.baseClass) { + return null; // no conversion + } + + var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass); + if (rv === null) { + return null; + } + return desiredClass.downcast(rv); + } + + + + + function getInheritedInstanceCount() { + return Object.keys(registeredInstances).length; + } + + function getLiveInheritedInstances() { + var rv = []; + for (var k in registeredInstances) { + if (registeredInstances.hasOwnProperty(k)) { + rv.push(registeredInstances[k]); + } + } + return rv; + } + + function setDelayFunction(fn) { + delayFunction = fn; + if (deletionQueue.length && delayFunction) { + delayFunction(flushPendingDeletes); + } + }function init_embind() { + Module['getInheritedInstanceCount'] = getInheritedInstanceCount; + Module['getLiveInheritedInstances'] = getLiveInheritedInstances; + Module['flushPendingDeletes'] = flushPendingDeletes; + Module['setDelayFunction'] = setDelayFunction; + }var registeredInstances={}; + + function getBasestPointer(class_, ptr) { + if (ptr === undefined) { + throwBindingError('ptr should not be undefined'); + } + while (class_.baseClass) { + ptr = class_.upcast(ptr); + class_ = class_.baseClass; + } + return ptr; + }function getInheritedInstance(class_, ptr) { + ptr = getBasestPointer(class_, ptr); + return registeredInstances[ptr]; + } + + function makeClassHandle(prototype, record) { + if (!record.ptrType || !record.ptr) { + throwInternalError('makeClassHandle requires ptr and ptrType'); + } + var hasSmartPtrType = !!record.smartPtrType; + var hasSmartPtr = !!record.smartPtr; + if (hasSmartPtrType !== hasSmartPtr) { + throwInternalError('Both smartPtrType and smartPtr must be specified'); + } + record.count = { value: 1 }; + return Object.create(prototype, { + $$: { + value: record, + }, + }); + }function RegisteredPointer_fromWireType(ptr) { + // ptr is a raw pointer (or a raw smartpointer) + + // rawPointer is a maybe-null raw pointer + var rawPointer = this.getPointee(ptr); + if (!rawPointer) { + this.destructor(ptr); + return null; + } + + var registeredInstance = getInheritedInstance(this.registeredClass, rawPointer); + if (undefined !== registeredInstance) { + // JS object has been neutered, time to repopulate it + if (0 === registeredInstance.$$.count.value) { + registeredInstance.$$.ptr = rawPointer; + registeredInstance.$$.smartPtr = ptr; + return registeredInstance['clone'](); + } else { + // else, just increment reference count on existing object + // it already has a reference to the smart pointer + var rv = registeredInstance['clone'](); + this.destructor(ptr); + return rv; + } + } + + function makeDefaultHandle() { + if (this.isSmartPointer) { + return makeClassHandle(this.registeredClass.instancePrototype, { + ptrType: this.pointeeType, + ptr: rawPointer, + smartPtrType: this, + smartPtr: ptr, + }); + } else { + return makeClassHandle(this.registeredClass.instancePrototype, { + ptrType: this, + ptr: ptr, + }); + } + } + + var actualType = this.registeredClass.getActualType(rawPointer); + var registeredPointerRecord = registeredPointers[actualType]; + if (!registeredPointerRecord) { + return makeDefaultHandle.call(this); + } + + var toType; + if (this.isConst) { + toType = registeredPointerRecord.constPointerType; + } else { + toType = registeredPointerRecord.pointerType; + } + var dp = downcastPointer( + rawPointer, + this.registeredClass, + toType.registeredClass); + if (dp === null) { + return makeDefaultHandle.call(this); + } + if (this.isSmartPointer) { + return makeClassHandle(toType.registeredClass.instancePrototype, { + ptrType: toType, + ptr: dp, + smartPtrType: this, + smartPtr: ptr, + }); + } else { + return makeClassHandle(toType.registeredClass.instancePrototype, { + ptrType: toType, + ptr: dp, + }); + } + }function init_RegisteredPointer() { + RegisteredPointer.prototype.getPointee = RegisteredPointer_getPointee; + RegisteredPointer.prototype.destructor = RegisteredPointer_destructor; + RegisteredPointer.prototype['argPackAdvance'] = 8; + RegisteredPointer.prototype['readValueFromPointer'] = simpleReadValueFromPointer; + RegisteredPointer.prototype['deleteObject'] = RegisteredPointer_deleteObject; + RegisteredPointer.prototype['fromWireType'] = RegisteredPointer_fromWireType; + }function RegisteredPointer( + name, + registeredClass, + isReference, + isConst, + + // smart pointer properties + isSmartPointer, + pointeeType, + sharingPolicy, + rawGetPointee, + rawConstructor, + rawShare, + rawDestructor + ) { + this.name = name; + this.registeredClass = registeredClass; + this.isReference = isReference; + this.isConst = isConst; + + // smart pointer properties + this.isSmartPointer = isSmartPointer; + this.pointeeType = pointeeType; + this.sharingPolicy = sharingPolicy; + this.rawGetPointee = rawGetPointee; + this.rawConstructor = rawConstructor; + this.rawShare = rawShare; + this.rawDestructor = rawDestructor; + + if (!isSmartPointer && registeredClass.baseClass === undefined) { + if (isConst) { + this['toWireType'] = constNoSmartPtrRawPointerToWireType; + this.destructorFunction = null; + } else { + this['toWireType'] = nonConstNoSmartPtrRawPointerToWireType; + this.destructorFunction = null; + } + } else { + this['toWireType'] = genericPointerToWireType; + // Here we must leave this.destructorFunction undefined, since whether genericPointerToWireType returns + // a pointer that needs to be freed up is runtime-dependent, and cannot be evaluated at registration time. + // TODO: Create an alternative mechanism that allows removing the use of var destructors = []; array in + // craftInvokerFunction altogether. + } + } + + function replacePublicSymbol(name, value, numArguments) { + if (!Module.hasOwnProperty(name)) { + throwInternalError('Replacing nonexistant public symbol'); + } + // If there's an overload table for this symbol, replace the symbol in the overload table instead. + if (undefined !== Module[name].overloadTable && undefined !== numArguments) { + Module[name].overloadTable[numArguments] = value; + } + else { + Module[name] = value; + Module[name].argCount = numArguments; + } + } + + function embind__requireFunction(signature, rawFunction) { + signature = readLatin1String(signature); + + function makeDynCaller(dynCall) { + var args = []; + for (var i = 1; i < signature.length; ++i) { + args.push('a' + i); + } + + var name = 'dynCall_' + signature + '_' + rawFunction; + var body = 'return function ' + name + '(' + args.join(', ') + ') {\n'; + body += ' return dynCall(rawFunction' + (args.length ? ', ' : '') + args.join(', ') + ');\n'; + body += '};\n'; + + return (new Function('dynCall', 'rawFunction', body))(dynCall, rawFunction); + } + + var fp; + if (Module['FUNCTION_TABLE_' + signature] !== undefined) { + fp = Module['FUNCTION_TABLE_' + signature][rawFunction]; + } else if (typeof FUNCTION_TABLE !== "undefined") { + fp = FUNCTION_TABLE[rawFunction]; + } else { + // asm.js does not give direct access to the function tables, + // and thus we must go through the dynCall interface which allows + // calling into a signature's function table by pointer value. + // + // https://github.com/dherman/asm.js/issues/83 + // + // This has three main penalties: + // - dynCall is another function call in the path from JavaScript to C++. + // - JITs may not predict through the function table indirection at runtime. + var dc = Module["asm"]['dynCall_' + signature]; + if (dc === undefined) { + // We will always enter this branch if the signature + // contains 'f' and PRECISE_F32 is not enabled. + // + // Try again, replacing 'f' with 'd'. + dc = Module["asm"]['dynCall_' + signature.replace(/f/g, 'd')]; + if (dc === undefined) { + throwBindingError("No dynCall invoker for signature: " + signature); + } + } + fp = makeDynCaller(dc); + } + + if (typeof fp !== "function") { + throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction); + } + return fp; + } + + + var UnboundTypeError=undefined; + + function getTypeName(type) { + var ptr = ___getTypeName(type); + var rv = readLatin1String(ptr); + _free(ptr); + return rv; + }function throwUnboundTypeError(message, types) { + var unboundTypes = []; + var seen = {}; + function visit(type) { + if (seen[type]) { + return; + } + if (registeredTypes[type]) { + return; + } + if (typeDependencies[type]) { + typeDependencies[type].forEach(visit); + return; + } + unboundTypes.push(type); + seen[type] = true; + } + types.forEach(visit); + + throw new UnboundTypeError(message + ': ' + unboundTypes.map(getTypeName).join([', '])); + }function __embind_register_class( + rawType, + rawPointerType, + rawConstPointerType, + baseClassRawType, + getActualTypeSignature, + getActualType, + upcastSignature, + upcast, + downcastSignature, + downcast, + name, + destructorSignature, + rawDestructor + ) { + name = readLatin1String(name); + getActualType = embind__requireFunction(getActualTypeSignature, getActualType); + if (upcast) { + upcast = embind__requireFunction(upcastSignature, upcast); + } + if (downcast) { + downcast = embind__requireFunction(downcastSignature, downcast); + } + rawDestructor = embind__requireFunction(destructorSignature, rawDestructor); + var legalFunctionName = makeLegalFunctionName(name); + + exposePublicSymbol(legalFunctionName, function() { + // this code cannot run if baseClassRawType is zero + throwUnboundTypeError('Cannot construct ' + name + ' due to unbound types', [baseClassRawType]); + }); + + whenDependentTypesAreResolved( + [rawType, rawPointerType, rawConstPointerType], + baseClassRawType ? [baseClassRawType] : [], + function(base) { + base = base[0]; + + var baseClass; + var basePrototype; + if (baseClassRawType) { + baseClass = base.registeredClass; + basePrototype = baseClass.instancePrototype; + } else { + basePrototype = ClassHandle.prototype; + } + + var constructor = createNamedFunction(legalFunctionName, function() { + if (Object.getPrototypeOf(this) !== instancePrototype) { + throw new BindingError("Use 'new' to construct " + name); + } + if (undefined === registeredClass.constructor_body) { + throw new BindingError(name + " has no accessible constructor"); + } + var body = registeredClass.constructor_body[arguments.length]; + if (undefined === body) { + throw new BindingError("Tried to invoke ctor of " + name + " with invalid number of parameters (" + arguments.length + ") - expected (" + Object.keys(registeredClass.constructor_body).toString() + ") parameters instead!"); + } + return body.apply(this, arguments); + }); + + var instancePrototype = Object.create(basePrototype, { + constructor: { value: constructor }, + }); + + constructor.prototype = instancePrototype; + + var registeredClass = new RegisteredClass( + name, + constructor, + instancePrototype, + rawDestructor, + baseClass, + getActualType, + upcast, + downcast); + + var referenceConverter = new RegisteredPointer( + name, + registeredClass, + true, + false, + false); + + var pointerConverter = new RegisteredPointer( + name + '*', + registeredClass, + false, + false, + false); + + var constPointerConverter = new RegisteredPointer( + name + ' const*', + registeredClass, + false, + true, + false); + + registeredPointers[rawType] = { + pointerType: pointerConverter, + constPointerType: constPointerConverter + }; + + replacePublicSymbol(legalFunctionName, constructor); + + return [referenceConverter, pointerConverter, constPointerConverter]; + } + ); + } + + + function heap32VectorToArray(count, firstElement) { + var array = []; + for (var i = 0; i < count; i++) { + array.push(HEAP32[(firstElement >> 2) + i]); + } + return array; + } + + function runDestructors(destructors) { + while (destructors.length) { + var ptr = destructors.pop(); + var del = destructors.pop(); + del(ptr); + } + }function __embind_register_class_constructor( + rawClassType, + argCount, + rawArgTypesAddr, + invokerSignature, + invoker, + rawConstructor + ) { + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + invoker = embind__requireFunction(invokerSignature, invoker); + + whenDependentTypesAreResolved([], [rawClassType], function(classType) { + classType = classType[0]; + var humanName = 'constructor ' + classType.name; + + if (undefined === classType.registeredClass.constructor_body) { + classType.registeredClass.constructor_body = []; + } + if (undefined !== classType.registeredClass.constructor_body[argCount - 1]) { + throw new BindingError("Cannot register multiple constructors with identical number of parameters (" + (argCount-1) + ") for class '" + classType.name + "'! Overload resolution is currently only performed using the parameter count, not actual type info!"); + } + classType.registeredClass.constructor_body[argCount - 1] = function unboundTypeHandler() { + throwUnboundTypeError('Cannot construct ' + classType.name + ' due to unbound types', rawArgTypes); + }; + + whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) { + classType.registeredClass.constructor_body[argCount - 1] = function constructor_body() { + if (arguments.length !== argCount - 1) { + throwBindingError(humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount-1)); + } + var destructors = []; + var args = new Array(argCount); + args[0] = rawConstructor; + for (var i = 1; i < argCount; ++i) { + args[i] = argTypes[i]['toWireType'](destructors, arguments[i - 1]); + } + + var ptr = invoker.apply(null, args); + runDestructors(destructors); + + return argTypes[0]['fromWireType'](ptr); + }; + return []; + }); + return []; + }); + } + + + + function new_(constructor, argumentList) { + if (!(constructor instanceof Function)) { + throw new TypeError('new_ called with constructor type ' + typeof(constructor) + " which is not a function"); + } + + /* + * Previously, the following line was just: + + function dummy() {}; + + * Unfortunately, Chrome was preserving 'dummy' as the object's name, even though at creation, the 'dummy' has the + * correct constructor name. Thus, objects created with IMVU.new would show up in the debugger as 'dummy', which + * isn't very helpful. Using IMVU.createNamedFunction addresses the issue. Doublely-unfortunately, there's no way + * to write a test for this behavior. -NRD 2013.02.22 + */ + var dummy = createNamedFunction(constructor.name || 'unknownFunctionName', function(){}); + dummy.prototype = constructor.prototype; + var obj = new dummy; + + var r = constructor.apply(obj, argumentList); + return (r instanceof Object) ? r : obj; + }function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) { + // humanName: a human-readable string name for the function to be generated. + // argTypes: An array that contains the embind type objects for all types in the function signature. + // argTypes[0] is the type object for the function return value. + // argTypes[1] is the type object for function this object/class type, or null if not crafting an invoker for a class method. + // argTypes[2...] are the actual function parameters. + // classType: The embind type object for the class to be bound, or null if this is not a method of a class. + // cppInvokerFunc: JS Function object to the C++-side function that interops into C++ code. + // cppTargetFunc: Function pointer (an integer to FUNCTION_TABLE) to the target C++ function the cppInvokerFunc will end up calling. + var argCount = argTypes.length; + + if (argCount < 2) { + throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!"); + } + + var isClassMethodFunc = (argTypes[1] !== null && classType !== null); + + // Free functions with signature "void function()" do not need an invoker that marshalls between wire types. + // TODO: This omits argument count check - enable only at -O3 or similar. + // if (ENABLE_UNSAFE_OPTS && argCount == 2 && argTypes[0].name == "void" && !isClassMethodFunc) { + // return FUNCTION_TABLE[fn]; + // } + + + // Determine if we need to use a dynamic stack to store the destructors for the function parameters. + // TODO: Remove this completely once all function invokers are being dynamically generated. + var needsDestructorStack = false; + + for(var i = 1; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. + if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { // The type does not define a destructor function - must use dynamic stack + needsDestructorStack = true; + break; + } + } + + var returns = (argTypes[0].name !== "void"); + + var argsList = ""; + var argsListWired = ""; + for(var i = 0; i < argCount - 2; ++i) { + argsList += (i!==0?", ":"")+"arg"+i; + argsListWired += (i!==0?", ":"")+"arg"+i+"Wired"; + } + + var invokerFnBody = + "return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n" + + "if (arguments.length !== "+(argCount - 2)+") {\n" + + "throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount - 2)+" args!');\n" + + "}\n"; + + + if (needsDestructorStack) { + invokerFnBody += + "var destructors = [];\n"; + } + + var dtorStack = needsDestructorStack ? "destructors" : "null"; + var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"]; + var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; + + + if (isClassMethodFunc) { + invokerFnBody += "var thisWired = classParam.toWireType("+dtorStack+", this);\n"; + } + + for(var i = 0; i < argCount - 2; ++i) { + invokerFnBody += "var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n"; + args1.push("argType"+i); + args2.push(argTypes[i+2]); + } + + if (isClassMethodFunc) { + argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired; + } + + invokerFnBody += + (returns?"var rv = ":"") + "invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n"; + + if (needsDestructorStack) { + invokerFnBody += "runDestructors(destructors);\n"; + } else { + for(var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method. + var paramName = (i === 1 ? "thisWired" : ("arg"+(i - 2)+"Wired")); + if (argTypes[i].destructorFunction !== null) { + invokerFnBody += paramName+"_dtor("+paramName+"); // "+argTypes[i].name+"\n"; + args1.push(paramName+"_dtor"); + args2.push(argTypes[i].destructorFunction); + } + } + } + + if (returns) { + invokerFnBody += "var ret = retType.fromWireType(rv);\n" + + "return ret;\n"; + } else { + } + invokerFnBody += "}\n"; + + args1.push(invokerFnBody); + + var invokerFunction = new_(Function, args1).apply(null, args2); + return invokerFunction; + }function __embind_register_class_function( + rawClassType, + methodName, + argCount, + rawArgTypesAddr, // [ReturnType, ThisType, Args...] + invokerSignature, + rawInvoker, + context, + isPureVirtual + ) { + var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); + methodName = readLatin1String(methodName); + rawInvoker = embind__requireFunction(invokerSignature, rawInvoker); + + whenDependentTypesAreResolved([], [rawClassType], function(classType) { + classType = classType[0]; + var humanName = classType.name + '.' + methodName; + + if (isPureVirtual) { + classType.registeredClass.pureVirtualFunctions.push(methodName); + } + + function unboundTypesHandler() { + throwUnboundTypeError('Cannot call ' + humanName + ' due to unbound types', rawArgTypes); + } + + var proto = classType.registeredClass.instancePrototype; + var method = proto[methodName]; + if (undefined === method || (undefined === method.overloadTable && method.className !== classType.name && method.argCount === argCount - 2)) { + // This is the first overload to be registered, OR we are replacing a function in the base class with a function in the derived class. + unboundTypesHandler.argCount = argCount - 2; + unboundTypesHandler.className = classType.name; + proto[methodName] = unboundTypesHandler; + } else { + // There was an existing function with the same name registered. Set up a function overload routing table. + ensureOverloadTable(proto, methodName, humanName); + proto[methodName].overloadTable[argCount - 2] = unboundTypesHandler; + } + + whenDependentTypesAreResolved([], rawArgTypes, function(argTypes) { + + var memberFunction = craftInvokerFunction(humanName, argTypes, classType, rawInvoker, context); + + // Replace the initial unbound-handler-stub function with the appropriate member function, now that all types + // are resolved. If multiple overloads are registered for this function, the function goes into an overload table. + if (undefined === proto[methodName].overloadTable) { + // Set argCount in case an overload is registered later + memberFunction.argCount = argCount - 2; + proto[methodName] = memberFunction; + } else { + proto[methodName].overloadTable[argCount - 2] = memberFunction; + } + + return []; + }); + return []; + }); + } + + + + var emval_free_list=[]; + + var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle) { + if (handle > 4 && 0 === --emval_handle_array[handle].refcount) { + emval_handle_array[handle] = undefined; + emval_free_list.push(handle); + } + } + + + + function count_emval_handles() { + var count = 0; + for (var i = 5; i < emval_handle_array.length; ++i) { + if (emval_handle_array[i] !== undefined) { + ++count; + } + } + return count; + } + + function get_first_emval() { + for (var i = 5; i < emval_handle_array.length; ++i) { + if (emval_handle_array[i] !== undefined) { + return emval_handle_array[i]; + } + } + return null; + }function init_emval() { + Module['count_emval_handles'] = count_emval_handles; + Module['get_first_emval'] = get_first_emval; + }function __emval_register(value) { + + switch(value){ + case undefined :{ return 1; } + case null :{ return 2; } + case true :{ return 3; } + case false :{ return 4; } + default:{ + var handle = emval_free_list.length ? + emval_free_list.pop() : + emval_handle_array.length; + + emval_handle_array[handle] = {refcount: 1, value: value}; + return handle; + } + } + }function __embind_register_emval(rawType, name) { + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': function(handle) { + var rv = emval_handle_array[handle].value; + __emval_decref(handle); + return rv; + }, + 'toWireType': function(destructors, value) { + return __emval_register(value); + }, + 'argPackAdvance': 8, + 'readValueFromPointer': simpleReadValueFromPointer, + destructorFunction: null, // This type does not need a destructor + + // TODO: do we need a deleteObject here? write a test where + // emval is passed into JS via an interface + }); + } + + + function _embind_repr(v) { + if (v === null) { + return 'null'; + } + var t = typeof v; + if (t === 'object' || t === 'array' || t === 'function') { + return v.toString(); + } else { + return '' + v; + } + } + + function floatReadValueFromPointer(name, shift) { + switch (shift) { + case 2: return function(pointer) { + return this['fromWireType'](HEAPF32[pointer >> 2]); + }; + case 3: return function(pointer) { + return this['fromWireType'](HEAPF64[pointer >> 3]); + }; + default: + throw new TypeError("Unknown float type: " + name); + } + }function __embind_register_float(rawType, name, size) { + var shift = getShiftFromSize(size); + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': function(value) { + return value; + }, + 'toWireType': function(destructors, value) { + // todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could + // avoid the following if() and assume value is of proper type. + if (typeof value !== "number" && typeof value !== "boolean") { + throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name); + } + return value; + }, + 'argPackAdvance': 8, + 'readValueFromPointer': floatReadValueFromPointer(name, shift), + destructorFunction: null, // This type does not need a destructor + }); + } + + + function integerReadValueFromPointer(name, shift, signed) { + // integers are quite common, so generate very specialized functions + switch (shift) { + case 0: return signed ? + function readS8FromPointer(pointer) { return HEAP8[pointer]; } : + function readU8FromPointer(pointer) { return HEAPU8[pointer]; }; + case 1: return signed ? + function readS16FromPointer(pointer) { return HEAP16[pointer >> 1]; } : + function readU16FromPointer(pointer) { return HEAPU16[pointer >> 1]; }; + case 2: return signed ? + function readS32FromPointer(pointer) { return HEAP32[pointer >> 2]; } : + function readU32FromPointer(pointer) { return HEAPU32[pointer >> 2]; }; + default: + throw new TypeError("Unknown integer type: " + name); + } + }function __embind_register_integer(primitiveType, name, size, minRange, maxRange) { + name = readLatin1String(name); + if (maxRange === -1) { // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come out as 'i32 -1'. Always treat those as max u32. + maxRange = 4294967295; + } + + var shift = getShiftFromSize(size); + + var fromWireType = function(value) { + return value; + }; + + if (minRange === 0) { + var bitshift = 32 - 8*size; + fromWireType = function(value) { + return (value << bitshift) >>> bitshift; + }; + } + + var isUnsignedType = (name.indexOf('unsigned') != -1); + + registerType(primitiveType, { + name: name, + 'fromWireType': fromWireType, + 'toWireType': function(destructors, value) { + // todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could + // avoid the following two if()s and assume value is of proper type. + if (typeof value !== "number" && typeof value !== "boolean") { + throw new TypeError('Cannot convert "' + _embind_repr(value) + '" to ' + this.name); + } + if (value < minRange || value > maxRange) { + throw new TypeError('Passing a number "' + _embind_repr(value) + '" from JS side to C/C++ side to an argument of type "' + name + '", which is outside the valid range [' + minRange + ', ' + maxRange + ']!'); + } + return isUnsignedType ? (value >>> 0) : (value | 0); + }, + 'argPackAdvance': 8, + 'readValueFromPointer': integerReadValueFromPointer(name, shift, minRange !== 0), + destructorFunction: null, // This type does not need a destructor + }); + } + + function __embind_register_memory_view(rawType, dataTypeIndex, name) { + var typeMapping = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + ]; + + var TA = typeMapping[dataTypeIndex]; + + function decodeMemoryView(handle) { + handle = handle >> 2; + var heap = HEAPU32; + var size = heap[handle]; // in elements + var data = heap[handle + 1]; // byte offset into emscripten heap + return new TA(heap['buffer'], data, size); + } + + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': decodeMemoryView, + 'argPackAdvance': 8, + 'readValueFromPointer': decodeMemoryView, + }, { + ignoreDuplicateRegistrations: true, + }); + } + + function __embind_register_std_string(rawType, name) { + name = readLatin1String(name); + registerType(rawType, { + name: name, + 'fromWireType': function(value) { + var length = HEAPU32[value >> 2]; + var a = new Array(length); + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(HEAPU8[value + 4 + i]); + } + _free(value); + return a.join(''); + }, + 'toWireType': function(destructors, value) { + if (value instanceof ArrayBuffer) { + value = new Uint8Array(value); + } + + function getTAElement(ta, index) { + return ta[index]; + } + function getStringElement(string, index) { + return string.charCodeAt(index); + } + var getElement; + if (value instanceof Uint8Array) { + getElement = getTAElement; + } else if (value instanceof Uint8ClampedArray) { + getElement = getTAElement; + } else if (value instanceof Int8Array) { + getElement = getTAElement; + } else if (typeof value === 'string') { + getElement = getStringElement; + } else { + throwBindingError('Cannot pass non-string to std::string'); + } + + // assumes 4-byte alignment + var length = value.length; + var ptr = _malloc(4 + length); + HEAPU32[ptr >> 2] = length; + for (var i = 0; i < length; ++i) { + var charCode = getElement(value, i); + if (charCode > 255) { + _free(ptr); + throwBindingError('String has UTF-16 code units that do not fit in 8 bits'); + } + HEAPU8[ptr + 4 + i] = charCode; + } + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + 'argPackAdvance': 8, + 'readValueFromPointer': simpleReadValueFromPointer, + destructorFunction: function(ptr) { _free(ptr); }, + }); + } + + function __embind_register_std_wstring(rawType, charSize, name) { + // nb. do not cache HEAPU16 and HEAPU32, they may be destroyed by enlargeMemory(). + name = readLatin1String(name); + var getHeap, shift; + if (charSize === 2) { + getHeap = function() { return HEAPU16; }; + shift = 1; + } else if (charSize === 4) { + getHeap = function() { return HEAPU32; }; + shift = 2; + } + registerType(rawType, { + name: name, + 'fromWireType': function(value) { + var HEAP = getHeap(); + var length = HEAPU32[value >> 2]; + var a = new Array(length); + var start = (value + 4) >> shift; + for (var i = 0; i < length; ++i) { + a[i] = String.fromCharCode(HEAP[start + i]); + } + _free(value); + return a.join(''); + }, + 'toWireType': function(destructors, value) { + // assumes 4-byte alignment + var HEAP = getHeap(); + var length = value.length; + var ptr = _malloc(4 + length * charSize); + HEAPU32[ptr >> 2] = length; + var start = (ptr + 4) >> shift; + for (var i = 0; i < length; ++i) { + HEAP[start + i] = value.charCodeAt(i); + } + if (destructors !== null) { + destructors.push(_free, ptr); + } + return ptr; + }, + 'argPackAdvance': 8, + 'readValueFromPointer': simpleReadValueFromPointer, + destructorFunction: function(ptr) { _free(ptr); }, + }); + } + + function __embind_register_void(rawType, name) { + name = readLatin1String(name); + registerType(rawType, { + isVoid: true, // void return values can be optimized out sometimes + name: name, + 'argPackAdvance': 0, + 'fromWireType': function() { + return undefined; + }, + 'toWireType': function(destructors, o) { + // TODO: assert if anything else is given? + return undefined; + }, + }); + } + + + function __emval_incref(handle) { + if (handle > 4) { + emval_handle_array[handle].refcount += 1; + } + } + + + function requireRegisteredType(rawType, humanName) { + var impl = registeredTypes[rawType]; + if (undefined === impl) { + throwBindingError(humanName + " has unknown type " + getTypeName(rawType)); + } + return impl; + }function __emval_take_value(type, argv) { + type = requireRegisteredType(type, '_emval_take_value'); + var v = type['readValueFromPointer'](argv); + return __emval_register(v); + } + + function _abort() { + Module['abort'](); + } + + + + + function _emscripten_memcpy_big(dest, src, num) { + HEAPU8.set(HEAPU8.subarray(src, src+num), dest); + return dest; + } + + + + + var PTHREAD_SPECIFIC={};function _pthread_getspecific(key) { + return PTHREAD_SPECIFIC[key] || 0; + } + + + var PTHREAD_SPECIFIC_NEXT_KEY=1; + + var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _pthread_key_create(key, destructor) { + if (key == 0) { + return ERRNO_CODES.EINVAL; + } + HEAP32[((key)>>2)]=PTHREAD_SPECIFIC_NEXT_KEY; + // values start at 0 + PTHREAD_SPECIFIC[PTHREAD_SPECIFIC_NEXT_KEY] = 0; + PTHREAD_SPECIFIC_NEXT_KEY++; + return 0; + } + + function _pthread_once(ptr, func) { + if (!_pthread_once.seen) _pthread_once.seen = {}; + if (ptr in _pthread_once.seen) return; + Module['dynCall_v'](func); + _pthread_once.seen[ptr] = 1; + } + + function _pthread_setspecific(key, value) { + if (!(key in PTHREAD_SPECIFIC)) { + return ERRNO_CODES.EINVAL; + } + PTHREAD_SPECIFIC[key] = value; + return 0; + } + + + function ___setErrNo(value) { + if (Module['___errno_location']) HEAP32[((Module['___errno_location']())>>2)]=value; + else Module.printErr('failed to set errno from JS'); + return value; + } +embind_init_charCodes(); +BindingError = Module['BindingError'] = extendError(Error, 'BindingError');; +InternalError = Module['InternalError'] = extendError(Error, 'InternalError');; +init_ClassHandle(); +init_RegisteredPointer(); +init_embind();; +UnboundTypeError = Module['UnboundTypeError'] = extendError(Error, 'UnboundTypeError');; +init_emval();; +DYNAMICTOP_PTR = staticAlloc(4); + +STACK_BASE = STACKTOP = alignMemory(STATICTOP); + +STACK_MAX = STACK_BASE + TOTAL_STACK; + +DYNAMIC_BASE = alignMemory(STACK_MAX); + +HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE; + +staticSealed = true; // seal the static portion of memory + +assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack"); + +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 nullFunc_fi(x) { Module["printErr"]("Invalid function pointer called with signature 'fi'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_fii(x) { Module["printErr"]("Invalid function pointer called with signature 'fii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_i(x) { Module["printErr"]("Invalid function pointer called with signature 'i'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_ii(x) { Module["printErr"]("Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_iii(x) { Module["printErr"]("Invalid function pointer called with signature 'iii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_iiii(x) { Module["printErr"]("Invalid function pointer called with signature 'iiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_iiiif(x) { Module["printErr"]("Invalid function pointer called with signature 'iiiif'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_v(x) { Module["printErr"]("Invalid function pointer called with signature 'v'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_vi(x) { Module["printErr"]("Invalid function pointer called with signature 'vi'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_vii(x) { Module["printErr"]("Invalid function pointer called with signature 'vii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_viif(x) { Module["printErr"]("Invalid function pointer called with signature 'viif'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_viii(x) { Module["printErr"]("Invalid function pointer called with signature 'viii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_viiif(x) { Module["printErr"]("Invalid function pointer called with signature 'viiif'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_viiii(x) { Module["printErr"]("Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_viiiii(x) { Module["printErr"]("Invalid function pointer called with signature 'viiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +function nullFunc_viiiiii(x) { Module["printErr"]("Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } + +Module['wasmTableSize'] = 1344; + +Module['wasmMaxTableSize'] = 1344; + +function invoke_fi(index,a1) { + try { + return Module["dynCall_fi"](index,a1); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_fii(index,a1,a2) { + try { + return Module["dynCall_fii"](index,a1,a2); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_i(index) { + try { + return Module["dynCall_i"](index); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_ii(index,a1) { + try { + return Module["dynCall_ii"](index,a1); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_iii(index,a1,a2) { + try { + return Module["dynCall_iii"](index,a1,a2); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_iiii(index,a1,a2,a3) { + try { + return Module["dynCall_iiii"](index,a1,a2,a3); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_iiiif(index,a1,a2,a3,a4) { + try { + return Module["dynCall_iiiif"](index,a1,a2,a3,a4); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_v(index) { + try { + Module["dynCall_v"](index); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_vi(index,a1) { + try { + Module["dynCall_vi"](index,a1); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_vii(index,a1,a2) { + try { + Module["dynCall_vii"](index,a1,a2); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_viif(index,a1,a2,a3) { + try { + Module["dynCall_viif"](index,a1,a2,a3); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_viii(index,a1,a2,a3) { + try { + Module["dynCall_viii"](index,a1,a2,a3); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_viiif(index,a1,a2,a3,a4) { + try { + Module["dynCall_viiif"](index,a1,a2,a3,a4); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_viiii(index,a1,a2,a3,a4) { + try { + Module["dynCall_viiii"](index,a1,a2,a3,a4); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_viiiii(index,a1,a2,a3,a4,a5) { + try { + Module["dynCall_viiiii"](index,a1,a2,a3,a4,a5); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6) { + try { + Module["dynCall_viiiiii"](index,a1,a2,a3,a4,a5,a6); + } catch(e) { + if (typeof e !== 'number' && e !== 'longjmp') throw e; + Module["setThrew"](1, 0); + } +} + +Module.asmGlobalArg = {}; + +Module.asmLibraryArg = { "abort": abort, "assert": assert, "enlargeMemory": enlargeMemory, "getTotalMemory": getTotalMemory, "abortOnCannotGrowMemory": abortOnCannotGrowMemory, "abortStackOverflow": abortStackOverflow, "nullFunc_fi": nullFunc_fi, "nullFunc_fii": nullFunc_fii, "nullFunc_i": nullFunc_i, "nullFunc_ii": nullFunc_ii, "nullFunc_iii": nullFunc_iii, "nullFunc_iiii": nullFunc_iiii, "nullFunc_iiiif": nullFunc_iiiif, "nullFunc_v": nullFunc_v, "nullFunc_vi": nullFunc_vi, "nullFunc_vii": nullFunc_vii, "nullFunc_viif": nullFunc_viif, "nullFunc_viii": nullFunc_viii, "nullFunc_viiif": nullFunc_viiif, "nullFunc_viiii": nullFunc_viiii, "nullFunc_viiiii": nullFunc_viiiii, "nullFunc_viiiiii": nullFunc_viiiiii, "invoke_fi": invoke_fi, "invoke_fii": invoke_fii, "invoke_i": invoke_i, "invoke_ii": invoke_ii, "invoke_iii": invoke_iii, "invoke_iiii": invoke_iiii, "invoke_iiiif": invoke_iiiif, "invoke_v": invoke_v, "invoke_vi": invoke_vi, "invoke_vii": invoke_vii, "invoke_viif": invoke_viif, "invoke_viii": invoke_viii, "invoke_viiif": invoke_viiif, "invoke_viiii": invoke_viiii, "invoke_viiiii": invoke_viiiii, "invoke_viiiiii": invoke_viiiiii, "ClassHandle": ClassHandle, "ClassHandle_clone": ClassHandle_clone, "ClassHandle_delete": ClassHandle_delete, "ClassHandle_deleteLater": ClassHandle_deleteLater, "ClassHandle_isAliasOf": ClassHandle_isAliasOf, "ClassHandle_isDeleted": ClassHandle_isDeleted, "RegisteredClass": RegisteredClass, "RegisteredPointer": RegisteredPointer, "RegisteredPointer_deleteObject": RegisteredPointer_deleteObject, "RegisteredPointer_destructor": RegisteredPointer_destructor, "RegisteredPointer_fromWireType": RegisteredPointer_fromWireType, "RegisteredPointer_getPointee": RegisteredPointer_getPointee, "__ZSt18uncaught_exceptionv": __ZSt18uncaught_exceptionv, "___cxa_allocate_exception": ___cxa_allocate_exception, "___cxa_begin_catch": ___cxa_begin_catch, "___cxa_end_catch": ___cxa_end_catch, "___cxa_find_matching_catch": ___cxa_find_matching_catch, "___cxa_find_matching_catch_2": ___cxa_find_matching_catch_2, "___cxa_find_matching_catch_3": ___cxa_find_matching_catch_3, "___cxa_free_exception": ___cxa_free_exception, "___cxa_throw": ___cxa_throw, "___gxx_personality_v0": ___gxx_personality_v0, "___lock": ___lock, "___resumeException": ___resumeException, "___setErrNo": ___setErrNo, "___syscall140": ___syscall140, "___syscall146": ___syscall146, "___syscall54": ___syscall54, "___syscall6": ___syscall6, "___unlock": ___unlock, "__embind_register_bool": __embind_register_bool, "__embind_register_class": __embind_register_class, "__embind_register_class_constructor": __embind_register_class_constructor, "__embind_register_class_function": __embind_register_class_function, "__embind_register_emval": __embind_register_emval, "__embind_register_float": __embind_register_float, "__embind_register_integer": __embind_register_integer, "__embind_register_memory_view": __embind_register_memory_view, "__embind_register_std_string": __embind_register_std_string, "__embind_register_std_wstring": __embind_register_std_wstring, "__embind_register_void": __embind_register_void, "__emval_decref": __emval_decref, "__emval_incref": __emval_incref, "__emval_register": __emval_register, "__emval_take_value": __emval_take_value, "_abort": _abort, "_embind_repr": _embind_repr, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_pthread_getspecific": _pthread_getspecific, "_pthread_key_create": _pthread_key_create, "_pthread_once": _pthread_once, "_pthread_setspecific": _pthread_setspecific, "constNoSmartPtrRawPointerToWireType": constNoSmartPtrRawPointerToWireType, "count_emval_handles": count_emval_handles, "craftInvokerFunction": craftInvokerFunction, "createNamedFunction": createNamedFunction, "downcastPointer": downcastPointer, "embind__requireFunction": embind__requireFunction, "embind_init_charCodes": embind_init_charCodes, "ensureOverloadTable": ensureOverloadTable, "exposePublicSymbol": exposePublicSymbol, "extendError": extendError, "floatReadValueFromPointer": floatReadValueFromPointer, "flushPendingDeletes": flushPendingDeletes, "flush_NO_FILESYSTEM": flush_NO_FILESYSTEM, "genericPointerToWireType": genericPointerToWireType, "getBasestPointer": getBasestPointer, "getInheritedInstance": getInheritedInstance, "getInheritedInstanceCount": getInheritedInstanceCount, "getLiveInheritedInstances": getLiveInheritedInstances, "getShiftFromSize": getShiftFromSize, "getTypeName": getTypeName, "get_first_emval": get_first_emval, "heap32VectorToArray": heap32VectorToArray, "init_ClassHandle": init_ClassHandle, "init_RegisteredPointer": init_RegisteredPointer, "init_embind": init_embind, "init_emval": init_emval, "integerReadValueFromPointer": integerReadValueFromPointer, "makeClassHandle": makeClassHandle, "makeLegalFunctionName": makeLegalFunctionName, "new_": new_, "nonConstNoSmartPtrRawPointerToWireType": nonConstNoSmartPtrRawPointerToWireType, "readLatin1String": readLatin1String, "registerType": registerType, "replacePublicSymbol": replacePublicSymbol, "requireRegisteredType": requireRegisteredType, "runDestructor": runDestructor, "runDestructors": runDestructors, "setDelayFunction": setDelayFunction, "shallowCopyInternalPointer": shallowCopyInternalPointer, "simpleReadValueFromPointer": simpleReadValueFromPointer, "throwBindingError": throwBindingError, "throwInstanceAlreadyDeleted": throwInstanceAlreadyDeleted, "throwInternalError": throwInternalError, "throwUnboundTypeError": throwUnboundTypeError, "upcastPointer": upcastPointer, "whenDependentTypesAreResolved": whenDependentTypesAreResolved, "DYNAMICTOP_PTR": DYNAMICTOP_PTR, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX }; +// EMSCRIPTEN_START_ASM +var asm =Module["asm"]// EMSCRIPTEN_END_ASM +(Module.asmGlobalArg, Module.asmLibraryArg, buffer); + +var real___GLOBAL__sub_I_bind_cpp = asm["__GLOBAL__sub_I_bind_cpp"]; asm["__GLOBAL__sub_I_bind_cpp"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real___GLOBAL__sub_I_bind_cpp.apply(null, arguments); +}; + +var real___GLOBAL__sub_I_wasm_soundmeter_cc = asm["__GLOBAL__sub_I_wasm_soundmeter_cc"]; asm["__GLOBAL__sub_I_wasm_soundmeter_cc"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real___GLOBAL__sub_I_wasm_soundmeter_cc.apply(null, arguments); +}; + +var real____cxa_can_catch = asm["___cxa_can_catch"]; asm["___cxa_can_catch"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real____cxa_can_catch.apply(null, arguments); +}; + +var real____cxa_is_pointer_type = asm["___cxa_is_pointer_type"]; asm["___cxa_is_pointer_type"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real____cxa_is_pointer_type.apply(null, arguments); +}; + +var real____errno_location = asm["___errno_location"]; asm["___errno_location"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real____errno_location.apply(null, arguments); +}; + +var real____getTypeName = asm["___getTypeName"]; asm["___getTypeName"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real____getTypeName.apply(null, arguments); +}; + +var real__fflush = asm["_fflush"]; asm["_fflush"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real__fflush.apply(null, arguments); +}; + +var real__free = asm["_free"]; asm["_free"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real__free.apply(null, arguments); +}; + +var real__llvm_bswap_i32 = asm["_llvm_bswap_i32"]; asm["_llvm_bswap_i32"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real__llvm_bswap_i32.apply(null, arguments); +}; + +var real__malloc = asm["_malloc"]; asm["_malloc"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real__malloc.apply(null, arguments); +}; + +var real__sbrk = asm["_sbrk"]; asm["_sbrk"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real__sbrk.apply(null, arguments); +}; + +var real_establishStackSpace = asm["establishStackSpace"]; asm["establishStackSpace"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real_establishStackSpace.apply(null, arguments); +}; + +var real_getTempRet0 = asm["getTempRet0"]; asm["getTempRet0"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real_getTempRet0.apply(null, arguments); +}; + +var real_setTempRet0 = asm["setTempRet0"]; asm["setTempRet0"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real_setTempRet0.apply(null, arguments); +}; + +var real_setThrew = asm["setThrew"]; asm["setThrew"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real_setThrew.apply(null, arguments); +}; + +var real_stackAlloc = asm["stackAlloc"]; asm["stackAlloc"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real_stackAlloc.apply(null, arguments); +}; + +var real_stackRestore = asm["stackRestore"]; asm["stackRestore"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real_stackRestore.apply(null, arguments); +}; + +var real_stackSave = asm["stackSave"]; asm["stackSave"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return real_stackSave.apply(null, arguments); +}; +Module["asm"] = asm; +var __GLOBAL__sub_I_bind_cpp = Module["__GLOBAL__sub_I_bind_cpp"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["__GLOBAL__sub_I_bind_cpp"].apply(null, arguments) }; +var __GLOBAL__sub_I_wasm_soundmeter_cc = Module["__GLOBAL__sub_I_wasm_soundmeter_cc"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["__GLOBAL__sub_I_wasm_soundmeter_cc"].apply(null, arguments) }; +var ___cxa_can_catch = Module["___cxa_can_catch"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["___cxa_can_catch"].apply(null, arguments) }; +var ___cxa_is_pointer_type = Module["___cxa_is_pointer_type"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["___cxa_is_pointer_type"].apply(null, arguments) }; +var ___errno_location = Module["___errno_location"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["___errno_location"].apply(null, arguments) }; +var ___getTypeName = Module["___getTypeName"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["___getTypeName"].apply(null, arguments) }; +var _fflush = Module["_fflush"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["_fflush"].apply(null, arguments) }; +var _free = Module["_free"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["_free"].apply(null, arguments) }; +var _llvm_bswap_i32 = Module["_llvm_bswap_i32"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["_llvm_bswap_i32"].apply(null, arguments) }; +var _malloc = Module["_malloc"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["_malloc"].apply(null, arguments) }; +var _memcpy = Module["_memcpy"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["_memcpy"].apply(null, arguments) }; +var _memset = Module["_memset"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["_memset"].apply(null, arguments) }; +var _sbrk = Module["_sbrk"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["_sbrk"].apply(null, arguments) }; +var establishStackSpace = Module["establishStackSpace"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["establishStackSpace"].apply(null, arguments) }; +var getTempRet0 = Module["getTempRet0"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["getTempRet0"].apply(null, arguments) }; +var runPostSets = Module["runPostSets"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["runPostSets"].apply(null, arguments) }; +var setTempRet0 = Module["setTempRet0"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["setTempRet0"].apply(null, arguments) }; +var setThrew = Module["setThrew"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["setThrew"].apply(null, arguments) }; +var stackAlloc = Module["stackAlloc"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["stackAlloc"].apply(null, arguments) }; +var stackRestore = Module["stackRestore"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["stackRestore"].apply(null, arguments) }; +var stackSave = Module["stackSave"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["stackSave"].apply(null, arguments) }; +var dynCall_fi = Module["dynCall_fi"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_fi"].apply(null, arguments) }; +var dynCall_fii = Module["dynCall_fii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_fii"].apply(null, arguments) }; +var dynCall_i = Module["dynCall_i"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_i"].apply(null, arguments) }; +var dynCall_ii = Module["dynCall_ii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_ii"].apply(null, arguments) }; +var dynCall_iii = Module["dynCall_iii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_iii"].apply(null, arguments) }; +var dynCall_iiii = Module["dynCall_iiii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_iiii"].apply(null, arguments) }; +var dynCall_iiiif = Module["dynCall_iiiif"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_iiiif"].apply(null, arguments) }; +var dynCall_v = Module["dynCall_v"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_v"].apply(null, arguments) }; +var dynCall_vi = Module["dynCall_vi"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_vi"].apply(null, arguments) }; +var dynCall_vii = Module["dynCall_vii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_vii"].apply(null, arguments) }; +var dynCall_viif = Module["dynCall_viif"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_viif"].apply(null, arguments) }; +var dynCall_viii = Module["dynCall_viii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_viii"].apply(null, arguments) }; +var dynCall_viiif = Module["dynCall_viiif"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_viiif"].apply(null, arguments) }; +var dynCall_viiii = Module["dynCall_viiii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_viiii"].apply(null, arguments) }; +var dynCall_viiiii = Module["dynCall_viiiii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_viiiii"].apply(null, arguments) }; +var dynCall_viiiiii = Module["dynCall_viiiiii"] = function() { + assert(runtimeInitialized, 'you need to wait for the runtime to be ready (e.g. wait for main() to be called)'); + assert(!runtimeExited, 'the runtime was exited (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + return Module["asm"]["dynCall_viiiiii"].apply(null, arguments) }; +; + + + +// === Auto-generated postamble setup entry stuff === + +Module['asm'] = asm; + +if (!Module["intArrayFromString"]) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["intArrayToString"]) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["ccall"]) Module["ccall"] = function() { abort("'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["cwrap"]) Module["cwrap"] = function() { abort("'cwrap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["setValue"]) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["getValue"]) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["allocate"]) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["getMemory"]) Module["getMemory"] = function() { abort("'getMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["Pointer_stringify"]) Module["Pointer_stringify"] = function() { abort("'Pointer_stringify' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["AsciiToString"]) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["stringToAscii"]) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["UTF8ArrayToString"]) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["UTF8ToString"]) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["stringToUTF8Array"]) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["stringToUTF8"]) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["lengthBytesUTF8"]) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["UTF16ToString"]) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["stringToUTF16"]) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["lengthBytesUTF16"]) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["UTF32ToString"]) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["stringToUTF32"]) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["lengthBytesUTF32"]) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["allocateUTF8"]) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["stackTrace"]) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["addOnPreRun"]) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["addOnInit"]) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["addOnPreMain"]) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["addOnExit"]) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["addOnPostRun"]) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["writeStringToMemory"]) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["writeArrayToMemory"]) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["writeAsciiToMemory"]) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["addRunDependency"]) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["removeRunDependency"]) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS"]) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["FS_createFolder"]) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS_createPath"]) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS_createDataFile"]) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS_createPreloadedFile"]) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS_createLazyFile"]) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS_createLink"]) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS_createDevice"]) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["FS_unlink"]) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Module["GL"]) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["staticAlloc"]) Module["staticAlloc"] = function() { abort("'staticAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["dynamicAlloc"]) Module["dynamicAlloc"] = function() { abort("'dynamicAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["warnOnce"]) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["loadDynamicLibrary"]) Module["loadDynamicLibrary"] = function() { abort("'loadDynamicLibrary' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["loadWebAssemblyModule"]) Module["loadWebAssemblyModule"] = function() { abort("'loadWebAssemblyModule' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["getLEB"]) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["getFunctionTables"]) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["alignFunctionTables"]) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["registerFunctions"]) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["addFunction"]) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["removeFunction"]) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["getFuncWrapper"]) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["prettyPrint"]) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["makeBigInt"]) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["dynCall"]) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Module["getCompilerSetting"]) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") };if (!Module["ALLOC_NORMAL"]) Object.defineProperty(Module, "ALLOC_NORMAL", { get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Module["ALLOC_STACK"]) Object.defineProperty(Module, "ALLOC_STACK", { get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Module["ALLOC_STATIC"]) Object.defineProperty(Module, "ALLOC_STATIC", { get: function() { abort("'ALLOC_STATIC' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Module["ALLOC_DYNAMIC"]) Object.defineProperty(Module, "ALLOC_DYNAMIC", { get: function() { abort("'ALLOC_DYNAMIC' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Module["ALLOC_NONE"]) Object.defineProperty(Module, "ALLOC_NONE", { get: function() { abort("'ALLOC_NONE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); + + + + +/** + * @constructor + * @extends {Error} + * @this {ExitStatus} + */ +function ExitStatus(status) { + this.name = "ExitStatus"; + this.message = "Program terminated with exit(" + status + ")"; + this.status = status; +}; +ExitStatus.prototype = new Error(); +ExitStatus.prototype.constructor = ExitStatus; + +var initialStackTop; +var calledMain = false; + +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 (!Module['calledRun']) run(); + if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled +} + + + + + +/** @type {function(Array=)} */ +function run(args) { + args = args || Module['arguments']; + + if (runDependencies > 0) { + return; + } + + writeStackCookie(); + + preRun(); + + if (runDependencies > 0) return; // a preRun added a dependency, run will be called later + if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame + + function doRun() { + if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening + Module['calledRun'] = true; + + if (ABORT) return; + + ensureInitRuntime(); + + preMain(); + + if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized'](); + + assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]'); + + postRun(); + } + + if (Module['setStatus']) { + Module['setStatus']('Running...'); + setTimeout(function() { + setTimeout(function() { + Module['setStatus'](''); + }, 1); + doRun(); + }, 1); + } else { + doRun(); + } + checkStackCookie(); +} +Module['run'] = run; + +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 NO_FILESYSTEM + // mode (which has its own special function for this; otherwise, all + // the code is inside libc) + var print = Module['print']; + var printErr = Module['printErr']; + var has = false; + Module['print'] = Module['printErr'] = function(x) { + has = true; + } + try { // it doesn't matter if it fails + var flush = flush_NO_FILESYSTEM; + if (flush) flush(0); + } catch(e) {} + Module['print'] = print; + Module['printErr'] = printErr; + if (has) { + warnOnce('stdio streams had content in them that was not flushed. you should set NO_EXIT_RUNTIME to 0 (see the FAQ), or make sure to emit a newline when you printf etc.'); + } +} + +function exit(status, implicit) { + checkUnflushedContent(); + + // if this is just main exit-ing implicitly, and the status is 0, then we + // don't need to do anything here and can just leave. if the status is + // non-zero, though, then we need to report it. + // (we may have warned about this earlier, if a situation justifies doing so) + if (implicit && Module['noExitRuntime'] && status === 0) { + return; + } + + if (Module['noExitRuntime']) { + // if exit() was called, we may warn the user if the runtime isn't actually being shut down + if (!implicit) { + Module.printErr('exit(' + status + ') called, but NO_EXIT_RUNTIME is set, so halting execution but not exiting the runtime or preventing further async execution (build with NO_EXIT_RUNTIME=0, if you want a true shutdown)'); + } + } else { + + ABORT = true; + EXITSTATUS = status; + STACKTOP = initialStackTop; + + exitRuntime(); + + if (Module['onExit']) Module['onExit'](status); + } + + if (ENVIRONMENT_IS_NODE) { + process['exit'](status); + } + Module['quit'](status, new ExitStatus(status)); +} +Module['exit'] = exit; + +var abortDecorators = []; + +function abort(what) { + if (Module['onAbort']) { + Module['onAbort'](what); + } + + if (what !== undefined) { + Module.print(what); + Module.printErr(what); + what = JSON.stringify(what) + } else { + what = ''; + } + + ABORT = true; + EXITSTATUS = 1; + + var extra = ''; + var output = 'abort(' + what + ') at ' + stackTrace() + extra; + if (abortDecorators) { + abortDecorators.forEach(function(decorator) { + output = decorator(output, what); + }); + } + throw output; +} +Module['abort'] = abort; + +// {{PRE_RUN_ADDITIONS}} + +if (Module['preInit']) { + if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; + while (Module['preInit'].length > 0) { + Module['preInit'].pop()(); + } +} + + +Module["noExitRuntime"] = true; + +run(); + +// {{POST_RUN_ADDITIONS}} + + + + + +// {{MODULE_ADDITIONS}} + + + diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.wasm b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e05ce19a0748b16bcc019a17f85f787eb90b6d21 GIT binary patch literal 83590 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 literal 0 HcmV?d00001 diff --git a/src/content/getusermedia/wasm-volume/setup.sh b/src/content/getusermedia/wasm-volume/setup.sh new file mode 100755 index 000000000..dddd9e72b --- /dev/null +++ b/src/content/getusermedia/wasm-volume/setup.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Code to setup the webassembly repo for experimentation +# + +# Install Emscripten prerequisites + +sudo apt-get install build-essential cmake python2.7 nodejs + +# Install the WebAssembly toolchain +# Normally VERSION should be "latest", but bugs. +VERSION=sdk-1.37.34-64bit + +if [ ! -f emsdk ]; then + git clone https://github.com/juj/emsdk.git + (cd emsdk && ./emsdk install $VERSION && ./emsdk activate $VERSION) +fi +echo "You have to do . emsdk/emsdk_env.sh before compiling" From da61409d001a7ed9408b545e20d5ac9c600bec58 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Wed, 14 Mar 2018 12:22:28 +0100 Subject: [PATCH 2/3] Working example --- .../getusermedia/wasm-volume/js/main.js | 10 ++++---- .../wasm-volume/js/wasm-soundmeter-wrapper.js | 11 ++++++--- .../wasm-volume/js/wasm-soundmeter.cc | 23 ++++++++++++------ .../wasm-volume/js/wasm-soundmeter.js | 8 +++--- .../wasm-volume/js/wasm-soundmeter.wasm | Bin 83590 -> 83053 bytes 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/content/getusermedia/wasm-volume/js/main.js b/src/content/getusermedia/wasm-volume/js/main.js index bc85d6e26..f9d7e882f 100644 --- a/src/content/getusermedia/wasm-volume/js/main.js +++ b/src/content/getusermedia/wasm-volume/js/main.js @@ -24,11 +24,11 @@ var Module = { var instantMeter = document.querySelector('#instant meter'); var slowMeter = document.querySelector('#slow meter'); -var clipMeter = document.querySelector('#clip meter'); +var wasmMeter = document.querySelector('#wasm meter'); var instantValueDisplay = document.querySelector('#instant .value'); var slowValueDisplay = document.querySelector('#slow .value'); -var clipValueDisplay = document.querySelector('#clip .value'); +var wasmValueDisplay = document.querySelector('#wasm .value'); try { window.AudioContext = window.AudioContext || window.webkitAudioContext; @@ -60,15 +60,15 @@ function handleSuccess(stream) { soundMeter.slow.toFixed(2); }, 200); }); - var wasmMeter = window.wasmMeter = new WasmSoundMeter(window.audioContext); - wasmMeter.connectToSource(stream, function(e) { + var wasmSoundMeter = window.wasmSoundMeter = new WasmSoundMeter(window.audioContext); + wasmSoundMeter.connectToSource(stream, function(e) { if (e) { alert(e); return; } setInterval(function() { wasmMeter.value = wasmValueDisplay.innerText = - wasmMeter.instant; + wasmSoundMeter.instant.toFixed(2); }, 200); }); } diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js index 15605a3a3..0d1cd558a 100644 --- a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js +++ b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter-wrapper.js @@ -19,12 +19,15 @@ function WasmSoundMeter(context) { this.slow = 0.0; this.clip = 0.0; this.script = context.createScriptProcessor(2048, 1, 1); - this.measurer = new Module.SoundMeter(); + this.measurer = new Module.SoundMeter(2048); var that = this; this.script.onaudioprocess = function(event) { - var input = event.inputBuffer.getChannelData(0); - // Waiting for how to pass Float32Array to JS - // that.measurer.load_data(input); + var inputbuf = event.inputBuffer.getChannelData(0); + var asmbuf = that.measurer.data_buffer(); + for (let i = 0; i < inputbuf.length; i++) { + asmbuf.set(i, inputbuf[i]); + } + that.measurer.process_data_buffer(); that.instant = that.measurer.get_fast_volume(); that.slow = that.measurer.get_slow_volume(); }; diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc index fa8305aea..23fcdaeff 100644 --- a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc +++ b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.cc @@ -9,13 +9,15 @@ // This uses the "Embind" method of defining the interface. // http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#embind +#include #include class SoundMeter { public: - SoundMeter() {}; - void load_data(std::vector& data); - std::vector data() { return data_; } // pass-by-value + SoundMeter(size_t buffer_size) + : data_(buffer_size) {}; + std::vector* data_buffer() { return &data_; } // pass by reference + void process_data_buffer(); float get_fast_volume() { return decay_short_; } float get_slow_volume() { return decay_long_; } private: @@ -24,15 +26,20 @@ class SoundMeter { std::vector data_; }; -void SoundMeter::load_data(std::vector& data) { - +void SoundMeter::process_data_buffer() { + float sum = 0.0; + for (int i = 0; i < data_.size(); i++) { + sum += data_[i] * data_[i]; + } + decay_short_ = sqrt(sum / data_.size()); + decay_long_ = 0.95 * decay_long_ + 0.05 * decay_short_; } EMSCRIPTEN_BINDINGS(random_string) { emscripten::class_("SoundMeter") - .constructor() - .function("load_data", &SoundMeter::load_data) - .function("data", &SoundMeter::data) + .constructor() + .function("data_buffer", &SoundMeter::data_buffer, emscripten::allow_raw_pointers()) + .function("process_data_buffer", &SoundMeter::process_data_buffer) .function("get_fast_volume", &SoundMeter::get_fast_volume) .function("get_slow_volume", &SoundMeter::get_slow_volume); } diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js index 9c89bc800..d26b35114 100644 --- a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js +++ b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.js @@ -1728,7 +1728,7 @@ var ASM_CONSTS = []; STATIC_BASE = GLOBAL_BASE; -STATICTOP = STATIC_BASE + 9152; +STATICTOP = STATIC_BASE + 9168; /* global initializers */ __ATINIT__.push({ func: function() { __GLOBAL__sub_I_wasm_soundmeter_cc() } }, { func: function() { __GLOBAL__sub_I_bind_cpp() } }); @@ -1737,7 +1737,7 @@ STATICTOP = STATIC_BASE + 9152; -var STATIC_BUMP = 9152; +var STATIC_BUMP = 9168; Module["STATIC_BASE"] = STATIC_BASE; Module["STATIC_BUMP"] = STATIC_BUMP; @@ -3700,9 +3700,9 @@ function nullFunc_viiiii(x) { Module["printErr"]("Invalid function pointer calle function nullFunc_viiiiii(x) { Module["printErr"]("Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); Module["printErr"]("Build with ASSERTIONS=2 for more info.");abort(x) } -Module['wasmTableSize'] = 1344; +Module['wasmTableSize'] = 1280; -Module['wasmMaxTableSize'] = 1344; +Module['wasmMaxTableSize'] = 1280; function invoke_fi(index,a1) { try { diff --git a/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.wasm b/src/content/getusermedia/wasm-volume/js/wasm-soundmeter.wasm index e05ce19a0748b16bcc019a17f85f787eb90b6d21..bbadbb49534b0b8e3c72b530011278f6f16cbf80 100644 GIT binary patch delta 14060 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 K6N;%%{Qm-iO(J{% delta 14206 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 From 2fe27ed585a8748f6e9780936cf26f98980e221b Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Wed, 14 Mar 2018 13:10:18 +0100 Subject: [PATCH 3/3] Added comment on serving over HTTP --- src/content/getusermedia/wasm-volume/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/content/getusermedia/wasm-volume/README.md b/src/content/getusermedia/wasm-volume/README.md index d58bf56f6..683320696 100644 --- a/src/content/getusermedia/wasm-volume/README.md +++ b/src/content/getusermedia/wasm-volume/README.md @@ -12,3 +12,8 @@ To setup: Run `setup.sh`, and then `source emsdk/emsdk_env.sh` To compile: Run `make` +The resulting content has to be served from a http: URL with the root +pointing above the "content" directory, because WASM fetching uses CORS, +and there are links to "../../.." in the HTML files here. + +