| |
| // === Auto-generated postamble setup entry stuff === |
| |
| #if MEM_INIT_METHOD == 2 |
| #if USE_PTHREADS |
| if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) (function(s) { |
| #else |
| if (memoryInitializer) (function(s) { |
| #endif |
| var i, n = s.length; |
| #if ASSERTIONS |
| n -= 4; |
| var crc, bit, table = new Int32Array(256); |
| for (i = 0; i < 256; ++i) { |
| for (crc = i, bit = 0; bit < 8; ++bit) |
| crc = (crc >>> 1) ^ ((crc & 1) * 0xedb88320); |
| table[i] = crc >>> 0; |
| } |
| crc = -1; |
| crc = table[(crc ^ n) & 0xff] ^ (crc >>> 8); |
| crc = table[(crc ^ (n >>> 8)) & 0xff] ^ (crc >>> 8); |
| for (i = 0; i < s.length; ++i) { |
| crc = table[(crc ^ s.charCodeAt(i)) & 0xff] ^ (crc >>> 8); |
| } |
| assert(crc === 0, "memory initializer checksum"); |
| #endif |
| for (i = 0; i < n; ++i) { |
| HEAPU8[Runtime.GLOBAL_BASE + i] = s.charCodeAt(i); |
| } |
| })(memoryInitializer); |
| #else |
| #if MEM_INIT_METHOD == 1 |
| #if USE_PTHREADS |
| if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) { |
| #else |
| if (memoryInitializer) { |
| #endif |
| if (typeof Module['locateFile'] === 'function') { |
| memoryInitializer = Module['locateFile'](memoryInitializer); |
| } else if (Module['memoryInitializerPrefixURL']) { |
| memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer; |
| } |
| if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) { |
| var data = Module['readBinary'](memoryInitializer); |
| HEAPU8.set(data, Runtime.GLOBAL_BASE); |
| } else { |
| addRunDependency('memory initializer'); |
| var applyMemoryInitializer = function(data) { |
| if (data.byteLength) data = new Uint8Array(data); |
| #if ASSERTIONS |
| for (var i = 0; i < data.length; i++) { |
| assert(HEAPU8[Runtime.GLOBAL_BASE + i] === 0, "area for memory initializer should not have been touched before it's loaded"); |
| } |
| #endif |
| HEAPU8.set(data, Runtime.GLOBAL_BASE); |
| removeRunDependency('memory initializer'); |
| } |
| var request = Module['memoryInitializerRequest']; |
| if (request) { |
| // a network request has already been created, just use that |
| if (request.response) { |
| setTimeout(function() { |
| applyMemoryInitializer(request.response); |
| }, 0); // it's already here; but, apply it asynchronously |
| } else { |
| request.addEventListener('load', function() { // wait for it |
| if (request.status !== 200 && request.status !== 0) { |
| console.warn('a problem seems to have happened with Module.memoryInitializerRequest, status: ' + request.status); |
| } |
| if (!request.response || typeof request.response !== 'object' || !request.response.byteLength) { |
| console.warn('a problem seems to have happened with Module.memoryInitializerRequest response (expected ArrayBuffer): ' + request.response); |
| } |
| applyMemoryInitializer(request.response); |
| }); |
| } |
| } else { |
| // fetch it from the network ourselves |
| Browser.asyncLoad(memoryInitializer, applyMemoryInitializer, function() { |
| throw 'could not load memory initializer ' + memoryInitializer; |
| }); |
| } |
| } |
| } |
| #endif |
| #endif |
| |
| 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 preloadStartTime = null; |
| 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 |
| } |
| |
| Module['callMain'] = Module.callMain = function callMain(args) { |
| assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)'); |
| assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called'); |
| |
| args = args || []; |
| |
| ensureInitRuntime(); |
| |
| var argc = args.length+1; |
| function pad() { |
| for (var i = 0; i < {{{ QUANTUM_SIZE }}}-1; i++) { |
| argv.push(0); |
| } |
| } |
| var argv = [allocate(intArrayFromString(Module['thisProgram']), 'i8', ALLOC_NORMAL) ]; |
| pad(); |
| for (var i = 0; i < argc-1; i = i + 1) { |
| argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL)); |
| pad(); |
| } |
| argv.push(0); |
| argv = allocate(argv, 'i32', ALLOC_NORMAL); |
| |
| initialStackTop = Runtime.stackSave(); |
| #if EMTERPRETIFY_ASYNC |
| var initialEmtStackTop = asm.emtStackSave(); |
| #endif |
| |
| try { |
| #if BENCHMARK |
| var start = Date.now(); |
| #endif |
| |
| var ret = Module['_main'](argc, argv, 0); |
| |
| #if BENCHMARK |
| Module.realPrint('main() took ' + (Date.now() - start) + ' milliseconds'); |
| #endif |
| |
| // if we're not running an evented main loop, it's time to exit |
| exit(ret, /* implicit = */ true); |
| } |
| catch(e) { |
| if (e instanceof ExitStatus) { |
| // exit() throws this once it's done to make sure execution |
| // has been stopped completely |
| return; |
| } else if (e == 'SimulateInfiniteLoop') { |
| // running an evented main loop, don't immediately exit |
| Module['noExitRuntime'] = true; |
| Runtime.stackRestore(initialStackTop); |
| #if EMTERPRETIFY_ASYNC |
| asm.emtStackRestore(initialEmtStackTop); |
| #endif |
| return; |
| } else { |
| if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]); |
| throw e; |
| } |
| } finally { |
| calledMain = true; |
| } |
| } |
| |
| {{GLOBAL_VARS}} |
| |
| function run(args) { |
| args = args || Module['arguments']; |
| |
| if (preloadStartTime === null) preloadStartTime = Date.now(); |
| |
| if (runDependencies > 0) { |
| #if ASSERTIONS |
| Module.printErr('run() called, but dependencies remain, so not running'); |
| #endif |
| return; |
| } |
| |
| 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 ASSERTIONS |
| if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) { |
| Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms'); |
| } |
| #endif |
| |
| if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized'](); |
| |
| if (Module['_main'] && shouldRunNow) Module['callMain'](args); |
| |
| postRun(); |
| } |
| |
| if (Module['setStatus']) { |
| Module['setStatus']('Running...'); |
| setTimeout(function() { |
| setTimeout(function() { |
| Module['setStatus'](''); |
| }, 1); |
| doRun(); |
| }, 1); |
| } else { |
| doRun(); |
| } |
| } |
| Module['run'] = Module.run = run; |
| |
| function exit(status, implicit) { |
| if (implicit && Module['noExitRuntime']) { |
| #if ASSERTIONS |
| Module.printErr('exit(' + status + ') implicitly called by end of main(), but noExitRuntime, so not exiting the runtime (you can use emscripten_force_exit, if you want to force a true shutdown)'); |
| #endif |
| return; |
| } |
| |
| if (Module['noExitRuntime']) { |
| #if ASSERTIONS |
| Module.printErr('exit(' + status + ') called, but noExitRuntime, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)'); |
| #endif |
| } else { |
| #if USE_PTHREADS |
| PThread.terminateAllThreads(); |
| #endif |
| |
| ABORT = true; |
| EXITSTATUS = status; |
| STACKTOP = initialStackTop; |
| |
| exitRuntime(); |
| |
| if (Module['onExit']) Module['onExit'](status); |
| } |
| |
| #if NODE_STDOUT_FLUSH_WORKAROUND |
| if (ENVIRONMENT_IS_NODE) { |
| // Work around a node.js bug where stdout buffer is not flushed at process exit: |
| // Instead of process.exit() directly, wait for stdout flush event. |
| // See https://github.com/joyent/node/issues/1669 and https://github.com/kripken/emscripten/issues/2582 |
| // Workaround is based on https://github.com/RReverser/acorn/commit/50ab143cecc9ed71a2d66f78b4aec3bb2e9844f6 |
| process['stdout']['once']('drain', function () { |
| process['exit'](status); |
| }); |
| console.log(' '); // Make sure to print something to force the drain event to occur, in case the stdout buffer was empty. |
| // Work around another node bug where sometimes 'drain' is never fired - make another effort |
| // to emit the exit status, after a significant delay (if node hasn't fired drain by then, give up) |
| setTimeout(function() { |
| process['exit'](status); |
| }, 500); |
| } else |
| #endif |
| if (ENVIRONMENT_IS_SHELL && typeof quit === 'function') { |
| quit(status); |
| } |
| // if we reach here, we must throw an exception to halt the current execution |
| throw new ExitStatus(status); |
| } |
| Module['exit'] = Module.exit = exit; |
| |
| var abortDecorators = []; |
| |
| function abort(what) { |
| #if USE_PTHREADS |
| if (ENVIRONMENT_IS_PTHREAD) console.error('Pthread aborting at ' + new Error().stack); |
| #endif |
| if (what !== undefined) { |
| Module.print(what); |
| Module.printErr(what); |
| what = JSON.stringify(what) |
| } else { |
| what = ''; |
| } |
| |
| ABORT = true; |
| EXITSTATUS = 1; |
| |
| #if ASSERTIONS == 0 |
| var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.'; |
| #else |
| var extra = ''; |
| #endif |
| |
| var output = 'abort(' + what + ') at ' + stackTrace() + extra; |
| if (abortDecorators) { |
| abortDecorators.forEach(function(decorator) { |
| output = decorator(output, what); |
| }); |
| } |
| throw output; |
| } |
| Module['abort'] = 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()(); |
| } |
| } |
| |
| // shouldRunNow refers to calling main(), not run(). |
| #if INVOKE_RUN |
| var shouldRunNow = true; |
| #else |
| var shouldRunNow = false; |
| #endif |
| if (Module['noInitialRun']) { |
| shouldRunNow = false; |
| } |
| |
| #if NO_EXIT_RUNTIME |
| Module["noExitRuntime"] = true; |
| #endif |
| |
| #if USE_PTHREADS |
| if (!ENVIRONMENT_IS_PTHREAD) run(); |
| #else |
| run(); |
| #endif |
| |
| // {{POST_RUN_ADDITIONS}} |
| |
| #if BUILD_AS_WORKER |
| |
| var messageBuffer = null; |
| |
| function messageResender() { |
| if (runtimeInitialized) { |
| assert(messageBuffer && messageBuffer.length > 0); |
| messageBuffer.forEach(function(message) { |
| onmessage(message); |
| }); |
| messageBuffer = null; |
| } else { |
| setTimeout(messageResender, 100); |
| } |
| } |
| |
| var buffer = 0, bufferSize = 0; |
| var workerResponded = false, workerCallbackId = -1; |
| |
| onmessage = function onmessage(msg) { |
| // if main has not yet been called (mem init file, other async things), buffer messages |
| if (!runtimeInitialized) { |
| if (!messageBuffer) { |
| messageBuffer = []; |
| setTimeout(messageResender, 100); |
| } |
| messageBuffer.push(msg); |
| return; |
| } |
| |
| var func = Module['_' + msg.data['funcName']]; |
| if (!func) throw 'invalid worker function to call: ' + msg.data['funcName']; |
| var data = msg.data['data']; |
| if (data) { |
| if (!data.byteLength) data = new Uint8Array(data); |
| if (!buffer || bufferSize < data.length) { |
| if (buffer) _free(buffer); |
| bufferSize = data.length; |
| buffer = _malloc(data.length); |
| } |
| HEAPU8.set(data, buffer); |
| } |
| |
| workerResponded = false; |
| workerCallbackId = msg.data['callbackId']; |
| if (data) { |
| func(buffer, data.length); |
| } else { |
| func(0, 0); |
| } |
| } |
| |
| #endif |
| |