@thenick775/mgba-wasm 2.1.0 → 2.1.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mgba.js CHANGED
@@ -48,6 +48,11 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR
48
48
  // it with a specific name.
49
49
  var ENVIRONMENT_IS_PTHREAD = ENVIRONMENT_IS_WORKER && self.name?.startsWith('em-pthread');
50
50
 
51
+ if (ENVIRONMENT_IS_PTHREAD) {
52
+ assert(!globalThis.moduleLoaded, 'module should only be loaded once on each pthread worker');
53
+ globalThis.moduleLoaded = true;
54
+ }
55
+
51
56
  // --pre-jses are emitted after the Module integration code, so that they can
52
57
  // refer to Module (if they choose; they can also define Module)
53
58
  // include: /home/mgba/src/src/platform/wasm/pre.js
@@ -479,6 +484,21 @@ Module.setCoreSettings = (coreSettings) => {
479
484
 
480
485
  if (coreSettings?.frameSkip !== undefined)
481
486
  setIntegerCoreSetting('frameSkip', coreSettings.frameSkip);
487
+
488
+ if (coreSettings.audioSampleRate !== undefined)
489
+ setIntegerCoreSetting('audioSampleRate', coreSettings.audioSampleRate);
490
+
491
+ if (coreSettings.audioBufferSize !== undefined)
492
+ setIntegerCoreSetting('audioBufferSize', coreSettings.audioBufferSize);
493
+
494
+ if (coreSettings.videoSync !== undefined)
495
+ setIntegerCoreSetting('videoSync', coreSettings.videoSync);
496
+
497
+ if (coreSettings.audioSync !== undefined)
498
+ setIntegerCoreSetting('audioSync', coreSettings.audioSync);
499
+
500
+ if (coreSettings.threadedVideo !== undefined)
501
+ setIntegerCoreSetting('threadedVideo', coreSettings.threadedVideo);
482
502
  };
483
503
  // end include: /home/mgba/src/src/platform/wasm/pre.js
484
504
 
