@sie-js/wbxml 1.0.0 → 1.1.0

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/build/wbxml.js CHANGED
@@ -1,45 +1,56 @@
1
1
  // This code implements the `-sMODULARIZE` settings by taking the generated
2
2
  // JS program code (INNER_JS_CODE) and wrapping it in a factory function.
3
3
 
4
- // When targetting node and ES6 we use `await import ..` in the generated code
4
+ // When targeting node and ES6 we use `await import ..` in the generated code
5
5
  // so the outer function needs to be marked as async.
6
6
  async function Module(moduleArg = {}) {
7
- var moduleRtn;
8
-
7
+ var Module = moduleArg;
9
8
  // include: shell.js
10
9
  // include: minimum_runtime_check.js
11
10
  (function() {
12
11
  // "30.0.0" -> 300000
13
12
  function humanReadableVersionToPacked(str) {
14
13
  str = str.split('-')[0]; // Remove any trailing part from e.g. "12.53.3-alpha"
15
- var vers = str.split('.').slice(0, 3);
14
+ let vers = str.split('.').slice(0, 3);
16
15
  while(vers.length < 3) vers.push('00');
17
16
  vers = vers.map((n, i, arr) => n.padStart(2, '0'));
18
17
  return vers.join('');
19
18
  }
20
19
  // 300000 -> "30.0.0"
21
- var packedVersionToHumanReadable = n => [n / 10000 | 0, (n / 100 | 0) % 100, n % 100].join('.');
20
+ const packedVersionToHumanReadable = n => [n / 10_000 | 0, (n / 100 | 0) % 100, n % 100].join('.');
21
+
22
+ const TARGET_NOT_SUPPORTED = 2147483647;
22
23
 
23
- var TARGET_NOT_SUPPORTED = 2147483647;
24
+ // Note: We use a typeof check here instead of optional chaining using
25
+ // globalThis because older browsers might not have globalThis defined.
26
+
27
+ // We skip the node version checking when running on Bun/Deno since the node
28
+ // version they report doesn't seem to be useful.
29
+ if (typeof process !== 'undefined' && !process.versions?.bun && typeof Deno === "undefined") {
30
+ const currentNodeVersion = process.versions?.node ? humanReadableVersionToPacked(process.versions.node) : TARGET_NOT_SUPPORTED;
31
+ if (currentNodeVersion < 180300) {
32
+ throw new Error(`This emscripten-generated code requires node v${ packedVersionToHumanReadable(180300) } (detected v${packedVersionToHumanReadable(currentNodeVersion)})`);
33
+ }
34
+ }
24
35
 
25
- var currentNodeVersion = typeof process !== 'undefined' && process?.versions?.node ? humanReadableVersionToPacked(process.versions.node) : TARGET_NOT_SUPPORTED;
26
- if (currentNodeVersion < 160000) {
27
- throw new Error(`This emscripten-generated code requires node v${ packedVersionToHumanReadable(160000) } (detected v${packedVersionToHumanReadable(currentNodeVersion)})`);
36
+ const userAgent = typeof navigator !== 'undefined' && navigator.userAgent;
37
+ if (!userAgent) {
38
+ return;
28
39
  }
29
40
 
30
- var currentSafariVersion = typeof navigator !== 'undefined' && navigator?.userAgent?.includes("Safari/") && navigator.userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/) ? humanReadableVersionToPacked(navigator.userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/)[1]) : TARGET_NOT_SUPPORTED;
31
- if (currentSafariVersion < 150000) {
32
- throw new Error(`This emscripten-generated code requires Safari v${ packedVersionToHumanReadable(150000) } (detected v${currentSafariVersion})`);
41
+ const currentSafariVersion = userAgent.includes("Safari/") && !userAgent.includes("Chrome/") && userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/) ? humanReadableVersionToPacked(userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/)[1]) : TARGET_NOT_SUPPORTED;
42
+ if (currentSafariVersion < 150400) {
43
+ throw new Error(`This emscripten-generated code requires Safari v${ packedVersionToHumanReadable(150400) } (detected v${currentSafariVersion})`);
33
44
  }
34
45
 
35
- var currentFirefoxVersion = typeof navigator !== 'undefined' && navigator?.userAgent?.match(/Firefox\/(\d+(?:\.\d+)?)/) ? parseFloat(navigator.userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
36
- if (currentFirefoxVersion < 79) {
37
- throw new Error(`This emscripten-generated code requires Firefox v79 (detected v${currentFirefoxVersion})`);
46
+ const currentFirefoxVersion = userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/) ? parseFloat(userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
47
+ if (currentFirefoxVersion < 92) {
48
+ throw new Error(`This emscripten-generated code requires Firefox v92 (detected v${currentFirefoxVersion})`);
38
49
  }
39
50
 
40
- var currentChromeVersion = typeof navigator !== 'undefined' && navigator?.userAgent?.match(/Chrome\/(\d+(?:\.\d+)?)/) ? parseFloat(navigator.userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
41
- if (currentChromeVersion < 85) {
42
- throw new Error(`This emscripten-generated code requires Chrome v85 (detected v${currentChromeVersion})`);
51
+ const currentChromeVersion = userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/) ? parseFloat(userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
52
+ if (currentChromeVersion < 93) {
53
+ throw new Error(`This emscripten-generated code requires Chrome v93 (detected v${currentChromeVersion})`);
43
54
  }
44
55
  })();
45
56
 
@@ -57,7 +68,6 @@ async function Module(moduleArg = {}) {
57
68
  // after the generated code, you will need to define var Module = {};
58
69
  // before the code. Then that object will be used in the code, and you
59
70
  // can continue to use Module afterwards as well.
60
- var Module = moduleArg;
61
71
 
62
72
  // Determine the runtime environment we are in. You can customize this by
63
73
  // setting the ENVIRONMENT setting at compile time (see settings.js).
@@ -73,7 +83,7 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR
73
83
  if (ENVIRONMENT_IS_NODE) {
74
84
  // When building an ES module `require` is not normally available.
75
85
  // We need to use `createRequire()` to construct the require()` function.
76
- const { createRequire } = await import('module');
86
+ const { createRequire } = await import('node:module');
77
87
  /** @suppress{duplicate} */
78
88
  var require = createRequire(import.meta.url);
79
89
 
@@ -83,7 +93,7 @@ if (ENVIRONMENT_IS_NODE) {
83
93
  // refer to Module (if they choose; they can also define Module)
84
94
 
85
95
 
86
- var arguments_ = [];
96
+ var programArgs = [];
87
97
  var thisProgram = './this.program';
88
98
  var quit_ = (status, toThrow) => {
89
99
  throw toThrow;
@@ -106,10 +116,10 @@ if (ENVIRONMENT_IS_NODE) {
106
116
 
107
117
  // These modules will usually be used on Node.js. Load them eagerly to avoid
108
118
  // the complexity of lazy-loading.
109
- var fs = require('fs');
119
+ var fs = require('node:fs');
110
120
 
111
121
  if (_scriptName.startsWith('file:')) {
112
- scriptDirectory = require('path').dirname(require('url').fileURLToPath(_scriptName)) + '/';
122
+ scriptDirectory = require('node:path').dirname(require('node:url').fileURLToPath(_scriptName)) + '/';
113
123
  }
114
124
 
115
125
  // include: node_shell_read.js
@@ -125,7 +135,7 @@ readAsync = async (filename, binary = true) => {
125
135
  // See the comment in the `readBinary` function.
126
136
  filename = isFileURI(filename) ? new URL(filename) : filename;
127
137
  var ret = fs.readFileSync(filename, binary ? undefined : 'utf8');
128
- assert(binary ? Buffer.isBuffer(ret) : typeof ret == 'string');
138
+ assert(binary ? Buffer.isBuffer(ret) : typeof ret === 'string');
129
139
  return ret;
130
140
  };
131
141
  // end include: node_shell_read.js
@@ -133,7 +143,7 @@ readAsync = async (filename, binary = true) => {
133
143
  thisProgram = process.argv[1].replace(/\\/g, '/');
134
144
  }
135
145
 
136
- arguments_ = process.argv.slice(2);
146
+ programArgs = process.argv.slice(2);
137
147
 
138
148
  quit_ = (status, toThrow) => {
139
149
  process.exitCode = status;
@@ -201,7 +211,7 @@ var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
201
211
  // perform assertions in shell.js after we set up out() and err(), as otherwise
202
212
  // if an assertion fails it cannot print the message
203
213
 
204
- assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.');
214
+ assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time (add `shell` to `-sENVIRONMENT` to enable)');
205
215
 
206
216
  // end include: shell.js
207
217
 
@@ -233,7 +243,7 @@ if (!globalThis.WebAssembly) {
233
243
  var ABORT = false;
234
244
 
235
245
  // set by exit() and abort(). Passed to 'onExit' handler.
236
- // NOTE: This is also used as the process return code code in shell environments
246
+ // NOTE: This is also used as the process return code in shell environments
237
247
  // but only when noExitRuntime is false.
238
248
  var EXITSTATUS;
239
249
 
@@ -258,16 +268,19 @@ function assert(condition, text) {
258
268
  var isFileURI = (filename) => filename.startsWith('file://');
259
269
 
260
270
  // include: runtime_common.js
261
- // include: runtime_stack_check.js
262
- // end include: runtime_stack_check.js
263
271
  // include: runtime_exceptions.js
272
+ // Base Emscripten EH error class
273
+ class EmscriptenEH {}
274
+
275
+ class EmscriptenSjLj extends EmscriptenEH {}
276
+
264
277
  // end include: runtime_exceptions.js
265
278
  // include: runtime_debug.js
266
279
  var runtimeDebug = true; // Switch to false at runtime to disable logging at the right times
267
280
 
268
281
  // Used by XXXXX_DEBUG settings to output debug messages.
269
282
  function dbg(...args) {
270
- if (!runtimeDebug && typeof runtimeDebug != 'undefined') return;
283
+ if (!runtimeDebug && typeof runtimeDebug !== 'undefined') return;
271
284
  // TODO(sbc): Make this configurable somehow. Its not always convenient for
272
285
  // logging to show up as warnings.
273
286
  console.warn(...args);
@@ -275,22 +288,38 @@ function dbg(...args) {
275
288
 
276
289
  // Endianness check
277
290
  (() => {
278
- var h16 = new Int16Array(1);
279
- var h8 = new Int8Array(h16.buffer);
291
+ const h16 = new Int16Array(1);
292
+ const h8 = new Int8Array(h16.buffer);
280
293
  h16[0] = 0x6373;
281
294
  if (h8[0] !== 0x73 || h8[1] !== 0x63) abort('Runtime error: expected the system to be little-endian! (Run with -sSUPPORT_BIG_ENDIAN to bypass)');
282
295
  })();
283
296
 
284
297
  function consumedModuleProp(prop) {
285
- if (!Object.getOwnPropertyDescriptor(Module, prop)) {
286
- Object.defineProperty(Module, prop, {
287
- configurable: true,
288
- set() {
289
- 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'`);
290
-
298
+ let value = Module[prop];
299
+ const msg = `Attempt to modify \`Module.${prop}\` after it has already been processed. This can happen, for example, when code is injected via '--post-js' rather than '--pre-js'`;
300
+ if (Array.isArray(value)) {
301
+ value = new Proxy(value, {
302
+ set(target, key, val) {
303
+ abort(msg);
304
+ return false;
305
+ },
306
+ defineProperty(target, key, descriptor) {
307
+ abort(msg);
308
+ return false;
309
+ },
310
+ deleteProperty(target, key) {
311
+ abort(msg);
312
+ return false;
291
313
  }
292
314
  });
293
315
  }
316
+ Object.defineProperty(Module, prop, {
317
+ configurable: true,
318
+ get() { return value; },
319
+ set() {
320
+ abort(msg);
321
+ }
322
+ });
294
323
  }
295
324
 
296
325
  function makeInvalidEarlyAccess(name) {
@@ -330,7 +359,7 @@ function unexportedRuntimeSymbol(sym) {
330
359
  Object.defineProperty(Module, sym, {
331
360
  configurable: true,
332
361
  get() {
333
- var msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
362
+ let msg = `'${sym}' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the Emscripten FAQ)`;
334
363
  if (isExportedByForceFilesystem(sym)) {
335
364
  msg += '. Alternatively, forcing filesystem support (-sFORCE_FILESYSTEM) can export this for you';
336
365
  }
@@ -341,34 +370,7 @@ function unexportedRuntimeSymbol(sym) {
341
370
  }
342
371
 
343
372
  // end include: runtime_debug.js
344
- var readyPromiseResolve, readyPromiseReject;
345
-
346
373
  // Memory management
347
- var
348
- /** @type {!Int8Array} */
349
- HEAP8,
350
- /** @type {!Uint8Array} */
351
- HEAPU8,
352
- /** @type {!Int16Array} */
353
- HEAP16,
354
- /** @type {!Uint16Array} */
355
- HEAPU16,
356
- /** @type {!Int32Array} */
357
- HEAP32,
358
- /** @type {!Uint32Array} */
359
- HEAPU32,
360
- /** @type {!Float32Array} */
361
- HEAPF32,
362
- /** @type {!Float64Array} */
363
- HEAPF64;
364
-
365
- // BigInt64Array type is not correctly defined in closure
366
- var
367
- /** not-@type {!BigInt64Array} */
368
- HEAP64,
369
- /* BigUint64Array type is not correctly defined in closure
370
- /** not-@type {!BigUint64Array} */
371
- HEAPU64;
372
374
 
373
375
  var runtimeInitialized = false;
374
376
 
@@ -376,18 +378,27 @@ var runtimeExited = false;
376
378
 
377
379
 
378
380
 
381
+ // When ALLOW_MEMORY_GROWTH is enabled, the conversion from Wasm
382
+ // memory to ArrayBuffer requires some additional logic.
383
+ function getMemoryBuffer() {
384
+ return wasmMemory.buffer;
385
+ }
386
+
379
387
  function updateMemoryViews() {
380
- var b = wasmMemory.buffer;
388
+ // If we already have a heap that is resizeable/growable buffer we don't
389
+ // need to do anything in updateMemoryViews.
390
+ if (HEAP8?.buffer?.resizable) return;
391
+ var b = getMemoryBuffer();
381
392
  HEAP8 = new Int8Array(b);
382
- HEAP16 = new Int16Array(b);
393
+
383
394
  Module['HEAPU8'] = HEAPU8 = new Uint8Array(b);
384
- HEAPU16 = new Uint16Array(b);
385
- HEAP32 = new Int32Array(b);
395
+
396
+
386
397
  Module['HEAPU32'] = HEAPU32 = new Uint32Array(b);
387
- HEAPF32 = new Float32Array(b);
388
- HEAPF64 = new Float64Array(b);
389
- HEAP64 = new BigInt64Array(b);
390
- HEAPU64 = new BigUint64Array(b);
398
+
399
+
400
+
401
+
391
402
  }
392
403
 
393
404
  // include: memoryprofiler.js
@@ -404,39 +415,39 @@ function initRuntime() {
404
415
  assert(!runtimeInitialized);
405
416
  runtimeInitialized = true;
406
417
 
407
- // Begin ATINITS hooks
408
- if (!Module['noFSInit'] && !FS.initialized) FS.init();
409
- TTY.init();
410
- // End ATINITS hooks
418
+ // No ATINITS hooks
411
419
 
412
420
  wasmExports['__wasm_call_ctors']();
413
421
 
414
- // Begin ATPOSTCTORS hooks
415
- FS.ignorePermissions = false;
416
- // End ATPOSTCTORS hooks
422
+ // No ATPOSTCTORS hooks
423
+
417
424
  }
418
425
 
426
+ var runtimeExiting = false;
427
+
419
428
  function exitRuntime() {
420
429
  assert(!runtimeExited);
421
- // PThreads reuse the runtime from the main thread.
430
+ assert(!runtimeExiting, 'Re-entrant call to exitRuntime()! This can happen if an atexit() registered callback throws an exception.');
431
+ runtimeExiting = true;
422
432
  ___funcs_on_exit(); // Native atexit() functions
423
433
  // Begin ATEXITS hooks
424
- FS.quit();
425
- TTY.shutdown();
434
+ clearTimers();
435
+ flush_NO_FILESYSTEM()
426
436
  // End ATEXITS hooks
427
437
  runtimeExited = true;
428
438
  }
429
439
 
430
440
  function postRun() {
431
- // PThreads reuse the runtime from the main thread.
432
441
 
433
442
  // No ATPOSTRUNS hooks
434
443
  }
435
444
 
436
- /** @param {string|number=} what */
445
+ /**
446
+ * @param {string|number=} what
447
+ */
437
448
  function abort(what) {
438
449
 
439
- what = 'Aborted(' + what + ')';
450
+ what = `Aborted(${what})`;
440
451
  // TODO(sbc): Should we remove printing and leave it up to whoever
441
452
  // catches the exception?
442
453
  err(what);
@@ -451,30 +462,34 @@ function abort(what) {
451
462
  // a trap or not based on a hidden field within the object. So at the moment
452
463
  // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
453
464
  // allows this in the wasm spec.
465
+ throw new WebAssembly.RuntimeError(what);
466
+ }
454
467
 
455
- // Suppress closure compiler warning here. Closure compiler's builtin extern
456
- // definition for WebAssembly.RuntimeError claims it takes no arguments even
457
- // though it can.
458
- // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
459
- /** @suppress {checkTypes} */
460
- var e = new WebAssembly.RuntimeError(what);
461
-
462
- readyPromiseReject?.(e);
463
- // Throw the error whether or not MODULARIZE is set because abort is used
464
- // in code paths apart from instantiation where an exception is expected
465
- // to be thrown when abort is called.
466
- throw e;
468
+ // show errors on likely calls to FS when it was not included
469
+ function fsMissing() {
470
+ abort('Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -sFORCE_FILESYSTEM');
467
471
  }
472
+ var FS = {
473
+ init: fsMissing,
474
+ createDataFile: fsMissing,
475
+ createPreloadedFile: fsMissing,
476
+ createLazyFile: fsMissing,
477
+ open: fsMissing,
478
+ mkdev: fsMissing,
479
+ registerDevice: fsMissing,
480
+ analyzePath: fsMissing,
481
+ ErrnoError: fsMissing,
482
+ };
468
483
 
469
- function createExportWrapper(name, nargs) {
484
+
485
+ function createExportWrapper(name, func, nargs) {
486
+ assert(func);
470
487
  return (...args) => {
471
488
  assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
472
489
  assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`);
473
- var f = wasmExports[name];
474
- assert(f, `exported native function \`${name}\` not found`);
475
490
  // Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
476
491
  assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
477
- return f(...args);
492
+ return func(...args);
478
493
  };
479
494
  }
480
495
 
@@ -495,7 +510,7 @@ function getBinarySync(file) {
495
510
  if (readBinary) {
496
511
  return readBinary(file);
497
512
  }
498
- // Throwing a plain string here, even though it not normally adviables since
513
+ // Throwing a plain string here, even though it not normally advisable since
499
514
  // this gets turning into an `abort` in instantiateArrayBuffer.
500
515
  throw 'both async and sync fetching of the wasm failed';
501
516
  }
@@ -505,8 +520,8 @@ async function getWasmBinary(binaryFile) {
505
520
  if (!wasmBinary) {
506
521
  // Fetch the binary using readAsync
507
522
  try {
508
- var response = await readAsync(binaryFile);
509
- return new Uint8Array(response);
523
+ // Await so a rejection is caught and falls back to getBinarySync.
524
+ return await readAsync(binaryFile);
510
525
  } catch {
511
526
  // Fall back to getBinarySync below;
512
527
  }
@@ -534,12 +549,9 @@ async function instantiateArrayBuffer(binaryFile, imports) {
534
549
 
535
550
  async function instantiateAsync(binary, binaryFile, imports) {
536
551
  if (!binary
537
- // Avoid instantiateStreaming() on Node.js environment for now, as while
538
- // Node.js v18.1.0 implements it, it does not have a full fetch()
539
- // implementation yet.
540
- //
541
- // Reference:
542
- // https://github.com/emscripten-core/emscripten/pull/16917
552
+ // Avoid using instantiateStreaming() on Node.js since the `fetch()` API
553
+ // does not support `file://` URLs.
554
+ // See: https://github.com/emscripten-core/emscripten/pull/16917
543
555
  && !ENVIRONMENT_IS_NODE
544
556
  ) {
545
557
  try {
@@ -572,8 +584,7 @@ async function createWasm() {
572
584
  // Load the wasm module and create an instance of using native support in the JS engine.
573
585
  // handle a generated wasm instance, receiving its exports and
574
586
  // performing other necessary setup
575
- /** @param {WebAssembly.Module=} module*/
576
- function receiveInstance(instance, module) {
587
+ function receiveInstance(instance) {
577
588
  wasmExports = instance.exports;
578
589
 
579
590
  assignWasmExports(wasmExports);
@@ -610,7 +621,6 @@ async function createWasm() {
610
621
 
611
622
  // Begin JS library code
612
623
 
613
-
614
624
  class ExitStatus {
615
625
  name = 'ExitStatus';
616
626
  constructor(status) {
@@ -618,66 +628,22 @@ async function createWasm() {
618
628
  this.status = status;
619
629
  }
620
630
  }
621
-
631
+ /** @type {!Int8Array} */
632
+ var HEAP8;
622
633
  var callRuntimeCallbacks = (callbacks) => {
623
634
  while (callbacks.length > 0) {
624
635
  // Pass the module as the first argument.
625
636
  callbacks.shift()(Module);
626
637
  }
627
638
  };
628
-
629
-
630
- /**
631
- * @param {number} ptr
632
- * @param {string} type
633
- */
634
- function getValue(ptr, type = 'i8') {
635
- if (type.endsWith('*')) type = '*';
636
- switch (type) {
637
- case 'i1': return HEAP8[ptr];
638
- case 'i8': return HEAP8[ptr];
639
- case 'i16': return HEAP16[((ptr)>>1)];
640
- case 'i32': return HEAP32[((ptr)>>2)];
641
- case 'i64': return HEAP64[((ptr)>>3)];
642
- case 'float': return HEAPF32[((ptr)>>2)];
643
- case 'double': return HEAPF64[((ptr)>>3)];
644
- case '*': return HEAPU32[((ptr)>>2)];
645
- default: abort(`invalid type for getValue: ${type}`);
646
- }
647
- }
648
-
649
- var ptrToString = (ptr) => {
639
+ function ptrToString(ptr) {
650
640
  assert(typeof ptr === 'number', `ptrToString expects a number, got ${typeof ptr}`);
651
641
  // Convert to 32-bit unsigned value
652
642
  ptr >>>= 0;
653
643
  return '0x' + ptr.toString(16).padStart(8, '0');
654
- };
655
-
656
-
657
- /**
658
- * @param {number} ptr
659
- * @param {number} value
660
- * @param {string} type
661
- */
662
- function setValue(ptr, value, type = 'i8') {
663
- if (type.endsWith('*')) type = '*';
664
- switch (type) {
665
- case 'i1': HEAP8[ptr] = value; break;
666
- case 'i8': HEAP8[ptr] = value; break;
667
- case 'i16': HEAP16[((ptr)>>1)] = value; break;
668
- case 'i32': HEAP32[((ptr)>>2)] = value; break;
669
- case 'i64': HEAP64[((ptr)>>3)] = BigInt(value); break;
670
- case 'float': HEAPF32[((ptr)>>2)] = value; break;
671
- case 'double': HEAPF64[((ptr)>>3)] = value; break;
672
- case '*': HEAPU32[((ptr)>>2)] = value; break;
673
- default: abort(`invalid type for setValue: ${type}`);
674
644
  }
675
- }
676
-
677
645
  var stackRestore = (val) => __emscripten_stack_restore(val);
678
-
679
646
  var stackSave = () => _emscripten_stack_get_current();
680
-
681
647
  var warnOnce = (text) => {
682
648
  warnOnce.shown ||= {};
683
649
  if (!warnOnce.shown[text]) {
@@ -687,10 +653,17 @@ async function createWasm() {
687
653
  }
688
654
  };
689
655
 
690
-
691
-
656
+ /** @type {!Uint8Array} */
657
+ var HEAPU8;
692
658
  var UTF8Decoder = globalThis.TextDecoder && new TextDecoder();
693
659
 
660
+ /**
661
+ * heapOrArray is either a regular array, or a JavaScript typed array view.
662
+ * @param {number} idx
663
+ * @param {number=} maxBytesToRead
664
+ * @param {boolean=} ignoreNul
665
+ * @return {number}
666
+ */
694
667
  var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
695
668
  var maxIdx = idx + maxBytesToRead;
696
669
  if (ignoreNul) return maxIdx;
@@ -702,17 +675,16 @@ async function createWasm() {
702
675
  return idx;
703
676
  };
704
677
 
705
-
706
678
  /**
707
- * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
708
- * array that contains uint8 values, returns a copy of that string as a
709
- * Javascript String object.
710
- * heapOrArray is either a regular array, or a JavaScript typed array view.
711
- * @param {number=} idx
712
- * @param {number=} maxBytesToRead
713
- * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character.
714
- * @return {string}
715
- */
679
+ * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
680
+ * array that contains uint8 values, returns a copy of that string as a
681
+ * Javascript String object.
682
+ * heapOrArray is either a regular array, or a JavaScript typed array view.
683
+ * @param {number=} idx
684
+ * @param {number=} maxBytesToRead
685
+ * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character.
686
+ * @return {string}
687
+ */
716
688
  var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead, ignoreNul) => {
717
689
 
718
690
  var endPtr = findStringEnd(heapOrArray, idx, maxBytesToRead, ignoreNul);
@@ -735,7 +707,7 @@ async function createWasm() {
735
707
  if ((u0 & 0xF0) == 0xE0) {
736
708
  u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
737
709
  } else {
738
- 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!');
710
+ 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!`);
739
711
  u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
740
712
  }
741
713
 
@@ -750,28 +722,25 @@ async function createWasm() {
750
722
  };
751
723
 
752
724
  /**
753
- * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
754
- * emscripten HEAP, returns a copy of that string as a Javascript String object.
755
- *
756
- * @param {number} ptr
757
- * @param {number=} maxBytesToRead - An optional length that specifies the
758
- * maximum number of bytes to read. You can omit this parameter to scan the
759
- * string until the first 0 byte. If maxBytesToRead is passed, and the string
760
- * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
761
- * string will cut short at that byte index.
762
- * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character.
763
- * @return {string}
764
- */
725
+ * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
726
+ * emscripten HEAP, returns a copy of that string as a Javascript String object.
727
+ *
728
+ * @param {number} ptr
729
+ * @param {number=} maxBytesToRead - An optional length that specifies the
730
+ * maximum number of bytes to read. You can omit this parameter to scan the
731
+ * string until the first 0 byte. If maxBytesToRead is passed, and the string
732
+ * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
733
+ * string will cut short at that byte index.
734
+ * @param {boolean=} ignoreNul - If true, the function will not stop on a NUL character.
735
+ * @return {string}
736
+ */
765
737
  var UTF8ToString = (ptr, maxBytesToRead, ignoreNul) => {
766
- assert(typeof ptr == 'number', `UTF8ToString expects a number (got ${typeof ptr})`);
738
+ assert(typeof ptr === 'number', `UTF8ToString expects a number (got ${typeof ptr})`);
767
739
  return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead, ignoreNul) : '';
768
740
  };
769
741
  var ___assert_fail = (condition, filename, line, func) =>
770
742
  abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
771
-
772
743
  var wasmTableMirror = [];
773
-
774
-
775
744
  var getWasmTableEntry = (funcPtr) => {
776
745
  var func = wasmTableMirror[funcPtr];
777
746
  if (!func) {
@@ -779,2775 +748,27 @@ async function createWasm() {
779
748
  wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
780
749
  }
781
750
  /** @suppress {checkTypes} */
782
- assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
751
+ assert(wasmTable.get(funcPtr) == func, 'table mirror is out of date');
783
752
  return func;
784
753
  };
785
754
  var ___call_sighandler = (fp, sig) => getWasmTableEntry(fp)(sig);
786
-
787
- var syscallGetVarargI = () => {
788
- assert(SYSCALLS.varargs != undefined);
789
- // the `+` prepended here is necessary to convince the JSCompiler that varargs is indeed a number.
790
- var ret = HEAP32[((+SYSCALLS.varargs)>>2)];
791
- SYSCALLS.varargs += 4;
792
- return ret;
793
- };
794
-
795
- var PATH = {
796
- isAbs:(path) => path.charAt(0) === '/',
797
- splitPath:(filename) => {
798
- var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
799
- return splitPathRe.exec(filename).slice(1);
800
- },
801
- normalizeArray:(parts, allowAboveRoot) => {
802
- // if the path tries to go above the root, `up` ends up > 0
803
- var up = 0;
804
- for (var i = parts.length - 1; i >= 0; i--) {
805
- var last = parts[i];
806
- if (last === '.') {
807
- parts.splice(i, 1);
808
- } else if (last === '..') {
809
- parts.splice(i, 1);
810
- up++;
811
- } else if (up) {
812
- parts.splice(i, 1);
813
- up--;
814
- }
815
- }
816
- // if the path is allowed to go above the root, restore leading ..s
817
- if (allowAboveRoot) {
818
- for (; up; up--) {
819
- parts.unshift('..');
820
- }
821
- }
822
- return parts;
823
- },
824
- normalize:(path) => {
825
- var isAbsolute = PATH.isAbs(path),
826
- trailingSlash = path.slice(-1) === '/';
827
- // Normalize the path
828
- path = PATH.normalizeArray(path.split('/').filter((p) => !!p), !isAbsolute).join('/');
829
- if (!path && !isAbsolute) {
830
- path = '.';
831
- }
832
- if (path && trailingSlash) {
833
- path += '/';
834
- }
835
- return (isAbsolute ? '/' : '') + path;
836
- },
837
- dirname:(path) => {
838
- var result = PATH.splitPath(path),
839
- root = result[0],
840
- dir = result[1];
841
- if (!root && !dir) {
842
- // No dirname whatsoever
843
- return '.';
844
- }
845
- if (dir) {
846
- // It has a dirname, strip trailing slash
847
- dir = dir.slice(0, -1);
848
- }
849
- return root + dir;
850
- },
851
- basename:(path) => path && path.match(/([^\/]+|\/)\/*$/)[1],
852
- join:(...paths) => PATH.normalize(paths.join('/')),
853
- join2:(l, r) => PATH.normalize(l + '/' + r),
854
- };
855
-
856
- var initRandomFill = () => {
857
- // This block is not needed on v19+ since crypto.getRandomValues is builtin
858
- if (ENVIRONMENT_IS_NODE) {
859
- var nodeCrypto = require('crypto');
860
- return (view) => nodeCrypto.randomFillSync(view);
861
- }
862
-
863
- return (view) => crypto.getRandomValues(view);
864
- };
865
- var randomFill = (view) => {
866
- // Lazily init on the first invocation.
867
- (randomFill = initRandomFill())(view);
868
- };
869
-
870
-
871
-
872
- var PATH_FS = {
873
- resolve:(...args) => {
874
- var resolvedPath = '',
875
- resolvedAbsolute = false;
876
- for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
877
- var path = (i >= 0) ? args[i] : FS.cwd();
878
- // Skip empty and invalid entries
879
- if (typeof path != 'string') {
880
- throw new TypeError('Arguments to path.resolve must be strings');
881
- } else if (!path) {
882
- return ''; // an invalid portion invalidates the whole thing
883
- }
884
- resolvedPath = path + '/' + resolvedPath;
885
- resolvedAbsolute = PATH.isAbs(path);
886
- }
887
- // At this point the path should be resolved to a full absolute path, but
888
- // handle relative paths to be safe (might happen when process.cwd() fails)
889
- resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter((p) => !!p), !resolvedAbsolute).join('/');
890
- return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
891
- },
892
- relative:(from, to) => {
893
- from = PATH_FS.resolve(from).slice(1);
894
- to = PATH_FS.resolve(to).slice(1);
895
- function trim(arr) {
896
- var start = 0;
897
- for (; start < arr.length; start++) {
898
- if (arr[start] !== '') break;
899
- }
900
- var end = arr.length - 1;
901
- for (; end >= 0; end--) {
902
- if (arr[end] !== '') break;
903
- }
904
- if (start > end) return [];
905
- return arr.slice(start, end - start + 1);
906
- }
907
- var fromParts = trim(from.split('/'));
908
- var toParts = trim(to.split('/'));
909
- var length = Math.min(fromParts.length, toParts.length);
910
- var samePartsLength = length;
911
- for (var i = 0; i < length; i++) {
912
- if (fromParts[i] !== toParts[i]) {
913
- samePartsLength = i;
914
- break;
915
- }
916
- }
917
- var outputParts = [];
918
- for (var i = samePartsLength; i < fromParts.length; i++) {
919
- outputParts.push('..');
920
- }
921
- outputParts = outputParts.concat(toParts.slice(samePartsLength));
922
- return outputParts.join('/');
923
- },
924
- };
925
-
926
-
927
-
928
- var FS_stdin_getChar_buffer = [];
929
-
930
- var lengthBytesUTF8 = (str) => {
931
- var len = 0;
932
- for (var i = 0; i < str.length; ++i) {
933
- // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
934
- // unit, not a Unicode code point of the character! So decode
935
- // UTF16->UTF32->UTF8.
936
- // See http://unicode.org/faq/utf_bom.html#utf16-3
937
- var c = str.charCodeAt(i); // possibly a lead surrogate
938
- if (c <= 0x7F) {
939
- len++;
940
- } else if (c <= 0x7FF) {
941
- len += 2;
942
- } else if (c >= 0xD800 && c <= 0xDFFF) {
943
- len += 4; ++i;
944
- } else {
945
- len += 3;
946
- }
947
- }
948
- return len;
949
- };
950
-
951
- var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
952
- assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`);
953
- // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
954
- // undefined and false each don't write out any bytes.
955
- if (!(maxBytesToWrite > 0))
956
- return 0;
957
-
958
- var startIdx = outIdx;
959
- var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
960
- for (var i = 0; i < str.length; ++i) {
961
- // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
962
- // and https://www.ietf.org/rfc/rfc2279.txt
963
- // and https://tools.ietf.org/html/rfc3629
964
- var u = str.codePointAt(i);
965
- if (u <= 0x7F) {
966
- if (outIdx >= endIdx) break;
967
- heap[outIdx++] = u;
968
- } else if (u <= 0x7FF) {
969
- if (outIdx + 1 >= endIdx) break;
970
- heap[outIdx++] = 0xC0 | (u >> 6);
971
- heap[outIdx++] = 0x80 | (u & 63);
972
- } else if (u <= 0xFFFF) {
973
- if (outIdx + 2 >= endIdx) break;
974
- heap[outIdx++] = 0xE0 | (u >> 12);
975
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
976
- heap[outIdx++] = 0x80 | (u & 63);
977
- } else {
978
- if (outIdx + 3 >= endIdx) break;
979
- 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).');
980
- heap[outIdx++] = 0xF0 | (u >> 18);
981
- heap[outIdx++] = 0x80 | ((u >> 12) & 63);
982
- heap[outIdx++] = 0x80 | ((u >> 6) & 63);
983
- heap[outIdx++] = 0x80 | (u & 63);
984
- // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16.
985
- // We need to manually skip over the second code unit for correct iteration.
986
- i++;
987
- }
988
- }
989
- // Null-terminate the pointer to the buffer.
990
- heap[outIdx] = 0;
991
- return outIdx - startIdx;
992
- };
993
- /** @type {function(string, boolean=, number=)} */
994
- var intArrayFromString = (stringy, dontAddNull, length) => {
995
- var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
996
- var u8array = new Array(len);
997
- var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
998
- if (dontAddNull) u8array.length = numBytesWritten;
999
- return u8array;
755
+ var __abort_js = () =>
756
+ abort('native code called abort()');
757
+ var runtimeKeepaliveCounter = 0;
758
+ var __emscripten_runtime_keepalive_clear = () => {
759
+ runtimeKeepaliveCounter = 0;
1000
760
  };
1001
- var FS_stdin_getChar = () => {
1002
- if (!FS_stdin_getChar_buffer.length) {
1003
- var result = null;
1004
- if (ENVIRONMENT_IS_NODE) {
1005
- // we will read data by chunks of BUFSIZE
1006
- var BUFSIZE = 256;
1007
- var buf = Buffer.alloc(BUFSIZE);
1008
- var bytesRead = 0;
1009
-
1010
- // For some reason we must suppress a closure warning here, even though
1011
- // fd definitely exists on process.stdin, and is even the proper way to
1012
- // get the fd of stdin,
1013
- // https://github.com/nodejs/help/issues/2136#issuecomment-523649904
1014
- // This started to happen after moving this logic out of library_tty.js,
1015
- // so it is related to the surrounding code in some unclear manner.
1016
- /** @suppress {missingProperties} */
1017
- var fd = process.stdin.fd;
1018
-
1019
- try {
1020
- bytesRead = fs.readSync(fd, buf, 0, BUFSIZE);
1021
- } catch(e) {
1022
- // Cross-platform differences: on Windows, reading EOF throws an
1023
- // exception, but on other OSes, reading EOF returns 0. Uniformize
1024
- // behavior by treating the EOF exception to return 0.
1025
- if (e.toString().includes('EOF')) bytesRead = 0;
1026
- else throw e;
1027
- }
1028
-
1029
- if (bytesRead > 0) {
1030
- result = buf.slice(0, bytesRead).toString('utf-8');
1031
- }
1032
- } else
1033
- if (globalThis.window?.prompt) {
1034
- // Browser.
1035
- result = window.prompt('Input: '); // returns null on cancel
1036
- if (result !== null) {
1037
- result += '\n';
1038
- }
1039
- } else
1040
- {}
1041
- if (!result) {
1042
- return null;
1043
- }
1044
- FS_stdin_getChar_buffer = intArrayFromString(result, true);
761
+ var handleException = (e) => {
762
+ // Certain exception types we do not treat as errors since they are used for
763
+ // internal control flow.
764
+ // 1. ExitStatus, which is thrown by exit()
765
+ // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
766
+ // that wish to return to JS event loop.
767
+ if (e instanceof ExitStatus || e == 'unwind') {
768
+ return EXITSTATUS;
1045
769
  }
1046
- return FS_stdin_getChar_buffer.shift();
1047
- };
1048
- var TTY = {
1049
- ttys:[],
1050
- init() {
1051
- // https://github.com/emscripten-core/emscripten/pull/1555
1052
- // if (ENVIRONMENT_IS_NODE) {
1053
- // // currently, FS.init does not distinguish if process.stdin is a file or TTY
1054
- // // device, it always assumes it's a TTY device. because of this, we're forcing
1055
- // // process.stdin to UTF8 encoding to at least make stdin reading compatible
1056
- // // with text files until FS.init can be refactored.
1057
- // process.stdin.setEncoding('utf8');
1058
- // }
1059
- },
1060
- shutdown() {
1061
- // https://github.com/emscripten-core/emscripten/pull/1555
1062
- // if (ENVIRONMENT_IS_NODE) {
1063
- // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
1064
- // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
1065
- // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
1066
- // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
1067
- // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
1068
- // process.stdin.pause();
1069
- // }
1070
- },
1071
- register(dev, ops) {
1072
- TTY.ttys[dev] = { input: [], output: [], ops: ops };
1073
- FS.registerDevice(dev, TTY.stream_ops);
1074
- },
1075
- stream_ops:{
1076
- open(stream) {
1077
- var tty = TTY.ttys[stream.node.rdev];
1078
- if (!tty) {
1079
- throw new FS.ErrnoError(43);
1080
- }
1081
- stream.tty = tty;
1082
- stream.seekable = false;
1083
- },
1084
- close(stream) {
1085
- // flush any pending line data
1086
- stream.tty.ops.fsync(stream.tty);
1087
- },
1088
- fsync(stream) {
1089
- stream.tty.ops.fsync(stream.tty);
1090
- },
1091
- read(stream, buffer, offset, length, pos /* ignored */) {
1092
- if (!stream.tty || !stream.tty.ops.get_char) {
1093
- throw new FS.ErrnoError(60);
1094
- }
1095
- var bytesRead = 0;
1096
- for (var i = 0; i < length; i++) {
1097
- var result;
1098
- try {
1099
- result = stream.tty.ops.get_char(stream.tty);
1100
- } catch (e) {
1101
- throw new FS.ErrnoError(29);
1102
- }
1103
- if (result === undefined && bytesRead === 0) {
1104
- throw new FS.ErrnoError(6);
1105
- }
1106
- if (result === null || result === undefined) break;
1107
- bytesRead++;
1108
- buffer[offset+i] = result;
1109
- }
1110
- if (bytesRead) {
1111
- stream.node.atime = Date.now();
1112
- }
1113
- return bytesRead;
1114
- },
1115
- write(stream, buffer, offset, length, pos) {
1116
- if (!stream.tty || !stream.tty.ops.put_char) {
1117
- throw new FS.ErrnoError(60);
1118
- }
1119
- try {
1120
- for (var i = 0; i < length; i++) {
1121
- stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
1122
- }
1123
- } catch (e) {
1124
- throw new FS.ErrnoError(29);
1125
- }
1126
- if (length) {
1127
- stream.node.mtime = stream.node.ctime = Date.now();
1128
- }
1129
- return i;
1130
- },
1131
- },
1132
- default_tty_ops:{
1133
- get_char(tty) {
1134
- return FS_stdin_getChar();
1135
- },
1136
- put_char(tty, val) {
1137
- if (val === null || val === 10) {
1138
- out(UTF8ArrayToString(tty.output));
1139
- tty.output = [];
1140
- } else {
1141
- if (val != 0) tty.output.push(val); // val == 0 would cut text output off in the middle.
1142
- }
1143
- },
1144
- fsync(tty) {
1145
- if (tty.output?.length > 0) {
1146
- out(UTF8ArrayToString(tty.output));
1147
- tty.output = [];
1148
- }
1149
- },
1150
- ioctl_tcgets(tty) {
1151
- // typical setting
1152
- return {
1153
- c_iflag: 25856,
1154
- c_oflag: 5,
1155
- c_cflag: 191,
1156
- c_lflag: 35387,
1157
- c_cc: [
1158
- 0x03, 0x1c, 0x7f, 0x15, 0x04, 0x00, 0x01, 0x00, 0x11, 0x13, 0x1a, 0x00,
1159
- 0x12, 0x0f, 0x17, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1161
- ]
1162
- };
1163
- },
1164
- ioctl_tcsets(tty, optional_actions, data) {
1165
- // currently just ignore
1166
- return 0;
1167
- },
1168
- ioctl_tiocgwinsz(tty) {
1169
- return [24, 80];
1170
- },
1171
- },
1172
- default_tty1_ops:{
1173
- put_char(tty, val) {
1174
- if (val === null || val === 10) {
1175
- err(UTF8ArrayToString(tty.output));
1176
- tty.output = [];
1177
- } else {
1178
- if (val != 0) tty.output.push(val);
1179
- }
1180
- },
1181
- fsync(tty) {
1182
- if (tty.output?.length > 0) {
1183
- err(UTF8ArrayToString(tty.output));
1184
- tty.output = [];
1185
- }
1186
- },
1187
- },
1188
- };
1189
-
1190
-
1191
- var mmapAlloc = (size) => {
1192
- abort('internal error: mmapAlloc called but `emscripten_builtin_memalign` native symbol not exported');
770
+ quit_(1, e);
1193
771
  };
1194
- var MEMFS = {
1195
- ops_table:null,
1196
- mount(mount) {
1197
- return MEMFS.createNode(null, '/', 16895, 0);
1198
- },
1199
- createNode(parent, name, mode, dev) {
1200
- if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
1201
- // no supported
1202
- throw new FS.ErrnoError(63);
1203
- }
1204
- MEMFS.ops_table ||= {
1205
- dir: {
1206
- node: {
1207
- getattr: MEMFS.node_ops.getattr,
1208
- setattr: MEMFS.node_ops.setattr,
1209
- lookup: MEMFS.node_ops.lookup,
1210
- mknod: MEMFS.node_ops.mknod,
1211
- rename: MEMFS.node_ops.rename,
1212
- unlink: MEMFS.node_ops.unlink,
1213
- rmdir: MEMFS.node_ops.rmdir,
1214
- readdir: MEMFS.node_ops.readdir,
1215
- symlink: MEMFS.node_ops.symlink
1216
- },
1217
- stream: {
1218
- llseek: MEMFS.stream_ops.llseek
1219
- }
1220
- },
1221
- file: {
1222
- node: {
1223
- getattr: MEMFS.node_ops.getattr,
1224
- setattr: MEMFS.node_ops.setattr
1225
- },
1226
- stream: {
1227
- llseek: MEMFS.stream_ops.llseek,
1228
- read: MEMFS.stream_ops.read,
1229
- write: MEMFS.stream_ops.write,
1230
- mmap: MEMFS.stream_ops.mmap,
1231
- msync: MEMFS.stream_ops.msync
1232
- }
1233
- },
1234
- link: {
1235
- node: {
1236
- getattr: MEMFS.node_ops.getattr,
1237
- setattr: MEMFS.node_ops.setattr,
1238
- readlink: MEMFS.node_ops.readlink
1239
- },
1240
- stream: {}
1241
- },
1242
- chrdev: {
1243
- node: {
1244
- getattr: MEMFS.node_ops.getattr,
1245
- setattr: MEMFS.node_ops.setattr
1246
- },
1247
- stream: FS.chrdev_stream_ops
1248
- }
1249
- };
1250
- var node = FS.createNode(parent, name, mode, dev);
1251
- if (FS.isDir(node.mode)) {
1252
- node.node_ops = MEMFS.ops_table.dir.node;
1253
- node.stream_ops = MEMFS.ops_table.dir.stream;
1254
- node.contents = {};
1255
- } else if (FS.isFile(node.mode)) {
1256
- node.node_ops = MEMFS.ops_table.file.node;
1257
- node.stream_ops = MEMFS.ops_table.file.stream;
1258
- node.usedBytes = 0; // The actual number of bytes used in the typed array, as opposed to contents.length which gives the whole capacity.
1259
- // When the byte data of the file is populated, this will point to either a typed array, or a normal JS array. Typed arrays are preferred
1260
- // for performance, and used by default. However, typed arrays are not resizable like normal JS arrays are, so there is a small disk size
1261
- // penalty involved for appending file writes that continuously grow a file similar to std::vector capacity vs used -scheme.
1262
- node.contents = null;
1263
- } else if (FS.isLink(node.mode)) {
1264
- node.node_ops = MEMFS.ops_table.link.node;
1265
- node.stream_ops = MEMFS.ops_table.link.stream;
1266
- } else if (FS.isChrdev(node.mode)) {
1267
- node.node_ops = MEMFS.ops_table.chrdev.node;
1268
- node.stream_ops = MEMFS.ops_table.chrdev.stream;
1269
- }
1270
- node.atime = node.mtime = node.ctime = Date.now();
1271
- // add the new node to the parent
1272
- if (parent) {
1273
- parent.contents[name] = node;
1274
- parent.atime = parent.mtime = parent.ctime = node.atime;
1275
- }
1276
- return node;
1277
- },
1278
- getFileDataAsTypedArray(node) {
1279
- if (!node.contents) return new Uint8Array(0);
1280
- if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
1281
- return new Uint8Array(node.contents);
1282
- },
1283
- expandFileStorage(node, newCapacity) {
1284
- var prevCapacity = node.contents ? node.contents.length : 0;
1285
- if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
1286
- // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity.
1287
- // For small filesizes (<1MB), perform size*2 geometric increase, but for large sizes, do a much more conservative size*1.125 increase to
1288
- // avoid overshooting the allocation cap by a very large margin.
1289
- var CAPACITY_DOUBLING_MAX = 1024 * 1024;
1290
- newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
1291
- if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
1292
- var oldContents = node.contents;
1293
- node.contents = new Uint8Array(newCapacity); // Allocate new storage.
1294
- if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); // Copy old data over to the new storage.
1295
- },
1296
- resizeFileStorage(node, newSize) {
1297
- if (node.usedBytes == newSize) return;
1298
- if (newSize == 0) {
1299
- node.contents = null; // Fully decommit when requesting a resize to zero.
1300
- node.usedBytes = 0;
1301
- } else {
1302
- var oldContents = node.contents;
1303
- node.contents = new Uint8Array(newSize); // Allocate new storage.
1304
- if (oldContents) {
1305
- node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
1306
- }
1307
- node.usedBytes = newSize;
1308
- }
1309
- },
1310
- node_ops:{
1311
- getattr(node) {
1312
- var attr = {};
1313
- // device numbers reuse inode numbers.
1314
- attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
1315
- attr.ino = node.id;
1316
- attr.mode = node.mode;
1317
- attr.nlink = 1;
1318
- attr.uid = 0;
1319
- attr.gid = 0;
1320
- attr.rdev = node.rdev;
1321
- if (FS.isDir(node.mode)) {
1322
- attr.size = 4096;
1323
- } else if (FS.isFile(node.mode)) {
1324
- attr.size = node.usedBytes;
1325
- } else if (FS.isLink(node.mode)) {
1326
- attr.size = node.link.length;
1327
- } else {
1328
- attr.size = 0;
1329
- }
1330
- attr.atime = new Date(node.atime);
1331
- attr.mtime = new Date(node.mtime);
1332
- attr.ctime = new Date(node.ctime);
1333
- // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
1334
- // but this is not required by the standard.
1335
- attr.blksize = 4096;
1336
- attr.blocks = Math.ceil(attr.size / attr.blksize);
1337
- return attr;
1338
- },
1339
- setattr(node, attr) {
1340
- for (const key of ["mode", "atime", "mtime", "ctime"]) {
1341
- if (attr[key] != null) {
1342
- node[key] = attr[key];
1343
- }
1344
- }
1345
- if (attr.size !== undefined) {
1346
- MEMFS.resizeFileStorage(node, attr.size);
1347
- }
1348
- },
1349
- lookup(parent, name) {
1350
- throw new FS.ErrnoError(44);
1351
- },
1352
- mknod(parent, name, mode, dev) {
1353
- return MEMFS.createNode(parent, name, mode, dev);
1354
- },
1355
- rename(old_node, new_dir, new_name) {
1356
- var new_node;
1357
- try {
1358
- new_node = FS.lookupNode(new_dir, new_name);
1359
- } catch (e) {}
1360
- if (new_node) {
1361
- if (FS.isDir(old_node.mode)) {
1362
- // if we're overwriting a directory at new_name, make sure it's empty.
1363
- for (var i in new_node.contents) {
1364
- throw new FS.ErrnoError(55);
1365
- }
1366
- }
1367
- FS.hashRemoveNode(new_node);
1368
- }
1369
- // do the internal rewiring
1370
- delete old_node.parent.contents[old_node.name];
1371
- new_dir.contents[new_name] = old_node;
1372
- old_node.name = new_name;
1373
- new_dir.ctime = new_dir.mtime = old_node.parent.ctime = old_node.parent.mtime = Date.now();
1374
- },
1375
- unlink(parent, name) {
1376
- delete parent.contents[name];
1377
- parent.ctime = parent.mtime = Date.now();
1378
- },
1379
- rmdir(parent, name) {
1380
- var node = FS.lookupNode(parent, name);
1381
- for (var i in node.contents) {
1382
- throw new FS.ErrnoError(55);
1383
- }
1384
- delete parent.contents[name];
1385
- parent.ctime = parent.mtime = Date.now();
1386
- },
1387
- readdir(node) {
1388
- return ['.', '..', ...Object.keys(node.contents)];
1389
- },
1390
- symlink(parent, newname, oldpath) {
1391
- var node = MEMFS.createNode(parent, newname, 0o777 | 40960, 0);
1392
- node.link = oldpath;
1393
- return node;
1394
- },
1395
- readlink(node) {
1396
- if (!FS.isLink(node.mode)) {
1397
- throw new FS.ErrnoError(28);
1398
- }
1399
- return node.link;
1400
- },
1401
- },
1402
- stream_ops:{
1403
- read(stream, buffer, offset, length, position) {
1404
- var contents = stream.node.contents;
1405
- if (position >= stream.node.usedBytes) return 0;
1406
- var size = Math.min(stream.node.usedBytes - position, length);
1407
- assert(size >= 0);
1408
- if (size > 8 && contents.subarray) { // non-trivial, and typed array
1409
- buffer.set(contents.subarray(position, position + size), offset);
1410
- } else {
1411
- for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
1412
- }
1413
- return size;
1414
- },
1415
- write(stream, buffer, offset, length, position, canOwn) {
1416
- // The data buffer should be a typed array view
1417
- assert(!(buffer instanceof ArrayBuffer));
1418
- // If the buffer is located in main memory (HEAP), and if
1419
- // memory can grow, we can't hold on to references of the
1420
- // memory buffer, as they may get invalidated. That means we
1421
- // need to do copy its contents.
1422
- if (buffer.buffer === HEAP8.buffer) {
1423
- canOwn = false;
1424
- }
1425
-
1426
- if (!length) return 0;
1427
- var node = stream.node;
1428
- node.mtime = node.ctime = Date.now();
1429
-
1430
- if (buffer.subarray && (!node.contents || node.contents.subarray)) { // This write is from a typed array to a typed array?
1431
- if (canOwn) {
1432
- assert(position === 0, 'canOwn must imply no weird position inside the file');
1433
- node.contents = buffer.subarray(offset, offset + length);
1434
- node.usedBytes = length;
1435
- return length;
1436
- } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
1437
- node.contents = buffer.slice(offset, offset + length);
1438
- node.usedBytes = length;
1439
- return length;
1440
- } else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
1441
- node.contents.set(buffer.subarray(offset, offset + length), position);
1442
- return length;
1443
- }
1444
- }
1445
-
1446
- // Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
1447
- MEMFS.expandFileStorage(node, position+length);
1448
- if (node.contents.subarray && buffer.subarray) {
1449
- // Use typed array write which is available.
1450
- node.contents.set(buffer.subarray(offset, offset + length), position);
1451
- } else {
1452
- for (var i = 0; i < length; i++) {
1453
- node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
1454
- }
1455
- }
1456
- node.usedBytes = Math.max(node.usedBytes, position + length);
1457
- return length;
1458
- },
1459
- llseek(stream, offset, whence) {
1460
- var position = offset;
1461
- if (whence === 1) {
1462
- position += stream.position;
1463
- } else if (whence === 2) {
1464
- if (FS.isFile(stream.node.mode)) {
1465
- position += stream.node.usedBytes;
1466
- }
1467
- }
1468
- if (position < 0) {
1469
- throw new FS.ErrnoError(28);
1470
- }
1471
- return position;
1472
- },
1473
- mmap(stream, length, position, prot, flags) {
1474
- if (!FS.isFile(stream.node.mode)) {
1475
- throw new FS.ErrnoError(43);
1476
- }
1477
- var ptr;
1478
- var allocated;
1479
- var contents = stream.node.contents;
1480
- // Only make a new copy when MAP_PRIVATE is specified.
1481
- if (!(flags & 2) && contents && contents.buffer === HEAP8.buffer) {
1482
- // We can't emulate MAP_SHARED when the file is not backed by the
1483
- // buffer we're mapping to (e.g. the HEAP buffer).
1484
- allocated = false;
1485
- ptr = contents.byteOffset;
1486
- } else {
1487
- allocated = true;
1488
- ptr = mmapAlloc(length);
1489
- if (!ptr) {
1490
- throw new FS.ErrnoError(48);
1491
- }
1492
- if (contents) {
1493
- // Try to avoid unnecessary slices.
1494
- if (position > 0 || position + length < contents.length) {
1495
- if (contents.subarray) {
1496
- contents = contents.subarray(position, position + length);
1497
- } else {
1498
- contents = Array.prototype.slice.call(contents, position, position + length);
1499
- }
1500
- }
1501
- HEAP8.set(contents, ptr);
1502
- }
1503
- }
1504
- return { ptr, allocated };
1505
- },
1506
- msync(stream, buffer, offset, length, mmapFlags) {
1507
- MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
1508
- // should we check if bytesWritten and length are the same?
1509
- return 0;
1510
- },
1511
- },
1512
- };
1513
-
1514
- var FS_modeStringToFlags = (str) => {
1515
- var flagModes = {
1516
- 'r': 0,
1517
- 'r+': 2,
1518
- 'w': 512 | 64 | 1,
1519
- 'w+': 512 | 64 | 2,
1520
- 'a': 1024 | 64 | 1,
1521
- 'a+': 1024 | 64 | 2,
1522
- };
1523
- var flags = flagModes[str];
1524
- if (typeof flags == 'undefined') {
1525
- throw new Error(`Unknown file open mode: ${str}`);
1526
- }
1527
- return flags;
1528
- };
1529
-
1530
- var FS_getMode = (canRead, canWrite) => {
1531
- var mode = 0;
1532
- if (canRead) mode |= 292 | 73;
1533
- if (canWrite) mode |= 146;
1534
- return mode;
1535
- };
1536
-
1537
-
1538
-
1539
-
1540
- var strError = (errno) => UTF8ToString(_strerror(errno));
1541
-
1542
- var ERRNO_CODES = {
1543
- 'EPERM': 63,
1544
- 'ENOENT': 44,
1545
- 'ESRCH': 71,
1546
- 'EINTR': 27,
1547
- 'EIO': 29,
1548
- 'ENXIO': 60,
1549
- 'E2BIG': 1,
1550
- 'ENOEXEC': 45,
1551
- 'EBADF': 8,
1552
- 'ECHILD': 12,
1553
- 'EAGAIN': 6,
1554
- 'EWOULDBLOCK': 6,
1555
- 'ENOMEM': 48,
1556
- 'EACCES': 2,
1557
- 'EFAULT': 21,
1558
- 'ENOTBLK': 105,
1559
- 'EBUSY': 10,
1560
- 'EEXIST': 20,
1561
- 'EXDEV': 75,
1562
- 'ENODEV': 43,
1563
- 'ENOTDIR': 54,
1564
- 'EISDIR': 31,
1565
- 'EINVAL': 28,
1566
- 'ENFILE': 41,
1567
- 'EMFILE': 33,
1568
- 'ENOTTY': 59,
1569
- 'ETXTBSY': 74,
1570
- 'EFBIG': 22,
1571
- 'ENOSPC': 51,
1572
- 'ESPIPE': 70,
1573
- 'EROFS': 69,
1574
- 'EMLINK': 34,
1575
- 'EPIPE': 64,
1576
- 'EDOM': 18,
1577
- 'ERANGE': 68,
1578
- 'ENOMSG': 49,
1579
- 'EIDRM': 24,
1580
- 'ECHRNG': 106,
1581
- 'EL2NSYNC': 156,
1582
- 'EL3HLT': 107,
1583
- 'EL3RST': 108,
1584
- 'ELNRNG': 109,
1585
- 'EUNATCH': 110,
1586
- 'ENOCSI': 111,
1587
- 'EL2HLT': 112,
1588
- 'EDEADLK': 16,
1589
- 'ENOLCK': 46,
1590
- 'EBADE': 113,
1591
- 'EBADR': 114,
1592
- 'EXFULL': 115,
1593
- 'ENOANO': 104,
1594
- 'EBADRQC': 103,
1595
- 'EBADSLT': 102,
1596
- 'EDEADLOCK': 16,
1597
- 'EBFONT': 101,
1598
- 'ENOSTR': 100,
1599
- 'ENODATA': 116,
1600
- 'ETIME': 117,
1601
- 'ENOSR': 118,
1602
- 'ENONET': 119,
1603
- 'ENOPKG': 120,
1604
- 'EREMOTE': 121,
1605
- 'ENOLINK': 47,
1606
- 'EADV': 122,
1607
- 'ESRMNT': 123,
1608
- 'ECOMM': 124,
1609
- 'EPROTO': 65,
1610
- 'EMULTIHOP': 36,
1611
- 'EDOTDOT': 125,
1612
- 'EBADMSG': 9,
1613
- 'ENOTUNIQ': 126,
1614
- 'EBADFD': 127,
1615
- 'EREMCHG': 128,
1616
- 'ELIBACC': 129,
1617
- 'ELIBBAD': 130,
1618
- 'ELIBSCN': 131,
1619
- 'ELIBMAX': 132,
1620
- 'ELIBEXEC': 133,
1621
- 'ENOSYS': 52,
1622
- 'ENOTEMPTY': 55,
1623
- 'ENAMETOOLONG': 37,
1624
- 'ELOOP': 32,
1625
- 'EOPNOTSUPP': 138,
1626
- 'EPFNOSUPPORT': 139,
1627
- 'ECONNRESET': 15,
1628
- 'ENOBUFS': 42,
1629
- 'EAFNOSUPPORT': 5,
1630
- 'EPROTOTYPE': 67,
1631
- 'ENOTSOCK': 57,
1632
- 'ENOPROTOOPT': 50,
1633
- 'ESHUTDOWN': 140,
1634
- 'ECONNREFUSED': 14,
1635
- 'EADDRINUSE': 3,
1636
- 'ECONNABORTED': 13,
1637
- 'ENETUNREACH': 40,
1638
- 'ENETDOWN': 38,
1639
- 'ETIMEDOUT': 73,
1640
- 'EHOSTDOWN': 142,
1641
- 'EHOSTUNREACH': 23,
1642
- 'EINPROGRESS': 26,
1643
- 'EALREADY': 7,
1644
- 'EDESTADDRREQ': 17,
1645
- 'EMSGSIZE': 35,
1646
- 'EPROTONOSUPPORT': 66,
1647
- 'ESOCKTNOSUPPORT': 137,
1648
- 'EADDRNOTAVAIL': 4,
1649
- 'ENETRESET': 39,
1650
- 'EISCONN': 30,
1651
- 'ENOTCONN': 53,
1652
- 'ETOOMANYREFS': 141,
1653
- 'EUSERS': 136,
1654
- 'EDQUOT': 19,
1655
- 'ESTALE': 72,
1656
- 'ENOTSUP': 138,
1657
- 'ENOMEDIUM': 148,
1658
- 'EILSEQ': 25,
1659
- 'EOVERFLOW': 61,
1660
- 'ECANCELED': 11,
1661
- 'ENOTRECOVERABLE': 56,
1662
- 'EOWNERDEAD': 62,
1663
- 'ESTRPIPE': 135,
1664
- };
1665
-
1666
- var asyncLoad = async (url) => {
1667
- var arrayBuffer = await readAsync(url);
1668
- assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
1669
- return new Uint8Array(arrayBuffer);
1670
- };
1671
-
1672
-
1673
- var FS_createDataFile = (...args) => FS.createDataFile(...args);
1674
-
1675
- var getUniqueRunDependency = (id) => {
1676
- var orig = id;
1677
- while (1) {
1678
- if (!runDependencyTracking[id]) return id;
1679
- id = orig + Math.random();
1680
- }
1681
- };
1682
-
1683
- var runDependencies = 0;
1684
-
1685
-
1686
- var dependenciesFulfilled = null;
1687
-
1688
- var runDependencyTracking = {
1689
- };
1690
-
1691
- var runDependencyWatcher = null;
1692
- var removeRunDependency = (id) => {
1693
- runDependencies--;
1694
-
1695
- assert(id, 'removeRunDependency requires an ID');
1696
- assert(runDependencyTracking[id]);
1697
- delete runDependencyTracking[id];
1698
- if (runDependencies == 0) {
1699
- if (runDependencyWatcher !== null) {
1700
- clearInterval(runDependencyWatcher);
1701
- runDependencyWatcher = null;
1702
- }
1703
- if (dependenciesFulfilled) {
1704
- var callback = dependenciesFulfilled;
1705
- dependenciesFulfilled = null;
1706
- callback(); // can add another dependenciesFulfilled
1707
- }
1708
- }
1709
- };
1710
-
1711
-
1712
- var addRunDependency = (id) => {
1713
- runDependencies++;
1714
-
1715
- assert(id, 'addRunDependency requires an ID')
1716
- assert(!runDependencyTracking[id]);
1717
- runDependencyTracking[id] = 1;
1718
- if (runDependencyWatcher === null && globalThis.setInterval) {
1719
- // Check for missing dependencies every few seconds
1720
- runDependencyWatcher = setInterval(() => {
1721
- if (ABORT) {
1722
- clearInterval(runDependencyWatcher);
1723
- runDependencyWatcher = null;
1724
- return;
1725
- }
1726
- var shown = false;
1727
- for (var dep in runDependencyTracking) {
1728
- if (!shown) {
1729
- shown = true;
1730
- err('still waiting on run dependencies:');
1731
- }
1732
- err(`dependency: ${dep}`);
1733
- }
1734
- if (shown) {
1735
- err('(end of list)');
1736
- }
1737
- }, 10000);
1738
- // Prevent this timer from keeping the runtime alive if nothing
1739
- // else is.
1740
- runDependencyWatcher.unref?.()
1741
- }
1742
- };
1743
-
1744
-
1745
- var preloadPlugins = [];
1746
- var FS_handledByPreloadPlugin = async (byteArray, fullname) => {
1747
- // Ensure plugins are ready.
1748
- if (typeof Browser != 'undefined') Browser.init();
1749
-
1750
- for (var plugin of preloadPlugins) {
1751
- if (plugin['canHandle'](fullname)) {
1752
- assert(plugin['handle'].constructor.name === 'AsyncFunction', 'Filesystem plugin handlers must be async functions (See #24914)')
1753
- return plugin['handle'](byteArray, fullname);
1754
- }
1755
- }
1756
- // In no plugin handled this file then return the original/unmodified
1757
- // byteArray.
1758
- return byteArray;
1759
- };
1760
- var FS_preloadFile = async (parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish) => {
1761
- // TODO we should allow people to just pass in a complete filename instead
1762
- // of parent and name being that we just join them anyways
1763
- var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent;
1764
- var dep = getUniqueRunDependency(`cp ${fullname}`); // might have several active requests for the same fullname
1765
- addRunDependency(dep);
1766
-
1767
- try {
1768
- var byteArray = url;
1769
- if (typeof url == 'string') {
1770
- byteArray = await asyncLoad(url);
1771
- }
1772
-
1773
- byteArray = await FS_handledByPreloadPlugin(byteArray, fullname);
1774
- preFinish?.();
1775
- if (!dontCreateFile) {
1776
- FS_createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
1777
- }
1778
- } finally {
1779
- removeRunDependency(dep);
1780
- }
1781
- };
1782
- var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
1783
- FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror);
1784
- };
1785
- var FS = {
1786
- root:null,
1787
- mounts:[],
1788
- devices:{
1789
- },
1790
- streams:[],
1791
- nextInode:1,
1792
- nameTable:null,
1793
- currentPath:"/",
1794
- initialized:false,
1795
- ignorePermissions:true,
1796
- filesystems:null,
1797
- syncFSRequests:0,
1798
- ErrnoError:class extends Error {
1799
- name = 'ErrnoError';
1800
- // We set the `name` property to be able to identify `FS.ErrnoError`
1801
- // - the `name` is a standard ECMA-262 property of error objects. Kind of good to have it anyway.
1802
- // - when using PROXYFS, an error can come from an underlying FS
1803
- // as different FS objects have their own FS.ErrnoError each,
1804
- // the test `err instanceof FS.ErrnoError` won't detect an error coming from another filesystem, causing bugs.
1805
- // we'll use the reliable test `err.name == "ErrnoError"` instead
1806
- constructor(errno) {
1807
- super(runtimeInitialized ? strError(errno) : '');
1808
- this.errno = errno;
1809
- for (var key in ERRNO_CODES) {
1810
- if (ERRNO_CODES[key] === errno) {
1811
- this.code = key;
1812
- break;
1813
- }
1814
- }
1815
- }
1816
- },
1817
- FSStream:class {
1818
- shared = {};
1819
- get object() {
1820
- return this.node;
1821
- }
1822
- set object(val) {
1823
- this.node = val;
1824
- }
1825
- get isRead() {
1826
- return (this.flags & 2097155) !== 1;
1827
- }
1828
- get isWrite() {
1829
- return (this.flags & 2097155) !== 0;
1830
- }
1831
- get isAppend() {
1832
- return (this.flags & 1024);
1833
- }
1834
- get flags() {
1835
- return this.shared.flags;
1836
- }
1837
- set flags(val) {
1838
- this.shared.flags = val;
1839
- }
1840
- get position() {
1841
- return this.shared.position;
1842
- }
1843
- set position(val) {
1844
- this.shared.position = val;
1845
- }
1846
- },
1847
- FSNode:class {
1848
- node_ops = {};
1849
- stream_ops = {};
1850
- readMode = 292 | 73;
1851
- writeMode = 146;
1852
- mounted = null;
1853
- constructor(parent, name, mode, rdev) {
1854
- if (!parent) {
1855
- parent = this; // root node sets parent to itself
1856
- }
1857
- this.parent = parent;
1858
- this.mount = parent.mount;
1859
- this.id = FS.nextInode++;
1860
- this.name = name;
1861
- this.mode = mode;
1862
- this.rdev = rdev;
1863
- this.atime = this.mtime = this.ctime = Date.now();
1864
- }
1865
- get read() {
1866
- return (this.mode & this.readMode) === this.readMode;
1867
- }
1868
- set read(val) {
1869
- val ? this.mode |= this.readMode : this.mode &= ~this.readMode;
1870
- }
1871
- get write() {
1872
- return (this.mode & this.writeMode) === this.writeMode;
1873
- }
1874
- set write(val) {
1875
- val ? this.mode |= this.writeMode : this.mode &= ~this.writeMode;
1876
- }
1877
- get isFolder() {
1878
- return FS.isDir(this.mode);
1879
- }
1880
- get isDevice() {
1881
- return FS.isChrdev(this.mode);
1882
- }
1883
- },
1884
- lookupPath(path, opts = {}) {
1885
- if (!path) {
1886
- throw new FS.ErrnoError(44);
1887
- }
1888
- opts.follow_mount ??= true
1889
-
1890
- if (!PATH.isAbs(path)) {
1891
- path = FS.cwd() + '/' + path;
1892
- }
1893
-
1894
- // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
1895
- linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
1896
- // split the absolute path
1897
- var parts = path.split('/').filter((p) => !!p);
1898
-
1899
- // start at the root
1900
- var current = FS.root;
1901
- var current_path = '/';
1902
-
1903
- for (var i = 0; i < parts.length; i++) {
1904
- var islast = (i === parts.length-1);
1905
- if (islast && opts.parent) {
1906
- // stop resolving
1907
- break;
1908
- }
1909
-
1910
- if (parts[i] === '.') {
1911
- continue;
1912
- }
1913
-
1914
- if (parts[i] === '..') {
1915
- current_path = PATH.dirname(current_path);
1916
- if (FS.isRoot(current)) {
1917
- path = current_path + '/' + parts.slice(i + 1).join('/');
1918
- // We're making progress here, don't let many consecutive ..'s
1919
- // lead to ELOOP
1920
- nlinks--;
1921
- continue linkloop;
1922
- } else {
1923
- current = current.parent;
1924
- }
1925
- continue;
1926
- }
1927
-
1928
- current_path = PATH.join2(current_path, parts[i]);
1929
- try {
1930
- current = FS.lookupNode(current, parts[i]);
1931
- } catch (e) {
1932
- // if noent_okay is true, suppress a ENOENT in the last component
1933
- // and return an object with an undefined node. This is needed for
1934
- // resolving symlinks in the path when creating a file.
1935
- if ((e?.errno === 44) && islast && opts.noent_okay) {
1936
- return { path: current_path };
1937
- }
1938
- throw e;
1939
- }
1940
-
1941
- // jump to the mount's root node if this is a mountpoint
1942
- if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) {
1943
- current = current.mounted.root;
1944
- }
1945
-
1946
- // by default, lookupPath will not follow a symlink if it is the final path component.
1947
- // setting opts.follow = true will override this behavior.
1948
- if (FS.isLink(current.mode) && (!islast || opts.follow)) {
1949
- if (!current.node_ops.readlink) {
1950
- throw new FS.ErrnoError(52);
1951
- }
1952
- var link = current.node_ops.readlink(current);
1953
- if (!PATH.isAbs(link)) {
1954
- link = PATH.dirname(current_path) + '/' + link;
1955
- }
1956
- path = link + '/' + parts.slice(i + 1).join('/');
1957
- continue linkloop;
1958
- }
1959
- }
1960
- return { path: current_path, node: current };
1961
- }
1962
- throw new FS.ErrnoError(32);
1963
- },
1964
- getPath(node) {
1965
- var path;
1966
- while (true) {
1967
- if (FS.isRoot(node)) {
1968
- var mount = node.mount.mountpoint;
1969
- if (!path) return mount;
1970
- return mount[mount.length-1] !== '/' ? `${mount}/${path}` : mount + path;
1971
- }
1972
- path = path ? `${node.name}/${path}` : node.name;
1973
- node = node.parent;
1974
- }
1975
- },
1976
- hashName(parentid, name) {
1977
- var hash = 0;
1978
-
1979
- for (var i = 0; i < name.length; i++) {
1980
- hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
1981
- }
1982
- return ((parentid + hash) >>> 0) % FS.nameTable.length;
1983
- },
1984
- hashAddNode(node) {
1985
- var hash = FS.hashName(node.parent.id, node.name);
1986
- node.name_next = FS.nameTable[hash];
1987
- FS.nameTable[hash] = node;
1988
- },
1989
- hashRemoveNode(node) {
1990
- var hash = FS.hashName(node.parent.id, node.name);
1991
- if (FS.nameTable[hash] === node) {
1992
- FS.nameTable[hash] = node.name_next;
1993
- } else {
1994
- var current = FS.nameTable[hash];
1995
- while (current) {
1996
- if (current.name_next === node) {
1997
- current.name_next = node.name_next;
1998
- break;
1999
- }
2000
- current = current.name_next;
2001
- }
2002
- }
2003
- },
2004
- lookupNode(parent, name) {
2005
- var errCode = FS.mayLookup(parent);
2006
- if (errCode) {
2007
- throw new FS.ErrnoError(errCode);
2008
- }
2009
- var hash = FS.hashName(parent.id, name);
2010
- for (var node = FS.nameTable[hash]; node; node = node.name_next) {
2011
- var nodeName = node.name;
2012
- if (node.parent.id === parent.id && nodeName === name) {
2013
- return node;
2014
- }
2015
- }
2016
- // if we failed to find it in the cache, call into the VFS
2017
- return FS.lookup(parent, name);
2018
- },
2019
- createNode(parent, name, mode, rdev) {
2020
- assert(typeof parent == 'object')
2021
- var node = new FS.FSNode(parent, name, mode, rdev);
2022
-
2023
- FS.hashAddNode(node);
2024
-
2025
- return node;
2026
- },
2027
- destroyNode(node) {
2028
- FS.hashRemoveNode(node);
2029
- },
2030
- isRoot(node) {
2031
- return node === node.parent;
2032
- },
2033
- isMountpoint(node) {
2034
- return !!node.mounted;
2035
- },
2036
- isFile(mode) {
2037
- return (mode & 61440) === 32768;
2038
- },
2039
- isDir(mode) {
2040
- return (mode & 61440) === 16384;
2041
- },
2042
- isLink(mode) {
2043
- return (mode & 61440) === 40960;
2044
- },
2045
- isChrdev(mode) {
2046
- return (mode & 61440) === 8192;
2047
- },
2048
- isBlkdev(mode) {
2049
- return (mode & 61440) === 24576;
2050
- },
2051
- isFIFO(mode) {
2052
- return (mode & 61440) === 4096;
2053
- },
2054
- isSocket(mode) {
2055
- return (mode & 49152) === 49152;
2056
- },
2057
- flagsToPermissionString(flag) {
2058
- var perms = ['r', 'w', 'rw'][flag & 3];
2059
- if ((flag & 512)) {
2060
- perms += 'w';
2061
- }
2062
- return perms;
2063
- },
2064
- nodePermissions(node, perms) {
2065
- if (FS.ignorePermissions) {
2066
- return 0;
2067
- }
2068
- // return 0 if any user, group or owner bits are set.
2069
- if (perms.includes('r') && !(node.mode & 292)) {
2070
- return 2;
2071
- } else if (perms.includes('w') && !(node.mode & 146)) {
2072
- return 2;
2073
- } else if (perms.includes('x') && !(node.mode & 73)) {
2074
- return 2;
2075
- }
2076
- return 0;
2077
- },
2078
- mayLookup(dir) {
2079
- if (!FS.isDir(dir.mode)) return 54;
2080
- var errCode = FS.nodePermissions(dir, 'x');
2081
- if (errCode) return errCode;
2082
- if (!dir.node_ops.lookup) return 2;
2083
- return 0;
2084
- },
2085
- mayCreate(dir, name) {
2086
- if (!FS.isDir(dir.mode)) {
2087
- return 54;
2088
- }
2089
- try {
2090
- var node = FS.lookupNode(dir, name);
2091
- return 20;
2092
- } catch (e) {
2093
- }
2094
- return FS.nodePermissions(dir, 'wx');
2095
- },
2096
- mayDelete(dir, name, isdir) {
2097
- var node;
2098
- try {
2099
- node = FS.lookupNode(dir, name);
2100
- } catch (e) {
2101
- return e.errno;
2102
- }
2103
- var errCode = FS.nodePermissions(dir, 'wx');
2104
- if (errCode) {
2105
- return errCode;
2106
- }
2107
- if (isdir) {
2108
- if (!FS.isDir(node.mode)) {
2109
- return 54;
2110
- }
2111
- if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
2112
- return 10;
2113
- }
2114
- } else {
2115
- if (FS.isDir(node.mode)) {
2116
- return 31;
2117
- }
2118
- }
2119
- return 0;
2120
- },
2121
- mayOpen(node, flags) {
2122
- if (!node) {
2123
- return 44;
2124
- }
2125
- if (FS.isLink(node.mode)) {
2126
- return 32;
2127
- } else if (FS.isDir(node.mode)) {
2128
- if (FS.flagsToPermissionString(flags) !== 'r' // opening for write
2129
- || (flags & (512 | 64))) { // TODO: check for O_SEARCH? (== search for dir only)
2130
- return 31;
2131
- }
2132
- }
2133
- return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
2134
- },
2135
- checkOpExists(op, err) {
2136
- if (!op) {
2137
- throw new FS.ErrnoError(err);
2138
- }
2139
- return op;
2140
- },
2141
- MAX_OPEN_FDS:4096,
2142
- nextfd() {
2143
- for (var fd = 0; fd <= FS.MAX_OPEN_FDS; fd++) {
2144
- if (!FS.streams[fd]) {
2145
- return fd;
2146
- }
2147
- }
2148
- throw new FS.ErrnoError(33);
2149
- },
2150
- getStreamChecked(fd) {
2151
- var stream = FS.getStream(fd);
2152
- if (!stream) {
2153
- throw new FS.ErrnoError(8);
2154
- }
2155
- return stream;
2156
- },
2157
- getStream:(fd) => FS.streams[fd],
2158
- createStream(stream, fd = -1) {
2159
- assert(fd >= -1);
2160
-
2161
- // clone it, so we can return an instance of FSStream
2162
- stream = Object.assign(new FS.FSStream(), stream);
2163
- if (fd == -1) {
2164
- fd = FS.nextfd();
2165
- }
2166
- stream.fd = fd;
2167
- FS.streams[fd] = stream;
2168
- return stream;
2169
- },
2170
- closeStream(fd) {
2171
- FS.streams[fd] = null;
2172
- },
2173
- dupStream(origStream, fd = -1) {
2174
- var stream = FS.createStream(origStream, fd);
2175
- stream.stream_ops?.dup?.(stream);
2176
- return stream;
2177
- },
2178
- doSetAttr(stream, node, attr) {
2179
- var setattr = stream?.stream_ops.setattr;
2180
- var arg = setattr ? stream : node;
2181
- setattr ??= node.node_ops.setattr;
2182
- FS.checkOpExists(setattr, 63)
2183
- setattr(arg, attr);
2184
- },
2185
- chrdev_stream_ops:{
2186
- open(stream) {
2187
- var device = FS.getDevice(stream.node.rdev);
2188
- // override node's stream ops with the device's
2189
- stream.stream_ops = device.stream_ops;
2190
- // forward the open call
2191
- stream.stream_ops.open?.(stream);
2192
- },
2193
- llseek() {
2194
- throw new FS.ErrnoError(70);
2195
- },
2196
- },
2197
- major:(dev) => ((dev) >> 8),
2198
- minor:(dev) => ((dev) & 0xff),
2199
- makedev:(ma, mi) => ((ma) << 8 | (mi)),
2200
- registerDevice(dev, ops) {
2201
- FS.devices[dev] = { stream_ops: ops };
2202
- },
2203
- getDevice:(dev) => FS.devices[dev],
2204
- getMounts(mount) {
2205
- var mounts = [];
2206
- var check = [mount];
2207
-
2208
- while (check.length) {
2209
- var m = check.pop();
2210
-
2211
- mounts.push(m);
2212
-
2213
- check.push(...m.mounts);
2214
- }
2215
-
2216
- return mounts;
2217
- },
2218
- syncfs(populate, callback) {
2219
- if (typeof populate == 'function') {
2220
- callback = populate;
2221
- populate = false;
2222
- }
2223
-
2224
- FS.syncFSRequests++;
2225
-
2226
- if (FS.syncFSRequests > 1) {
2227
- err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`);
2228
- }
2229
-
2230
- var mounts = FS.getMounts(FS.root.mount);
2231
- var completed = 0;
2232
-
2233
- function doCallback(errCode) {
2234
- assert(FS.syncFSRequests > 0);
2235
- FS.syncFSRequests--;
2236
- return callback(errCode);
2237
- }
2238
-
2239
- function done(errCode) {
2240
- if (errCode) {
2241
- if (!done.errored) {
2242
- done.errored = true;
2243
- return doCallback(errCode);
2244
- }
2245
- return;
2246
- }
2247
- if (++completed >= mounts.length) {
2248
- doCallback(null);
2249
- }
2250
- };
2251
-
2252
- // sync all mounts
2253
- mounts.forEach((mount) => {
2254
- if (!mount.type.syncfs) {
2255
- return done(null);
2256
- }
2257
- mount.type.syncfs(mount, populate, done);
2258
- });
2259
- },
2260
- mount(type, opts, mountpoint) {
2261
- if (typeof type == 'string') {
2262
- // The filesystem was not included, and instead we have an error
2263
- // message stored in the variable.
2264
- throw type;
2265
- }
2266
- var root = mountpoint === '/';
2267
- var pseudo = !mountpoint;
2268
- var node;
2269
-
2270
- if (root && FS.root) {
2271
- throw new FS.ErrnoError(10);
2272
- } else if (!root && !pseudo) {
2273
- var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
2274
-
2275
- mountpoint = lookup.path; // use the absolute path
2276
- node = lookup.node;
2277
-
2278
- if (FS.isMountpoint(node)) {
2279
- throw new FS.ErrnoError(10);
2280
- }
2281
-
2282
- if (!FS.isDir(node.mode)) {
2283
- throw new FS.ErrnoError(54);
2284
- }
2285
- }
2286
-
2287
- var mount = {
2288
- type,
2289
- opts,
2290
- mountpoint,
2291
- mounts: []
2292
- };
2293
-
2294
- // create a root node for the fs
2295
- var mountRoot = type.mount(mount);
2296
- mountRoot.mount = mount;
2297
- mount.root = mountRoot;
2298
-
2299
- if (root) {
2300
- FS.root = mountRoot;
2301
- } else if (node) {
2302
- // set as a mountpoint
2303
- node.mounted = mount;
2304
-
2305
- // add the new mount to the current mount's children
2306
- if (node.mount) {
2307
- node.mount.mounts.push(mount);
2308
- }
2309
- }
2310
-
2311
- return mountRoot;
2312
- },
2313
- unmount(mountpoint) {
2314
- var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
2315
-
2316
- if (!FS.isMountpoint(lookup.node)) {
2317
- throw new FS.ErrnoError(28);
2318
- }
2319
-
2320
- // destroy the nodes for this mount, and all its child mounts
2321
- var node = lookup.node;
2322
- var mount = node.mounted;
2323
- var mounts = FS.getMounts(mount);
2324
-
2325
- Object.keys(FS.nameTable).forEach((hash) => {
2326
- var current = FS.nameTable[hash];
2327
-
2328
- while (current) {
2329
- var next = current.name_next;
2330
-
2331
- if (mounts.includes(current.mount)) {
2332
- FS.destroyNode(current);
2333
- }
2334
-
2335
- current = next;
2336
- }
2337
- });
2338
-
2339
- // no longer a mountpoint
2340
- node.mounted = null;
2341
-
2342
- // remove this mount from the child mounts
2343
- var idx = node.mount.mounts.indexOf(mount);
2344
- assert(idx !== -1);
2345
- node.mount.mounts.splice(idx, 1);
2346
- },
2347
- lookup(parent, name) {
2348
- return parent.node_ops.lookup(parent, name);
2349
- },
2350
- mknod(path, mode, dev) {
2351
- var lookup = FS.lookupPath(path, { parent: true });
2352
- var parent = lookup.node;
2353
- var name = PATH.basename(path);
2354
- if (!name) {
2355
- throw new FS.ErrnoError(28);
2356
- }
2357
- if (name === '.' || name === '..') {
2358
- throw new FS.ErrnoError(20);
2359
- }
2360
- var errCode = FS.mayCreate(parent, name);
2361
- if (errCode) {
2362
- throw new FS.ErrnoError(errCode);
2363
- }
2364
- if (!parent.node_ops.mknod) {
2365
- throw new FS.ErrnoError(63);
2366
- }
2367
- return parent.node_ops.mknod(parent, name, mode, dev);
2368
- },
2369
- statfs(path) {
2370
- return FS.statfsNode(FS.lookupPath(path, {follow: true}).node);
2371
- },
2372
- statfsStream(stream) {
2373
- // We keep a separate statfsStream function because noderawfs overrides
2374
- // it. In noderawfs, stream.node is sometimes null. Instead, we need to
2375
- // look at stream.path.
2376
- return FS.statfsNode(stream.node);
2377
- },
2378
- statfsNode(node) {
2379
- // NOTE: None of the defaults here are true. We're just returning safe and
2380
- // sane values. Currently nodefs and rawfs replace these defaults,
2381
- // other file systems leave them alone.
2382
- var rtn = {
2383
- bsize: 4096,
2384
- frsize: 4096,
2385
- blocks: 1e6,
2386
- bfree: 5e5,
2387
- bavail: 5e5,
2388
- files: FS.nextInode,
2389
- ffree: FS.nextInode - 1,
2390
- fsid: 42,
2391
- flags: 2,
2392
- namelen: 255,
2393
- };
2394
-
2395
- if (node.node_ops.statfs) {
2396
- Object.assign(rtn, node.node_ops.statfs(node.mount.opts.root));
2397
- }
2398
- return rtn;
2399
- },
2400
- create(path, mode = 0o666) {
2401
- mode &= 4095;
2402
- mode |= 32768;
2403
- return FS.mknod(path, mode, 0);
2404
- },
2405
- mkdir(path, mode = 0o777) {
2406
- mode &= 511 | 512;
2407
- mode |= 16384;
2408
- return FS.mknod(path, mode, 0);
2409
- },
2410
- mkdirTree(path, mode) {
2411
- var dirs = path.split('/');
2412
- var d = '';
2413
- for (var dir of dirs) {
2414
- if (!dir) continue;
2415
- if (d || PATH.isAbs(path)) d += '/';
2416
- d += dir;
2417
- try {
2418
- FS.mkdir(d, mode);
2419
- } catch(e) {
2420
- if (e.errno != 20) throw e;
2421
- }
2422
- }
2423
- },
2424
- mkdev(path, mode, dev) {
2425
- if (typeof dev == 'undefined') {
2426
- dev = mode;
2427
- mode = 0o666;
2428
- }
2429
- mode |= 8192;
2430
- return FS.mknod(path, mode, dev);
2431
- },
2432
- symlink(oldpath, newpath) {
2433
- if (!PATH_FS.resolve(oldpath)) {
2434
- throw new FS.ErrnoError(44);
2435
- }
2436
- var lookup = FS.lookupPath(newpath, { parent: true });
2437
- var parent = lookup.node;
2438
- if (!parent) {
2439
- throw new FS.ErrnoError(44);
2440
- }
2441
- var newname = PATH.basename(newpath);
2442
- var errCode = FS.mayCreate(parent, newname);
2443
- if (errCode) {
2444
- throw new FS.ErrnoError(errCode);
2445
- }
2446
- if (!parent.node_ops.symlink) {
2447
- throw new FS.ErrnoError(63);
2448
- }
2449
- return parent.node_ops.symlink(parent, newname, oldpath);
2450
- },
2451
- rename(old_path, new_path) {
2452
- var old_dirname = PATH.dirname(old_path);
2453
- var new_dirname = PATH.dirname(new_path);
2454
- var old_name = PATH.basename(old_path);
2455
- var new_name = PATH.basename(new_path);
2456
- // parents must exist
2457
- var lookup, old_dir, new_dir;
2458
-
2459
- // let the errors from non existent directories percolate up
2460
- lookup = FS.lookupPath(old_path, { parent: true });
2461
- old_dir = lookup.node;
2462
- lookup = FS.lookupPath(new_path, { parent: true });
2463
- new_dir = lookup.node;
2464
-
2465
- if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
2466
- // need to be part of the same mount
2467
- if (old_dir.mount !== new_dir.mount) {
2468
- throw new FS.ErrnoError(75);
2469
- }
2470
- // source must exist
2471
- var old_node = FS.lookupNode(old_dir, old_name);
2472
- // old path should not be an ancestor of the new path
2473
- var relative = PATH_FS.relative(old_path, new_dirname);
2474
- if (relative.charAt(0) !== '.') {
2475
- throw new FS.ErrnoError(28);
2476
- }
2477
- // new path should not be an ancestor of the old path
2478
- relative = PATH_FS.relative(new_path, old_dirname);
2479
- if (relative.charAt(0) !== '.') {
2480
- throw new FS.ErrnoError(55);
2481
- }
2482
- // see if the new path already exists
2483
- var new_node;
2484
- try {
2485
- new_node = FS.lookupNode(new_dir, new_name);
2486
- } catch (e) {
2487
- // not fatal
2488
- }
2489
- // early out if nothing needs to change
2490
- if (old_node === new_node) {
2491
- return;
2492
- }
2493
- // we'll need to delete the old entry
2494
- var isdir = FS.isDir(old_node.mode);
2495
- var errCode = FS.mayDelete(old_dir, old_name, isdir);
2496
- if (errCode) {
2497
- throw new FS.ErrnoError(errCode);
2498
- }
2499
- // need delete permissions if we'll be overwriting.
2500
- // need create permissions if new doesn't already exist.
2501
- errCode = new_node ?
2502
- FS.mayDelete(new_dir, new_name, isdir) :
2503
- FS.mayCreate(new_dir, new_name);
2504
- if (errCode) {
2505
- throw new FS.ErrnoError(errCode);
2506
- }
2507
- if (!old_dir.node_ops.rename) {
2508
- throw new FS.ErrnoError(63);
2509
- }
2510
- if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
2511
- throw new FS.ErrnoError(10);
2512
- }
2513
- // if we are going to change the parent, check write permissions
2514
- if (new_dir !== old_dir) {
2515
- errCode = FS.nodePermissions(old_dir, 'w');
2516
- if (errCode) {
2517
- throw new FS.ErrnoError(errCode);
2518
- }
2519
- }
2520
- // remove the node from the lookup hash
2521
- FS.hashRemoveNode(old_node);
2522
- // do the underlying fs rename
2523
- try {
2524
- old_dir.node_ops.rename(old_node, new_dir, new_name);
2525
- // update old node (we do this here to avoid each backend
2526
- // needing to)
2527
- old_node.parent = new_dir;
2528
- } catch (e) {
2529
- throw e;
2530
- } finally {
2531
- // add the node back to the hash (in case node_ops.rename
2532
- // changed its name)
2533
- FS.hashAddNode(old_node);
2534
- }
2535
- },
2536
- rmdir(path) {
2537
- var lookup = FS.lookupPath(path, { parent: true });
2538
- var parent = lookup.node;
2539
- var name = PATH.basename(path);
2540
- var node = FS.lookupNode(parent, name);
2541
- var errCode = FS.mayDelete(parent, name, true);
2542
- if (errCode) {
2543
- throw new FS.ErrnoError(errCode);
2544
- }
2545
- if (!parent.node_ops.rmdir) {
2546
- throw new FS.ErrnoError(63);
2547
- }
2548
- if (FS.isMountpoint(node)) {
2549
- throw new FS.ErrnoError(10);
2550
- }
2551
- parent.node_ops.rmdir(parent, name);
2552
- FS.destroyNode(node);
2553
- },
2554
- readdir(path) {
2555
- var lookup = FS.lookupPath(path, { follow: true });
2556
- var node = lookup.node;
2557
- var readdir = FS.checkOpExists(node.node_ops.readdir, 54);
2558
- return readdir(node);
2559
- },
2560
- unlink(path) {
2561
- var lookup = FS.lookupPath(path, { parent: true });
2562
- var parent = lookup.node;
2563
- if (!parent) {
2564
- throw new FS.ErrnoError(44);
2565
- }
2566
- var name = PATH.basename(path);
2567
- var node = FS.lookupNode(parent, name);
2568
- var errCode = FS.mayDelete(parent, name, false);
2569
- if (errCode) {
2570
- // According to POSIX, we should map EISDIR to EPERM, but
2571
- // we instead do what Linux does (and we must, as we use
2572
- // the musl linux libc).
2573
- throw new FS.ErrnoError(errCode);
2574
- }
2575
- if (!parent.node_ops.unlink) {
2576
- throw new FS.ErrnoError(63);
2577
- }
2578
- if (FS.isMountpoint(node)) {
2579
- throw new FS.ErrnoError(10);
2580
- }
2581
- parent.node_ops.unlink(parent, name);
2582
- FS.destroyNode(node);
2583
- },
2584
- readlink(path) {
2585
- var lookup = FS.lookupPath(path);
2586
- var link = lookup.node;
2587
- if (!link) {
2588
- throw new FS.ErrnoError(44);
2589
- }
2590
- if (!link.node_ops.readlink) {
2591
- throw new FS.ErrnoError(28);
2592
- }
2593
- return link.node_ops.readlink(link);
2594
- },
2595
- stat(path, dontFollow) {
2596
- var lookup = FS.lookupPath(path, { follow: !dontFollow });
2597
- var node = lookup.node;
2598
- var getattr = FS.checkOpExists(node.node_ops.getattr, 63);
2599
- return getattr(node);
2600
- },
2601
- fstat(fd) {
2602
- var stream = FS.getStreamChecked(fd);
2603
- var node = stream.node;
2604
- var getattr = stream.stream_ops.getattr;
2605
- var arg = getattr ? stream : node;
2606
- getattr ??= node.node_ops.getattr;
2607
- FS.checkOpExists(getattr, 63)
2608
- return getattr(arg);
2609
- },
2610
- lstat(path) {
2611
- return FS.stat(path, true);
2612
- },
2613
- doChmod(stream, node, mode, dontFollow) {
2614
- FS.doSetAttr(stream, node, {
2615
- mode: (mode & 4095) | (node.mode & ~4095),
2616
- ctime: Date.now(),
2617
- dontFollow
2618
- });
2619
- },
2620
- chmod(path, mode, dontFollow) {
2621
- var node;
2622
- if (typeof path == 'string') {
2623
- var lookup = FS.lookupPath(path, { follow: !dontFollow });
2624
- node = lookup.node;
2625
- } else {
2626
- node = path;
2627
- }
2628
- FS.doChmod(null, node, mode, dontFollow);
2629
- },
2630
- lchmod(path, mode) {
2631
- FS.chmod(path, mode, true);
2632
- },
2633
- fchmod(fd, mode) {
2634
- var stream = FS.getStreamChecked(fd);
2635
- FS.doChmod(stream, stream.node, mode, false);
2636
- },
2637
- doChown(stream, node, dontFollow) {
2638
- FS.doSetAttr(stream, node, {
2639
- timestamp: Date.now(),
2640
- dontFollow
2641
- // we ignore the uid / gid for now
2642
- });
2643
- },
2644
- chown(path, uid, gid, dontFollow) {
2645
- var node;
2646
- if (typeof path == 'string') {
2647
- var lookup = FS.lookupPath(path, { follow: !dontFollow });
2648
- node = lookup.node;
2649
- } else {
2650
- node = path;
2651
- }
2652
- FS.doChown(null, node, dontFollow);
2653
- },
2654
- lchown(path, uid, gid) {
2655
- FS.chown(path, uid, gid, true);
2656
- },
2657
- fchown(fd, uid, gid) {
2658
- var stream = FS.getStreamChecked(fd);
2659
- FS.doChown(stream, stream.node, false);
2660
- },
2661
- doTruncate(stream, node, len) {
2662
- if (FS.isDir(node.mode)) {
2663
- throw new FS.ErrnoError(31);
2664
- }
2665
- if (!FS.isFile(node.mode)) {
2666
- throw new FS.ErrnoError(28);
2667
- }
2668
- var errCode = FS.nodePermissions(node, 'w');
2669
- if (errCode) {
2670
- throw new FS.ErrnoError(errCode);
2671
- }
2672
- FS.doSetAttr(stream, node, {
2673
- size: len,
2674
- timestamp: Date.now()
2675
- });
2676
- },
2677
- truncate(path, len) {
2678
- if (len < 0) {
2679
- throw new FS.ErrnoError(28);
2680
- }
2681
- var node;
2682
- if (typeof path == 'string') {
2683
- var lookup = FS.lookupPath(path, { follow: true });
2684
- node = lookup.node;
2685
- } else {
2686
- node = path;
2687
- }
2688
- FS.doTruncate(null, node, len);
2689
- },
2690
- ftruncate(fd, len) {
2691
- var stream = FS.getStreamChecked(fd);
2692
- if (len < 0 || (stream.flags & 2097155) === 0) {
2693
- throw new FS.ErrnoError(28);
2694
- }
2695
- FS.doTruncate(stream, stream.node, len);
2696
- },
2697
- utime(path, atime, mtime) {
2698
- var lookup = FS.lookupPath(path, { follow: true });
2699
- var node = lookup.node;
2700
- var setattr = FS.checkOpExists(node.node_ops.setattr, 63);
2701
- setattr(node, {
2702
- atime: atime,
2703
- mtime: mtime
2704
- });
2705
- },
2706
- open(path, flags, mode = 0o666) {
2707
- if (path === "") {
2708
- throw new FS.ErrnoError(44);
2709
- }
2710
- flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
2711
- if ((flags & 64)) {
2712
- mode = (mode & 4095) | 32768;
2713
- } else {
2714
- mode = 0;
2715
- }
2716
- var node;
2717
- var isDirPath;
2718
- if (typeof path == 'object') {
2719
- node = path;
2720
- } else {
2721
- isDirPath = path.endsWith("/");
2722
- // noent_okay makes it so that if the final component of the path
2723
- // doesn't exist, lookupPath returns `node: undefined`. `path` will be
2724
- // updated to point to the target of all symlinks.
2725
- var lookup = FS.lookupPath(path, {
2726
- follow: !(flags & 131072),
2727
- noent_okay: true
2728
- });
2729
- node = lookup.node;
2730
- path = lookup.path;
2731
- }
2732
- // perhaps we need to create the node
2733
- var created = false;
2734
- if ((flags & 64)) {
2735
- if (node) {
2736
- // if O_CREAT and O_EXCL are set, error out if the node already exists
2737
- if ((flags & 128)) {
2738
- throw new FS.ErrnoError(20);
2739
- }
2740
- } else if (isDirPath) {
2741
- throw new FS.ErrnoError(31);
2742
- } else {
2743
- // node doesn't exist, try to create it
2744
- // Ignore the permission bits here to ensure we can `open` this new
2745
- // file below. We use chmod below the apply the permissions once the
2746
- // file is open.
2747
- node = FS.mknod(path, mode | 0o777, 0);
2748
- created = true;
2749
- }
2750
- }
2751
- if (!node) {
2752
- throw new FS.ErrnoError(44);
2753
- }
2754
- // can't truncate a device
2755
- if (FS.isChrdev(node.mode)) {
2756
- flags &= ~512;
2757
- }
2758
- // if asked only for a directory, then this must be one
2759
- if ((flags & 65536) && !FS.isDir(node.mode)) {
2760
- throw new FS.ErrnoError(54);
2761
- }
2762
- // check permissions, if this is not a file we just created now (it is ok to
2763
- // create and write to a file with read-only permissions; it is read-only
2764
- // for later use)
2765
- if (!created) {
2766
- var errCode = FS.mayOpen(node, flags);
2767
- if (errCode) {
2768
- throw new FS.ErrnoError(errCode);
2769
- }
2770
- }
2771
- // do truncation if necessary
2772
- if ((flags & 512) && !created) {
2773
- FS.truncate(node, 0);
2774
- }
2775
- // we've already handled these, don't pass down to the underlying vfs
2776
- flags &= ~(128 | 512 | 131072);
2777
-
2778
- // register the stream with the filesystem
2779
- var stream = FS.createStream({
2780
- node,
2781
- path: FS.getPath(node), // we want the absolute path to the node
2782
- flags,
2783
- seekable: true,
2784
- position: 0,
2785
- stream_ops: node.stream_ops,
2786
- // used by the file family libc calls (fopen, fwrite, ferror, etc.)
2787
- ungotten: [],
2788
- error: false
2789
- });
2790
- // call the new stream's open function
2791
- if (stream.stream_ops.open) {
2792
- stream.stream_ops.open(stream);
2793
- }
2794
- if (created) {
2795
- FS.chmod(node, mode & 0o777);
2796
- }
2797
- return stream;
2798
- },
2799
- close(stream) {
2800
- if (FS.isClosed(stream)) {
2801
- throw new FS.ErrnoError(8);
2802
- }
2803
- if (stream.getdents) stream.getdents = null; // free readdir state
2804
- try {
2805
- if (stream.stream_ops.close) {
2806
- stream.stream_ops.close(stream);
2807
- }
2808
- } catch (e) {
2809
- throw e;
2810
- } finally {
2811
- FS.closeStream(stream.fd);
2812
- }
2813
- stream.fd = null;
2814
- },
2815
- isClosed(stream) {
2816
- return stream.fd === null;
2817
- },
2818
- llseek(stream, offset, whence) {
2819
- if (FS.isClosed(stream)) {
2820
- throw new FS.ErrnoError(8);
2821
- }
2822
- if (!stream.seekable || !stream.stream_ops.llseek) {
2823
- throw new FS.ErrnoError(70);
2824
- }
2825
- if (whence != 0 && whence != 1 && whence != 2) {
2826
- throw new FS.ErrnoError(28);
2827
- }
2828
- stream.position = stream.stream_ops.llseek(stream, offset, whence);
2829
- stream.ungotten = [];
2830
- return stream.position;
2831
- },
2832
- read(stream, buffer, offset, length, position) {
2833
- assert(offset >= 0);
2834
- if (length < 0 || position < 0) {
2835
- throw new FS.ErrnoError(28);
2836
- }
2837
- if (FS.isClosed(stream)) {
2838
- throw new FS.ErrnoError(8);
2839
- }
2840
- if ((stream.flags & 2097155) === 1) {
2841
- throw new FS.ErrnoError(8);
2842
- }
2843
- if (FS.isDir(stream.node.mode)) {
2844
- throw new FS.ErrnoError(31);
2845
- }
2846
- if (!stream.stream_ops.read) {
2847
- throw new FS.ErrnoError(28);
2848
- }
2849
- var seeking = typeof position != 'undefined';
2850
- if (!seeking) {
2851
- position = stream.position;
2852
- } else if (!stream.seekable) {
2853
- throw new FS.ErrnoError(70);
2854
- }
2855
- var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
2856
- if (!seeking) stream.position += bytesRead;
2857
- return bytesRead;
2858
- },
2859
- write(stream, buffer, offset, length, position, canOwn) {
2860
- assert(offset >= 0);
2861
- if (length < 0 || position < 0) {
2862
- throw new FS.ErrnoError(28);
2863
- }
2864
- if (FS.isClosed(stream)) {
2865
- throw new FS.ErrnoError(8);
2866
- }
2867
- if ((stream.flags & 2097155) === 0) {
2868
- throw new FS.ErrnoError(8);
2869
- }
2870
- if (FS.isDir(stream.node.mode)) {
2871
- throw new FS.ErrnoError(31);
2872
- }
2873
- if (!stream.stream_ops.write) {
2874
- throw new FS.ErrnoError(28);
2875
- }
2876
- if (stream.seekable && stream.flags & 1024) {
2877
- // seek to the end before writing in append mode
2878
- FS.llseek(stream, 0, 2);
2879
- }
2880
- var seeking = typeof position != 'undefined';
2881
- if (!seeking) {
2882
- position = stream.position;
2883
- } else if (!stream.seekable) {
2884
- throw new FS.ErrnoError(70);
2885
- }
2886
- var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
2887
- if (!seeking) stream.position += bytesWritten;
2888
- return bytesWritten;
2889
- },
2890
- mmap(stream, length, position, prot, flags) {
2891
- // User requests writing to file (prot & PROT_WRITE != 0).
2892
- // Checking if we have permissions to write to the file unless
2893
- // MAP_PRIVATE flag is set. According to POSIX spec it is possible
2894
- // to write to file opened in read-only mode with MAP_PRIVATE flag,
2895
- // as all modifications will be visible only in the memory of
2896
- // the current process.
2897
- if ((prot & 2) !== 0
2898
- && (flags & 2) === 0
2899
- && (stream.flags & 2097155) !== 2) {
2900
- throw new FS.ErrnoError(2);
2901
- }
2902
- if ((stream.flags & 2097155) === 1) {
2903
- throw new FS.ErrnoError(2);
2904
- }
2905
- if (!stream.stream_ops.mmap) {
2906
- throw new FS.ErrnoError(43);
2907
- }
2908
- if (!length) {
2909
- throw new FS.ErrnoError(28);
2910
- }
2911
- return stream.stream_ops.mmap(stream, length, position, prot, flags);
2912
- },
2913
- msync(stream, buffer, offset, length, mmapFlags) {
2914
- assert(offset >= 0);
2915
- if (!stream.stream_ops.msync) {
2916
- return 0;
2917
- }
2918
- return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags);
2919
- },
2920
- ioctl(stream, cmd, arg) {
2921
- if (!stream.stream_ops.ioctl) {
2922
- throw new FS.ErrnoError(59);
2923
- }
2924
- return stream.stream_ops.ioctl(stream, cmd, arg);
2925
- },
2926
- readFile(path, opts = {}) {
2927
- opts.flags = opts.flags || 0;
2928
- opts.encoding = opts.encoding || 'binary';
2929
- if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
2930
- abort(`Invalid encoding type "${opts.encoding}"`);
2931
- }
2932
- var stream = FS.open(path, opts.flags);
2933
- var stat = FS.stat(path);
2934
- var length = stat.size;
2935
- var buf = new Uint8Array(length);
2936
- FS.read(stream, buf, 0, length, 0);
2937
- if (opts.encoding === 'utf8') {
2938
- buf = UTF8ArrayToString(buf);
2939
- }
2940
- FS.close(stream);
2941
- return buf;
2942
- },
2943
- writeFile(path, data, opts = {}) {
2944
- opts.flags = opts.flags || 577;
2945
- var stream = FS.open(path, opts.flags, opts.mode);
2946
- if (typeof data == 'string') {
2947
- data = new Uint8Array(intArrayFromString(data, true));
2948
- }
2949
- if (ArrayBuffer.isView(data)) {
2950
- FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
2951
- } else {
2952
- abort('Unsupported data type');
2953
- }
2954
- FS.close(stream);
2955
- },
2956
- cwd:() => FS.currentPath,
2957
- chdir(path) {
2958
- var lookup = FS.lookupPath(path, { follow: true });
2959
- if (lookup.node === null) {
2960
- throw new FS.ErrnoError(44);
2961
- }
2962
- if (!FS.isDir(lookup.node.mode)) {
2963
- throw new FS.ErrnoError(54);
2964
- }
2965
- var errCode = FS.nodePermissions(lookup.node, 'x');
2966
- if (errCode) {
2967
- throw new FS.ErrnoError(errCode);
2968
- }
2969
- FS.currentPath = lookup.path;
2970
- },
2971
- createDefaultDirectories() {
2972
- FS.mkdir('/tmp');
2973
- FS.mkdir('/home');
2974
- FS.mkdir('/home/web_user');
2975
- },
2976
- createDefaultDevices() {
2977
- // create /dev
2978
- FS.mkdir('/dev');
2979
- // setup /dev/null
2980
- FS.registerDevice(FS.makedev(1, 3), {
2981
- read: () => 0,
2982
- write: (stream, buffer, offset, length, pos) => length,
2983
- llseek: () => 0,
2984
- });
2985
- FS.mkdev('/dev/null', FS.makedev(1, 3));
2986
- // setup /dev/tty and /dev/tty1
2987
- // stderr needs to print output using err() rather than out()
2988
- // so we register a second tty just for it.
2989
- TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
2990
- TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
2991
- FS.mkdev('/dev/tty', FS.makedev(5, 0));
2992
- FS.mkdev('/dev/tty1', FS.makedev(6, 0));
2993
- // setup /dev/[u]random
2994
- // use a buffer to avoid overhead of individual crypto calls per byte
2995
- var randomBuffer = new Uint8Array(1024), randomLeft = 0;
2996
- var randomByte = () => {
2997
- if (randomLeft === 0) {
2998
- randomFill(randomBuffer);
2999
- randomLeft = randomBuffer.byteLength;
3000
- }
3001
- return randomBuffer[--randomLeft];
3002
- };
3003
- FS.createDevice('/dev', 'random', randomByte);
3004
- FS.createDevice('/dev', 'urandom', randomByte);
3005
- // we're not going to emulate the actual shm device,
3006
- // just create the tmp dirs that reside in it commonly
3007
- FS.mkdir('/dev/shm');
3008
- FS.mkdir('/dev/shm/tmp');
3009
- },
3010
- createSpecialDirectories() {
3011
- // create /proc/self/fd which allows /proc/self/fd/6 => readlink gives the
3012
- // name of the stream for fd 6 (see test_unistd_ttyname)
3013
- FS.mkdir('/proc');
3014
- var proc_self = FS.mkdir('/proc/self');
3015
- FS.mkdir('/proc/self/fd');
3016
- FS.mount({
3017
- mount() {
3018
- var node = FS.createNode(proc_self, 'fd', 16895, 73);
3019
- node.stream_ops = {
3020
- llseek: MEMFS.stream_ops.llseek,
3021
- };
3022
- node.node_ops = {
3023
- lookup(parent, name) {
3024
- var fd = +name;
3025
- var stream = FS.getStreamChecked(fd);
3026
- var ret = {
3027
- parent: null,
3028
- mount: { mountpoint: 'fake' },
3029
- node_ops: { readlink: () => stream.path },
3030
- id: fd + 1,
3031
- };
3032
- ret.parent = ret; // make it look like a simple root node
3033
- return ret;
3034
- },
3035
- readdir() {
3036
- return Array.from(FS.streams.entries())
3037
- .filter(([k, v]) => v)
3038
- .map(([k, v]) => k.toString());
3039
- }
3040
- };
3041
- return node;
3042
- }
3043
- }, {}, '/proc/self/fd');
3044
- },
3045
- createStandardStreams(input, output, error) {
3046
- // TODO deprecate the old functionality of a single
3047
- // input / output callback and that utilizes FS.createDevice
3048
- // and instead require a unique set of stream ops
3049
-
3050
- // by default, we symlink the standard streams to the
3051
- // default tty devices. however, if the standard streams
3052
- // have been overwritten we create a unique device for
3053
- // them instead.
3054
- if (input) {
3055
- FS.createDevice('/dev', 'stdin', input);
3056
- } else {
3057
- FS.symlink('/dev/tty', '/dev/stdin');
3058
- }
3059
- if (output) {
3060
- FS.createDevice('/dev', 'stdout', null, output);
3061
- } else {
3062
- FS.symlink('/dev/tty', '/dev/stdout');
3063
- }
3064
- if (error) {
3065
- FS.createDevice('/dev', 'stderr', null, error);
3066
- } else {
3067
- FS.symlink('/dev/tty1', '/dev/stderr');
3068
- }
3069
-
3070
- // open default streams for the stdin, stdout and stderr devices
3071
- var stdin = FS.open('/dev/stdin', 0);
3072
- var stdout = FS.open('/dev/stdout', 1);
3073
- var stderr = FS.open('/dev/stderr', 1);
3074
- assert(stdin.fd === 0, `invalid handle for stdin (${stdin.fd})`);
3075
- assert(stdout.fd === 1, `invalid handle for stdout (${stdout.fd})`);
3076
- assert(stderr.fd === 2, `invalid handle for stderr (${stderr.fd})`);
3077
- },
3078
- staticInit() {
3079
- FS.nameTable = new Array(4096);
3080
-
3081
- FS.mount(MEMFS, {}, '/');
3082
-
3083
- FS.createDefaultDirectories();
3084
- FS.createDefaultDevices();
3085
- FS.createSpecialDirectories();
3086
-
3087
- FS.filesystems = {
3088
- 'MEMFS': MEMFS,
3089
- };
3090
- },
3091
- init(input, output, error) {
3092
- 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)');
3093
- FS.initialized = true;
3094
-
3095
- // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
3096
-
3097
- FS.createStandardStreams(input, output, error);
3098
- },
3099
- quit() {
3100
- FS.initialized = false;
3101
- // force-flush all streams, so we get musl std streams printed out
3102
- _fflush(0);
3103
- // close all of our streams
3104
- for (var stream of FS.streams) {
3105
- if (stream) {
3106
- FS.close(stream);
3107
- }
3108
- }
3109
- },
3110
- findObject(path, dontResolveLastLink) {
3111
- var ret = FS.analyzePath(path, dontResolveLastLink);
3112
- if (!ret.exists) {
3113
- return null;
3114
- }
3115
- return ret.object;
3116
- },
3117
- analyzePath(path, dontResolveLastLink) {
3118
- // operate from within the context of the symlink's target
3119
- try {
3120
- var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
3121
- path = lookup.path;
3122
- } catch (e) {
3123
- }
3124
- var ret = {
3125
- isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
3126
- parentExists: false, parentPath: null, parentObject: null
3127
- };
3128
- try {
3129
- var lookup = FS.lookupPath(path, { parent: true });
3130
- ret.parentExists = true;
3131
- ret.parentPath = lookup.path;
3132
- ret.parentObject = lookup.node;
3133
- ret.name = PATH.basename(path);
3134
- lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
3135
- ret.exists = true;
3136
- ret.path = lookup.path;
3137
- ret.object = lookup.node;
3138
- ret.name = lookup.node.name;
3139
- ret.isRoot = lookup.path === '/';
3140
- } catch (e) {
3141
- ret.error = e.errno;
3142
- };
3143
- return ret;
3144
- },
3145
- createPath(parent, path, canRead, canWrite) {
3146
- parent = typeof parent == 'string' ? parent : FS.getPath(parent);
3147
- var parts = path.split('/').reverse();
3148
- while (parts.length) {
3149
- var part = parts.pop();
3150
- if (!part) continue;
3151
- var current = PATH.join2(parent, part);
3152
- try {
3153
- FS.mkdir(current);
3154
- } catch (e) {
3155
- if (e.errno != 20) throw e;
3156
- }
3157
- parent = current;
3158
- }
3159
- return current;
3160
- },
3161
- createFile(parent, name, properties, canRead, canWrite) {
3162
- var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
3163
- var mode = FS_getMode(canRead, canWrite);
3164
- return FS.create(path, mode);
3165
- },
3166
- createDataFile(parent, name, data, canRead, canWrite, canOwn) {
3167
- var path = name;
3168
- if (parent) {
3169
- parent = typeof parent == 'string' ? parent : FS.getPath(parent);
3170
- path = name ? PATH.join2(parent, name) : parent;
3171
- }
3172
- var mode = FS_getMode(canRead, canWrite);
3173
- var node = FS.create(path, mode);
3174
- if (data) {
3175
- if (typeof data == 'string') {
3176
- var arr = new Array(data.length);
3177
- for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
3178
- data = arr;
3179
- }
3180
- // make sure we can write to the file
3181
- FS.chmod(node, mode | 146);
3182
- var stream = FS.open(node, 577);
3183
- FS.write(stream, data, 0, data.length, 0, canOwn);
3184
- FS.close(stream);
3185
- FS.chmod(node, mode);
3186
- }
3187
- },
3188
- createDevice(parent, name, input, output) {
3189
- var path = PATH.join2(typeof parent == 'string' ? parent : FS.getPath(parent), name);
3190
- var mode = FS_getMode(!!input, !!output);
3191
- FS.createDevice.major ??= 64;
3192
- var dev = FS.makedev(FS.createDevice.major++, 0);
3193
- // Create a fake device that a set of stream ops to emulate
3194
- // the old behavior.
3195
- FS.registerDevice(dev, {
3196
- open(stream) {
3197
- stream.seekable = false;
3198
- },
3199
- close(stream) {
3200
- // flush any pending line data
3201
- if (output?.buffer?.length) {
3202
- output(10);
3203
- }
3204
- },
3205
- read(stream, buffer, offset, length, pos /* ignored */) {
3206
- var bytesRead = 0;
3207
- for (var i = 0; i < length; i++) {
3208
- var result;
3209
- try {
3210
- result = input();
3211
- } catch (e) {
3212
- throw new FS.ErrnoError(29);
3213
- }
3214
- if (result === undefined && bytesRead === 0) {
3215
- throw new FS.ErrnoError(6);
3216
- }
3217
- if (result === null || result === undefined) break;
3218
- bytesRead++;
3219
- buffer[offset+i] = result;
3220
- }
3221
- if (bytesRead) {
3222
- stream.node.atime = Date.now();
3223
- }
3224
- return bytesRead;
3225
- },
3226
- write(stream, buffer, offset, length, pos) {
3227
- for (var i = 0; i < length; i++) {
3228
- try {
3229
- output(buffer[offset+i]);
3230
- } catch (e) {
3231
- throw new FS.ErrnoError(29);
3232
- }
3233
- }
3234
- if (length) {
3235
- stream.node.mtime = stream.node.ctime = Date.now();
3236
- }
3237
- return i;
3238
- }
3239
- });
3240
- return FS.mkdev(path, mode, dev);
3241
- },
3242
- forceLoadFile(obj) {
3243
- if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
3244
- if (globalThis.XMLHttpRequest) {
3245
- abort("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
3246
- } else { // Command-line.
3247
- try {
3248
- obj.contents = readBinary(obj.url);
3249
- } catch (e) {
3250
- throw new FS.ErrnoError(29);
3251
- }
3252
- }
3253
- },
3254
- createLazyFile(parent, name, url, canRead, canWrite) {
3255
- // Lazy chunked Uint8Array (implements get and length from Uint8Array).
3256
- // Actual getting is abstracted away for eventual reuse.
3257
- class LazyUint8Array {
3258
- lengthKnown = false;
3259
- chunks = []; // Loaded chunks. Index is the chunk number
3260
- get(idx) {
3261
- if (idx > this.length-1 || idx < 0) {
3262
- return undefined;
3263
- }
3264
- var chunkOffset = idx % this.chunkSize;
3265
- var chunkNum = (idx / this.chunkSize)|0;
3266
- return this.getter(chunkNum)[chunkOffset];
3267
- }
3268
- setDataGetter(getter) {
3269
- this.getter = getter;
3270
- }
3271
- cacheLength() {
3272
- // Find length
3273
- var xhr = new XMLHttpRequest();
3274
- xhr.open('HEAD', url, false);
3275
- xhr.send(null);
3276
- if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status);
3277
- var datalength = Number(xhr.getResponseHeader("Content-length"));
3278
- var header;
3279
- var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
3280
- var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
3281
-
3282
- var chunkSize = 1024*1024; // Chunk size in bytes
3283
-
3284
- if (!hasByteServing) chunkSize = datalength;
3285
-
3286
- // Function to get a range from the remote URL.
3287
- var doXHR = (from, to) => {
3288
- if (from > to) abort("invalid range (" + from + ", " + to + ") or no bytes requested!");
3289
- if (to > datalength-1) abort("only " + datalength + " bytes available! programmer error!");
3290
-
3291
- // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
3292
- var xhr = new XMLHttpRequest();
3293
- xhr.open('GET', url, false);
3294
- if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
3295
-
3296
- // Some hints to the browser that we want binary data.
3297
- xhr.responseType = 'arraybuffer';
3298
- if (xhr.overrideMimeType) {
3299
- xhr.overrideMimeType('text/plain; charset=x-user-defined');
3300
- }
3301
-
3302
- xhr.send(null);
3303
- if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status);
3304
- if (xhr.response !== undefined) {
3305
- return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
3306
- }
3307
- return intArrayFromString(xhr.responseText || '', true);
3308
- };
3309
- var lazyArray = this;
3310
- lazyArray.setDataGetter((chunkNum) => {
3311
- var start = chunkNum * chunkSize;
3312
- var end = (chunkNum+1) * chunkSize - 1; // including this byte
3313
- end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
3314
- if (typeof lazyArray.chunks[chunkNum] == 'undefined') {
3315
- lazyArray.chunks[chunkNum] = doXHR(start, end);
3316
- }
3317
- if (typeof lazyArray.chunks[chunkNum] == 'undefined') abort('doXHR failed!');
3318
- return lazyArray.chunks[chunkNum];
3319
- });
3320
-
3321
- if (usesGzip || !datalength) {
3322
- // if the server uses gzip or doesn't supply the length, we have to download the whole file to get the (uncompressed) length
3323
- chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
3324
- datalength = this.getter(0).length;
3325
- chunkSize = datalength;
3326
- out("LazyFiles on gzip forces download of the whole file when length is accessed");
3327
- }
3328
-
3329
- this._length = datalength;
3330
- this._chunkSize = chunkSize;
3331
- this.lengthKnown = true;
3332
- }
3333
- get length() {
3334
- if (!this.lengthKnown) {
3335
- this.cacheLength();
3336
- }
3337
- return this._length;
3338
- }
3339
- get chunkSize() {
3340
- if (!this.lengthKnown) {
3341
- this.cacheLength();
3342
- }
3343
- return this._chunkSize;
3344
- }
3345
- }
3346
-
3347
- if (globalThis.XMLHttpRequest) {
3348
- if (!ENVIRONMENT_IS_WORKER) abort('Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc');
3349
- var lazyArray = new LazyUint8Array();
3350
- var properties = { isDevice: false, contents: lazyArray };
3351
- } else {
3352
- var properties = { isDevice: false, url: url };
3353
- }
3354
-
3355
- var node = FS.createFile(parent, name, properties, canRead, canWrite);
3356
- // This is a total hack, but I want to get this lazy file code out of the
3357
- // core of MEMFS. If we want to keep this lazy file concept I feel it should
3358
- // be its own thin LAZYFS proxying calls to MEMFS.
3359
- if (properties.contents) {
3360
- node.contents = properties.contents;
3361
- } else if (properties.url) {
3362
- node.contents = null;
3363
- node.url = properties.url;
3364
- }
3365
- // Add a function that defers querying the file size until it is asked the first time.
3366
- Object.defineProperties(node, {
3367
- usedBytes: {
3368
- get: function() { return this.contents.length; }
3369
- }
3370
- });
3371
- // override each stream op with one that tries to force load the lazy file first
3372
- var stream_ops = {};
3373
- var keys = Object.keys(node.stream_ops);
3374
- keys.forEach((key) => {
3375
- var fn = node.stream_ops[key];
3376
- stream_ops[key] = (...args) => {
3377
- FS.forceLoadFile(node);
3378
- return fn(...args);
3379
- };
3380
- });
3381
- function writeChunks(stream, buffer, offset, length, position) {
3382
- var contents = stream.node.contents;
3383
- if (position >= contents.length)
3384
- return 0;
3385
- var size = Math.min(contents.length - position, length);
3386
- assert(size >= 0);
3387
- if (contents.slice) { // normal array
3388
- for (var i = 0; i < size; i++) {
3389
- buffer[offset + i] = contents[position + i];
3390
- }
3391
- } else {
3392
- for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
3393
- buffer[offset + i] = contents.get(position + i);
3394
- }
3395
- }
3396
- return size;
3397
- }
3398
- // use a custom read function
3399
- stream_ops.read = (stream, buffer, offset, length, position) => {
3400
- FS.forceLoadFile(node);
3401
- return writeChunks(stream, buffer, offset, length, position)
3402
- };
3403
- // use a custom mmap function
3404
- stream_ops.mmap = (stream, length, position, prot, flags) => {
3405
- FS.forceLoadFile(node);
3406
- var ptr = mmapAlloc(length);
3407
- if (!ptr) {
3408
- throw new FS.ErrnoError(48);
3409
- }
3410
- writeChunks(stream, HEAP8, ptr, length, position);
3411
- return { ptr, allocated: true };
3412
- };
3413
- node.stream_ops = stream_ops;
3414
- return node;
3415
- },
3416
- absolutePath() {
3417
- abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
3418
- },
3419
- createFolder() {
3420
- abort('FS.createFolder has been removed; use FS.mkdir instead');
3421
- },
3422
- createLink() {
3423
- abort('FS.createLink has been removed; use FS.symlink instead');
3424
- },
3425
- joinPath() {
3426
- abort('FS.joinPath has been removed; use PATH.join instead');
3427
- },
3428
- mmapAlloc() {
3429
- abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
3430
- },
3431
- standardizePath() {
3432
- abort('FS.standardizePath has been removed; use PATH.normalize instead');
3433
- },
3434
- };
3435
-
3436
- var SYSCALLS = {
3437
- DEFAULT_POLLMASK:5,
3438
- calculateAt(dirfd, path, allowEmpty) {
3439
- if (PATH.isAbs(path)) {
3440
- return path;
3441
- }
3442
- // relative path
3443
- var dir;
3444
- if (dirfd === -100) {
3445
- dir = FS.cwd();
3446
- } else {
3447
- var dirstream = SYSCALLS.getStreamFromFD(dirfd);
3448
- dir = dirstream.path;
3449
- }
3450
- if (path.length == 0) {
3451
- if (!allowEmpty) {
3452
- throw new FS.ErrnoError(44);;
3453
- }
3454
- return dir;
3455
- }
3456
- return dir + '/' + path;
3457
- },
3458
- writeStat(buf, stat) {
3459
- HEAPU32[((buf)>>2)] = stat.dev;
3460
- HEAPU32[(((buf)+(4))>>2)] = stat.mode;
3461
- HEAPU32[(((buf)+(8))>>2)] = stat.nlink;
3462
- HEAPU32[(((buf)+(12))>>2)] = stat.uid;
3463
- HEAPU32[(((buf)+(16))>>2)] = stat.gid;
3464
- HEAPU32[(((buf)+(20))>>2)] = stat.rdev;
3465
- HEAP64[(((buf)+(24))>>3)] = BigInt(stat.size);
3466
- HEAP32[(((buf)+(32))>>2)] = 4096;
3467
- HEAP32[(((buf)+(36))>>2)] = stat.blocks;
3468
- var atime = stat.atime.getTime();
3469
- var mtime = stat.mtime.getTime();
3470
- var ctime = stat.ctime.getTime();
3471
- HEAP64[(((buf)+(40))>>3)] = BigInt(Math.floor(atime / 1000));
3472
- HEAPU32[(((buf)+(48))>>2)] = (atime % 1000) * 1000 * 1000;
3473
- HEAP64[(((buf)+(56))>>3)] = BigInt(Math.floor(mtime / 1000));
3474
- HEAPU32[(((buf)+(64))>>2)] = (mtime % 1000) * 1000 * 1000;
3475
- HEAP64[(((buf)+(72))>>3)] = BigInt(Math.floor(ctime / 1000));
3476
- HEAPU32[(((buf)+(80))>>2)] = (ctime % 1000) * 1000 * 1000;
3477
- HEAP64[(((buf)+(88))>>3)] = BigInt(stat.ino);
3478
- return 0;
3479
- },
3480
- writeStatFs(buf, stats) {
3481
- HEAPU32[(((buf)+(4))>>2)] = stats.bsize;
3482
- HEAPU32[(((buf)+(60))>>2)] = stats.bsize;
3483
- HEAP64[(((buf)+(8))>>3)] = BigInt(stats.blocks);
3484
- HEAP64[(((buf)+(16))>>3)] = BigInt(stats.bfree);
3485
- HEAP64[(((buf)+(24))>>3)] = BigInt(stats.bavail);
3486
- HEAP64[(((buf)+(32))>>3)] = BigInt(stats.files);
3487
- HEAP64[(((buf)+(40))>>3)] = BigInt(stats.ffree);
3488
- HEAPU32[(((buf)+(48))>>2)] = stats.fsid;
3489
- HEAPU32[(((buf)+(64))>>2)] = stats.flags; // ST_NOSUID
3490
- HEAPU32[(((buf)+(56))>>2)] = stats.namelen;
3491
- },
3492
- doMsync(addr, stream, len, flags, offset) {
3493
- if (!FS.isFile(stream.node.mode)) {
3494
- throw new FS.ErrnoError(43);
3495
- }
3496
- if (flags & 2) {
3497
- // MAP_PRIVATE calls need not to be synced back to underlying fs
3498
- return 0;
3499
- }
3500
- var buffer = HEAPU8.slice(addr, addr + len);
3501
- FS.msync(stream, buffer, offset, len, flags);
3502
- },
3503
- getStreamFromFD(fd) {
3504
- var stream = FS.getStreamChecked(fd);
3505
- return stream;
3506
- },
3507
- varargs:undefined,
3508
- getStr(ptr) {
3509
- var ret = UTF8ToString(ptr);
3510
- return ret;
3511
- },
3512
- };
3513
- function ___syscall_openat(dirfd, path, flags, varargs) {
3514
- SYSCALLS.varargs = varargs;
3515
- try {
3516
-
3517
- path = SYSCALLS.getStr(path);
3518
- path = SYSCALLS.calculateAt(dirfd, path);
3519
- var mode = varargs ? syscallGetVarargI() : 0;
3520
- return FS.open(path, flags, mode).fd;
3521
- } catch (e) {
3522
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
3523
- return -e.errno;
3524
- }
3525
- }
3526
-
3527
- var __abort_js = () =>
3528
- abort('native code called abort()');
3529
-
3530
- var runtimeKeepaliveCounter = 0;
3531
- var __emscripten_runtime_keepalive_clear = () => {
3532
- runtimeKeepaliveCounter = 0;
3533
- };
3534
-
3535
- var timers = {
3536
- };
3537
-
3538
- var handleException = (e) => {
3539
- // Certain exception types we do not treat as errors since they are used for
3540
- // internal control flow.
3541
- // 1. ExitStatus, which is thrown by exit()
3542
- // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
3543
- // that wish to return to JS event loop.
3544
- if (e instanceof ExitStatus || e == 'unwind') {
3545
- return EXITSTATUS;
3546
- }
3547
- quit_(1, e);
3548
- };
3549
-
3550
-
3551
772
  var keepRuntimeAlive = () => runtimeKeepaliveCounter > 0;
3552
773
  var _proc_exit = (code) => {
3553
774
  EXITSTATUS = code;
@@ -3556,8 +777,6 @@ async function createWasm() {
3556
777
  }
3557
778
  quit_(code, new ExitStatus(code));
3558
779
  };
3559
-
3560
-
3561
780
  /** @param {boolean|number=} implicit */
3562
781
  var exitJS = (status, implicit) => {
3563
782
  EXITSTATUS = status;
@@ -3569,15 +788,11 @@ async function createWasm() {
3569
788
  // if exit() was called explicitly, warn the user if the runtime isn't actually being shut down
3570
789
  if (keepRuntimeAlive() && !implicit) {
3571
790
  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)`;
3572
- readyPromiseReject?.(msg);
3573
791
  err(msg);
3574
792
  }
3575
793
 
3576
794
  _proc_exit(status);
3577
795
  };
3578
- var _exit = exitJS;
3579
-
3580
-
3581
796
  var maybeExit = () => {
3582
797
  if (runtimeExited) {
3583
798
  return;
@@ -3590,20 +805,26 @@ async function createWasm() {
3590
805
  }
3591
806
  }
3592
807
  };
3593
- var callUserCallback = (func) => {
808
+ var callUserCallback = (func, ...args) => {
3594
809
  if (runtimeExited || ABORT) {
3595
810
  err('user callback triggered after runtime exited or application aborted. Ignoring.');
3596
811
  return;
3597
812
  }
3598
813
  try {
3599
- func();
3600
- maybeExit();
814
+ return func(...args);
3601
815
  } catch (e) {
3602
816
  handleException(e);
817
+ } finally {
818
+ maybeExit();
819
+ }
820
+ };
821
+ var timers = {
822
+ };
823
+ var clearTimers = () => {
824
+ for (var t of Object.values(timers)) {
825
+ clearTimeout(t.id);
3603
826
  }
3604
827
  };
3605
-
3606
-
3607
828
  var _emscripten_get_now = () => performance.now();
3608
829
  var __setitimer_js = (which, timeout_ms) => {
3609
830
  // First, clear any existing timer.
@@ -3619,26 +840,22 @@ async function createWasm() {
3619
840
  var id = setTimeout(() => {
3620
841
  assert(which in timers);
3621
842
  delete timers[which];
3622
- callUserCallback(() => __emscripten_timeout(which, _emscripten_get_now()));
843
+ callUserCallback(__emscripten_timeout, which, _emscripten_get_now());
3623
844
  }, timeout_ms);
3624
845
  timers[which] = { id, timeout_ms };
3625
846
  return 0;
3626
847
  };
3627
-
3628
848
  var _emscripten_date_now = () => Date.now();
3629
-
849
+ var alignMemory = (size, alignment) => {
850
+ assert(alignment, 'alignment argument is required');
851
+ return Math.ceil(size / alignment) * alignment;
852
+ };
3630
853
  var getHeapMax = () =>
3631
854
  // Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
3632
855
  // full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
3633
856
  // for any code that deals with heap sizes, which would require special
3634
857
  // casing all heap size related code to treat 0 specially.
3635
858
  2147483648;
3636
-
3637
- var alignMemory = (size, alignment) => {
3638
- assert(alignment, "alignment argument is required");
3639
- return Math.ceil(size / alignment) * alignment;
3640
- };
3641
-
3642
859
  var growMemory = (size) => {
3643
860
  var oldHeapSize = wasmMemory.buffer.byteLength;
3644
861
  var pages = ((size - oldHeapSize + 65535) / 65536) | 0;
@@ -3650,7 +867,7 @@ async function createWasm() {
3650
867
  } catch(e) {
3651
868
  err(`growMemory: Attempted to grow heap from ${oldHeapSize} bytes to ${size} bytes, but got error: ${e}`);
3652
869
  }
3653
- // implicit 0 return to save code size (caller will cast "undefined" into 0
870
+ // implicit 0 return to save code size (caller will cast 'undefined' into 0
3654
871
  // anyhow)
3655
872
  };
3656
873
  var _emscripten_resize_heap = (requestedSize) => {
@@ -3705,16 +922,15 @@ async function createWasm() {
3705
922
  err(`Failed to grow the heap from ${oldSize} bytes to ${newSize} bytes, not enough memory!`);
3706
923
  return false;
3707
924
  };
3708
-
925
+ /** @type {!Uint32Array} */
926
+ var HEAPU32;
3709
927
  var ENV = {
3710
928
  };
3711
-
3712
- var getExecutableName = () => thisProgram || './this.program';
929
+ var getExecutableName = () => thisProgram;
3713
930
  var getEnvStrings = () => {
3714
931
  if (!getEnvStrings.strings) {
3715
932
  // Default values.
3716
- // Browser language detection #8751
3717
- var lang = ((typeof navigator == 'object' && navigator.language) || 'C').replace('-', '_') + '.UTF-8';
933
+ var lang = (globalThis.navigator?.language ?? 'C').replace('-', '_') + '.UTF-8';
3718
934
  var env = {
3719
935
  'USER': 'web_user',
3720
936
  'LOGNAME': 'web_user',
@@ -3740,9 +956,50 @@ async function createWasm() {
3740
956
  }
3741
957
  return getEnvStrings.strings;
3742
958
  };
959
+ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
960
+ assert(typeof str === 'string', `stringToUTF8Array expects a string (got ${typeof str})`);
961
+ // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
962
+ // undefined and false each don't write out any bytes.
963
+ if (!(maxBytesToWrite > 0))
964
+ return 0;
3743
965
 
966
+ var startIdx = outIdx;
967
+ var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
968
+ for (var i = 0; i < str.length; ++i) {
969
+ // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
970
+ // and https://www.ietf.org/rfc/rfc2279.txt
971
+ // and https://tools.ietf.org/html/rfc3629
972
+ var u = str.codePointAt(i);
973
+ if (u <= 0x7F) {
974
+ if (outIdx >= endIdx) break;
975
+ heap[outIdx++] = u;
976
+ } else if (u <= 0x7FF) {
977
+ if (outIdx + 1 >= endIdx) break;
978
+ heap[outIdx++] = 0xC0 | (u >> 6);
979
+ heap[outIdx++] = 0x80 | (u & 63);
980
+ } else if (u <= 0xFFFF) {
981
+ if (outIdx + 2 >= endIdx) break;
982
+ heap[outIdx++] = 0xE0 | (u >> 12);
983
+ heap[outIdx++] = 0x80 | ((u >> 6) & 63);
984
+ heap[outIdx++] = 0x80 | (u & 63);
985
+ } else {
986
+ if (outIdx + 3 >= endIdx) break;
987
+ 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).`);
988
+ heap[outIdx++] = 0xF0 | (u >> 18);
989
+ heap[outIdx++] = 0x80 | ((u >> 12) & 63);
990
+ heap[outIdx++] = 0x80 | ((u >> 6) & 63);
991
+ heap[outIdx++] = 0x80 | (u & 63);
992
+ // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16.
993
+ // We need to manually skip over the second code unit for correct iteration.
994
+ i++;
995
+ }
996
+ }
997
+ // Null-terminate the pointer to the buffer.
998
+ heap[outIdx] = 0;
999
+ return outIdx - startIdx;
1000
+ };
3744
1001
  var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
3745
- assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!');
1002
+ assert(typeof maxBytesToWrite === 'number', 'stringToUTF8 requires a third parameter that specifies the length of the output buffer');
3746
1003
  return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
3747
1004
  };
3748
1005
  var _environ_get = (__environ, environ_buf) => {
@@ -3756,8 +1013,25 @@ async function createWasm() {
3756
1013
  }
3757
1014
  return 0;
3758
1015
  };
3759
-
3760
-
1016
+ var lengthBytesUTF8 = (str) => {
1017
+ var len = 0;
1018
+ for (var i = 0; i < str.length; ++i) {
1019
+ var u = str.codePointAt(i);
1020
+ if (u <= 0x7F) {
1021
+ len++;
1022
+ } else if (u <= 0x7FF) {
1023
+ len += 2;
1024
+ } else if (u <= 0xFFFF) {
1025
+ len += 3;
1026
+ } else {
1027
+ len += 4;
1028
+ // Gotcha: if codePoint is over 0xFFFF, it is represented as a surrogate pair in UTF-16.
1029
+ // We need to manually skip over the second code unit for correct iteration.
1030
+ i++;
1031
+ }
1032
+ }
1033
+ return len;
1034
+ };
3761
1035
  var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
3762
1036
  var strings = getEnvStrings();
3763
1037
  HEAPU32[((penviron_count)>>2)] = strings.length;
@@ -3768,123 +1042,69 @@ async function createWasm() {
3768
1042
  HEAPU32[((penviron_buf_size)>>2)] = bufSize;
3769
1043
  return 0;
3770
1044
  };
3771
-
3772
- function _fd_close(fd) {
3773
- try {
3774
-
3775
- var stream = SYSCALLS.getStreamFromFD(fd);
3776
- FS.close(stream);
3777
- return 0;
3778
- } catch (e) {
3779
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
3780
- return e.errno;
3781
- }
3782
- }
3783
-
3784
- /** @param {number=} offset */
3785
- var doReadv = (stream, iov, iovcnt, offset) => {
3786
- var ret = 0;
3787
- for (var i = 0; i < iovcnt; i++) {
3788
- var ptr = HEAPU32[((iov)>>2)];
3789
- var len = HEAPU32[(((iov)+(4))>>2)];
3790
- iov += 8;
3791
- var curr = FS.read(stream, HEAP8, ptr, len, offset);
3792
- if (curr < 0) return -1;
3793
- ret += curr;
3794
- if (curr < len) break; // nothing more to read
3795
- if (typeof offset != 'undefined') {
3796
- offset += curr;
3797
- }
3798
- }
3799
- return ret;
1045
+ var _fd_close = (fd) => {
1046
+ abort('fd_close called without SYSCALLS_REQUIRE_FILESYSTEM');
3800
1047
  };
3801
-
3802
- function _fd_read(fd, iov, iovcnt, pnum) {
3803
- try {
3804
-
3805
- var stream = SYSCALLS.getStreamFromFD(fd);
3806
- var num = doReadv(stream, iov, iovcnt);
3807
- HEAPU32[((pnum)>>2)] = num;
3808
- return 0;
3809
- } catch (e) {
3810
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
3811
- return e.errno;
3812
- }
3813
- }
3814
-
3815
-
3816
- var INT53_MAX = 9007199254740992;
3817
-
3818
- var INT53_MIN = -9007199254740992;
1048
+ const INT53_MAX = 9007199254740992;
1049
+ const INT53_MIN = -9007199254740992;
3819
1050
  var bigintToI53Checked = (num) => (num < INT53_MIN || num > INT53_MAX) ? NaN : Number(num);
3820
1051
  function _fd_seek(fd, offset, whence, newOffset) {
3821
1052
  offset = bigintToI53Checked(offset);
3822
1053
 
3823
1054
 
3824
- try {
3825
-
3826
- if (isNaN(offset)) return 61;
3827
- var stream = SYSCALLS.getStreamFromFD(fd);
3828
- FS.llseek(stream, offset, whence);
3829
- HEAP64[((newOffset)>>3)] = BigInt(stream.position);
3830
- if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
3831
- return 0;
3832
- } catch (e) {
3833
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
3834
- return e.errno;
3835
- }
3836
- ;
1055
+ return 70;
1056
+ ;
3837
1057
  }
3838
-
3839
- /** @param {number=} offset */
3840
- var doWritev = (stream, iov, iovcnt, offset) => {
3841
- var ret = 0;
1058
+ var printCharBuffers = [null,[],[]];
1059
+ var printChar = (stream, curr) => {
1060
+ var buffer = printCharBuffers[stream];
1061
+ assert(buffer);
1062
+ if (!curr || curr === 10) {
1063
+ (stream === 1 ? out : err)(UTF8ArrayToString(buffer));
1064
+ buffer.length = 0;
1065
+ } else {
1066
+ buffer.push(curr);
1067
+ }
1068
+ };
1069
+ var flush_NO_FILESYSTEM = () => {
1070
+ // flush anything remaining in the buffers during shutdown
1071
+ _fflush(0);
1072
+ if (printCharBuffers[1].length) printChar(1, 10);
1073
+ if (printCharBuffers[2].length) printChar(2, 10);
1074
+ };
1075
+ var _fd_write = (fd, iov, iovcnt, pnum) => {
1076
+ // hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0
1077
+ var num = 0;
3842
1078
  for (var i = 0; i < iovcnt; i++) {
3843
1079
  var ptr = HEAPU32[((iov)>>2)];
3844
1080
  var len = HEAPU32[(((iov)+(4))>>2)];
3845
1081
  iov += 8;
3846
- var curr = FS.write(stream, HEAP8, ptr, len, offset);
3847
- if (curr < 0) return -1;
3848
- ret += curr;
3849
- if (curr < len) {
3850
- // No more space to write.
3851
- break;
3852
- }
3853
- if (typeof offset != 'undefined') {
3854
- offset += curr;
1082
+ for (var j = 0; j < len; j++) {
1083
+ printChar(fd, HEAPU8[ptr+j]);
3855
1084
  }
1085
+ num += len;
3856
1086
  }
3857
- return ret;
3858
- };
3859
-
3860
- function _fd_write(fd, iov, iovcnt, pnum) {
3861
- try {
3862
-
3863
- var stream = SYSCALLS.getStreamFromFD(fd);
3864
- var num = doWritev(stream, iov, iovcnt);
3865
1087
  HEAPU32[((pnum)>>2)] = num;
3866
1088
  return 0;
3867
- } catch (e) {
3868
- if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
3869
- return e.errno;
3870
- }
3871
- }
3872
-
1089
+ };
3873
1090
 
1091
+ var initRandomFill = () => {
1092
+ // This block is not needed on v19+ since crypto.getRandomValues is builtin
1093
+ if (ENVIRONMENT_IS_NODE) {
1094
+ var nodeCrypto = require('node:crypto');
1095
+ return (view) => (nodeCrypto.randomFillSync(view), 0);
1096
+ }
1097
+
1098
+ return (view) => (crypto.getRandomValues(view), 0);
1099
+ };
1100
+ var randomFill = (view) => (randomFill = initRandomFill())(view);
1101
+ var _random_get = (buffer, size) => randomFill(HEAPU8.subarray(buffer, buffer + size));
3874
1102
 
3875
1103
  var getCFunc = (ident) => {
3876
1104
  var func = Module['_' + ident]; // closure exported function
3877
- assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
1105
+ assert(func, `Cannot call unknown function ${ident}, make sure it is exported`);
3878
1106
  return func;
3879
1107
  };
3880
-
3881
- var writeArrayToMemory = (array, buffer) => {
3882
- assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
3883
- HEAP8.set(array, buffer);
3884
- };
3885
-
3886
-
3887
-
3888
1108
  var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
3889
1109
  var stringToUTF8OnStack = (str) => {
3890
1110
  var size = lengthBytesUTF8(str) + 1;
@@ -3892,17 +1112,17 @@ async function createWasm() {
3892
1112
  stringToUTF8(str, ret, size);
3893
1113
  return ret;
3894
1114
  };
3895
-
3896
-
3897
-
3898
-
1115
+ var writeArrayToMemory = (array, buffer) => {
1116
+ assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
1117
+ HEAP8.set(array, buffer);
1118
+ };
3899
1119
 
3900
1120
  /**
3901
- * @param {string|null=} returnType
3902
- * @param {Array=} argTypes
3903
- * @param {Array=} args
3904
- * @param {Object=} opts
3905
- */
1121
+ * @param {string|null=} returnType
1122
+ * @param {Array=} argTypes
1123
+ * @param {Array=} args
1124
+ * @param {Object=} opts
1125
+ */
3906
1126
  var ccall = (ident, returnType, argTypes, args, opts) => {
3907
1127
  // For fast lookup of conversion functions
3908
1128
  var toC = {
@@ -3931,12 +1151,12 @@ async function createWasm() {
3931
1151
  var func = getCFunc(ident);
3932
1152
  var cArgs = [];
3933
1153
  var stack = 0;
3934
- assert(returnType !== 'array', 'Return type should not be "array".');
1154
+ assert(returnType !== 'array', 'return type should not be "array"');
3935
1155
  if (args) {
3936
1156
  for (var i = 0; i < args.length; i++) {
3937
1157
  var converter = toC[argTypes[i]];
3938
1158
  if (converter) {
3939
- if (stack === 0) stack = stackSave();
1159
+ if (!stack) stack = stackSave();
3940
1160
  cArgs[i] = converter(args[i]);
3941
1161
  } else {
3942
1162
  cArgs[i] = args[i];
@@ -3945,7 +1165,7 @@ async function createWasm() {
3945
1165
  }
3946
1166
  var ret = func(...cArgs);
3947
1167
  function onDone(ret) {
3948
- if (stack !== 0) stackRestore(stack);
1168
+ if (stack) stackRestore(stack);
3949
1169
  return convertReturnValue(ret);
3950
1170
  }
3951
1171
 
@@ -3954,18 +1174,17 @@ async function createWasm() {
3954
1174
  };
3955
1175
 
3956
1176
  /**
3957
- * @param {string=} returnType
3958
- * @param {Array=} argTypes
3959
- * @param {Object=} opts
3960
- */
1177
+ * @param {string=} returnType
1178
+ * @param {Array=} argTypes
1179
+ * @param {Object=} opts
1180
+ */
3961
1181
  var cwrap = (ident, returnType, argTypes, opts) => {
3962
1182
  return (...args) => ccall(ident, returnType, argTypes, args, opts);
3963
1183
  };
3964
1184
 
3965
1185
 
3966
- FS.createPreloadedFile = FS_createPreloadedFile;
3967
- FS.preloadFile = FS_preloadFile;
3968
- FS.staticInit();;
1186
+
1187
+ var _exit = exitJS;
3969
1188
  // End JS library code
3970
1189
 
3971
1190
  // include: postlibrary.js
@@ -3974,7 +1193,12 @@ async function createWasm() {
3974
1193
 
3975
1194
  {
3976
1195
 
3977
- // No ATMODULES hooks
1196
+ // Begin ATMODULES hooks
1197
+
1198
+ Module['FS_createDataFile'] = FS.createDataFile;
1199
+ Module['FS_createPreloadedFile'] = FS.createPreloadedFile;
1200
+
1201
+ // End ATMODULES hooks
3978
1202
 
3979
1203
  checkIncomingModuleAPI();
3980
1204
 
@@ -3982,20 +1206,20 @@ async function createWasm() {
3982
1206
 
3983
1207
 
3984
1208
  // Assertions on removed incoming Module JS APIs.
3985
- assert(typeof Module['memoryInitializerPrefixURL'] == 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
3986
- assert(typeof Module['pthreadMainPrefixURL'] == 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
3987
- assert(typeof Module['cdInitializerPrefixURL'] == 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
3988
- assert(typeof Module['filePackagePrefixURL'] == 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
3989
- assert(typeof Module['read'] == 'undefined', 'Module.read option was removed');
3990
- assert(typeof Module['readAsync'] == 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
3991
- assert(typeof Module['readBinary'] == 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
3992
- assert(typeof Module['setWindowTitle'] == 'undefined', 'Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)');
3993
- assert(typeof Module['TOTAL_MEMORY'] == 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
3994
- assert(typeof Module['ENVIRONMENT'] == 'undefined', 'Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
3995
- assert(typeof Module['STACK_SIZE'] == 'undefined', 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
1209
+ assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead');
1210
+ assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead');
1211
+ assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead');
1212
+ assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead');
1213
+ assert(typeof Module['read'] === 'undefined', 'Module.read option was removed');
1214
+ assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)');
1215
+ assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)');
1216
+ assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify emscripten_set_window_title in JS)');
1217
+ assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY');
1218
+ assert(typeof Module['ENVIRONMENT'] === 'undefined', 'Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
1219
+ assert(typeof Module['STACK_SIZE'] === 'undefined', 'STACK_SIZE can no longer be set at runtime. Use -sSTACK_SIZE at link time')
3996
1220
  // If memory is defined in wasm, the user can't provide it, or set INITIAL_MEMORY
3997
- assert(typeof Module['wasmMemory'] == 'undefined', 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
3998
- assert(typeof Module['INITIAL_MEMORY'] == 'undefined', 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
1221
+ assert(typeof Module['wasmMemory'] === 'undefined', 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
1222
+ assert(typeof Module['INITIAL_MEMORY'] === 'undefined', 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
3999
1223
 
4000
1224
  }
4001
1225
 
@@ -4017,6 +1241,7 @@ async function createWasm() {
4017
1241
  'createNamedFunction',
4018
1242
  'zeroMemory',
4019
1243
  'withStackSave',
1244
+ 'strError',
4020
1245
  'inetPton4',
4021
1246
  'inetNtop4',
4022
1247
  'inetPton6',
@@ -4030,8 +1255,13 @@ async function createWasm() {
4030
1255
  'dynCall',
4031
1256
  'runtimeKeepalivePush',
4032
1257
  'runtimeKeepalivePop',
1258
+ 'asyncLoad',
4033
1259
  'asmjsMangle',
1260
+ 'mmapAlloc',
4034
1261
  'HandleAllocator',
1262
+ 'getUniqueRunDependency',
1263
+ 'addRunDependency',
1264
+ 'removeRunDependency',
4035
1265
  'addOnPreRun',
4036
1266
  'addOnInit',
4037
1267
  'addOnPostCtor',
@@ -4048,6 +1278,9 @@ async function createWasm() {
4048
1278
  'getFunctionAddress',
4049
1279
  'addFunction',
4050
1280
  'removeFunction',
1281
+ 'setValue',
1282
+ 'getValue',
1283
+ 'intArrayFromString',
4051
1284
  'intArrayToString',
4052
1285
  'AsciiToString',
4053
1286
  'stringToAscii',
@@ -4076,12 +1309,14 @@ async function createWasm() {
4076
1309
  'registerOrientationChangeEventCallback',
4077
1310
  'fillFullscreenChangeEventData',
4078
1311
  'registerFullscreenChangeEventCallback',
1312
+ 'callCanvasResizedCallback',
4079
1313
  'JSEvents_requestFullscreen',
4080
1314
  'JSEvents_resizeCanvasForFullscreen',
4081
1315
  'registerRestoreOldStyle',
4082
1316
  'hideEverythingExceptGivenElement',
4083
1317
  'restoreHiddenElements',
4084
1318
  'setLetterbox',
1319
+ 'currentFullscreenStrategy',
4085
1320
  'softFullscreenResizeWebGLRenderTarget',
4086
1321
  'doRequestFullscreen',
4087
1322
  'fillPointerlockChangeEventData',
@@ -4105,6 +1340,7 @@ async function createWasm() {
4105
1340
  'wasiRightsToMuslOFlags',
4106
1341
  'wasiOFlagsToMuslOFlags',
4107
1342
  'safeSetTimeout',
1343
+ 'safeClearTimeout',
4108
1344
  'setImmediateWrapped',
4109
1345
  'safeRequestAnimationFrame',
4110
1346
  'clearImmediateWrapped',
@@ -4112,6 +1348,7 @@ async function createWasm() {
4112
1348
  'registerPreMainLoop',
4113
1349
  'getPromise',
4114
1350
  'makePromise',
1351
+ 'addPromise',
4115
1352
  'idsToPromises',
4116
1353
  'makePromiseCallback',
4117
1354
  'Browser_asyncPrepareDataCounter',
@@ -4121,6 +1358,12 @@ async function createWasm() {
4121
1358
  'addDays',
4122
1359
  'getSocketFromFD',
4123
1360
  'getSocketAddress',
1361
+ 'FS_createPreloadedFile',
1362
+ 'FS_preloadFile',
1363
+ 'FS_modeStringToFlags',
1364
+ 'FS_getMode',
1365
+ 'FS_fileDataToTypedArray',
1366
+ 'FS_stdin_getChar',
4124
1367
  'FS_mkdirTree',
4125
1368
  '_setNetworkCallback',
4126
1369
  ];
@@ -4133,17 +1376,17 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
4133
1376
  'callMain',
4134
1377
  'abort',
4135
1378
  'wasmExports',
4136
- 'HEAPF32',
4137
- 'HEAPF64',
1379
+ 'INT53_MAX',
1380
+ 'INT53_MIN',
1381
+ 'bigintToI53Checked',
4138
1382
  'HEAP8',
4139
1383
  'HEAP16',
4140
1384
  'HEAPU16',
4141
1385
  'HEAP32',
1386
+ 'HEAPF32',
1387
+ 'HEAPF64',
4142
1388
  'HEAP64',
4143
1389
  'HEAPU64',
4144
- 'INT53_MAX',
4145
- 'INT53_MIN',
4146
- 'bigintToI53Checked',
4147
1390
  'stackSave',
4148
1391
  'stackRestore',
4149
1392
  'stackAlloc',
@@ -4153,31 +1396,23 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
4153
1396
  'growMemory',
4154
1397
  'ENV',
4155
1398
  'ERRNO_CODES',
4156
- 'strError',
4157
1399
  'DNS',
4158
1400
  'Protocols',
4159
- 'Sockets',
4160
1401
  'timers',
4161
1402
  'warnOnce',
4162
1403
  'readEmAsmArgsArray',
4163
1404
  'getExecutableName',
1405
+ 'getWasmTableEntry',
4164
1406
  'handleException',
4165
1407
  'keepRuntimeAlive',
4166
1408
  'callUserCallback',
4167
1409
  'maybeExit',
4168
- 'asyncLoad',
4169
1410
  'alignMemory',
4170
- 'mmapAlloc',
4171
1411
  'wasmTable',
4172
- 'getUniqueRunDependency',
4173
1412
  'noExitRuntime',
4174
- 'addRunDependency',
4175
- 'removeRunDependency',
4176
1413
  'ccall',
4177
1414
  'freeTableIndexes',
4178
1415
  'functionsInTableMap',
4179
- 'setValue',
4180
- 'getValue',
4181
1416
  'PATH',
4182
1417
  'PATH_FS',
4183
1418
  'UTF8Decoder',
@@ -4186,33 +1421,26 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
4186
1421
  'stringToUTF8Array',
4187
1422
  'stringToUTF8',
4188
1423
  'lengthBytesUTF8',
4189
- 'intArrayFromString',
4190
1424
  'UTF16Decoder',
4191
1425
  'stringToUTF8OnStack',
4192
1426
  'writeArrayToMemory',
4193
1427
  'JSEvents',
4194
1428
  'specialHTMLTargets',
4195
1429
  'findCanvasEventTarget',
4196
- 'currentFullscreenStrategy',
4197
1430
  'restoreOldWindowedStyle',
4198
1431
  'UNWIND_CACHE',
4199
1432
  'ExitStatus',
4200
1433
  'getEnvStrings',
4201
- 'doReadv',
4202
- 'doWritev',
1434
+ 'flush_NO_FILESYSTEM',
4203
1435
  'initRandomFill',
4204
1436
  'randomFill',
4205
1437
  'emSetImmediate',
4206
- 'emClearImmediate_deps',
4207
1438
  'emClearImmediate',
4208
1439
  'promiseMap',
4209
1440
  'Browser',
4210
1441
  'requestFullscreen',
4211
- 'requestFullScreen',
4212
1442
  'setCanvasSize',
4213
- 'getUserMedia',
4214
1443
  'createContext',
4215
- 'getPreloadedImageData__data',
4216
1444
  'wget',
4217
1445
  'MONTH_DAYS_REGULAR',
4218
1446
  'MONTH_DAYS_LEAP',
@@ -4220,28 +1448,12 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
4220
1448
  'MONTH_DAYS_LEAP_CUMULATIVE',
4221
1449
  'SYSCALLS',
4222
1450
  'preloadPlugins',
4223
- 'FS_createPreloadedFile',
4224
- 'FS_preloadFile',
4225
- 'FS_modeStringToFlags',
4226
- 'FS_getMode',
4227
1451
  'FS_stdin_getChar_buffer',
4228
- 'FS_stdin_getChar',
4229
1452
  'FS_unlink',
4230
1453
  'FS_createPath',
4231
1454
  'FS_createDevice',
4232
1455
  'FS_readFile',
4233
1456
  'FS',
4234
- 'FS_root',
4235
- 'FS_mounts',
4236
- 'FS_devices',
4237
- 'FS_streams',
4238
- 'FS_nextInode',
4239
- 'FS_nameTable',
4240
- 'FS_currentPath',
4241
- 'FS_initialized',
4242
- 'FS_ignorePermissions',
4243
- 'FS_filesystems',
4244
- 'FS_syncFSRequests',
4245
1457
  'FS_lookupPath',
4246
1458
  'FS_getPath',
4247
1459
  'FS_hashName',
@@ -4273,7 +1485,6 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
4273
1485
  'FS_closeStream',
4274
1486
  'FS_dupStream',
4275
1487
  'FS_doSetAttr',
4276
- 'FS_chrdev_stream_ops',
4277
1488
  'FS_major',
4278
1489
  'FS_minor',
4279
1490
  'FS_makedev',
@@ -4292,6 +1503,7 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
4292
1503
  'FS_mkdir',
4293
1504
  'FS_mkdev',
4294
1505
  'FS_symlink',
1506
+ 'FS_link',
4295
1507
  'FS_rename',
4296
1508
  'FS_rmdir',
4297
1509
  'FS_readdir',
@@ -4330,18 +1542,10 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
4330
1542
  'FS_staticInit',
4331
1543
  'FS_init',
4332
1544
  'FS_quit',
4333
- 'FS_findObject',
4334
- 'FS_analyzePath',
4335
1545
  'FS_createFile',
4336
1546
  'FS_createDataFile',
4337
1547
  'FS_forceLoadFile',
4338
1548
  'FS_createLazyFile',
4339
- 'FS_absolutePath',
4340
- 'FS_createFolder',
4341
- 'FS_createLink',
4342
- 'FS_joinPath',
4343
- 'FS_mmapAlloc',
4344
- 'FS_standardizePath',
4345
1549
  'MEMFS',
4346
1550
  'TTY',
4347
1551
  'PIPEFS',
@@ -4357,45 +1561,21 @@ unexportedSymbols.forEach(unexportedRuntimeSymbol);
4357
1561
 
4358
1562
  function checkIncomingModuleAPI() {
4359
1563
  ignoredModuleProp('ENVIRONMENT');
4360
- ignoredModuleProp('GL_MAX_TEXTURE_IMAGE_UNITS');
4361
- ignoredModuleProp('SDL_canPlayWithWebAudio');
4362
- ignoredModuleProp('SDL_numSimultaneouslyQueuedBuffers');
4363
- ignoredModuleProp('INITIAL_MEMORY');
4364
- ignoredModuleProp('wasmMemory');
4365
1564
  ignoredModuleProp('arguments');
4366
- ignoredModuleProp('buffer');
4367
1565
  ignoredModuleProp('canvas');
4368
- ignoredModuleProp('doNotCaptureKeyboard');
4369
1566
  ignoredModuleProp('dynamicLibraries');
4370
1567
  ignoredModuleProp('elementPointerLock');
4371
- ignoredModuleProp('extraStackTrace');
4372
- ignoredModuleProp('forcedAspectRatio');
4373
1568
  ignoredModuleProp('instantiateWasm');
4374
- ignoredModuleProp('keyboardListeningElement');
4375
- ignoredModuleProp('freePreloadedMediaOnUse');
4376
- ignoredModuleProp('loadSplitModule');
4377
1569
  ignoredModuleProp('locateFile');
4378
- ignoredModuleProp('logReadFiles');
4379
- ignoredModuleProp('mainScriptUrlOrBlob');
4380
- ignoredModuleProp('mem');
4381
1570
  ignoredModuleProp('monitorRunDependencies');
4382
1571
  ignoredModuleProp('noExitRuntime');
4383
1572
  ignoredModuleProp('noInitialRun');
4384
1573
  ignoredModuleProp('onAbort');
4385
- ignoredModuleProp('onCustomMessage');
4386
1574
  ignoredModuleProp('onExit');
4387
- ignoredModuleProp('onFree');
4388
- ignoredModuleProp('onFullScreen');
4389
- ignoredModuleProp('onMalloc');
4390
- ignoredModuleProp('onRealloc');
4391
1575
  ignoredModuleProp('onRuntimeInitialized');
4392
- ignoredModuleProp('postMainLoop');
4393
1576
  ignoredModuleProp('postRun');
4394
1577
  ignoredModuleProp('preInit');
4395
- ignoredModuleProp('preMainLoop');
4396
1578
  ignoredModuleProp('preRun');
4397
- ignoredModuleProp('preinitializedWebGLContext');
4398
- ignoredModuleProp('preloadPlugins');
4399
1579
  ignoredModuleProp('print');
4400
1580
  ignoredModuleProp('printErr');
4401
1581
  ignoredModuleProp('setStatus');
@@ -4405,9 +1585,34 @@ function checkIncomingModuleAPI() {
4405
1585
  ignoredModuleProp('stdout');
4406
1586
  ignoredModuleProp('thisProgram');
4407
1587
  ignoredModuleProp('wasm');
4408
- ignoredModuleProp('wasmBinary');
4409
1588
  ignoredModuleProp('websocket');
4410
1589
  ignoredModuleProp('fetchSettings');
1590
+ ignoredModuleProp('logReadFiles');
1591
+ ignoredModuleProp('loadSplitModule');
1592
+ ignoredModuleProp('onMalloc');
1593
+ ignoredModuleProp('onRealloc');
1594
+ ignoredModuleProp('onFree');
1595
+ ignoredModuleProp('onSbrkGrow');
1596
+ ignoredModuleProp('onCOSCacheHit');
1597
+ ignoredModuleProp('onCOSCacheMiss');
1598
+ ignoredModuleProp('onCOSStore');
1599
+ ignoredModuleProp('GL_MAX_TEXTURE_IMAGE_UNITS');
1600
+ ignoredModuleProp('SDL_canPlayWithWebAudio');
1601
+ ignoredModuleProp('SDL_numSimultaneouslyQueuedBuffers');
1602
+ ignoredModuleProp('freePreloadedMediaOnUse');
1603
+ ignoredModuleProp('preinitializedWebGLContext');
1604
+ ignoredModuleProp('keyboardListeningElement');
1605
+ ignoredModuleProp('doNotCaptureKeyboard');
1606
+ ignoredModuleProp('extraStackTrace');
1607
+ ignoredModuleProp('preloadPlugins');
1608
+ ignoredModuleProp('preMainLoop');
1609
+ ignoredModuleProp('postMainLoop');
1610
+ ignoredModuleProp('forcedAspectRatio');
1611
+ ignoredModuleProp('mainScriptUrlOrBlob');
1612
+ ignoredModuleProp('onFullScreen');
1613
+ ignoredModuleProp('INITIAL_MEMORY');
1614
+ ignoredModuleProp('wasmMemory');
1615
+ ignoredModuleProp('wasmBinary');
4411
1616
  }
4412
1617
 
4413
1618
  // Imports from the Wasm binary.
@@ -4419,6 +1624,7 @@ var ___funcs_on_exit = makeInvalidEarlyAccess('___funcs_on_exit');
4419
1624
  var _fflush = makeInvalidEarlyAccess('_fflush');
4420
1625
  var __emscripten_timeout = makeInvalidEarlyAccess('__emscripten_timeout');
4421
1626
  var _strerror = makeInvalidEarlyAccess('_strerror');
1627
+ var _setThrew = makeInvalidEarlyAccess('_setThrew');
4422
1628
  var __emscripten_stack_restore = makeInvalidEarlyAccess('__emscripten_stack_restore');
4423
1629
  var __emscripten_stack_alloc = makeInvalidEarlyAccess('__emscripten_stack_alloc');
4424
1630
  var _emscripten_stack_get_current = makeInvalidEarlyAccess('_emscripten_stack_get_current');
@@ -4428,31 +1634,33 @@ var wasmMemory = makeInvalidEarlyAccess('wasmMemory');
4428
1634
  var wasmTable = makeInvalidEarlyAccess('wasmTable');
4429
1635
 
4430
1636
  function assignWasmExports(wasmExports) {
4431
- assert(typeof wasmExports['xml2wbxml'] != 'undefined', 'missing Wasm export: xml2wbxml');
4432
- _xml2wbxml = Module['_xml2wbxml'] = createExportWrapper('xml2wbxml', 8);
4433
- assert(typeof wasmExports['free'] != 'undefined', 'missing Wasm export: free');
4434
- _free = Module['_free'] = createExportWrapper('free', 1);
4435
- assert(typeof wasmExports['wbxml2xml'] != 'undefined', 'missing Wasm export: wbxml2xml');
4436
- _wbxml2xml = Module['_wbxml2xml'] = createExportWrapper('wbxml2xml', 9);
4437
- assert(typeof wasmExports['malloc'] != 'undefined', 'missing Wasm export: malloc');
4438
- _malloc = Module['_malloc'] = createExportWrapper('malloc', 1);
4439
- assert(typeof wasmExports['__funcs_on_exit'] != 'undefined', 'missing Wasm export: __funcs_on_exit');
4440
- ___funcs_on_exit = createExportWrapper('__funcs_on_exit', 0);
4441
- assert(typeof wasmExports['fflush'] != 'undefined', 'missing Wasm export: fflush');
4442
- _fflush = createExportWrapper('fflush', 1);
4443
- assert(typeof wasmExports['_emscripten_timeout'] != 'undefined', 'missing Wasm export: _emscripten_timeout');
4444
- __emscripten_timeout = createExportWrapper('_emscripten_timeout', 2);
4445
- assert(typeof wasmExports['strerror'] != 'undefined', 'missing Wasm export: strerror');
4446
- _strerror = createExportWrapper('strerror', 1);
4447
- assert(typeof wasmExports['_emscripten_stack_restore'] != 'undefined', 'missing Wasm export: _emscripten_stack_restore');
1637
+ assert(typeof wasmExports['xml2wbxml'] !== 'undefined', 'missing Wasm export: xml2wbxml');
1638
+ assert(typeof wasmExports['free'] !== 'undefined', 'missing Wasm export: free');
1639
+ assert(typeof wasmExports['wbxml2xml'] !== 'undefined', 'missing Wasm export: wbxml2xml');
1640
+ assert(typeof wasmExports['malloc'] !== 'undefined', 'missing Wasm export: malloc');
1641
+ assert(typeof wasmExports['__funcs_on_exit'] !== 'undefined', 'missing Wasm export: __funcs_on_exit');
1642
+ assert(typeof wasmExports['fflush'] !== 'undefined', 'missing Wasm export: fflush');
1643
+ assert(typeof wasmExports['_emscripten_timeout'] !== 'undefined', 'missing Wasm export: _emscripten_timeout');
1644
+ assert(typeof wasmExports['strerror'] !== 'undefined', 'missing Wasm export: strerror');
1645
+ assert(typeof wasmExports['setThrew'] !== 'undefined', 'missing Wasm export: setThrew');
1646
+ assert(typeof wasmExports['_emscripten_stack_restore'] !== 'undefined', 'missing Wasm export: _emscripten_stack_restore');
1647
+ assert(typeof wasmExports['_emscripten_stack_alloc'] !== 'undefined', 'missing Wasm export: _emscripten_stack_alloc');
1648
+ assert(typeof wasmExports['emscripten_stack_get_current'] !== 'undefined', 'missing Wasm export: emscripten_stack_get_current');
1649
+ assert(typeof wasmExports['memory'] !== 'undefined', 'missing Wasm export: memory');
1650
+ assert(typeof wasmExports['__indirect_function_table'] !== 'undefined', 'missing Wasm export: __indirect_function_table');
1651
+ _xml2wbxml = Module['_xml2wbxml'] = createExportWrapper('xml2wbxml', wasmExports['xml2wbxml'], 8);
1652
+ _free = Module['_free'] = createExportWrapper('free', wasmExports['free'], 1);
1653
+ _wbxml2xml = Module['_wbxml2xml'] = createExportWrapper('wbxml2xml', wasmExports['wbxml2xml'], 9);
1654
+ _malloc = Module['_malloc'] = createExportWrapper('malloc', wasmExports['malloc'], 1);
1655
+ ___funcs_on_exit = createExportWrapper('__funcs_on_exit', wasmExports['__funcs_on_exit'], 0);
1656
+ _fflush = createExportWrapper('fflush', wasmExports['fflush'], 1);
1657
+ __emscripten_timeout = createExportWrapper('_emscripten_timeout', wasmExports['_emscripten_timeout'], 2);
1658
+ _strerror = createExportWrapper('strerror', wasmExports['strerror'], 1);
1659
+ _setThrew = createExportWrapper('setThrew', wasmExports['setThrew'], 2);
4448
1660
  __emscripten_stack_restore = wasmExports['_emscripten_stack_restore'];
4449
- assert(typeof wasmExports['_emscripten_stack_alloc'] != 'undefined', 'missing Wasm export: _emscripten_stack_alloc');
4450
1661
  __emscripten_stack_alloc = wasmExports['_emscripten_stack_alloc'];
4451
- assert(typeof wasmExports['emscripten_stack_get_current'] != 'undefined', 'missing Wasm export: emscripten_stack_get_current');
4452
1662
  _emscripten_stack_get_current = wasmExports['emscripten_stack_get_current'];
4453
- assert(typeof wasmExports['memory'] != 'undefined', 'missing Wasm export: memory');
4454
1663
  memory = wasmMemory = Module['wasmMemory'] = wasmExports['memory'];
4455
- assert(typeof wasmExports['__indirect_function_table'] != 'undefined', 'missing Wasm export: __indirect_function_table');
4456
1664
  __indirect_function_table = wasmTable = wasmExports['__indirect_function_table'];
4457
1665
  }
4458
1666
 
@@ -4462,8 +1670,6 @@ var wasmImports = {
4462
1670
  /** @export */
4463
1671
  __call_sighandler: ___call_sighandler,
4464
1672
  /** @export */
4465
- __syscall_openat: ___syscall_openat,
4466
- /** @export */
4467
1673
  _abort_js: __abort_js,
4468
1674
  /** @export */
4469
1675
  _emscripten_runtime_keepalive_clear: __emscripten_runtime_keepalive_clear,
@@ -4480,13 +1686,13 @@ var wasmImports = {
4480
1686
  /** @export */
4481
1687
  fd_close: _fd_close,
4482
1688
  /** @export */
4483
- fd_read: _fd_read,
4484
- /** @export */
4485
1689
  fd_seek: _fd_seek,
4486
1690
  /** @export */
4487
1691
  fd_write: _fd_write,
4488
1692
  /** @export */
4489
- proc_exit: _proc_exit
1693
+ proc_exit: _proc_exit,
1694
+ /** @export */
1695
+ random_get: _random_get
4490
1696
  };
4491
1697
 
4492
1698
 
@@ -4495,70 +1701,33 @@ var wasmImports = {
4495
1701
 
4496
1702
  var calledRun;
4497
1703
 
4498
- function run() {
4499
-
4500
- if (runDependencies > 0) {
4501
- dependenciesFulfilled = run;
4502
- return;
4503
- }
1704
+ async function run() {
1705
+ assert(!calledRun);
1706
+ calledRun = true;
4504
1707
 
4505
1708
  preRun();
4506
1709
 
4507
- // a preRun added a dependency, run will be called later
4508
- if (runDependencies > 0) {
4509
- dependenciesFulfilled = run;
4510
- return;
4511
- }
4512
-
4513
- function doRun() {
4514
- // run may have just been called through dependencies being fulfilled just in this very frame,
4515
- // or while the async setStatus time below was happening
4516
- assert(!calledRun);
4517
- calledRun = true;
4518
- Module['calledRun'] = true;
4519
-
4520
- if (ABORT) return;
1710
+ if (ABORT) return;
4521
1711
 
4522
- initRuntime();
1712
+ initRuntime();
4523
1713
 
4524
- readyPromiseResolve?.(Module);
1714
+ assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');
4525
1715
 
4526
- assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');
4527
-
4528
- postRun();
4529
- }
4530
-
4531
- {
4532
- doRun();
4533
- }
1716
+ postRun();
4534
1717
  }
4535
1718
 
4536
1719
  var wasmExports;
4537
1720
 
4538
1721
  // In modularize mode the generated code is within a factory function so we
4539
1722
  // can use await here (since it's not top-level-await).
4540
- wasmExports = await (createWasm());
4541
-
4542
- run();
1723
+ wasmExports = await createWasm();
1724
+ await run();
4543
1725
 
4544
1726
  // end include: postamble.js
4545
1727
 
4546
1728
  // include: postamble_modularize.js
4547
1729
  // In MODULARIZE mode we wrap the generated code in a factory function
4548
1730
  // and return either the Module itself, or a promise of the module.
4549
- //
4550
- // We assign to the `moduleRtn` global here and configure closure to see
4551
- // this as and extern so it won't get minified.
4552
-
4553
- if (runtimeInitialized) {
4554
- moduleRtn = Module;
4555
- } else {
4556
- // Set up the promise that indicates the Module is initialized
4557
- moduleRtn = new Promise((resolve, reject) => {
4558
- readyPromiseResolve = resolve;
4559
- readyPromiseReject = reject;
4560
- });
4561
- }
4562
1731
 
4563
1732
  // Assertion for attempting to access module properties on the incoming
4564
1733
  // moduleArg. In the past we used this object as the prototype of the module
@@ -4579,7 +1748,7 @@ for (const prop of Object.keys(Module)) {
4579
1748
 
4580
1749
 
4581
1750
 
4582
- return moduleRtn;
1751
+ return Module;
4583
1752
  }
4584
1753
 
4585
1754
  // Export using a UMD style export, or ES6 exports if selected