@@ -508,6 +528,12 @@ function locateFile(path) {
508
528
  // Hooks that are implemented differently in different runtime environments.
509
529
  var readAsync, readBinary;
510
530
 
531
+ if (ENVIRONMENT_IS_SHELL) {
532
+
533
+ if ((typeof process == 'object' && typeof require === 'function') || typeof window == 'object' || typeof WorkerGlobalScope != 'undefined') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
534
+
535
+ } else
536
+
511
537
  // Note that this includes Node.js workers when relevant (pthreads is enabled).
512
538
  // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
513
539
  // ENVIRONMENT_IS_NODE.
@@ -534,6 +560,8 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
534
560
  scriptDirectory = scriptDirectory.slice(0, scriptDirectory.replace(/[?#].*/, '').lastIndexOf('/')+1);
535
561
  }
536
562
 
563
+ if (!(typeof window == 'object' || typeof WorkerGlobalScope != 'undefined')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)');
564
+
537
565
  {
538
566
  // include: web_or_worker_shell_read.js
539
567
  if (ENVIRONMENT_IS_WORKER) {
@@ -547,6 +575,7 @@ if (ENVIRONMENT_IS_WORKER) {
547
575
  }
548
576
 
549
577
  readAsync = async (url) => {
578
+ assert(!isFileURI(url), "readAsync does not work with file:// URLs");
550
579
  var response = await fetch(url, { credentials: 'same-origin' });
551
580
  if (response.ok) {
552
581
  return response.arrayBuffer();
@@ -557,6 +586,7 @@ if (ENVIRONMENT_IS_WORKER) {
557
586
  }
558
587
  } else
559
588
  {
589
+ throw new Error('environment detection error');
560
590
  }
561
591
 
562
592
  var out = Module['print'] || console.log.bind(console);
@@ -567,17 +597,49 @@ Object.assign(Module, moduleOverrides);
567
597
  // Free the object hierarchy contained in the overrides, this lets the GC
568
598
  // reclaim data used.
569
599
  moduleOverrides = null;
600
+ checkIncomingModuleAPI();
570
601
 
571
602
  // Emit code to handle expected values on the Module object. This applies Module.x
572
603
  // to the proper local x. This has two benefits: first, we only emit it if it is
573
604
  // expected to arrive, and second, by using a local everywhere else that can be
574
605
  // minified.
575
606
 
576
- if (Module['arguments']) arguments_ = Module['arguments'];
607
+ if (Module['arguments']) arguments_ = Module['arguments'];legacyModuleProp('arguments', 'arguments_');
577
608
 
578
- if (Module['thisProgram']) thisProgram = Module['thisProgram'];
609
+ if (Module['thisProgram']) thisProgram = Module['thisProgram'];legacyModuleProp('thisProgram', 'thisProgram');
579
610
 
580
611
  // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
612
+ // Assertions on removed incoming Module JS APIs.
613
+ assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
614
+ assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
615
+ assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
616
+ assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
617
+ assert(typeof Module['read'] == 'undefined', 'Module.read option was removed');
618
+ assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
619
+ assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
620
+ assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)');
621
+ assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
622
+ legacyModuleProp('asm', 'wasmExports');
623
+ legacyModuleProp('readAsync', 'readAsync');
624
+ legacyModuleProp('readBinary', 'readBinary');
625
+ legacyModuleProp('setWindowTitle', 'setWindowTitle');
626
+ var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js';
627
+ var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js';
628
+ var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js';
629
+ var FETCHFS = 'FETCHFS is no longer included by default; build with -lfetchfs.js';
630
+ var ICASEFS = 'ICASEFS is no longer included by default; build with -licasefs.js';
631
+ var JSFILEFS = 'JSFILEFS is no longer included by default; build with -ljsfilefs.js';
632
+ var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
633
+
634
+ var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
635
+
636
+ assert(
637
+ ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER || ENVIRONMENT_IS_NODE, 'Pthreads do not work in this environment yet (need Web Workers, or an alternative to them)');
638
+
639
+ assert(!ENVIRONMENT_IS_NODE, 'node environment detected but not enabled at build time. Add `node` to `-sENVIRONMENT` to enable.');
640
+
641
+ assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.');
642
+
581
643
  // end include: shell.js
582
644
 
583
645
  // include: preamble.js
@@ -591,7 +653,11 @@ if (Module['thisProgram']) thisProgram = Module['thisProgram'];
591
653
  // An online HTML version (which may be of a different version of Emscripten)
592
654
  // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
593
655
 
594
- var wasmBinary = Module['wasmBinary'];
656
+ var wasmBinary = Module['wasmBinary'];legacyModuleProp('wasmBinary', 'wasmBinary');
657
+
658
+ if (typeof WebAssembly != 'object') {
659
+ err('no native wasm support detected');
660
+ }
595
661
 
596
662
  // Wasm globals
597
663
 
@@ -620,13 +686,13 @@ var EXITSTATUS;
620
686
  /** @type {function(*, string=)} */
621
687
  function assert(condition, text) {
622
688
  if (!condition) {
623
- // This build was created without ASSERTIONS defined. `assert()` should not
624
- // ever be called in this configuration but in case there are callers in
625
- // the wild leave this simple abort() implementation here for now.
626
- abort(text);
689
+ abort('Assertion failed' + (text ? ': ' + text : ''));
627
690
  }
628
691
  }
629
692
 
693
+ // We used to include malloc/free by default in the past. Show a helpful error in
694
+ // builds with assertions.
695
+
630
696
  // Memory management
631
697
 
632
698
  var HEAP,
@@ -663,10 +729,176 @@ var isFileURI = (filename) => filename.startsWith('file://');
663
729
 
664
730
  // include: runtime_shared.js
665
731
  // include: runtime_stack_check.js
732
+ // Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
733
+ function writeStackCookie() {
734
+ var max = _emscripten_stack_get_end();
735
+ assert((max & 3) == 0);
736
+ // If the stack ends at address zero we write our cookies 4 bytes into the
737
+ // stack. This prevents interference with SAFE_HEAP and ASAN which also
738
+ // monitor writes to address zero.
739
+ if (max == 0) {
740
+ max += 4;
741
+ }
742
+ // The stack grow downwards towards _emscripten_stack_get_end.
743
+ // We write cookies to the final two words in the stack and detect if they are
744
+ // ever overwritten.
745
+ HEAPU32[((max)>>2)] = 0x02135467;
746
+ HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
747
+ // Also test the global address 0 for integrity.
748
+ HEAPU32[((0)>>2)] = 1668509029;
749
+ }
750
+
751
+ function checkStackCookie() {
752
+ if (ABORT) return;
753
+ var max = _emscripten_stack_get_end();
754
+ // See writeStackCookie().
755
+ if (max == 0) {
756
+ max += 4;
757
+ }
758
+ var cookie1 = HEAPU32[((max)>>2)];
759
+ var cookie2 = HEAPU32[(((max)+(4))>>2)];
760
+ if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
761
+ abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
762
+ }
763
+ // Also test the global address 0 for integrity.
764
+ if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) {
765
+ abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
766
+ }
767
+ }
666
768
  // end include: runtime_stack_check.js
667
769
  // include: runtime_exceptions.js
668
770
  // end include: runtime_exceptions.js
669
771
  // include: runtime_debug.js
772
+ // Endianness check
773
+ (() => {
774
+ var h16 = new Int16Array(1);
775
+ var h8 = new Int8Array(h16.buffer);
776
+ h16[0] = 0x6373;
777
+ if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)';
778
+ })();
779
+
780
+ if (Module['ENVIRONMENT']) {
781
+ throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
782
+ }
783
+
784
+ function legacyModuleProp(prop, newName, incoming=true) {
785
+ if (!Object.getOwnPropertyDescriptor(Module, prop)) {
786
+ Object.defineProperty(Module, prop, {
787
+ configurable: true,
788
+ get() {
789
+ let extra = incoming ? ' (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)' : '';
790
+ abort(`\`Module.${prop}\` has been replaced by \`${newName}\`` + extra);
791
+
792
+ }
793
+ });
794
+ }
795
+ }
796
+
797
+ function consumedModuleProp(prop) {
798
+ if (!Object.getOwnPropertyDescriptor(Module, prop)) {
799
+ Object.defineProperty(Module, prop, {
800
+ configurable: true,
801
+ set() {
802
+ abort(`Attempt to set \`Module.${prop}\` after it has already been processed. This can happen, for example, when code is injected via '--post-js' rather than '--pre-js'`);
803
+
804
+ }
805
+ });
806
+ }
807
+ }
808
+
809
+ function ignoredModuleProp(prop) {
810
+ if (Object.getOwnPropertyDescriptor(Module, prop)) {
811
+ abort(`\`Module.${prop}\` was supplied but \`${prop}\` not included in INCOMING_MODULE_JS_API`);
812
+ }
813
+ }
814
+
815
+ // forcing the filesystem exports a few things by default
816
+ function isExportedByForceFilesystem(name) {
817
+ return name === 'FS_createPath' ||
818
+ name === 'FS_createDataFile' ||
819
+ name === 'FS_createPreloadedFile' ||
820
+ name === 'FS_unlink' ||
821
+ name === 'addRunDependency' ||
822
+ // The old FS has some functionality that WasmFS lacks.
823
+ name === 'FS_createLazyFile' ||
824
+ name === 'FS_createDevice' ||
825
+ name === 'removeRunDependency';
826
+ }
827
+
828
+ /**
829
+ * Intercept access to a global symbol. This enables us to give informative
830
+ * warnings/errors when folks attempt to use symbols they did not include in
831
+ * their build, or no symbols that no longer exist.
832
+ */
833
+ function hookGlobalSymbolAccess(sym, func) {
834
+ if (typeof globalThis != 'undefined' && !Object.getOwnPropertyDescriptor(globalThis, sym)) {
835
+ Object.defineProperty(globalThis, sym, {
836
+ configurable: true,
837
+ get() {
838
+ func();
839
+ return undefined;
840
+ }
841
+ });
842
+ }
843
+ }
844
+
845
+ function missingGlobal(sym, msg) {
846
+ hookGlobalSymbolAccess(sym, () => {
847
+ warnOnce(`\`${sym}\` is not longer defined by emscripten. ${msg}`);
848
+ });
849
+ }
850
+
851
+ missingGlobal('buffer', 'Please use HEAP8.buffer or wasmMemory.buffer');
852
+ missingGlobal('asm', 'Please use wasmExports instead');
853
+
854
+ function missingLibrarySymbol(sym) {
855
+ hookGlobalSymbolAccess(sym, () => {
856
+ // Can't `abort()` here because it would break code that does runtime
857
+ // checks. e.g. `if (typeof SDL === 'undefined')`.
858
+ var msg = `\`${sym}\` is a library symbol and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line`;
859
+ // DEFAULT_LIBRARY_FUNCS_TO_INCLUDE requires the name as it appears in
860
+ // library.js, which means $name for a JS name with no prefix, or name
861
+ // for a JS name like _name.
862
+ var librarySymbol = sym;
863
+ if (!librarySymbol.startsWith('_')) {
864
+ librarySymbol = '$' + sym;
865
+ }
866
+ msg += ` (e.g. -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE='${librarySymbol}')`;
867
+ if (isExportedByForceFilesystem(sym)) {
868
+ msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
869
+ }
870
+ warnOnce(msg);
871
+ });
872
+
873
+ // Any symbol that is not included from the JS library is also (by definition)
874
+ // not exported on the Module object.
875
+ unexportedRuntimeSymbol(sym);
876
+ }
877
+
878
+ function unexportedRuntimeSymbol(sym) {
879
+ if (ENVIRONMENT_IS_PTHREAD) {
880
+ return;
881
+ }
882
+ if (!Object.getOwnPropertyDescriptor(Module, sym)) {
883
+ Object.defineProperty(Module, sym, {
884
+ configurable: true,
885
+ get() {
886
+ var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
887
+ if (isExportedByForceFilesystem(sym)) {
888
+ msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
889
+ }
890
+ abort(msg);
891
+ }
892
+ });
893
+ }
894
+ }
895
+
896
+ // Used by XXXXX_DEBUG settings to output debug messages.
897
+ function dbg(...args) {
898
+ // TODO(sbc): Make this configurable somehow. Its not always convenient for
899
+ // logging to show up as warnings.
900
+ console.warn(...args);
901
+ }
670
902
  // end include: runtime_debug.js
671
903
  // include: memoryprofiler.js
672
904
  // end include: memoryprofiler.js
@@ -675,6 +907,10 @@ var isFileURI = (filename) => filename.startsWith('file://');
675
907
  // This code runs only on pthread web workers and handles pthread setup
676
908
  // and communication with the main thread via postMessage.
677
909
 
910
+ // Unique ID of the current pthread worker (zero on non-pthread-workers
911
+ // including the main thread).
912
+ var workerID = 0;
913
+
678
914
  if (ENVIRONMENT_IS_PTHREAD) {
679
915
  var wasmModuleReceived;
680
916
 
@@ -688,6 +924,7 @@ if (ENVIRONMENT_IS_PTHREAD) {
688
924
 
689
925
  if (!Module['printErr'])
690
926
  err = threadPrintErr;
927
+ dbg = threadPrintErr;
691
928
  function threadAlert(...args) {
692
929
  var text = args.join(' ');
693
930
  postMessage({cmd: 'alert', text, threadId: _pthread_self()});
@@ -704,6 +941,7 @@ if (ENVIRONMENT_IS_PTHREAD) {
704
941
  //dbg('msgData: ' + Object.keys(msgData));
705
942
  var cmd = msgData.cmd;
706
943
  if (cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code.
944
+ workerID = msgData.workerID;
707
945
 
708
946
  // Until we initialize the runtime, queue up any further incoming messages.
709
947
  let messageQueue = [];
@@ -742,6 +980,7 @@ if (ENVIRONMENT_IS_PTHREAD) {
742
980
 
743
981
  wasmModuleReceived(msgData.wasmModule);
744
982
  } else if (cmd === 'run') {
983
+ assert(msgData.pthread_ptr);
745
984
  // Call inside JS module to set up the stack frame for this pthread in JS module scope.
746
985
  // This needs to be the first thing that we do, as we cannot call to any C/C++ functions
747
986
  // until the thread stack is initialized.
@@ -784,6 +1023,8 @@ if (ENVIRONMENT_IS_PTHREAD) {
784
1023
  err(msgData);
785
1024
  }
786
1025
  } catch(ex) {
1026
+ err(`worker: onmessage() captured an uncaught exception: ${ex}`);
1027
+ if (ex?.stack) err(ex.stack);
787
1028
  __emscripten_thread_crashed();
788
1029
  throw ex;
789
1030
  }
@@ -810,6 +1051,11 @@ function updateMemoryViews() {
810
1051
  }
811
1052
 
812
1053
  // end include: runtime_shared.js
1054
+ assert(!Module['STACK_SIZE'], 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
1055
+
1056
+ assert(typeof Int32Array != 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray != undefined && Int32Array.prototype.set != undefined,
1057
+ 'JS engine does not provide full typed array support');
1058
+
813
1059
  // In non-standalone/normal mode, we create the memory here.
814
1060
  // include: runtime_init_memory.js
815
1061
  // Create the wasm memory. (Note: this only applies if IMPORTED_MEMORY is defined)
@@ -822,8 +1068,9 @@ if (!ENVIRONMENT_IS_PTHREAD) {
822
1068
  wasmMemory = Module['wasmMemory'];
823
1069
  } else
824
1070
  {
825
- var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 268435456;
1071
+ var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 268435456;legacyModuleProp('INITIAL_MEMORY', 'INITIAL_MEMORY');
826
1072
 
1073
+ assert(INITIAL_MEMORY >= 65536, 'INITIAL_MEMORY should be larger than STACK_SIZE, was ' + INITIAL_MEMORY + '! (STACK_SIZE=' + 65536 + ')');
827
1074
  /** @suppress {checkTypes} */
828
1075
  wasmMemory = new WebAssembly.Memory({
829
1076
  'initial': INITIAL_MEMORY / 65536,
@@ -838,20 +1085,25 @@ if (!ENVIRONMENT_IS_PTHREAD) {
838
1085
  // end include: runtime_init_memory.js
839
1086
 
840
1087
  function preRun() {
1088
+ assert(!ENVIRONMENT_IS_PTHREAD); // PThreads reuse the runtime from the main thread.
841
1089
  if (Module['preRun']) {
842
1090
  if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
843
1091
  while (Module['preRun'].length) {
844
1092
  addOnPreRun(Module['preRun'].shift());
845
1093
  }
846
1094
  }
1095
+ consumedModuleProp('preRun');
847
1096
  callRuntimeCallbacks(onPreRuns);
848
1097
  }
849
1098
 
850
1099
  function initRuntime() {
1100
+ assert(!runtimeInitialized);
851
1101
  runtimeInitialized = true;
852
1102
 
853
1103
  if (ENVIRONMENT_IS_PTHREAD) return startWorker(Module);
854
1104
 
1105
+ checkStackCookie();
1106
+
855
1107
  if (!Module['noFSInit'] && !FS.initialized) FS.init();
856
1108
  TTY.init();
857
1109
 
@@ -861,10 +1113,12 @@ TTY.init();
861
1113
  }
862
1114
 
863
1115
  function preMain() {
1116
+ checkStackCookie();
864
1117
 
865
1118
  }
866
1119
 
867
1120
  function postRun() {
1121
+ checkStackCookie();
868
1122
  if (ENVIRONMENT_IS_PTHREAD) return; // PThreads reuse the runtime from the main thread.
869
1123
 
870
1124
  if (Module['postRun']) {
@@ -873,6 +1127,7 @@ function postRun() {
873
1127
  addOnPostRun(Module['postRun'].shift());
874
1128
  }
875
1129
  }
1130
+ consumedModuleProp('postRun');
876
1131
 
877
1132
  callRuntimeCallbacks(onPostRuns);
878
1133
  }
@@ -886,9 +1141,15 @@ function postRun() {
886
1141
  // the dependencies are met.
887
1142
  var runDependencies = 0;
888
1143
  var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
1144
+ var runDependencyTracking = {};
1145
+ var runDependencyWatcher = null;
889
1146
 
890
1147
  function getUniqueRunDependency(id) {
891
- return id;
1148
+ var orig = id;
1149
+ while (1) {
1150
+ if (!runDependencyTracking[id]) return id;
1151
+ id = orig + Math.random();
1152
+ }
892
1153
  }
893
1154
 
894
1155
  function addRunDependency(id) {
@@ -896,6 +1157,33 @@ function addRunDependency(id) {
896
1157
 
897
1158
  Module['monitorRunDependencies']?.(runDependencies);
898
1159
 
1160
+ if (id) {
1161
+ assert(!runDependencyTracking[id]);
1162
+ runDependencyTracking[id] = 1;
1163
+ if (runDependencyWatcher === null && typeof setInterval != 'undefined') {
1164
+ // Check for missing dependencies every few seconds
1165
+ runDependencyWatcher = setInterval(() => {
1166
+ if (ABORT) {
1167
+ clearInterval(runDependencyWatcher);
1168
+ runDependencyWatcher = null;
1169
+ return;
1170
+ }
1171
+ var shown = false;
1172
+ for (var dep in runDependencyTracking) {
1173
+ if (!shown) {
1174
+ shown = true;
1175
+ err('still waiting on run dependencies:');
1176
+ }
1177
+ err(`dependency: ${dep}`);
1178
+ }
1179
+ if (shown) {
1180
+ err('(end of list)');
1181
+ }
1182
+ }, 10000);
1183
+ }
1184
+ } else {
1185
+ err('warning: run dependency added without ID');
1186
+ }
899
1187
  }
900
1188
 
901
1189
  function removeRunDependency(id) {
@@ -903,7 +1191,17 @@ function removeRunDependency(id) {
903
1191
 
904
1192
  Module['monitorRunDependencies']?.(runDependencies);
905
1193
 
1194
+ if (id) {
1195
+ assert(runDependencyTracking[id]);
1196
+ delete runDependencyTracking[id];
1197
+ } else {
1198
+ err('warning: run dependency removed without ID');
1199
+ }
906
1200
  if (runDependencies == 0) {
1201
+ if (runDependencyWatcher !== null) {
1202
+ clearInterval(runDependencyWatcher);
1203
+ runDependencyWatcher = null;
1204
+ }
907
1205
  if (dependenciesFulfilled) {
908
1206
  var callback = dependenciesFulfilled;
909
1207
  dependenciesFulfilled = null;
@@ -923,8 +1221,6 @@ function abort(what) {
923
1221
 
924
1222
  ABORT = true;
925
1223
 
926
- what += '. Build with -sASSERTIONS for more info.';
927
-
928
1224
  // Use a wasm runtime error, because a JS error might be seen as a foreign
929
1225
  // exception, which means we'd run destructors on it. We need the error to
930
1226
  // simply make the program stop.
@@ -948,6 +1244,17 @@ function abort(what) {
948
1244
  throw e;
949
1245
  }
950
1246
 
1247
+ function createExportWrapper(name, nargs) {
1248
+ return (...args) => {
1249
+ assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
1250
+ var f = wasmExports[name];
1251
+ assert(f, `exported native function \`${name}\` not found`);
1252
+ // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
1253
+ assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
1254
+ return f(...args);
1255
+ };
1256
+ }
1257
+
951
1258
  var wasmBinaryFile;
952
1259
  function findWasmBinary() {
953
1260
  if (Module['locateFile']) {
@@ -991,6 +1298,10 @@ async function instantiateArrayBuffer(binaryFile, imports) {
991
1298
  } catch (reason) {
992
1299
  err(`failed to asynchronously prepare wasm: ${reason}`);
993
1300
 
1301
+ // Warn on some common problems.
1302
+ if (isFileURI(wasmBinaryFile)) {
1303
+ err(`warning: Loading from a file URI (${wasmBinaryFile}) is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing`);
1304
+ }
994
1305
  abort(reason);
995
1306
  }
996
1307
  }
@@ -1038,6 +1349,7 @@ async function createWasm() {
1038
1349
 
1039
1350
  wasmTable = wasmExports['__indirect_function_table'];
1040
1351
 
1352
+ assert(wasmTable, 'table not found in wasm exports');
1041
1353
 
1042
1354
  // We now have the Wasm module loaded up, keep a reference to the compiled module so we can post it to the workers.
1043
1355
  wasmModule = module;
@@ -1048,9 +1360,15 @@ async function createWasm() {
1048
1360
  addRunDependency('wasm-instantiate');
1049
1361
 
1050
1362
  // Prefer streaming instantiation if available.
1363
+ // Async compilation can be confusing when an error on the page overwrites Module
1364
+ // (for example, if the order of elements is wrong, and the one defining Module is
1365
+ // later), so we save Module and check it later.
1366
+ var trueModule = Module;
1051
1367
  function receiveInstantiationResult(result) {
1052
1368
  // 'result' is a ResultObject object which has both the module and instance.
1053
1369
  // receiveInstance() will swap in the exports (to Module.asm) so they can be called
1370
+ assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
1371
+ trueModule = null;
1054
1372
  return receiveInstance(result['instance'], result['module']);
1055
1373
  }
1056
1374
 
@@ -1064,10 +1382,15 @@ async function createWasm() {
1064
1382
  // path.
1065
1383
  if (Module['instantiateWasm']) {
1066
1384
  return new Promise((resolve, reject) => {
1385
+ try {
1067
1386
  Module['instantiateWasm'](info, (mod, inst) => {
1068
1387
  receiveInstance(mod, inst);
1069
1388
  resolve(mod.exports);
1070
1389
  });
1390
+ } catch(e) {
1391
+ err(`Module.instantiateWasm callback failed with error: ${e}`);
1392
+ reject(e);
1393
+ }
1071
1394
  });
1072
1395
  }
1073
1396
 
@@ -1098,32 +1421,41 @@ async function createWasm() {
1098
1421
  // === Body ===
1099
1422
 
1100
1423
  var ASM_CONSTS = {
1101
- 310240: () => { console.error("thread instantiation failed") },
1102
- 310289: ($0, $1) => { Module.canvas.width = $0; Module.canvas.height = $1; },
1103
- 310346: ($0, $1, $2, $3, $4, $5, $6) => { Module.version = { gitCommit : UTF8ToString($0), gitShort : UTF8ToString($1), gitBranch : UTF8ToString($2), gitRevision : $3, binaryName : UTF8ToString($4), projectName : UTF8ToString($5), projectVersion : UTF8ToString($6) }; },
1104
- 310578: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1105
- 310676: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1106
- 310774: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1107
- 310872: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1108
- 310970: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1109
- 311068: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1110
- 311166: () => { FS.syncfs(function (err) { assert(!err); }) },
1111
- 311210: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },
1112
- 311435: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; },
1113
- 311582: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; },
1114
- 311816: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { if ((typeof navigator.userActivation) === 'undefined') { autoResumeAudioContext(SDL2.audioContext); } } } return SDL2.audioContext === undefined ? -1 : 0; },
1115
- 312368: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; },
1116
- 312436: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearInterval(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; SDL2.capture.silenceBuffer = undefined } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } },
1117
- 314129: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } if (SDL2.audio.silenceTimer !== undefined) { clearInterval(SDL2.audio.silenceTimer); SDL2.audio.silenceTimer = undefined; SDL2.audio.silenceBuffer = undefined; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); if (SDL2.audioContext.state === 'suspended') { SDL2.audio.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.audio.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { if ((typeof navigator.userActivation) !== 'undefined') { if (navigator.userActivation.hasBeenActive) { SDL2.audioContext.resume(); } } SDL2.audio.currentOutputBuffer = SDL2.audio.silenceBuffer; dynCall('vi', $2, [$3]); SDL2.audio.currentOutputBuffer = undefined; }; SDL2.audio.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); } },
1118
- 315304: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } },
1119
- 315909: ($0, $1) => { var SDL2 = Module['SDL2']; var buf = $0 >>> 2; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[buf + (j*numChannels + c)]; } } },
1120
- 316398: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearInterval(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); } if (SDL2.audio.silenceTimer !== undefined) { clearInterval(SDL2.audio.silenceTimer); } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } },
1121
- 317404: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); },
1122
- 318872: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; },
1123
- 319860: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } },
1124
- 319943: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } },
1125
- 320012: () => { return window.innerWidth; },
1126
- 320042: () => { return window.innerHeight; }
1424
+ 311808: () => { console.error("thread instantiation failed") },
1425
+ 311857: ($0, $1) => { console.log("using videoSync/audioSync", $0, $1) },
1426
+ 311910: ($0) => { console.log("using threadedVideo", $0) },
1427
+ 311953: ($0) => { console.log('setting core audio buffer size:', $0) },
1428
+ 312008: ($0, $1) => { Module.canvas.width = $0; Module.canvas.height = $1; },
1429
+ 312065: ($0) => { console.log('setting audioSampleRate', $0) },
1430
+ 312112: ($0) => { console.log('setting audioBufferSize', $0) },
1431
+ 312159: ($0) => { console.log('setting videoSync', $0) },
1432
+ 312200: ($0) => { console.log('setting audioSync', $0) },
1433
+ 312241: ($0) => { console.log('setting threadedVideo', $0) },
1434
+ 312286: ($0, $1, $2, $3, $4, $5, $6) => { Module.version = { gitCommit : UTF8ToString($0), gitShort : UTF8ToString($1), gitBranch : UTF8ToString($2), gitRevision : $3, binaryName : UTF8ToString($4), projectName : UTF8ToString($5), projectVersion : UTF8ToString($6) }; },
1435
+ 312518: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1436
+ 312616: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1437
+ 312714: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1438
+ 312812: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1439
+ 312910: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1440
+ 313008: ($0, $1) => { const funcPtr = $0; const ctx = $1; const func = wasmTable.get(funcPtr); if (func) func(ctx); },
1441
+ 313106: ($0, $1, $2, $3) => { console.log("desired spec values: sampleRate/samples", $0, $1); console.log("obtained spec values: sampleRate/samples", $2, $3) },
1442
+ 313238: () => { FS.syncfs(function (err) { assert(!err); }) },
1443
+ 313282: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },
1444
+ 313507: () => { if (typeof(AudioContext) !== 'undefined') { return true; } else if (typeof(webkitAudioContext) !== 'undefined') { return true; } return false; },
1445
+ 313654: () => { if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { return true; } return false; },
1446
+ 313888: ($0) => { if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } var SDL2 = Module['SDL2']; if (!$0) { SDL2.audio = {}; } else { SDL2.capture = {}; } if (!SDL2.audioContext) { if (typeof(AudioContext) !== 'undefined') { SDL2.audioContext = new AudioContext(); } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { if ((typeof navigator.userActivation) === 'undefined') { autoResumeAudioContext(SDL2.audioContext); } } } return SDL2.audioContext === undefined ? -1 : 0; },
1447
+ 314440: () => { var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; },
1448
+ 314508: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; var have_microphone = function(stream) { if (SDL2.capture.silenceTimer !== undefined) { clearInterval(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; SDL2.capture.silenceBuffer = undefined } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); SDL2.capture.stream = stream; }; var no_microphone = function(error) { }; SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; dynCall('vi', $2, [$3]); }; SDL2.capture.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); } else if (navigator.webkitGetUserMedia !== undefined) { navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); } },
1449
+ 316201: ($0, $1, $2, $3) => { var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } if (SDL2.audio.silenceTimer !== undefined) { clearInterval(SDL2.audio.silenceTimer); SDL2.audio.silenceTimer = undefined; SDL2.audio.silenceBuffer = undefined; } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); if (SDL2.audioContext.state === 'suspended') { SDL2.audio.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.audio.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { if ((typeof navigator.userActivation) !== 'undefined') { if (navigator.userActivation.hasBeenActive) { SDL2.audioContext.resume(); } } SDL2.audio.currentOutputBuffer = SDL2.audio.silenceBuffer; dynCall('vi', $2, [$3]); SDL2.audio.currentOutputBuffer = undefined; }; SDL2.audio.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); } },
1450
+ 317376: ($0, $1) => { var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); if (channelData.length != $1) { throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } if (numChannels == 1) { for (var j = 0; j < $1; ++j) { setValue($0 + (j * 4), channelData[j], 'float'); } } else { for (var j = 0; j < $1; ++j) { setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); } } } },
1451
+ 317981: ($0, $1) => { var SDL2 = Module['SDL2']; var buf = $0 >>> 2; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); if (channelData.length != $1) { throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; } for (var j = 0; j < $1; ++j) { channelData[j] = HEAPF32[buf + (j*numChannels + c)]; } } },
1452
+ 318470: ($0) => { var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { clearInterval(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); } if (SDL2.audio.silenceTimer !== undefined) { clearInterval(SDL2.audio.silenceTimer); } SDL2.audio = undefined; } if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { SDL2.audioContext.close(); SDL2.audioContext = undefined; } },
1453
+ 319476: ($0, $1, $2) => { var w = $0; var h = $1; var pixels = $2; if (!Module['SDL2']) Module['SDL2'] = {}; var SDL2 = Module['SDL2']; if (SDL2.ctxCanvas !== Module['canvas']) { SDL2.ctx = Module['createContext'](Module['canvas'], false, true); SDL2.ctxCanvas = Module['canvas']; } if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { SDL2.image = SDL2.ctx.createImageData(w, h); SDL2.w = w; SDL2.h = h; SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = 0xff; src++; dst += 4; } } else { if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; var i = 3; var j = i + 4*num; if (num % 8 == 0) { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; data8[i] = 0xff; i = i + 4 | 0; } } else { while (i < j) { data8[i] = 0xff; i = i + 4 | 0; } } } SDL2.ctx.putImageData(SDL2.image, 0, 0); },
1454
+ 320944: ($0, $1, $2, $3, $4) => { var w = $0; var h = $1; var hot_x = $2; var hot_y = $3; var pixels = $4; var canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; var ctx = canvas.getContext("2d"); var image = ctx.createImageData(w, h); var data = image.data; var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { num = data.length; while (dst < num) { var val = HEAP32[src]; data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; data[dst+3] = (val >> 24) & 0xff; src++; dst += 4; } } else { var data32 = new Int32Array(data.buffer); num = data32.length; data32.set(HEAP32.subarray(src, src + num)); } ctx.putImageData(image, 0, 0); var url = hot_x === 0 && hot_y === 0 ? "url(" + canvas.toDataURL() + "), auto" : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto"; var urlBuf = _malloc(url.length + 1); stringToUTF8(url, urlBuf, url.length + 1); return urlBuf; },
1455
+ 321932: ($0) => { if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } },
1456
+ 322015: () => { if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } },
1457
+ 322084: () => { return window.innerWidth; },
1458
+ 322114: () => { return window.innerHeight; }
1127
1459
  };
1128
1460
 
1129
1461
  // end include: preamble.js
@@ -1146,11 +1478,16 @@ var ASM_CONSTS = {
1146
1478
  // out its message handler here. This avoids having to check in each of
1147
1479
  // the onmessage handlers if the message was coming from valid worker.
1148
1480
  worker.onmessage = (e) => {
1481
+ var cmd = e['data'].cmd;
1482
+ err(`received "${cmd}" command from terminated worker: ${worker.workerID}`);
1149
1483
  };
1150
1484
  };
1151
1485
 
1152
1486
  var cleanupThread = (pthread_ptr) => {
1487
+ assert(!ENVIRONMENT_IS_PTHREAD, 'Internal Error! cleanupThread() can only ever be called from main application thread!');
1488
+ assert(pthread_ptr, 'Internal Error! Null pthread_ptr in cleanupThread!');
1153
1489
  var worker = PThread.pthreads[pthread_ptr];
1490
+ assert(worker);
1154
1491
  PThread.returnWorkerToPool(worker);
1155
1492
  };
1156
1493
 
@@ -1164,12 +1501,15 @@ var ASM_CONSTS = {
1164
1501
  var addOnPreRun = (cb) => onPreRuns.unshift(cb);
1165
1502
 
1166
1503
  var spawnThread = (threadParams) => {
1504
+ assert(!ENVIRONMENT_IS_PTHREAD, 'Internal Error! spawnThread() can only ever be called from main application thread!');
1505
+ assert(threadParams.pthread_ptr, 'Internal error, no pthread ptr!');
1167
1506
 
1168
1507
  var worker = PThread.getNewWorker();
1169
1508
  if (!worker) {
1170
1509
  // No available workers in the PThread pool.
1171
1510
  return 6;
1172
1511
  }
1512
+ assert(!worker.pthread_ptr, 'Internal error!');
1173
1513
 
1174
1514
  PThread.runningWorkers.push(worker);
1175
1515
 
@@ -1261,6 +1601,7 @@ var ASM_CONSTS = {
1261
1601
 
1262
1602
 
1263
1603
 
1604
+
1264
1605
  var handleException = (e) => {
1265
1606
  // Certain exception types we do not treat as errors since they are used for
1266
1607
  // internal control flow.
@@ -1270,6 +1611,12 @@ var ASM_CONSTS = {
1270
1611
  if (e instanceof ExitStatus || e == 'unwind') {
1271
1612
  return EXITSTATUS;
1272
1613
  }
1614
+ checkStackCookie();
1615
+ if (e instanceof WebAssembly.RuntimeError) {
1616
+ if (_emscripten_stack_get_current() <= 0) {
1617
+ err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to 65536)');
1618
+ }
1619
+ }
1273
1620
  quit_(1, e);
1274
1621
  };
1275
1622
 
@@ -1283,13 +1630,17 @@ var ASM_CONSTS = {
1283
1630
 
1284
1631
  }
1285
1632
 
1633
+
1286
1634
  /** @suppress {duplicate } */
1287
1635
  /** @param {boolean|number=} implicit */
1288
1636
  var exitJS = (status, implicit) => {
1289
1637
  EXITSTATUS = status;
1290
1638
 
1639
+ checkUnflushedContent();
1640
+
1291
1641
  if (ENVIRONMENT_IS_PTHREAD) {
1292
1642
  // implicit exit can never happen on a pthread
1643
+ assert(!implicit);
1293
1644
  // When running in a pthread we propagate the exit back to the main thread
1294
1645
  // where it can decide if the whole process should be shut down or not.
1295
1646
  // The pthread may have decided not to exit its own runtime, for example
@@ -1298,10 +1649,24 @@ var ASM_CONSTS = {
1298
1649
  throw 'unwind';
1299
1650
  }
1300
1651
 
1652
+ // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
1653
+ if (keepRuntimeAlive() && !implicit) {
1654
+ var msg = `program exited (with status: ${status}), but keepRuntimeAlive() is set (counter=${runtimeKeepaliveCounter}) due to an async operation, so halting execution but not exiting the runtime or preventing further async execution (you can use emscripten_force_exit, if you want to force a true shutdown)`;
1655
+ readyPromiseReject(msg);
1656
+ err(msg);
1657
+ }
1658
+
1301
1659
  _proc_exit(status);
1302
1660
  };
1303
1661
  var _exit = exitJS;
1304
1662
 
1663
+ var ptrToString = (ptr) => {
1664
+ assert(typeof ptr === 'number');
1665
+ // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
1666
+ ptr >>>= 0;
1667
+ return '0x' + ptr.toString(16).padStart(8, '0');
1668
+ };
1669
+
1305
1670
 
1306
1671
  var PThread = {
1307
1672
  unusedWorkers:[],
@@ -1309,13 +1674,29 @@ var ASM_CONSTS = {
1309
1674
  tlsInitFunctions:[],
1310
1675
  pthreads:{
1311
1676
  },
1677
+ nextWorkerID:1,
1678
+ debugInit() {
1679
+ function pthreadLogPrefix() {
1680
+ var t = 0;
1681
+ if (runtimeInitialized && typeof _pthread_self != 'undefined'
1682
+ ) {
1683
+ t = _pthread_self();
1684
+ }
1685
+ return `w:${workerID},t:${ptrToString(t)}: `;
1686
+ }
1687
+
1688
+ // Prefix all err()/dbg() messages with the calling thread ID.
1689
+ var origDbg = dbg;
1690
+ dbg = (...args) => origDbg(pthreadLogPrefix() + args.join(' '));
1691
+ },
1312
1692
  init() {
1693
+ PThread.debugInit();
1313
1694
  if ((!(ENVIRONMENT_IS_PTHREAD))) {
1314
1695
  PThread.initMainThread();
1315
1696
  }
1316
1697
  },
1317
1698
  initMainThread() {
1318
- var pthreadPoolSize = 3;
1699
+ var pthreadPoolSize = 5;
1319
1700
  // Start loading up the Worker pool, if requested.
1320
1701
  while (pthreadPoolSize--) {
1321
1702
  PThread.allocateUnusedWorker();
@@ -1328,6 +1709,7 @@ var ASM_CONSTS = {
1328
1709
  });
1329
1710
  },
1330
1711
  terminateAllThreads:() => {
1712
+ assert(!ENVIRONMENT_IS_PTHREAD, 'Internal Error! terminateAllThreads() can only ever be called from main application thread!');
1331
1713
  // Attempt to kill all workers. Sadly (at least on the web) there is no
1332
1714
  // way to terminate a worker synchronously, or to be notified when a
1333
1715
  // worker in actually terminated. This means there is some risk that
@@ -1415,10 +1797,16 @@ var ASM_CONSTS = {
1415
1797
 
1416
1798
  worker.onerror = (e) => {
1417
1799
  var message = 'worker sent an error!';
1800
+ if (worker.pthread_ptr) {
1801
+ message = `Pthread ${ptrToString(worker.pthread_ptr)} sent an error!`;
1802
+ }
1418
1803
  err(`${message} ${e.filename}:${e.lineno}: ${e.message}`);
1419
1804
  throw e;
1420
1805
  };
1421
1806
 
1807
+ assert(wasmMemory instanceof WebAssembly.Memory, 'WebAssembly memory should have been loaded by now!');
1808
+ assert(wasmModule instanceof WebAssembly.Module, 'WebAssembly Module should have been loaded by now!');
1809
+
1422
1810
  // When running on a pthread, none of the incoming parameters on the module
1423
1811
  // object are present. Proxy known handlers back to the main thread if specified.
1424
1812
  var handlers = [];
@@ -1434,12 +1822,15 @@ var ASM_CONSTS = {
1434
1822
  }
1435
1823
  }
1436
1824
 
1825
+ worker.workerID = PThread.nextWorkerID++;
1826
+
1437
1827
  // Ask the new worker to load up the Emscripten-compiled page. This is a heavy operation.
1438
1828
  worker.postMessage({
1439
1829
  cmd: 'load',
1440
1830
  handlers: handlers,
1441
1831
  wasmMemory,
1442
1832
  wasmModule,
1833
+ 'workerID': worker.workerID,
1443
1834
  });
1444
1835
  }),
1445
1836
  loadWasmModuleToAllWorkers(onMaybeReady) {
@@ -1464,13 +1855,20 @@ var ASM_CONSTS = {
1464
1855
  'type': 'module',
1465
1856
  // This is the way that we signal to the Web Worker that it is hosting
1466
1857
  // a pthread.
1467
- 'name': 'em-pthread',
1858
+ 'name': 'em-pthread-' + PThread.nextWorkerID,
1468
1859
  });
1469
1860
  PThread.unusedWorkers.push(worker);
1470
1861
  },
1471
1862
  getNewWorker() {
1472
1863
  if (PThread.unusedWorkers.length == 0) {
1473
1864
  // PTHREAD_POOL_SIZE_STRICT should show a warning and, if set to level `2`, return from the function.
1865
+ // However, if we're in Node.js, then we can create new workers on the fly and PTHREAD_POOL_SIZE_STRICT
1866
+ // should be ignored altogether.
1867
+ err('Tried to spawn a new thread, but the thread pool is exhausted.\n' +
1868
+ 'This might result in a deadlock unless some threads eventually exit or the code explicitly breaks out to the event loop.\n' +
1869
+ 'If you want to increase the pool size, use setting `-sPTHREAD_POOL_SIZE=...`.'
1870
+ + '\nIf you want to throw an explicit error instead of the risk of deadlocking in those cases, use setting `-sPTHREAD_POOL_SIZE_STRICT=2`.'
1871
+ );
1474
1872
  PThread.allocateUnusedWorker();
1475
1873
  PThread.loadWasmModuleToWorker(PThread.unusedWorkers[0]);
1476
1874
  }
@@ -1489,6 +1887,9 @@ var ASM_CONSTS = {
1489
1887
  var stackHigh = HEAPU32[(((pthread_ptr)+(52))>>2)];
1490
1888
  var stackSize = HEAPU32[(((pthread_ptr)+(56))>>2)];
1491
1889
  var stackLow = stackHigh - stackSize;
1890
+ assert(stackHigh != 0);
1891
+ assert(stackLow != 0);
1892
+ assert(stackHigh > stackLow, 'stackHigh must be higher then stackLow');
1492
1893
  // Set stack limits used by `emscripten/stack.h` function. These limits are
1493
1894
  // cached in wasm-side globals to make checks as fast as possible.
1494
1895
  _emscripten_stack_set_limits(stackHigh, stackLow);
@@ -1496,6 +1897,9 @@ var ASM_CONSTS = {
1496
1897
  // Call inside wasm module to set up the stack frame for this pthread in wasm module scope
1497
1898
  stackRestore(stackHigh);
1498
1899
 
1900
+ // Write the stack cookie last, after we have set up the proper bounds and
1901
+ // current position of the stack.
1902
+ writeStackCookie();
1499
1903
  };
1500
1904
 
1501
1905
 
@@ -1533,6 +1937,8 @@ var ASM_CONSTS = {
1533
1937
  /** @suppress {checkTypes} */
1534
1938
  wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
1535
1939
  }
1940
+ /** @suppress {checkTypes} */
1941
+ assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
1536
1942
  return func;
1537
1943
  };
1538
1944
  var invokeEntryPoint = (ptr, arg) => {
@@ -1561,6 +1967,7 @@ var ASM_CONSTS = {
1561
1967
 
1562
1968
  var result = getWasmTableEntry(ptr)(arg);
1563
1969
 
1970
+ checkStackCookie();
1564
1971
  function finish(result) {
1565
1972
  if (keepRuntimeAlive()) {
1566
1973
  EXITSTATUS = result;
@@ -1573,6 +1980,7 @@ var ASM_CONSTS = {
1573
1980
 
1574
1981
  var noExitRuntime = Module['noExitRuntime'] || true;
1575
1982
 
1983
+
1576
1984
  var registerTLSInit = (tlsInitFunc) => PThread.tlsInitFunctions.push(tlsInitFunc);
1577
1985
 
1578
1986
 
@@ -1598,6 +2006,14 @@ var ASM_CONSTS = {
1598
2006
 
1599
2007
 
1600
2008
 
2009
+ var warnOnce = (text) => {
2010
+ warnOnce.shown ||= {};
2011
+ if (!warnOnce.shown[text]) {
2012
+ warnOnce.shown[text] = 1;
2013
+ err(text);
2014
+ }
2015
+ };
2016
+
1601
2017
  var UTF8Decoder = typeof TextDecoder != 'undefined' ? new TextDecoder() : undefined;
1602
2018
 
1603
2019
  /**
@@ -1638,6 +2054,7 @@ var ASM_CONSTS = {
1638
2054
  if ((u0 & 0xF0) == 0xE0) {
1639
2055
  u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
1640
2056
  } else {
2057
+ if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte ' + ptrToString(u0) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!');
1641
2058
  u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
1642
2059
  }
1643
2060
 
@@ -1667,6 +2084,7 @@ var ASM_CONSTS = {
1667
2084
  * @return {string}
1668
2085
  */
1669
2086
  var UTF8ToString = (ptr, maxBytesToRead) => {
2087
+ assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`);
1670
2088
  return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : '';
1671
2089
  };
1672
2090
  var ___assert_fail = (condition, filename, line, func) =>
@@ -1690,6 +2108,7 @@ var ASM_CONSTS = {
1690
2108
 
1691
2109
  var ___pthread_create_js = (pthread_ptr, attr, startRoutine, arg) => {
1692
2110
  if (!_emscripten_has_threading_support()) {
2111
+ dbg('pthread_create: environment does not support SharedArrayBuffer, pthreads are not available');
1693
2112
  return 6;
1694
2113
  }
1695
2114
 
@@ -1733,6 +2152,7 @@ var ASM_CONSTS = {
1733
2152
 
1734
2153
  /** @suppress {duplicate } */
1735
2154
  var syscallGetVarargI = () => {
2155
+ assert(SYSCALLS.varargs != undefined);
1736
2156
  // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number.
1737
2157
  var ret = HEAP32[((+SYSCALLS.varargs)>>2)];
1738
2158
  SYSCALLS.varargs += 4;
@@ -1895,6 +2315,7 @@ var ASM_CONSTS = {
1895
2315
  };
1896
2316
 
1897
2317
  var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
2318
+ assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`);
1898
2319
  // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
1899
2320
  // undefined and false each don't write out any bytes.
1900
2321
  if (!(maxBytesToWrite > 0))
@@ -1929,6 +2350,7 @@ var ASM_CONSTS = {
1929
2350
  heap[outIdx++] = 0x80 | (u & 63);
1930
2351
  } else {
1931
2352
  if (outIdx + 3 >= endIdx) break;
2353
+ if (u > 0x10FFFF) warnOnce('Invalid Unicode code point ' + ptrToString(u) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x10FFFF).');
1932
2354
  heap[outIdx++] = 0xF0 | (u >> 18);
1933
2355
  heap[outIdx++] = 0x80 | ((u >> 12) & 63);
1934
2356
  heap[outIdx++] = 0x80 | ((u >> 6) & 63);
@@ -2114,6 +2536,7 @@ var ASM_CONSTS = {
2114
2536
  };
2115
2537
 
2116
2538
  var alignMemory = (size, alignment) => {
2539
+ assert(alignment, "alignment argument is required");
2117
2540
  return Math.ceil(size / alignment) * alignment;
2118
2541
  };
2119
2542
  var mmapAlloc = (size) => {
@@ -2279,7 +2702,7 @@ var ASM_CONSTS = {
2279
2702
  }
2280
2703
  },
2281
2704
  lookup(parent, name) {
2282
- throw MEMFS.doesNotExistError;
2705
+ throw new FS.ErrnoError(44);
2283
2706
  },
2284
2707
  mknod(parent, name, mode, dev) {
2285
2708
  return MEMFS.createNode(parent, name, mode, dev);
@@ -2336,6 +2759,7 @@ var ASM_CONSTS = {
2336
2759
  var contents = stream.node.contents;
2337
2760
  if (position >= stream.node.usedBytes) return 0;
2338
2761
  var size = Math.min(stream.node.usedBytes - position, length);
2762
+ assert(size >= 0);
2339
2763
  if (size > 8 && contents.subarray) { // non-trivial, and typed array
2340
2764
  buffer.set(contents.subarray(position, position + size), offset);
2341
2765
  } else {
@@ -2344,6 +2768,8 @@ var ASM_CONSTS = {
2344
2768
  return size;
2345
2769
  },
2346
2770
  write(stream, buffer, offset, length, position, canOwn) {
2771
+ // The data buffer should be a typed array view
2772
+ assert(!(buffer instanceof ArrayBuffer));
2347
2773
 
2348
2774
  if (!length) return 0;
2349
2775
  var node = stream.node;
@@ -2351,6 +2777,7 @@ var ASM_CONSTS = {
2351
2777
 
2352
2778
  if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
2353
2779
  if (canOwn) {
2780
+ assert(position === 0, 'canOwn must imply no weird position inside the file');
2354
2781
  node.contents = buffer.subarray(offset, offset + length);
2355
2782
  node.usedBytes = length;
2356
2783
  return length;
@@ -2438,6 +2865,7 @@ var ASM_CONSTS = {
2438
2865
 
2439
2866
  var asyncLoad = async (url) => {
2440
2867
  var arrayBuffer = await readAsync(url);
2868
+ assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
2441
2869
  return new Uint8Array(arrayBuffer);
2442
2870
  };
2443
2871
 
@@ -2526,6 +2954,7 @@ var ASM_CONSTS = {
2526
2954
  if (typeof indexedDB != 'undefined') return indexedDB;
2527
2955
  var ret = null;
2528
2956
  if (typeof window == 'object') ret = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
2957
+ assert(ret, 'IDBFS used, but indexedDB not supported');
2529
2958
  return ret;
2530
2959
  },
2531
2960
  DB_VERSION:21,
@@ -2888,6 +3317,134 @@ var ASM_CONSTS = {
2888
3317
  });
2889
3318
  },
2890
3319
  };
3320
+
3321
+
3322
+
3323
+ var strError = (errno) => UTF8ToString(_strerror(errno));
3324
+
3325
+ var ERRNO_CODES = {
3326
+ 'EPERM': 63,
3327
+ 'ENOENT': 44,
3328
+ 'ESRCH': 71,
3329
+ 'EINTR': 27,
3330
+ 'EIO': 29,
3331
+ 'ENXIO': 60,
3332
+ 'E2BIG': 1,
3333
+ 'ENOEXEC': 45,
3334
+ 'EBADF': 8,
3335
+ 'ECHILD': 12,
3336
+ 'EAGAIN': 6,
3337
+ 'EWOULDBLOCK': 6,
3338
+ 'ENOMEM': 48,
3339
+ 'EACCES': 2,
3340
+ 'EFAULT': 21,
3341
+ 'ENOTBLK': 105,
3342
+ 'EBUSY': 10,
3343
+ 'EEXIST': 20,
3344
+ 'EXDEV': 75,
3345
+ 'ENODEV': 43,
3346
+ 'ENOTDIR': 54,
3347
+ 'EISDIR': 31,
3348
+ 'EINVAL': 28,
3349
+ 'ENFILE': 41,
3350
+ 'EMFILE': 33,
3351
+ 'ENOTTY': 59,
3352
+ 'ETXTBSY': 74,
3353
+ 'EFBIG': 22,
3354
+ 'ENOSPC': 51,
3355
+ 'ESPIPE': 70,
3356
+ 'EROFS': 69,
3357
+ 'EMLINK': 34,
3358
+ 'EPIPE': 64,
3359
+ 'EDOM': 18,
3360
+ 'ERANGE': 68,
3361
+ 'ENOMSG': 49,
3362
+ 'EIDRM': 24,
3363
+ 'ECHRNG': 106,
3364
+ 'EL2NSYNC': 156,
3365
+ 'EL3HLT': 107,
3366
+ 'EL3RST': 108,
3367
+ 'ELNRNG': 109,
3368
+ 'EUNATCH': 110,
3369
+ 'ENOCSI': 111,
3370
+ 'EL2HLT': 112,
3371
+ 'EDEADLK': 16,
3372
+ 'ENOLCK': 46,
3373
+ 'EBADE': 113,
3374
+ 'EBADR': 114,
3375
+ 'EXFULL': 115,
3376
+ 'ENOANO': 104,
3377
+ 'EBADRQC': 103,
3378
+ 'EBADSLT': 102,
3379
+ 'EDEADLOCK': 16,
3380
+ 'EBFONT': 101,
3381
+ 'ENOSTR': 100,
3382
+ 'ENODATA': 116,
3383
+ 'ETIME': 117,
3384
+ 'ENOSR': 118,
3385
+ 'ENONET': 119,
3386
+ 'ENOPKG': 120,
3387
+ 'EREMOTE': 121,
3388
+ 'ENOLINK': 47,
3389
+ 'EADV': 122,
3390
+ 'ESRMNT': 123,
3391
+ 'ECOMM': 124,
3392
+ 'EPROTO': 65,
3393
+ 'EMULTIHOP': 36,
3394
+ 'EDOTDOT': 125,
3395
+ 'EBADMSG': 9,
3396
+ 'ENOTUNIQ': 126,
3397
+ 'EBADFD': 127,
3398
+ 'EREMCHG': 128,
3399
+ 'ELIBACC': 129,
3400
+ 'ELIBBAD': 130,
3401
+ 'ELIBSCN': 131,
3402
+ 'ELIBMAX': 132,
3403
+ 'ELIBEXEC': 133,
3404
+ 'ENOSYS': 52,
3405
+ 'ENOTEMPTY': 55,
3406
+ 'ENAMETOOLONG': 37,
3407
+ 'ELOOP': 32,
3408
+ 'EOPNOTSUPP': 138,
3409
+ 'EPFNOSUPPORT': 139,
3410
+ 'ECONNRESET': 15,
3411
+ 'ENOBUFS': 42,
3412
+ 'EAFNOSUPPORT': 5,
3413
+ 'EPROTOTYPE': 67,
3414
+ 'ENOTSOCK': 57,
3415
+ 'ENOPROTOOPT': 50,
3416
+ 'ESHUTDOWN': 140,
3417
+ 'ECONNREFUSED': 14,
3418
+ 'EADDRINUSE': 3,
3419
+ 'ECONNABORTED': 13,
3420
+ 'ENETUNREACH': 40,
3421
+ 'ENETDOWN': 38,
3422
+ 'ETIMEDOUT': 73,
3423
+ 'EHOSTDOWN': 142,
3424
+ 'EHOSTUNREACH': 23,
3425
+ 'EINPROGRESS': 26,
3426
+ 'EALREADY': 7,
3427
+ 'EDESTADDRREQ': 17,
3428
+ 'EMSGSIZE': 35,
3429
+ 'EPROTONOSUPPORT': 66,
3430
+ 'ESOCKTNOSUPPORT': 137,
3431
+ 'EADDRNOTAVAIL': 4,
3432
+ 'ENETRESET': 39,
3433
+ 'EISCONN': 30,
3434
+ 'ENOTCONN': 53,
3435
+ 'ETOOMANYREFS': 141,
3436
+ 'EUSERS': 136,
3437
+ 'EDQUOT': 19,
3438
+ 'ESTALE': 72,
3439
+ 'ENOTSUP': 138,
3440
+ 'ENOMEDIUM': 148,
3441
+ 'EILSEQ': 25,
3442
+ 'EOVERFLOW': 61,
3443
+ 'ECANCELED': 11,
3444
+ 'ENOTRECOVERABLE': 56,
3445
+ 'EOWNERDEAD': 62,
3446
+ 'ESTRPIPE': 135,
3447
+ };
2891
3448
  var FS = {
2892
3449
  root:null,
2893
3450
  mounts:[],
@@ -2903,7 +3460,7 @@ var ASM_CONSTS = {
2903
3460
  syncFSRequests:0,
2904
3461
  readFiles:{
2905
3462
  },
2906
- ErrnoError:class {
3463
+ ErrnoError:class extends Error {
2907
3464
  name = 'ErrnoError';
2908
3465
  // We set the `name` property to be able to identify `FS.ErrnoError`
2909
3466
  // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
@@ -2912,7 +3469,14 @@ var ASM_CONSTS = {
2912
3469
  // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
2913
3470
  // we'll use the reliable test `err.name == "ErrnoError"` instead
2914
3471
  constructor(errno) {
3472
+ super(runtimeInitialized ? strError(errno) : '');
2915
3473
  this.errno = errno;
3474
+ for (var key in ERRNO_CODES) {
3475
+ if (ERRNO_CODES[key] === errno) {
3476
+ this.code = key;
3477
+ break;
3478
+ }
3479
+ }
2916
3480
  }
2917
3481
  },
2918
3482
  FSStream:class {
@@ -3110,6 +3674,7 @@ var ASM_CONSTS = {
3110
3674
  return FS.lookup(parent, name);
3111
3675
  },
3112
3676
  createNode(parent, name, mode, rdev) {
3677
+ assert(typeof parent == 'object')
3113
3678
  var node = new FS.FSNode(parent, name, mode, rdev);
3114
3679
 
3115
3680
  FS.hashAddNode(node);
@@ -3248,6 +3813,7 @@ var ASM_CONSTS = {
3248
3813
  },
3249
3814
  getStream:(fd) => FS.streams[fd],
3250
3815
  createStream(stream, fd = -1) {
3816
+ assert(fd >= -1);
3251
3817
 
3252
3818
  // clone it, so we can return an instance of FSStream
3253
3819
  stream = Object.assign(new FS.FSStream(), stream);
@@ -3322,6 +3888,7 @@ var ASM_CONSTS = {
3322
3888
  var completed = 0;
3323
3889
 
3324
3890
  function doCallback(errCode) {
3891
+ assert(FS.syncFSRequests > 0);
3325
3892
  FS.syncFSRequests--;
3326
3893
  return callback(errCode);
3327
3894
  }
@@ -3348,6 +3915,11 @@ var ASM_CONSTS = {
3348
3915
  });
3349
3916
  },
3350
3917
  mount(type, opts, mountpoint) {
3918
+ if (typeof type == 'string') {
3919
+ // The filesystem was not included, and instead we have an error
3920
+ // message stored in the variable.
3921
+ throw type;
3922
+ }
3351
3923
  var root = mountpoint === '/';
3352
3924
  var pseudo = !mountpoint;
3353
3925
  var node;
@@ -3426,6 +3998,7 @@ var ASM_CONSTS = {
3426
3998
 
3427
3999
  // remove this mount from the child mounts
3428
4000
  var idx = node.mount.mounts.indexOf(mount);
4001
+ assert(idx !== -1);
3429
4002
  node.mount.mounts.splice(idx, 1);
3430
4003
  },
3431
4004
  lookup(parent, name) {
@@ -3918,6 +4491,7 @@ var ASM_CONSTS = {
3918
4491
  return stream.position;
3919
4492
  },
3920
4493
  read(stream, buffer, offset, length, position) {
4494
+ assert(offset >= 0);
3921
4495
  if (length < 0 || position < 0) {
3922
4496
  throw new FS.ErrnoError(28);
3923
4497
  }
@@ -3944,6 +4518,7 @@ var ASM_CONSTS = {
3944
4518
  return bytesRead;
3945
4519
  },
3946
4520
  write(stream, buffer, offset, length, position, canOwn) {
4521
+ assert(offset >= 0);
3947
4522
  if (length < 0 || position < 0) {
3948
4523
  throw new FS.ErrnoError(28);
3949
4524
  }
@@ -4015,6 +4590,7 @@ var ASM_CONSTS = {
4015
4590
  return stream.stream_ops.mmap(stream, length, position, prot, flags);
4016
4591
  },
4017
4592
  msync(stream, buffer, offset, length, mmapFlags) {
4593
+ assert(offset >= 0);
4018
4594
  if (!stream.stream_ops.msync) {
4019
4595
  return 0;
4020
4596
  }
@@ -4178,6 +4754,9 @@ var ASM_CONSTS = {
4178
4754
  var stdin = FS.open('/dev/stdin', 0);
4179
4755
  var stdout = FS.open('/dev/stdout', 1);
4180
4756
  var stderr = FS.open('/dev/stderr', 1);
4757
+ assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`);
4758
+ assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`);
4759
+ assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`);
4181
4760
  },
4182
4761
  staticInit() {
4183
4762
  FS.nameTable = new Array(4096);
@@ -4194,6 +4773,7 @@ var ASM_CONSTS = {
4194
4773
  };
4195
4774
  },
4196
4775
  init(input, output, error) {
4776
+ assert(!FS.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
4197
4777
  FS.initialized = true;
4198
4778
 
4199
4779
  // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
@@ -4206,6 +4786,7 @@ var ASM_CONSTS = {
4206
4786
  quit() {
4207
4787
  FS.initialized = false;
4208
4788
  // force-flush all streams, so we get musl std streams printed out
4789
+ _fflush(0);
4209
4790
  // close all of our streams
4210
4791
  for (var i = 0; i < FS.streams.length; i++) {
4211
4792
  var stream = FS.streams[i];
@@ -4492,6 +5073,7 @@ var ASM_CONSTS = {
4492
5073
  if (position >= contents.length)
4493
5074
  return 0;
4494
5075
  var size = Math.min(contents.length - position, length);
5076
+ assert(size >= 0);
4495
5077
  if (contents.slice) { // normal array
4496
5078
  for (var i = 0; i < size; i++) {
4497
5079
  buffer[offset + i] = contents[position + i];
@@ -4521,6 +5103,24 @@ var ASM_CONSTS = {
4521
5103
  node.stream_ops = stream_ops;
4522
5104
  return node;
4523
5105
  },
5106
+ absolutePath() {
5107
+ abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
5108
+ },
5109
+ createFolder() {
5110
+ abort('FS.createFolder has been removed; use FS.mkdir instead');
5111
+ },
5112
+ createLink() {
5113
+ abort('FS.createLink has been removed; use FS.symlink instead');
5114
+ },
5115
+ joinPath() {
5116
+ abort('FS.joinPath has been removed; use PATH.join instead');
5117
+ },
5118
+ mmapAlloc() {
5119
+ abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
5120
+ },
5121
+ standardizePath() {
5122
+ abort('FS.standardizePath has been removed; use PATH.normalize instead');
5123
+ },
4524
5124
  };
4525
5125
 
4526
5126
  var SYSCALLS = {
@@ -4699,6 +5299,7 @@ var ASM_CONSTS = {
4699
5299
 
4700
5300
 
4701
5301
  var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
5302
+ assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
4702
5303
  return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
4703
5304
  };
4704
5305
 
@@ -4772,6 +5373,7 @@ var ASM_CONSTS = {
4772
5373
  FS.isLink(child.mode) ? 10 : // DT_LNK, symbolic link.
4773
5374
  8; // DT_REG, regular file.
4774
5375
  }
5376
+ assert(id);
4775
5377
  HEAP64[((dirp + pos)>>3)] = BigInt(id);
4776
5378
  HEAP64[(((dirp + pos)+(8))>>3)] = BigInt((idx + 1) * struct_size);
4777
5379
  HEAP16[(((dirp + pos)+(16))>>1)] = 280;
@@ -4942,6 +5544,7 @@ var ASM_CONSTS = {
4942
5544
  var nofollow = flags & 256;
4943
5545
  var allowEmpty = flags & 4096;
4944
5546
  flags = flags & (~6400);
5547
+ assert(!flags, `unknown flags in __syscall_newfstatat: ${flags}`);
4945
5548
  path = SYSCALLS.calculateAt(dirfd, path, allowEmpty);
4946
5549
  return SYSCALLS.writeStat(buf, nofollow ? FS.lstat(path) : FS.stat(path));
4947
5550
  } catch (e) {
@@ -5080,6 +5683,7 @@ var ASM_CONSTS = {
5080
5683
  try {
5081
5684
 
5082
5685
  path = SYSCALLS.getStr(path);
5686
+ assert(flags === 0);
5083
5687
  path = SYSCALLS.calculateAt(dirfd, path, true);
5084
5688
  var now = Date.now(), atime, mtime;
5085
5689
  if (!times) {
@@ -5121,7 +5725,7 @@ var ASM_CONSTS = {
5121
5725
 
5122
5726
 
5123
5727
  var __abort_js = () =>
5124
- abort('');
5728
+ abort('native code called abort()');
5125
5729
 
5126
5730
  var __emscripten_init_main_thread_js = (tb) => {
5127
5731
  // Pass the thread address to the native code where they stored in wasm
@@ -5155,6 +5759,7 @@ var ASM_CONSTS = {
5155
5759
  };
5156
5760
  var callUserCallback = (func) => {
5157
5761
  if (ABORT) {
5762
+ err('user callback triggered after runtime exited or application aborted. Ignoring.');
5158
5763
  return;
5159
5764
  }
5160
5765
  try {
@@ -5174,6 +5779,7 @@ var ASM_CONSTS = {
5174
5779
  // thread.
5175
5780
  // TODO: How to make this work with wasm64?
5176
5781
  var wait = Atomics.waitAsync(HEAP32, ((pthread_ptr)>>2), pthread_ptr);
5782
+ assert(wait.async);
5177
5783
  wait.value.then(checkMailbox);
5178
5784
  var waitingAsync = pthread_ptr + 128;
5179
5785
  Atomics.store(HEAP32, ((waitingAsync)>>2), 1);
@@ -5204,6 +5810,7 @@ var ASM_CONSTS = {
5204
5810
  } else {
5205
5811
  var worker = PThread.pthreads[targetThread];
5206
5812
  if (!worker) {
5813
+ err(`Cannot send message to thread with ID ${targetThread}, unknown thread ID!`);
5207
5814
  return;
5208
5815
  }
5209
5816
  worker.postMessage({cmd: 'checkMailbox'});
@@ -5232,9 +5839,15 @@ var ASM_CONSTS = {
5232
5839
  }
5233
5840
  // Proxied JS library funcs use funcIndex and EM_ASM functions use emAsmAddr
5234
5841
  var func = emAsmAddr ? ASM_CONSTS[emAsmAddr] : proxiedFunctionTable[funcIndex];
5842
+ assert(!(funcIndex && emAsmAddr));
5843
+ assert(func.length == numCallArgs, 'Call args mismatch in _emscripten_receive_on_main_thread_js');
5235
5844
  PThread.currentProxiedOperationCallerThread = callingThread;
5236
5845
  var rtn = func(...proxiedJSCallArgs);
5237
5846
  PThread.currentProxiedOperationCallerThread = 0;
5847
+ // Proxied functions can return any type except bigint. All other types
5848
+ // cooerce to f64/double (the return type of this function in C) but not
5849
+ // bigint.
5850
+ assert(typeof rtn != "bigint");
5238
5851
  return rtn;
5239
5852
  };
5240
5853
 
@@ -5438,6 +6051,7 @@ var ASM_CONSTS = {
5438
6051
  }
5439
6052
 
5440
6053
 
6054
+
5441
6055
  var __tzset_js = (timezone, daylight, std_name, dst_name) => {
5442
6056
  // TODO: Use (malleable) environment variables instead of system settings.
5443
6057
  var currentYear = new Date().getFullYear();
@@ -5477,6 +6091,10 @@ var ASM_CONSTS = {
5477
6091
 
5478
6092
  var winterName = extractZone(winterOffset);
5479
6093
  var summerName = extractZone(summerOffset);
6094
+ assert(winterName);
6095
+ assert(summerName);
6096
+ assert(lengthBytesUTF8(winterName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${winterName})`);
6097
+ assert(lengthBytesUTF8(summerName) <= 16, `timezone name truncated to fit in TZNAME_MAX (${summerName})`);
5480
6098
  if (summerOffset < winterOffset) {
5481
6099
  // Northern hemisphere
5482
6100
  stringToUTF8(winterName, std_name, 17);
@@ -5525,6 +6143,7 @@ var ASM_CONSTS = {
5525
6143
  };
5526
6144
 
5527
6145
  var runtimeKeepalivePop = () => {
6146
+ assert(runtimeKeepaliveCounter > 0);
5528
6147
  runtimeKeepaliveCounter -= 1;
5529
6148
  };
5530
6149
  /** @param {number=} timeout */
@@ -5536,13 +6155,6 @@ var ASM_CONSTS = {
5536
6155
  }, timeout);
5537
6156
  };
5538
6157
 
5539
- var warnOnce = (text) => {
5540
- warnOnce.shown ||= {};
5541
- if (!warnOnce.shown[text]) {
5542
- warnOnce.shown[text] = 1;
5543
- err(text);
5544
- }
5545
- };
5546
6158
 
5547
6159
 
5548
6160
  var Browser = {
@@ -5579,8 +6191,10 @@ var ASM_CONSTS = {
5579
6191
  b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
5580
6192
  }
5581
6193
  var url = URL.createObjectURL(b);
6194
+ assert(typeof url == 'string', 'createObjectURL must return a url as a string');
5582
6195
  var img = new Image();
5583
6196
  img.onload = () => {
6197
+ assert(img.complete, `Image ${name} could not be decoded`);
5584
6198
  var canvas = /** @type {!HTMLCanvasElement} */ (document.createElement('canvas'));
5585
6199
  canvas.width = img.width;
5586
6200
  canvas.height = img.height;
@@ -5618,6 +6232,7 @@ var ASM_CONSTS = {
5618
6232
  }
5619
6233
  var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
5620
6234
  var url = URL.createObjectURL(b); // XXX we never revoke this!
6235
+ assert(typeof url == 'string', 'createObjectURL must return a url as a string');
5621
6236
  var audio = new Audio();
5622
6237
  audio.addEventListener('canplaythrough', () => finish(audio), false); // use addEventListener due to chromium bug 124926
5623
6238
  audio.onerror = function audio_onerror(event) {
@@ -5734,6 +6349,7 @@ var ASM_CONSTS = {
5734
6349
  if (!ctx) return null;
5735
6350
 
5736
6351
  if (setInModule) {
6352
+ if (!useWebGL) assert(typeof GLctx == 'undefined', 'cannot set in module if GLctx is used, but we are a non-GL context that would replace it');
5737
6353
  Module['ctx'] = ctx;
5738
6354
  if (useWebGL) GL.makeContextCurrent(contextHandle);
5739
6355
  Browser.useWebGL = useWebGL;
@@ -5803,6 +6419,9 @@ var ASM_CONSTS = {
5803
6419
 
5804
6420
  canvasContainer.requestFullscreen();
5805
6421
  },
6422
+ requestFullScreen() {
6423
+ abort('Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)');
6424
+ },
5806
6425
  exitFullscreen() {
5807
6426
  // This is workaround for chrome. Trying to exit from fullscreen
5808
6427
  // not in fullscreen state will cause "TypeError: Document not active"
@@ -5908,6 +6527,9 @@ var ASM_CONSTS = {
5908
6527
  // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
5909
6528
  var scrollX = ((typeof window.scrollX != 'undefined') ? window.scrollX : window.pageXOffset);
5910
6529
  var scrollY = ((typeof window.scrollY != 'undefined') ? window.scrollY : window.pageYOffset);
6530
+ // If this assert lands, it's likely because the browser doesn't support scrollX or pageXOffset
6531
+ // and we have no viable fallback.
6532
+ assert((typeof scrollX != 'undefined') && (typeof scrollY != 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');
5911
6533
  var adjustedX = pageX - (scrollX + rect.left);
5912
6534
  var adjustedY = pageY - (scrollY + rect.top);
5913
6535
 
@@ -6799,6 +7421,7 @@ var ASM_CONSTS = {
6799
7421
  * @param {boolean=} noSetTiming
6800
7422
  */
6801
7423
  var setMainLoop = (iterFunc, fps, simulateInfiniteLoop, arg, noSetTiming) => {
7424
+ assert(!MainLoop.func, 'emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.');
6802
7425
  MainLoop.func = iterFunc;
6803
7426
  MainLoop.arg = arg;
6804
7427
 
@@ -6857,6 +7480,11 @@ var ASM_CONSTS = {
6857
7480
  MainLoop.tickStartTime = _emscripten_get_now();
6858
7481
  }
6859
7482
 
7483
+ if (MainLoop.method === 'timeout' && Module['ctx']) {
7484
+ warnOnce('Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!');
7485
+ MainLoop.method = ''; // just warn once per call to set main loop
7486
+ }
7487
+
6860
7488
  MainLoop.runIter(iterFunc);
6861
7489
 
6862
7490
  // catch pauses from the main loop itself
@@ -6942,6 +7570,7 @@ var ASM_CONSTS = {
6942
7570
  for (var post of MainLoop.postMainLoop) {
6943
7571
  post();
6944
7572
  }
7573
+ checkStackCookie();
6945
7574
  },
6946
7575
  nextRAF:0,
6947
7576
  fakeRequestAnimationFrame(func) {
@@ -6972,6 +7601,7 @@ var ASM_CONSTS = {
6972
7601
  MainLoop.timingValue = value;
6973
7602
 
6974
7603
  if (!MainLoop.func) {
7604
+ err('emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.');
6975
7605
  return 1; // Return non-zero on failure, can't set timing mode when there is no main loop.
6976
7606
  }
6977
7607
 
@@ -7094,11 +7724,20 @@ var ASM_CONSTS = {
7094
7724
 
7095
7725
  var readEmAsmArgsArray = [];
7096
7726
  var readEmAsmArgs = (sigPtr, buf) => {
7727
+ // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array.
7728
+ assert(Array.isArray(readEmAsmArgsArray));
7729
+ // The input buffer is allocated on the stack, so it must be stack-aligned.
7730
+ assert(buf % 16 == 0);
7097
7731
  readEmAsmArgsArray.length = 0;
7098
7732
  var ch;
7099
7733
  // Most arguments are i32s, so shift the buffer pointer so it is a plain
7100
7734
  // index into HEAP32.
7101
7735
  while (ch = HEAPU8[sigPtr++]) {
7736
+ var chr = String.fromCharCode(ch);
7737
+ var validChars = ['d', 'f', 'i', 'p'];
7738
+ // In WASM_BIGINT mode we support passing i64 values as bigint.
7739
+ validChars.push('j');
7740
+ assert(validChars.includes(chr), `Invalid character ${ch}("${chr}") in readEmAsmArgs! Use only [${validChars}], and do not specify "v" for void return argument.`);
7102
7741
  // Floats are always passed as doubles, so all types except for 'i'
7103
7742
  // are 8 bytes and require alignment.
7104
7743
  var wide = (ch != 105);
@@ -7118,6 +7757,7 @@ var ASM_CONSTS = {
7118
7757
  };
7119
7758
  var runEmAsmFunction = (code, sigPtr, argbuf) => {
7120
7759
  var args = readEmAsmArgs(sigPtr, argbuf);
7760
+ assert(ASM_CONSTS.hasOwnProperty(code), `No EM_ASM constant found at address ${code}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
7121
7761
  return ASM_CONSTS[code](...args);
7122
7762
  };
7123
7763
  var _emscripten_asm_const_int = (code, sigPtr, argbuf) => {
@@ -7139,6 +7779,7 @@ var ASM_CONSTS = {
7139
7779
  // code paths as similar as possible on both sides.)
7140
7780
  return proxyToMainThread(0, emAsmAddr, sync, ...args);
7141
7781
  }
7782
+ assert(ASM_CONSTS.hasOwnProperty(emAsmAddr), `No EM_ASM constant found at address ${emAsmAddr}. The loaded WebAssembly file is likely out of sync with the generated JavaScript.`);
7142
7783
  return ASM_CONSTS[emAsmAddr](...args);
7143
7784
  };
7144
7785
  var _emscripten_asm_const_int_sync_on_main_thread = (emAsmAddr, sigPtr, argbuf) => runMainThreadEmAsm(emAsmAddr, sigPtr, argbuf, 1);
@@ -7152,6 +7793,11 @@ var ASM_CONSTS = {
7152
7793
 
7153
7794
 
7154
7795
  var _emscripten_check_blocking_allowed = () => {
7796
+
7797
+ if (ENVIRONMENT_IS_WORKER) return; // Blocking in a worker/pthread is fine.
7798
+
7799
+ warnOnce('Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread');
7800
+
7155
7801
  };
7156
7802
 
7157
7803
 
@@ -7234,6 +7880,8 @@ var ASM_CONSTS = {
7234
7880
  },
7235
7881
  registerOrRemoveHandler(eventHandler) {
7236
7882
  if (!eventHandler.target) {
7883
+ err('registerOrRemoveHandler: the target element for event handler registration does not exist, when processing the following event handler registration:');
7884
+ console.dir(eventHandler);
7237
7885
  return -4;
7238
7886
  }
7239
7887
  if (eventHandler.callbackfunc) {
@@ -7662,10 +8310,12 @@ var ASM_CONSTS = {
7662
8310
 
7663
8311
 
7664
8312
 
8313
+
7665
8314
  function _emscripten_force_exit(status) {
7666
8315
  if (ENVIRONMENT_IS_PTHREAD)
7667
8316
  return proxyToMainThread(42, 0, 1, status);
7668
8317
 
8318
+ warnOnce('emscripten_force_exit cannot actually shut down the runtime, as the build does not have EXIT_RUNTIME set');
7669
8319
  __emscripten_runtime_keepalive_clear();
7670
8320
  _exit(status);
7671
8321
 
@@ -7737,6 +8387,7 @@ var ASM_CONSTS = {
7737
8387
  if (ENVIRONMENT_IS_PTHREAD)
7738
8388
  return proxyToMainThread(45, 0, 1, index, gamepadState);
7739
8389
 
8390
+ if (!JSEvents.lastGamepadState) throw 'emscripten_get_gamepad_status() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';
7740
8391
  // INVALID_PARAM is returned on a Gamepad index that never was there.
7741
8392
  if (index < 0 || index >= JSEvents.lastGamepadState.length) return -5;
7742
8393
 
@@ -7764,6 +8415,7 @@ var ASM_CONSTS = {
7764
8415
  if (ENVIRONMENT_IS_PTHREAD)
7765
8416
  return proxyToMainThread(46, 0, 1);
7766
8417
 
8418
+ if (!JSEvents.lastGamepadState) throw 'emscripten_get_num_gamepads() can only be called after having first called emscripten_sample_gamepad_data() and that function has returned EMSCRIPTEN_RESULT_SUCCESS!';
7767
8419
  // N.B. Do not call emscripten_get_num_gamepads() unless having first called emscripten_sample_gamepad_data(), and that has returned EMSCRIPTEN_RESULT_SUCCESS.
7768
8420
  // Otherwise the following line will throw an exception.
7769
8421
  return JSEvents.lastGamepadState.length;
@@ -8683,10 +9335,17 @@ var ASM_CONSTS = {
8683
9335
  GLctx.getAttribLocation(GL.programs[program], UTF8ToString(name));
8684
9336
  var _emscripten_glGetAttribLocation = _glGetAttribLocation;
8685
9337
 
9338
+
9339
+ var readI53FromU64 = (ptr) => {
9340
+ return HEAPU32[((ptr)>>2)] + HEAPU32[(((ptr)+(4))>>2)] * 4294967296;
9341
+ };
8686
9342
  var writeI53ToI64 = (ptr, num) => {
8687
9343
  HEAPU32[((ptr)>>2)] = num;
8688
9344
  var lower = HEAPU32[((ptr)>>2)];
8689
9345
  HEAPU32[(((ptr)+(4))>>2)] = (num - lower)/4294967296;
9346
+ var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
9347
+ var offset = ((ptr)>>2);
9348
+ if (deserialized != num) warnOnce(`writeI53ToI64() out of range: serialized JS Number ${num} to Wasm heap as bytes lo=${ptrToString(HEAPU32[offset])}, hi=${ptrToString(HEAPU32[offset+1])}, which deserializes back to ${deserialized} instead!`);
8690
9349
  };
8691
9350
 
8692
9351
 
@@ -10600,7 +11259,7 @@ var ASM_CONSTS = {
10600
11259
 
10601
11260
 
10602
11261
  var abortOnCannotGrowMemory = (requestedSize) => {
10603
- abort('OOM');
11262
+ abort(`Cannot enlarge memory arrays to size ${requestedSize} bytes (OOM). Either (1) compile with -sINITIAL_MEMORY=X with X higher than the current value ${HEAP8.length}, (2) compile with -sALLOW_MEMORY_GROWTH which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -sABORTING_MALLOC=0`);
10604
11263
  };
10605
11264
  var _emscripten_resize_heap = (requestedSize) => {
10606
11265
  var oldSize = HEAPU8.length;
@@ -10622,6 +11281,7 @@ var ASM_CONSTS = {
10622
11281
  if (navigator.getGamepads) return (JSEvents.lastGamepadState = navigator.getGamepads())
10623
11282
  ? 0 : -1;
10624
11283
  } catch(e) {
11284
+ err(`navigator.getGamepads() exists, but failed to execute with exception ${e}. Disabling Gamepad access.`);
10625
11285
  navigator.getGamepads = null; // Disable getGamepads() so that it won't be attempted to be used again.
10626
11286
  }
10627
11287
  return -1;
@@ -10872,6 +11532,7 @@ var ASM_CONSTS = {
10872
11532
  JSEvents.keyEvent ||= _malloc(160);
10873
11533
 
10874
11534
  var keyEventHandlerFunc = (e) => {
11535
+ assert(e);
10875
11536
 
10876
11537
  var keyEventData = targetThread ? _malloc(160) : JSEvents.keyEvent; // This allocated block is passed as satellite data to the proxied function call, so the call frees up the data block when done.
10877
11538
  HEAPF64[((keyEventData)>>3)] = e.timeStamp;
@@ -10944,6 +11605,7 @@ var ASM_CONSTS = {
10944
11605
 
10945
11606
 
10946
11607
  var fillMouseEventData = (eventStruct, e, target) => {
11608
+ assert(eventStruct % 4 == 0);
10947
11609
  HEAPF64[((eventStruct)>>3)] = e.timeStamp;
10948
11610
  var idx = ((eventStruct)>>2);
10949
11611
  HEAP32[idx + 2] = e.screenX;
@@ -11172,6 +11834,7 @@ var ASM_CONSTS = {
11172
11834
  target = findEventTarget(target);
11173
11835
 
11174
11836
  var touchEventHandlerFunc = (e) => {
11837
+ assert(e);
11175
11838
  var t, touches = {}, et = e.touches;
11176
11839
  // To ease marshalling different kinds of touches that browser reports (all touches are listed in e.touches,
11177
11840
  // only changed touches in e.changedTouches, and touches on target at a.targetTouches), mark a boolean in
@@ -11427,6 +12090,7 @@ var ASM_CONSTS = {
11427
12090
 
11428
12091
  var stringToAscii = (str, buffer) => {
11429
12092
  for (var i = 0; i < str.length; ++i) {
12093
+ assert(str.charCodeAt(i) === (str.charCodeAt(i) & 0xff));
11430
12094
  HEAP8[buffer++] = str.charCodeAt(i);
11431
12095
  }
11432
12096
  // Null-terminate the string
@@ -11635,6 +12299,7 @@ var ASM_CONSTS = {
11635
12299
  };
11636
12300
 
11637
12301
  var dynCall = (sig, ptr, args = []) => {
12302
+ assert(getWasmTableEntry(ptr), `missing table entry in dynCall: ${ptr}`);
11638
12303
  var rtn = getWasmTableEntry(ptr)(...args);
11639
12304
  return rtn;
11640
12305
  };
@@ -11645,11 +12310,13 @@ var ASM_CONSTS = {
11645
12310
 
11646
12311
  var getCFunc = (ident) => {
11647
12312
  var func = Module['_' + ident]; // closure exported function
12313
+ assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
11648
12314
  return func;
11649
12315
  };
11650
12316
 
11651
12317
 
11652
12318
  var writeArrayToMemory = (array, buffer) => {
12319
+ assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
11653
12320
  HEAP8.set(array, buffer);
11654
12321
  };
11655
12322
 
@@ -11692,6 +12359,7 @@ var ASM_CONSTS = {
11692
12359
  var func = getCFunc(ident);
11693
12360
  var cArgs = [];
11694
12361
  var stack = 0;
12362
+ assert(returnType !== 'array', 'Return type should not be "array".');
11695
12363
  if (args) {
11696
12364
  for (var i = 0; i < args.length; i++) {
11697
12365
  var converter = toC[argTypes[i]];
@@ -11719,17 +12387,11 @@ var ASM_CONSTS = {
11719
12387
  * @param {Object=} opts
11720
12388
  */
11721
12389
  var cwrap = (ident, returnType, argTypes, opts) => {
11722
- // When the function takes numbers and returns a number, we can just return
11723
- // the original function
11724
- var numericArgs = !argTypes || argTypes.every((type) => type === 'number' || type === 'boolean');
11725
- var numericRet = returnType !== 'string';
11726
- if (numericRet && numericArgs && !opts) {
11727
- return getCFunc(ident);
11728
- }
11729
12390
  return (...args) => ccall(ident, returnType, argTypes, args, opts);
11730
12391
  };
11731
12392
 
11732
12393
  var uleb128Encode = (n, target) => {
12394
+ assert(n < 16384);
11733
12395
  if (n < 128) {
11734
12396
  target.push(n);
11735
12397
  } else {
@@ -11751,6 +12413,7 @@ var ASM_CONSTS = {
11751
12413
  results: sig[0] == 'v' ? [] : [typeNames[sig[0]]]
11752
12414
  };
11753
12415
  for (var i = 1; i < sig.length; ++i) {
12416
+ assert(sig[i] in typeNames, 'invalid signature char: ' + sig[i]);
11754
12417
  type.parameters.push(typeNames[sig[i]]);
11755
12418
  }
11756
12419
  return type;
@@ -11772,6 +12435,7 @@ var ASM_CONSTS = {
11772
12435
  target.push(0x60 /* form: func */);
11773
12436
  uleb128Encode(sigParam.length, target);
11774
12437
  for (var i = 0; i < sigParam.length; ++i) {
12438
+ assert(sigParam[i] in typeCodes, 'invalid signature char: ' + sigParam[i]);
11775
12439
  target.push(typeCodes[sigParam[i]]);
11776
12440
  }
11777
12441
 
@@ -11887,6 +12551,7 @@ var ASM_CONSTS = {
11887
12551
 
11888
12552
  /** @param {string=} sig */
11889
12553
  var addFunction = (func, sig) => {
12554
+ assert(typeof func != 'undefined');
11890
12555
  // Check if the function is already in the table, to ensure each function
11891
12556
  // gets a unique index.
11892
12557
  var rtn = getFunctionAddress(func);
@@ -11906,6 +12571,7 @@ var ASM_CONSTS = {
11906
12571
  if (!(err instanceof TypeError)) {
11907
12572
  throw err;
11908
12573
  }
12574
+ assert(typeof sig != 'undefined', 'Missing signature argument to addFunction: ' + func);
11909
12575
  var wrapped = convertJsFunctionToWasm(func, sig);
11910
12576
  setWasmTableEntry(ret, wrapped);
11911
12577
  }
@@ -11931,15 +12597,9 @@ PThread.init();;
11931
12597
  // Set module methods based on EXPORTED_RUNTIME_METHODS
11932
12598
  ;
11933
12599
 
11934
- // This error may happen quite a bit. To avoid overhead we reuse it (and
11935
- // suffer a lack of stack info).
11936
- MEMFS.doesNotExistError = new FS.ErrnoError(44);
11937
- /** @suppress {checkTypes} */
11938
- MEMFS.doesNotExistError.stack = '<generic error, no stack>';
11939
- ;
11940
-
11941
12600
  // exports
11942
12601
  Module['requestFullscreen'] = Browser.requestFullscreen;
12602
+ Module['requestFullScreen'] = Browser.requestFullScreen;
11943
12603
  Module['setCanvasSize'] = Browser.setCanvasSize;
11944
12604
  Module['getUserMedia'] = Browser.getUserMedia;
11945
12605
  Module['createContext'] = Browser.createContext;
@@ -12040,6 +12700,9 @@ var proxiedFunctionTable = [
12040
12700
  _fd_write
12041
12701
  ];
12042
12702
 
12703
+ function checkIncomingModuleAPI() {
12704
+ ignoredModuleProp('fetchSettings');
12705
+ }
12043
12706
  var wasmImports;
12044
12707
  function assignWasmImports() {
12045
12708
  wasmImports = {
@@ -12840,67 +13503,73 @@ function assignWasmImports() {
12840
13503
  };
12841
13504
  }
12842
13505
  var wasmExports = await createWasm();
12843
- var ___wasm_call_ctors = () => (___wasm_call_ctors = wasmExports['__wasm_call_ctors'])();
12844
- var _screenshot = Module['_screenshot'] = (a0) => (_screenshot = Module['_screenshot'] = wasmExports['screenshot'])(a0);
12845
- var _buttonPress = Module['_buttonPress'] = (a0) => (_buttonPress = Module['_buttonPress'] = wasmExports['buttonPress'])(a0);
12846
- var _buttonUnpress = Module['_buttonUnpress'] = (a0) => (_buttonUnpress = Module['_buttonUnpress'] = wasmExports['buttonUnpress'])(a0);
12847
- var _toggleRewind = Module['_toggleRewind'] = (a0) => (_toggleRewind = Module['_toggleRewind'] = wasmExports['toggleRewind'])(a0);
12848
- var _setVolume = Module['_setVolume'] = (a0) => (_setVolume = Module['_setVolume'] = wasmExports['setVolume'])(a0);
12849
- var _getVolume = Module['_getVolume'] = () => (_getVolume = Module['_getVolume'] = wasmExports['getVolume'])();
12850
- var _getMainLoopTimingMode = Module['_getMainLoopTimingMode'] = () => (_getMainLoopTimingMode = Module['_getMainLoopTimingMode'] = wasmExports['getMainLoopTimingMode'])();
12851
- var _getMainLoopTimingValue = Module['_getMainLoopTimingValue'] = () => (_getMainLoopTimingValue = Module['_getMainLoopTimingValue'] = wasmExports['getMainLoopTimingValue'])();
12852
- var _setMainLoopTiming = Module['_setMainLoopTiming'] = (a0, a1) => (_setMainLoopTiming = Module['_setMainLoopTiming'] = wasmExports['setMainLoopTiming'])(a0, a1);
12853
- var _setFastForwardMultiplier = Module['_setFastForwardMultiplier'] = (a0) => (_setFastForwardMultiplier = Module['_setFastForwardMultiplier'] = wasmExports['setFastForwardMultiplier'])(a0);
12854
- var _getFastForwardMultiplier = Module['_getFastForwardMultiplier'] = () => (_getFastForwardMultiplier = Module['_getFastForwardMultiplier'] = wasmExports['getFastForwardMultiplier'])();
12855
- var _quitGame = Module['_quitGame'] = () => (_quitGame = Module['_quitGame'] = wasmExports['quitGame'])();
12856
- var _free = (a0) => (_free = wasmExports['free'])(a0);
12857
- var _quitMgba = Module['_quitMgba'] = () => (_quitMgba = Module['_quitMgba'] = wasmExports['quitMgba'])();
12858
- var _quickReload = Module['_quickReload'] = () => (_quickReload = Module['_quickReload'] = wasmExports['quickReload'])();
12859
- var _pauseGame = Module['_pauseGame'] = () => (_pauseGame = Module['_pauseGame'] = wasmExports['pauseGame'])();
12860
- var _resumeGame = Module['_resumeGame'] = () => (_resumeGame = Module['_resumeGame'] = wasmExports['resumeGame'])();
12861
- var _setEventEnable = Module['_setEventEnable'] = (a0) => (_setEventEnable = Module['_setEventEnable'] = wasmExports['setEventEnable'])(a0);
12862
- var _bindKey = Module['_bindKey'] = (a0, a1) => (_bindKey = Module['_bindKey'] = wasmExports['bindKey'])(a0, a1);
12863
- var _saveState = Module['_saveState'] = (a0) => (_saveState = Module['_saveState'] = wasmExports['saveState'])(a0);
12864
- var _loadState = Module['_loadState'] = (a0) => (_loadState = Module['_loadState'] = wasmExports['loadState'])(a0);
12865
- var _autoLoadCheats = Module['_autoLoadCheats'] = () => (_autoLoadCheats = Module['_autoLoadCheats'] = wasmExports['autoLoadCheats'])();
12866
- var _loadGame = Module['_loadGame'] = (a0, a1) => (_loadGame = Module['_loadGame'] = wasmExports['loadGame'])(a0, a1);
12867
- var _saveStateSlot = Module['_saveStateSlot'] = (a0, a1) => (_saveStateSlot = Module['_saveStateSlot'] = wasmExports['saveStateSlot'])(a0, a1);
12868
- var _loadStateSlot = Module['_loadStateSlot'] = (a0, a1) => (_loadStateSlot = Module['_loadStateSlot'] = wasmExports['loadStateSlot'])(a0, a1);
12869
- var _addCoreCallbacks = Module['_addCoreCallbacks'] = (a0, a1, a2, a3, a4, a5) => (_addCoreCallbacks = Module['_addCoreCallbacks'] = wasmExports['addCoreCallbacks'])(a0, a1, a2, a3, a4, a5);
12870
- var _setIntegerCoreSetting = Module['_setIntegerCoreSetting'] = (a0, a1) => (_setIntegerCoreSetting = Module['_setIntegerCoreSetting'] = wasmExports['setIntegerCoreSetting'])(a0, a1);
12871
- var _setupConstants = Module['_setupConstants'] = () => (_setupConstants = Module['_setupConstants'] = wasmExports['setupConstants'])();
12872
- var _main = Module['_main'] = (a0, a1) => (_main = Module['_main'] = wasmExports['main'])(a0, a1);
12873
- var _malloc = (a0) => (_malloc = wasmExports['malloc'])(a0);
13506
+ var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0);
13507
+ var _screenshot = Module['_screenshot'] = createExportWrapper('screenshot', 1);
13508
+ var _buttonPress = Module['_buttonPress'] = createExportWrapper('buttonPress', 1);
13509
+ var _buttonUnpress = Module['_buttonUnpress'] = createExportWrapper('buttonUnpress', 1);
13510
+ var _toggleRewind = Module['_toggleRewind'] = createExportWrapper('toggleRewind', 1);
13511
+ var _setVolume = Module['_setVolume'] = createExportWrapper('setVolume', 1);
13512
+ var _getVolume = Module['_getVolume'] = createExportWrapper('getVolume', 0);
13513
+ var _getMainLoopTimingMode = Module['_getMainLoopTimingMode'] = createExportWrapper('getMainLoopTimingMode', 0);
13514
+ var _getMainLoopTimingValue = Module['_getMainLoopTimingValue'] = createExportWrapper('getMainLoopTimingValue', 0);
13515
+ var _setMainLoopTiming = Module['_setMainLoopTiming'] = createExportWrapper('setMainLoopTiming', 2);
13516
+ var _setFastForwardMultiplier = Module['_setFastForwardMultiplier'] = createExportWrapper('setFastForwardMultiplier', 1);
13517
+ var _getFastForwardMultiplier = Module['_getFastForwardMultiplier'] = createExportWrapper('getFastForwardMultiplier', 0);
13518
+ var _quitGame = Module['_quitGame'] = createExportWrapper('quitGame', 0);
13519
+ var _free = createExportWrapper('free', 1);
13520
+ var _quitMgba = Module['_quitMgba'] = createExportWrapper('quitMgba', 0);
13521
+ var _quickReload = Module['_quickReload'] = createExportWrapper('quickReload', 0);
13522
+ var _pauseGame = Module['_pauseGame'] = createExportWrapper('pauseGame', 0);
13523
+ var _resumeGame = Module['_resumeGame'] = createExportWrapper('resumeGame', 0);
13524
+ var _setEventEnable = Module['_setEventEnable'] = createExportWrapper('setEventEnable', 1);
13525
+ var _bindKey = Module['_bindKey'] = createExportWrapper('bindKey', 2);
13526
+ var _saveState = Module['_saveState'] = createExportWrapper('saveState', 1);
13527
+ var _loadState = Module['_loadState'] = createExportWrapper('loadState', 1);
13528
+ var _autoLoadCheats = Module['_autoLoadCheats'] = createExportWrapper('autoLoadCheats', 0);
13529
+ var _loadGame = Module['_loadGame'] = createExportWrapper('loadGame', 2);
13530
+ var _saveStateSlot = Module['_saveStateSlot'] = createExportWrapper('saveStateSlot', 2);
13531
+ var _loadStateSlot = Module['_loadStateSlot'] = createExportWrapper('loadStateSlot', 2);
13532
+ var _addCoreCallbacks = Module['_addCoreCallbacks'] = createExportWrapper('addCoreCallbacks', 6);
13533
+ var _setIntegerCoreSetting = Module['_setIntegerCoreSetting'] = createExportWrapper('setIntegerCoreSetting', 2);
13534
+ var _setupConstants = Module['_setupConstants'] = createExportWrapper('setupConstants', 0);
13535
+ var _main = Module['_main'] = createExportWrapper('main', 2);
13536
+ var _malloc = createExportWrapper('malloc', 1);
13537
+ var _strerror = createExportWrapper('strerror', 1);
13538
+ var _fflush = createExportWrapper('fflush', 1);
12874
13539
  var _pthread_self = () => (_pthread_self = wasmExports['pthread_self'])();
12875
- var __emscripten_tls_init = () => (__emscripten_tls_init = wasmExports['_emscripten_tls_init'])();
12876
- var _emscripten_builtin_memalign = (a0, a1) => (_emscripten_builtin_memalign = wasmExports['emscripten_builtin_memalign'])(a0, a1);
12877
- var __emscripten_run_callback_on_thread = (a0, a1, a2, a3, a4) => (__emscripten_run_callback_on_thread = wasmExports['_emscripten_run_callback_on_thread'])(a0, a1, a2, a3, a4);
12878
- var __emscripten_thread_init = (a0, a1, a2, a3, a4, a5) => (__emscripten_thread_init = wasmExports['_emscripten_thread_init'])(a0, a1, a2, a3, a4, a5);
12879
- var __emscripten_thread_crashed = () => (__emscripten_thread_crashed = wasmExports['_emscripten_thread_crashed'])();
12880
- var __emscripten_run_on_main_thread_js = (a0, a1, a2, a3, a4) => (__emscripten_run_on_main_thread_js = wasmExports['_emscripten_run_on_main_thread_js'])(a0, a1, a2, a3, a4);
12881
- var __emscripten_thread_free_data = (a0) => (__emscripten_thread_free_data = wasmExports['_emscripten_thread_free_data'])(a0);
12882
- var __emscripten_thread_exit = (a0) => (__emscripten_thread_exit = wasmExports['_emscripten_thread_exit'])(a0);
12883
- var __emscripten_check_mailbox = () => (__emscripten_check_mailbox = wasmExports['_emscripten_check_mailbox'])();
12884
- var _setThrew = (a0, a1) => (_setThrew = wasmExports['setThrew'])(a0, a1);
13540
+ var __emscripten_tls_init = createExportWrapper('_emscripten_tls_init', 0);
13541
+ var _emscripten_builtin_memalign = createExportWrapper('emscripten_builtin_memalign', 2);
13542
+ var __emscripten_run_callback_on_thread = createExportWrapper('_emscripten_run_callback_on_thread', 5);
13543
+ var __emscripten_thread_init = createExportWrapper('_emscripten_thread_init', 6);
13544
+ var __emscripten_thread_crashed = createExportWrapper('_emscripten_thread_crashed', 0);
13545
+ var _emscripten_stack_get_base = () => (_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'])();
13546
+ var _emscripten_stack_get_end = () => (_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'])();
13547
+ var __emscripten_run_on_main_thread_js = createExportWrapper('_emscripten_run_on_main_thread_js', 5);
13548
+ var __emscripten_thread_free_data = createExportWrapper('_emscripten_thread_free_data', 1);
13549
+ var __emscripten_thread_exit = createExportWrapper('_emscripten_thread_exit', 1);
13550
+ var __emscripten_check_mailbox = createExportWrapper('_emscripten_check_mailbox', 0);
13551
+ var _setThrew = createExportWrapper('setThrew', 2);
13552
+ var _emscripten_stack_init = () => (_emscripten_stack_init = wasmExports['emscripten_stack_init'])();
12885
13553
  var _emscripten_stack_set_limits = (a0, a1) => (_emscripten_stack_set_limits = wasmExports['emscripten_stack_set_limits'])(a0, a1);
13554
+ var _emscripten_stack_get_free = () => (_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'])();
12886
13555
  var __emscripten_stack_restore = (a0) => (__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'])(a0);
12887
13556
  var __emscripten_stack_alloc = (a0) => (__emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'])(a0);
12888
13557
  var _emscripten_stack_get_current = () => (_emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'])();
12889
- var _GBAInputInfo = Module['_GBAInputInfo'] = 122320;
12890
- var _binaryName = Module['_binaryName'] = 198352;
12891
- var _projectName = Module['_projectName'] = 198356;
12892
- var _projectVersion = Module['_projectVersion'] = 198360;
12893
- var _gitCommit = Module['_gitCommit'] = 198336;
12894
- var _gitCommitShort = Module['_gitCommitShort'] = 198340;
12895
- var _gitBranch = Module['_gitBranch'] = 198344;
12896
- var _gitRevision = Module['_gitRevision'] = 198348;
12897
- var _GBIORegisterNames = Module['_GBIORegisterNames'] = 60688;
12898
- var _GBSavestateMagic = Module['_GBSavestateMagic'] = 75952;
12899
- var _GBSavestateVersion = Module['_GBSavestateVersion'] = 75956;
12900
- var _GBA_LUX_LEVELS = Module['_GBA_LUX_LEVELS'] = 105424;
12901
- var _GBAVideoObjSizes = Module['_GBAVideoObjSizes'] = 149760;
12902
- var _GBASavestateMagic = Module['_GBASavestateMagic'] = 149536;
12903
- var _GBASavestateVersion = Module['_GBASavestateVersion'] = 149540;
13558
+ var _GBAInputInfo = Module['_GBAInputInfo'] = 123872;
13559
+ var _binaryName = Module['_binaryName'] = 199904;
13560
+ var _projectName = Module['_projectName'] = 199908;
13561
+ var _projectVersion = Module['_projectVersion'] = 199912;
13562
+ var _gitCommit = Module['_gitCommit'] = 199888;
13563
+ var _gitCommitShort = Module['_gitCommitShort'] = 199892;
13564
+ var _gitBranch = Module['_gitBranch'] = 199896;
13565
+ var _gitRevision = Module['_gitRevision'] = 199900;
13566
+ var _GBIORegisterNames = Module['_GBIORegisterNames'] = 62240;
13567
+ var _GBSavestateMagic = Module['_GBSavestateMagic'] = 77504;
13568
+ var _GBSavestateVersion = Module['_GBSavestateVersion'] = 77508;
13569
+ var _GBA_LUX_LEVELS = Module['_GBA_LUX_LEVELS'] = 106976;
13570
+ var _GBAVideoObjSizes = Module['_GBAVideoObjSizes'] = 151312;
13571
+ var _GBASavestateMagic = Module['_GBASavestateMagic'] = 151088;
13572
+ var _GBASavestateVersion = Module['_GBASavestateVersion'] = 151092;
12904
13573
  function invoke_iiiii(index,a1,a2,a3,a4) {
12905
13574
  var sp = stackSave();
12906
13575
  try {
@@ -13019,9 +13688,316 @@ Module['cwrap'] = cwrap;
13019
13688
  Module['addFunction'] = addFunction;
13020
13689
  Module['removeFunction'] = removeFunction;
13021
13690
  Module['FS'] = FS;
13691
+ var missingLibrarySymbols = [
13692
+ 'writeI53ToI64Clamped',
13693
+ 'writeI53ToI64Signaling',
13694
+ 'writeI53ToU64Clamped',
13695
+ 'writeI53ToU64Signaling',
13696
+ 'convertI32PairToI53',
13697
+ 'convertI32PairToI53Checked',
13698
+ 'convertU32PairToI53',
13699
+ 'getTempRet0',
13700
+ 'setTempRet0',
13701
+ 'growMemory',
13702
+ 'inetPton4',
13703
+ 'inetNtop4',
13704
+ 'inetPton6',
13705
+ 'inetNtop6',
13706
+ 'readSockaddr',
13707
+ 'writeSockaddr',
13708
+ 'emscriptenLog',
13709
+ 'getDynCaller',
13710
+ 'asmjsMangle',
13711
+ 'HandleAllocator',
13712
+ 'getNativeTypeSize',
13713
+ 'addOnInit',
13714
+ 'addOnPostCtor',
13715
+ 'addOnPreMain',
13716
+ 'STACK_SIZE',
13717
+ 'STACK_ALIGN',
13718
+ 'POINTER_SIZE',
13719
+ 'ASSERTIONS',
13720
+ 'reallyNegative',
13721
+ 'unSign',
13722
+ 'strLen',
13723
+ 'reSign',
13724
+ 'formatString',
13725
+ 'intArrayToString',
13726
+ 'AsciiToString',
13727
+ 'UTF16ToString',
13728
+ 'stringToUTF16',
13729
+ 'lengthBytesUTF16',
13730
+ 'UTF32ToString',
13731
+ 'stringToUTF32',
13732
+ 'lengthBytesUTF32',
13733
+ 'fillDeviceOrientationEventData',
13734
+ 'registerDeviceOrientationEventCallback',
13735
+ 'fillDeviceMotionEventData',
13736
+ 'registerDeviceMotionEventCallback',
13737
+ 'screenOrientation',
13738
+ 'fillOrientationChangeEventData',
13739
+ 'registerOrientationChangeEventCallback',
13740
+ 'hideEverythingExceptGivenElement',
13741
+ 'restoreHiddenElements',
13742
+ 'softFullscreenResizeWebGLRenderTarget',
13743
+ 'registerPointerlockErrorEventCallback',
13744
+ 'fillBatteryEventData',
13745
+ 'battery',
13746
+ 'registerBatteryEventCallback',
13747
+ 'jsStackTrace',
13748
+ 'getCallstack',
13749
+ 'convertPCtoSourceLocation',
13750
+ 'wasiRightsToMuslOFlags',
13751
+ 'wasiOFlagsToMuslOFlags',
13752
+ 'setImmediateWrapped',
13753
+ 'safeRequestAnimationFrame',
13754
+ 'clearImmediateWrapped',
13755
+ 'registerPostMainLoop',
13756
+ 'registerPreMainLoop',
13757
+ 'getPromise',
13758
+ 'makePromise',
13759
+ 'idsToPromises',
13760
+ 'makePromiseCallback',
13761
+ 'ExceptionInfo',
13762
+ 'findMatchingCatch',
13763
+ 'Browser_asyncPrepareDataCounter',
13764
+ 'arraySum',
13765
+ 'addDays',
13766
+ 'getSocketFromFD',
13767
+ 'getSocketAddress',
13768
+ 'FS_unlink',
13769
+ 'FS_mkdirTree',
13770
+ '_setNetworkCallback',
13771
+ 'writeGLArray',
13772
+ 'emscripten_webgl_destroy_context_before_on_calling_thread',
13773
+ 'registerWebGlEventCallback',
13774
+ 'runAndAbortIfError',
13775
+ 'ALLOC_NORMAL',
13776
+ 'ALLOC_STACK',
13777
+ 'allocate',
13778
+ 'writeStringToMemory',
13779
+ 'writeAsciiToMemory',
13780
+ 'setErrNo',
13781
+ 'demangle',
13782
+ 'stackTrace',
13783
+ ];
13784
+ missingLibrarySymbols.forEach(missingLibrarySymbol)
13785
+
13786
+ var unexportedSymbols = [
13787
+ 'run',
13788
+ 'addRunDependency',
13789
+ 'removeRunDependency',
13790
+ 'out',
13791
+ 'err',
13792
+ 'callMain',
13793
+ 'abort',
13794
+ 'wasmMemory',
13795
+ 'wasmExports',
13796
+ 'writeStackCookie',
13797
+ 'checkStackCookie',
13798
+ 'writeI53ToI64',
13799
+ 'readI53FromI64',
13800
+ 'readI53FromU64',
13801
+ 'INT53_MAX',
13802
+ 'INT53_MIN',
13803
+ 'bigintToI53Checked',
13804
+ 'stackSave',
13805
+ 'stackRestore',
13806
+ 'stackAlloc',
13807
+ 'ptrToString',
13808
+ 'zeroMemory',
13809
+ 'exitJS',
13810
+ 'getHeapMax',
13811
+ 'abortOnCannotGrowMemory',
13812
+ 'ENV',
13813
+ 'ERRNO_CODES',
13814
+ 'strError',
13815
+ 'DNS',
13816
+ 'Protocols',
13817
+ 'Sockets',
13818
+ 'timers',
13819
+ 'warnOnce',
13820
+ 'readEmAsmArgsArray',
13821
+ 'readEmAsmArgs',
13822
+ 'runEmAsmFunction',
13823
+ 'runMainThreadEmAsm',
13824
+ 'jstoi_q',
13825
+ 'jstoi_s',
13826
+ 'getExecutableName',
13827
+ 'listenOnce',
13828
+ 'autoResumeAudioContext',
13829
+ 'dynCall',
13830
+ 'handleException',
13831
+ 'keepRuntimeAlive',
13832
+ 'runtimeKeepalivePush',
13833
+ 'runtimeKeepalivePop',
13834
+ 'callUserCallback',
13835
+ 'maybeExit',
13836
+ 'asyncLoad',
13837
+ 'alignMemory',
13838
+ 'mmapAlloc',
13839
+ 'wasmTable',
13840
+ 'noExitRuntime',
13841
+ 'addOnPreRun',
13842
+ 'addOnExit',
13843
+ 'addOnPostRun',
13844
+ 'getCFunc',
13845
+ 'ccall',
13846
+ 'uleb128Encode',
13847
+ 'sigToWasmTypes',
13848
+ 'generateFuncType',
13849
+ 'convertJsFunctionToWasm',
13850
+ 'freeTableIndexes',
13851
+ 'functionsInTableMap',
13852
+ 'getEmptyTableSlot',
13853
+ 'updateTableMap',
13854
+ 'getFunctionAddress',
13855
+ 'setValue',
13856
+ 'getValue',
13857
+ 'PATH',
13858
+ 'PATH_FS',
13859
+ 'UTF8Decoder',
13860
+ 'UTF8ArrayToString',
13861
+ 'UTF8ToString',
13862
+ 'stringToUTF8Array',
13863
+ 'stringToUTF8',
13864
+ 'lengthBytesUTF8',
13865
+ 'intArrayFromString',
13866
+ 'stringToAscii',
13867
+ 'UTF16Decoder',
13868
+ 'stringToNewUTF8',
13869
+ 'stringToUTF8OnStack',
13870
+ 'writeArrayToMemory',
13871
+ 'JSEvents',
13872
+ 'registerKeyEventCallback',
13873
+ 'specialHTMLTargets',
13874
+ 'maybeCStringToJsString',
13875
+ 'findEventTarget',
13876
+ 'findCanvasEventTarget',
13877
+ 'getBoundingClientRect',
13878
+ 'fillMouseEventData',
13879
+ 'registerMouseEventCallback',
13880
+ 'registerWheelEventCallback',
13881
+ 'registerUiEventCallback',
13882
+ 'registerFocusEventCallback',
13883
+ 'fillFullscreenChangeEventData',
13884
+ 'registerFullscreenChangeEventCallback',
13885
+ 'JSEvents_requestFullscreen',
13886
+ 'JSEvents_resizeCanvasForFullscreen',
13887
+ 'registerRestoreOldStyle',
13888
+ 'setLetterbox',
13889
+ 'currentFullscreenStrategy',
13890
+ 'restoreOldWindowedStyle',
13891
+ 'doRequestFullscreen',
13892
+ 'fillPointerlockChangeEventData',
13893
+ 'registerPointerlockChangeEventCallback',
13894
+ 'requestPointerLock',
13895
+ 'fillVisibilityChangeEventData',
13896
+ 'registerVisibilityChangeEventCallback',
13897
+ 'registerTouchEventCallback',
13898
+ 'fillGamepadEventData',
13899
+ 'registerGamepadEventCallback',
13900
+ 'registerBeforeUnloadEventCallback',
13901
+ 'setCanvasElementSizeCallingThread',
13902
+ 'setCanvasElementSizeMainThread',
13903
+ 'setCanvasElementSize',
13904
+ 'getCanvasSizeCallingThread',
13905
+ 'getCanvasSizeMainThread',
13906
+ 'getCanvasElementSize',
13907
+ 'UNWIND_CACHE',
13908
+ 'ExitStatus',
13909
+ 'getEnvStrings',
13910
+ 'checkWasiClock',
13911
+ 'doReadv',
13912
+ 'doWritev',
13913
+ 'initRandomFill',
13914
+ 'randomFill',
13915
+ 'safeSetTimeout',
13916
+ 'emSetImmediate',
13917
+ 'emClearImmediate_deps',
13918
+ 'emClearImmediate',
13919
+ 'promiseMap',
13920
+ 'uncaughtExceptionCount',
13921
+ 'exceptionLast',
13922
+ 'exceptionCaught',
13923
+ 'Browser',
13924
+ 'getPreloadedImageData__data',
13925
+ 'wget',
13926
+ 'MONTH_DAYS_REGULAR',
13927
+ 'MONTH_DAYS_LEAP',
13928
+ 'MONTH_DAYS_REGULAR_CUMULATIVE',
13929
+ 'MONTH_DAYS_LEAP_CUMULATIVE',
13930
+ 'isLeapYear',
13931
+ 'ydayFromDate',
13932
+ 'SYSCALLS',
13933
+ 'preloadPlugins',
13934
+ 'FS_createPreloadedFile',
13935
+ 'FS_modeStringToFlags',
13936
+ 'FS_getMode',
13937
+ 'FS_stdin_getChar_buffer',
13938
+ 'FS_stdin_getChar',
13939
+ 'FS_createPath',
13940
+ 'FS_createDevice',
13941
+ 'FS_readFile',
13942
+ 'FS_createDataFile',
13943
+ 'FS_createLazyFile',
13944
+ 'MEMFS',
13945
+ 'TTY',
13946
+ 'PIPEFS',
13947
+ 'SOCKFS',
13948
+ 'tempFixedLengthArray',
13949
+ 'miniTempWebGLFloatBuffers',
13950
+ 'miniTempWebGLIntBuffers',
13951
+ 'heapObjectForWebGLType',
13952
+ 'toTypedArrayIndex',
13953
+ 'webgl_enable_WEBGL_multi_draw',
13954
+ 'webgl_enable_EXT_polygon_offset_clamp',
13955
+ 'webgl_enable_EXT_clip_control',
13956
+ 'webgl_enable_WEBGL_polygon_mode',
13957
+ 'GL',
13958
+ 'emscriptenWebGLGet',
13959
+ 'computeUnpackAlignedImageSize',
13960
+ 'colorChannelsInGlTextureFormat',
13961
+ 'emscriptenWebGLGetTexPixelData',
13962
+ 'emscriptenWebGLGetUniform',
13963
+ 'webglGetUniformLocation',
13964
+ 'webglPrepareUniformLocationsBeforeFirstUse',
13965
+ 'webglGetLeftBracePos',
13966
+ 'emscriptenWebGLGetVertexAttrib',
13967
+ '__glGetActiveAttribOrUniform',
13968
+ 'AL',
13969
+ 'GLUT',
13970
+ 'EGL',
13971
+ 'GLEW',
13972
+ 'IDBStore',
13973
+ 'emscriptenWebGLGetIndexed',
13974
+ 'webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance',
13975
+ 'webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance',
13976
+ 'allocateUTF8',
13977
+ 'allocateUTF8OnStack',
13978
+ 'print',
13979
+ 'printErr',
13980
+ 'PThread',
13981
+ 'terminateWorker',
13982
+ 'cleanupThread',
13983
+ 'registerTLSInit',
13984
+ 'spawnThread',
13985
+ 'exitOnMainThread',
13986
+ 'proxyToMainThread',
13987
+ 'proxiedJSCallArgs',
13988
+ 'invokeEntryPoint',
13989
+ 'checkMailbox',
13990
+ 'IDBFS',
13991
+ ];
13992
+ unexportedSymbols.forEach(unexportedRuntimeSymbol);
13022
13993
 
13023
13994
 
13995
+
13996
+ var calledRun;
13997
+
13024
13998
  function callMain() {
13999
+ assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on Module["onRuntimeInitialized"])');
14000
+ assert(typeof onPreRuns === 'undefined' || onPreRuns.length == 0, 'cannot call main when preRun functions remain to be called');
13025
14001
 
13026
14002
  var entryFunction = _main;
13027
14003
 
@@ -13040,6 +14016,17 @@ function callMain() {
13040
14016
  }
13041
14017
  }
13042
14018
 
14019
+ function stackCheckInit() {
14020
+ // This is normally called automatically during __wasm_call_ctors but need to
14021
+ // get these values before even running any of the ctors so we call it redundantly
14022
+ // here.
14023
+ // See $establishStackSpace for the equivalent code that runs on a thread
14024
+ assert(!ENVIRONMENT_IS_PTHREAD);
14025
+ _emscripten_stack_init();
14026
+ // TODO(sbc): Move writeStackCookie to native to to avoid this.
14027
+ writeStackCookie();
14028
+ }
14029
+
13043
14030
  function run() {
13044
14031
 
13045
14032
  if (runDependencies > 0) {
@@ -13053,6 +14040,8 @@ function run() {
13053
14040
  return;
13054
14041
  }
13055
14042
 
14043
+ stackCheckInit();
14044
+
13056
14045
  preRun();
13057
14046
 
13058
14047
  // a preRun added a dependency, run will be called later
@@ -13064,6 +14053,8 @@ function run() {
13064
14053
  function doRun() {
13065
14054
  // run may have just been called through dependencies being fulfilled just in this very frame,
13066
14055
  // or while the async setStatus time below was happening
14056
+ assert(!calledRun);
14057
+ calledRun = true;
13067
14058
  Module['calledRun'] = true;
13068
14059
 
13069
14060
  if (ABORT) return;
@@ -13074,8 +14065,9 @@ function run() {
13074
14065
 
13075
14066
  readyPromiseResolve(Module);
13076
14067
  Module['onRuntimeInitialized']?.();
14068
+ consumedModuleProp('onRuntimeInitialized');
13077
14069
 
13078
- var noInitialRun = Module['noInitialRun'];
14070
+ var noInitialRun = Module['noInitialRun'];legacyModuleProp('noInitialRun', 'noInitialRun');
13079
14071
  if (!noInitialRun) callMain();
13080
14072
 
13081
14073
  postRun();
@@ -13091,6 +14083,46 @@ function run() {
13091
14083
  {
13092
14084
  doRun();
13093
14085
  }
14086
+ checkStackCookie();
14087
+ }
14088
+
14089
+ function checkUnflushedContent() {
14090
+ // Compiler settings do not allow exiting the runtime, so flushing
14091
+ // the streams is not possible. but in ASSERTIONS mode we check
14092
+ // if there was something to flush, and if so tell the user they
14093
+ // should request that the runtime be exitable.
14094
+ // Normally we would not even include flush() at all, but in ASSERTIONS
14095
+ // builds we do so just for this check, and here we see if there is any
14096
+ // content to flush, that is, we check if there would have been
14097
+ // something a non-ASSERTIONS build would have not seen.
14098
+ // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0
14099
+ // mode (which has its own special function for this; otherwise, all
14100
+ // the code is inside libc)
14101
+ var oldOut = out;
14102
+ var oldErr = err;
14103
+ var has = false;
14104
+ out = err = (x) => {
14105
+ has = true;
14106
+ }
14107
+ try { // it doesn't matter if it fails
14108
+ _fflush(0);
14109
+ // also flush in the JS FS layer
14110
+ ['stdout', 'stderr'].forEach((name) => {
14111
+ var info = FS.analyzePath('/dev/' + name);
14112
+ if (!info) return;
14113
+ var stream = info.object;
14114
+ var rdev = stream.rdev;
14115
+ var tty = TTY.ttys[rdev];
14116
+ if (tty?.output?.length) {
14117
+ has = true;
14118
+ }
14119
+ });
14120
+ } catch(e) {}
14121
+ out = oldOut;
14122
+ err = oldErr;
14123
+ if (has) {
14124
+ warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the Emscripten FAQ), or make sure to emit a newline when you printf etc.');
14125
+ }
13094
14126
  }
13095
14127
 
13096
14128
  if (Module['preInit']) {
@@ -13099,6 +14131,7 @@ if (Module['preInit']) {
13099
14131
  Module['preInit'].pop()();
13100
14132
  }
13101
14133
  }
14134
+ consumedModuleProp('preInit');
13102
14135
 
13103
14136
  run();
13104
14137
 
@@ -13113,6 +14146,21 @@ run();
13113
14146
 
13114
14147
  moduleRtn = readyPromise;
13115
14148
 
14149
+ // Assertion for attempting to access module properties on the incoming
14150
+ // moduleArg. In the past we used this object as the prototype of the module
14151
+ // and assigned properties to it, but now we return a distinct object. This
14152
+ // keeps the instance private until it is ready (i.e the promise has been
14153
+ // resolved).
14154
+ for (const prop of Object.keys(Module)) {
14155
+ if (!(prop in moduleArg)) {
14156
+ Object.defineProperty(moduleArg, prop, {
14157
+ configurable: true,
14158
+ get() {
14159
+ abort(`Access to module property ('${prop}') is no longer possible via the module constructor argument; Instead, use the result of the module constructor.`)
14160
+ }
14161
+ });
14162
+ }
14163
+ }
13116
14164
  // end include: postamble_modularize.js
13117
14165
 
13118
14166
 
@@ -13121,6 +14169,15 @@ moduleRtn = readyPromise;
13121
14169
  }
13122
14170
  );
13123
14171
  })();
14172
+ (() => {
14173
+ // Create a small, never-async wrapper around mGBA which
14174
+ // checks for callers incorrectly using it with `new`.
14175
+ var real_mGBA = mGBA;
14176
+ mGBA = function(arg) {
14177
+ if (new.target) throw new Error("mGBA() should not be called with `new mGBA()`");
14178
+ return real_mGBA(arg);
14179
+ }
14180
+ })();
13124
14181
  export default mGBA;
13125
14182
  var isPthread = globalThis.self?.name?.startsWith('em-pthread');
13126
14183
  // When running as a pthread, construct a new instance on startup