funicular 0.3.0 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +486 -1
- data/demo/local_notes.html +207 -0
- data/demo/test_chartjs.html +9 -9
- data/demo/test_component.html +8 -8
- data/demo/test_error_boundary.html +44 -41
- data/demo/test_router.html +48 -48
- data/demo/tic-tac-toe.html +25 -25
- data/docs/architecture.md +227 -12
- data/docs/local_database.md +1035 -0
- data/lib/funicular/assets/funicular.rb +14 -0
- data/lib/funicular/configuration.rb +65 -0
- data/lib/funicular/epoch_header.rb +69 -0
- data/lib/funicular/epoch_stamping.rb +66 -0
- data/lib/funicular/helpers/picoruby_helper.rb +96 -1
- data/lib/funicular/railtie.rb +30 -0
- data/lib/funicular/schema.rb +45 -12
- data/lib/funicular/session_epoch.rb +110 -0
- data/lib/funicular/ssr/runtime.rb +58 -12
- data/lib/funicular/ssr.rb +25 -0
- data/lib/funicular/testing/node_runner.mjs +19 -0
- data/lib/funicular/testing.rb +47 -0
- data/lib/funicular/vendor/mrbc/VERSION +1 -1
- data/lib/funicular/vendor/mrbc/mrbc.js +655 -574
- data/lib/funicular/vendor/mrbc/mrbc.wasm +0 -0
- data/lib/funicular/vendor/picoruby/VERSION +1 -1
- data/lib/funicular/vendor/picoruby/debug/picoruby.js +800 -530
- data/lib/funicular/vendor/picoruby/debug/picoruby.wasm +0 -0
- data/lib/funicular/vendor/picoruby/dist/picoruby.js +2 -2
- data/lib/funicular/vendor/picoruby/dist/picoruby.wasm +0 -0
- data/lib/funicular/vendor/picoruby-test-node/VERSION +1 -1
- data/lib/funicular/vendor/picoruby-test-node/picoruby.js +2 -6909
- data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm +0 -0
- data/lib/funicular/version.rb +1 -1
- data/lib/funicular.rb +1 -0
- data/lib/generators/funicular/chat/templates/funicular_chat_component.rb.tt +37 -38
- data/lib/tasks/funicular.rake +10 -2
- data/minitest/callback_error_visibility_test.rb +48 -0
- data/minitest/configuration_test.rb +78 -0
- data/minitest/dsl_test.rb +264 -0
- data/minitest/epoch_header_test.rb +149 -0
- data/minitest/epoch_stamping_test.rb +225 -0
- data/minitest/fixtures/funicular_app/components/greeting_component.rb +5 -5
- data/minitest/fixtures/funicular_app/components/probe_component.rb +15 -0
- data/minitest/form_for_test.rb +2 -2
- data/minitest/hydration_test.rb +2 -2
- data/minitest/navigation_guard_test.rb +65 -0
- data/minitest/picoruby_helper_test.rb +236 -0
- data/minitest/schema_test.rb +47 -0
- data/minitest/session_epoch_test.rb +122 -0
- data/minitest/sig_tags_test.rb +30 -0
- data/minitest/ssr_database_test.rb +78 -0
- data/minitest/ssr_reload_test.rb +106 -0
- data/minitest/ssr_test.rb +41 -0
- data/minitest/testing_ensure_compiled_test.rb +52 -0
- data/minitest/validations_test.rb +35 -5
- data/minitest/view_context_test.rb +15 -15
- data/mrbgem.rake +2 -0
- data/mrblib/0_tags.rb +62 -0
- data/mrblib/cable.rb +1 -1
- data/mrblib/component.rb +226 -24
- data/mrblib/db.rb +3116 -0
- data/mrblib/error_boundary.rb +25 -19
- data/mrblib/file_upload.rb +17 -7
- data/mrblib/form_builder.rb +10 -10
- data/mrblib/funicular.rb +136 -17
- data/mrblib/http.rb +84 -107
- data/mrblib/model.rb +1178 -23
- data/mrblib/relation.rb +342 -0
- data/mrblib/router.rb +45 -4
- data/mrblib/styles.rb +122 -12
- data/mrblib/view_context.rb +3 -32
- data/sig/component.rbs +25 -4
- data/sig/db.rbs +328 -0
- data/sig/error_boundary.rbs +4 -4
- data/sig/funicular.rbs +5 -0
- data/sig/http.rbs +8 -21
- data/sig/model.rbs +101 -7
- data/sig/relation.rbs +44 -0
- data/sig/router.rbs +1 -0
- data/sig/styles.rbs +19 -5
- data/sig/tags.rbs +54 -0
- data/sig/view_context.rbs +47 -34
- metadata +23 -2
- data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm.map +0 -1
|
@@ -17,9 +17,14 @@
|
|
|
17
17
|
|
|
18
18
|
// Note: We use a typeof check here instead of optional chaining using
|
|
19
19
|
// globalThis because older browsers might not have globalThis defined.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
|
|
21
|
+
// We skip the node version checking when running on Bun/Deno since the node
|
|
22
|
+
// version they report doesn't seem to be useful.
|
|
23
|
+
if (typeof process !== 'undefined' && !process.versions?.bun && typeof Deno == "undefined") {
|
|
24
|
+
var currentNodeVersion = process.versions?.node ? humanReadableVersionToPacked(process.versions.node) : TARGET_NOT_SUPPORTED;
|
|
25
|
+
if (currentNodeVersion < 180300) {
|
|
26
|
+
throw new Error(`This emscripten-generated code requires node v${ packedVersionToHumanReadable(180300) } (detected v${packedVersionToHumanReadable(currentNodeVersion)})`);
|
|
27
|
+
}
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
var userAgent = typeof navigator !== 'undefined' && navigator.userAgent;
|
|
@@ -74,7 +79,7 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR
|
|
|
74
79
|
// refer to Module (if they choose; they can also define Module)
|
|
75
80
|
|
|
76
81
|
|
|
77
|
-
var
|
|
82
|
+
var programArgs = [];
|
|
78
83
|
var thisProgram = './this.program';
|
|
79
84
|
var quit_ = (status, toThrow) => {
|
|
80
85
|
throw toThrow;
|
|
@@ -134,7 +139,7 @@ readAsync = async (filename, binary = true) => {
|
|
|
134
139
|
thisProgram = process.argv[1].replace(/\\/g, '/');
|
|
135
140
|
}
|
|
136
141
|
|
|
137
|
-
|
|
142
|
+
programArgs = process.argv.slice(2);
|
|
138
143
|
|
|
139
144
|
// MODULARIZE will export the module in the proper place outside, we don't need to export here
|
|
140
145
|
if (typeof module != 'undefined') {
|
|
@@ -224,7 +229,7 @@ var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
|
|
|
224
229
|
// perform assertions in shell.js after we set up out() and err(), as otherwise
|
|
225
230
|
// if an assertion fails it cannot print the message
|
|
226
231
|
|
|
227
|
-
assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time
|
|
232
|
+
assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time (add `shell` to `-sENVIRONMENT` to enable)');
|
|
228
233
|
|
|
229
234
|
// end include: shell.js
|
|
230
235
|
|
|
@@ -288,45 +293,12 @@ function _free() {
|
|
|
288
293
|
var isFileURI = (filename) => filename.startsWith('file://');
|
|
289
294
|
|
|
290
295
|
// include: runtime_common.js
|
|
291
|
-
// include: runtime_stack_check.js
|
|
292
|
-
// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
|
|
293
|
-
function writeStackCookie() {
|
|
294
|
-
var max = _emscripten_stack_get_end();
|
|
295
|
-
assert((max & 3) == 0);
|
|
296
|
-
// If the stack ends at address zero we write our cookies 4 bytes into the
|
|
297
|
-
// stack. This prevents interference with SAFE_HEAP and ASAN which also
|
|
298
|
-
// monitor writes to address zero.
|
|
299
|
-
if (max == 0) {
|
|
300
|
-
max += 4;
|
|
301
|
-
}
|
|
302
|
-
// The stack grow downwards towards _emscripten_stack_get_end.
|
|
303
|
-
// We write cookies to the final two words in the stack and detect if they are
|
|
304
|
-
// ever overwritten.
|
|
305
|
-
HEAPU32[((max)>>2)] = 0x02135467;
|
|
306
|
-
HEAPU32[(((max)+(4))>>2)] = 0x89BACDFE;
|
|
307
|
-
// Also test the global address 0 for integrity.
|
|
308
|
-
HEAPU32[((0)>>2)] = 1668509029;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function checkStackCookie() {
|
|
312
|
-
if (ABORT) return;
|
|
313
|
-
var max = _emscripten_stack_get_end();
|
|
314
|
-
// See writeStackCookie().
|
|
315
|
-
if (max == 0) {
|
|
316
|
-
max += 4;
|
|
317
|
-
}
|
|
318
|
-
var cookie1 = HEAPU32[((max)>>2)];
|
|
319
|
-
var cookie2 = HEAPU32[(((max)+(4))>>2)];
|
|
320
|
-
if (cookie1 != 0x02135467 || cookie2 != 0x89BACDFE) {
|
|
321
|
-
abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords 0x89BACDFE and 0x2135467, but received ${ptrToString(cookie2)} ${ptrToString(cookie1)}`);
|
|
322
|
-
}
|
|
323
|
-
// Also test the global address 0 for integrity.
|
|
324
|
-
if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) {
|
|
325
|
-
abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
// end include: runtime_stack_check.js
|
|
329
296
|
// include: runtime_exceptions.js
|
|
297
|
+
// Base Emscripten EH error class
|
|
298
|
+
class EmscriptenEH {}
|
|
299
|
+
|
|
300
|
+
class EmscriptenSjLj extends EmscriptenEH {}
|
|
301
|
+
|
|
330
302
|
// end include: runtime_exceptions.js
|
|
331
303
|
// include: runtime_debug.js
|
|
332
304
|
var runtimeDebug = true; // Switch to false at runtime to disable logging at the right times
|
|
@@ -348,15 +320,31 @@ function dbg(...args) {
|
|
|
348
320
|
})();
|
|
349
321
|
|
|
350
322
|
function consumedModuleProp(prop) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
323
|
+
var value = Module[prop];
|
|
324
|
+
var 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'`;
|
|
325
|
+
if (Array.isArray(value)) {
|
|
326
|
+
value = new Proxy(value, {
|
|
327
|
+
set(target, key, val) {
|
|
328
|
+
abort(msg);
|
|
329
|
+
return false;
|
|
330
|
+
},
|
|
331
|
+
defineProperty(target, key, descriptor) {
|
|
332
|
+
abort(msg);
|
|
333
|
+
return false;
|
|
334
|
+
},
|
|
335
|
+
deleteProperty(target, key) {
|
|
336
|
+
abort(msg);
|
|
337
|
+
return false;
|
|
357
338
|
}
|
|
358
339
|
});
|
|
359
340
|
}
|
|
341
|
+
Object.defineProperty(Module, prop, {
|
|
342
|
+
configurable: true,
|
|
343
|
+
get() { return value; },
|
|
344
|
+
set() {
|
|
345
|
+
abort(msg);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
360
348
|
}
|
|
361
349
|
|
|
362
350
|
function makeInvalidEarlyAccess(name) {
|
|
@@ -453,32 +441,52 @@ function unexportedRuntimeSymbol(sym) {
|
|
|
453
441
|
}
|
|
454
442
|
|
|
455
443
|
// end include: runtime_debug.js
|
|
444
|
+
// include: runtime_stack_check.js
|
|
445
|
+
const stackCookie1 = 0x02135467;
|
|
446
|
+
const stackCookie2 = 0x89BACDFE;
|
|
447
|
+
|
|
448
|
+
// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
|
|
449
|
+
function writeStackCookie() {
|
|
450
|
+
var max = _emscripten_stack_get_end();
|
|
451
|
+
assert((max & 3) == 0);
|
|
452
|
+
// If the stack ends at address zero we write our cookies 4 bytes into the
|
|
453
|
+
// stack. This prevents interference with SAFE_HEAP and ASAN which also
|
|
454
|
+
// monitor writes to address zero.
|
|
455
|
+
if (max == 0) {
|
|
456
|
+
max += 4;
|
|
457
|
+
}
|
|
458
|
+
// The stack grow downwards towards _emscripten_stack_get_end.
|
|
459
|
+
// We write cookies to the final two words in the stack and detect if they are
|
|
460
|
+
// ever overwritten.
|
|
461
|
+
HEAPU32[((max)>>2)] = stackCookie1;
|
|
462
|
+
HEAPU32[(((max)+(4))>>2)] = stackCookie2;
|
|
463
|
+
// Also test the global address 0 for integrity.
|
|
464
|
+
HEAPU32[((0)>>2)] = 1668509029;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function u32ToHexString(num) {
|
|
468
|
+
return '0x' + (num >>> 0).toString(16).padStart(8, '0');
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function checkStackCookie() {
|
|
472
|
+
if (ABORT) return;
|
|
473
|
+
var max = _emscripten_stack_get_end();
|
|
474
|
+
// See writeStackCookie().
|
|
475
|
+
if (max == 0) {
|
|
476
|
+
max += 4;
|
|
477
|
+
}
|
|
478
|
+
var val1 = HEAPU32[((max)>>2)];
|
|
479
|
+
var val2 = HEAPU32[(((max)+(4))>>2)];
|
|
480
|
+
if (val1 != stackCookie1 || val2 != stackCookie2) {
|
|
481
|
+
abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords ${u32ToHexString(stackCookie2)} and ${u32ToHexString(stackCookie1)}, but received ${u32ToHexString(val2)} ${u32ToHexString(val1)}`);
|
|
482
|
+
}
|
|
483
|
+
// Also test the global address 0 for integrity.
|
|
484
|
+
if (HEAPU32[((0)>>2)] != 0x63736d65 /* 'emsc' */) {
|
|
485
|
+
abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
// end include: runtime_stack_check.js
|
|
456
489
|
// Memory management
|
|
457
|
-
var
|
|
458
|
-
/** @type {!Int8Array} */
|
|
459
|
-
HEAP8,
|
|
460
|
-
/** @type {!Uint8Array} */
|
|
461
|
-
HEAPU8,
|
|
462
|
-
/** @type {!Int16Array} */
|
|
463
|
-
HEAP16,
|
|
464
|
-
/** @type {!Uint16Array} */
|
|
465
|
-
HEAPU16,
|
|
466
|
-
/** @type {!Int32Array} */
|
|
467
|
-
HEAP32,
|
|
468
|
-
/** @type {!Uint32Array} */
|
|
469
|
-
HEAPU32,
|
|
470
|
-
/** @type {!Float32Array} */
|
|
471
|
-
HEAPF32,
|
|
472
|
-
/** @type {!Float64Array} */
|
|
473
|
-
HEAPF64;
|
|
474
|
-
|
|
475
|
-
// BigInt64Array type is not correctly defined in closure
|
|
476
|
-
var
|
|
477
|
-
/** not-@type {!BigInt64Array} */
|
|
478
|
-
HEAP64,
|
|
479
|
-
/* BigUint64Array type is not correctly defined in closure
|
|
480
|
-
/** not-@type {!BigUint64Array} */
|
|
481
|
-
HEAPU64;
|
|
482
490
|
|
|
483
491
|
var runtimeInitialized = false;
|
|
484
492
|
|
|
@@ -486,18 +494,27 @@ var runtimeExited = false;
|
|
|
486
494
|
|
|
487
495
|
|
|
488
496
|
|
|
497
|
+
// When ALLOW_MEMORY_GROWTH is enabled, the conversion from Wasm
|
|
498
|
+
// memory to ArrayBuffer requires some additional logic.
|
|
499
|
+
function getMemoryBuffer() {
|
|
500
|
+
return wasmMemory.buffer;
|
|
501
|
+
}
|
|
502
|
+
|
|
489
503
|
function updateMemoryViews() {
|
|
490
|
-
|
|
504
|
+
// If we already have a heap that is resizeable/growable buffer we don't
|
|
505
|
+
// need to do anything in updateMemoryViews.
|
|
506
|
+
if (HEAP8?.buffer?.resizable) return;
|
|
507
|
+
var b = getMemoryBuffer();
|
|
491
508
|
HEAP8 = new Int8Array(b);
|
|
492
509
|
HEAP16 = new Int16Array(b);
|
|
493
510
|
HEAPU8 = new Uint8Array(b);
|
|
494
|
-
|
|
511
|
+
|
|
495
512
|
HEAP32 = new Int32Array(b);
|
|
496
513
|
HEAPU32 = new Uint32Array(b);
|
|
497
|
-
|
|
498
|
-
|
|
514
|
+
|
|
515
|
+
|
|
499
516
|
HEAP64 = new BigInt64Array(b);
|
|
500
|
-
|
|
517
|
+
|
|
501
518
|
}
|
|
502
519
|
|
|
503
520
|
// include: memoryprofiler.js
|
|
@@ -507,11 +524,10 @@ assert(globalThis.Int32Array && globalThis.Float64Array && Int32Array.prototype.
|
|
|
507
524
|
'JS engine does not provide full typed array support');
|
|
508
525
|
|
|
509
526
|
function preRun() {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}
|
|
527
|
+
var preRun = Module['preRun'];
|
|
528
|
+
if (preRun) {
|
|
529
|
+
if (typeof preRun == 'function') preRun = [preRun];
|
|
530
|
+
onPreRuns.push(...preRun);
|
|
515
531
|
}
|
|
516
532
|
consumedModuleProp('preRun');
|
|
517
533
|
// Begin ATPRERUNS hooks
|
|
@@ -535,17 +551,17 @@ TTY.init();
|
|
|
535
551
|
// Begin ATPOSTCTORS hooks
|
|
536
552
|
FS.ignorePermissions = false;
|
|
537
553
|
// End ATPOSTCTORS hooks
|
|
538
|
-
}
|
|
539
554
|
|
|
540
|
-
function preMain() {
|
|
541
555
|
checkStackCookie();
|
|
542
|
-
// No ATMAINS hooks
|
|
543
556
|
}
|
|
544
557
|
|
|
558
|
+
var runtimeExiting = false;
|
|
559
|
+
|
|
545
560
|
function exitRuntime() {
|
|
546
561
|
assert(!runtimeExited);
|
|
562
|
+
assert(!runtimeExiting, 'Re-entrant call to exitRuntime()! This can happen if an atexit() registered callback throws an exception.');
|
|
563
|
+
runtimeExiting = true;
|
|
547
564
|
checkStackCookie();
|
|
548
|
-
// PThreads reuse the runtime from the main thread.
|
|
549
565
|
___funcs_on_exit(); // Native atexit() functions
|
|
550
566
|
// Begin ATEXITS hooks
|
|
551
567
|
FS.quit();
|
|
@@ -556,13 +572,11 @@ TTY.shutdown();
|
|
|
556
572
|
|
|
557
573
|
function postRun() {
|
|
558
574
|
checkStackCookie();
|
|
559
|
-
// PThreads reuse the runtime from the main thread.
|
|
560
575
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
576
|
+
var postRun = Module['postRun'];
|
|
577
|
+
if (postRun) {
|
|
578
|
+
if (typeof postRun == 'function') postRun = [postRun];
|
|
579
|
+
onPostRuns.push(...postRun);
|
|
566
580
|
}
|
|
567
581
|
consumedModuleProp('postRun');
|
|
568
582
|
|
|
@@ -571,11 +585,13 @@ function postRun() {
|
|
|
571
585
|
// End ATPOSTRUNS hooks
|
|
572
586
|
}
|
|
573
587
|
|
|
574
|
-
/**
|
|
588
|
+
/**
|
|
589
|
+
* @param {string|number=} what
|
|
590
|
+
*/
|
|
575
591
|
function abort(what) {
|
|
576
592
|
Module['onAbort']?.(what);
|
|
577
593
|
|
|
578
|
-
what =
|
|
594
|
+
what = `Aborted(${what})`;
|
|
579
595
|
// TODO(sbc): Should we remove printing and leave it up to whoever
|
|
580
596
|
// catches the exception?
|
|
581
597
|
err(what);
|
|
@@ -604,15 +620,14 @@ function abort(what) {
|
|
|
604
620
|
throw e;
|
|
605
621
|
}
|
|
606
622
|
|
|
607
|
-
function createExportWrapper(name, nargs) {
|
|
623
|
+
function createExportWrapper(name, func, nargs) {
|
|
624
|
+
assert(func);
|
|
608
625
|
return (...args) => {
|
|
609
626
|
assert(runtimeInitialized, `native function \`${name}\` called before runtime initialization`);
|
|
610
627
|
assert(!runtimeExited, `native function \`${name}\` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)`);
|
|
611
|
-
var f = wasmExports[name];
|
|
612
|
-
assert(f, `exported native function \`${name}\` not found`);
|
|
613
628
|
// Only assert for too many arguments. Too few can be valid since the missing arguments will be zero filled.
|
|
614
629
|
assert(args.length <= nargs, `native function \`${name}\` called with ${args.length} args but expects ${nargs}`);
|
|
615
|
-
return
|
|
630
|
+
return func(...args);
|
|
616
631
|
};
|
|
617
632
|
}
|
|
618
633
|
|
|
@@ -623,9 +638,6 @@ function findWasmBinary() {
|
|
|
623
638
|
}
|
|
624
639
|
|
|
625
640
|
function getBinarySync(file) {
|
|
626
|
-
if (file == wasmBinaryFile && wasmBinary) {
|
|
627
|
-
return new Uint8Array(wasmBinary);
|
|
628
|
-
}
|
|
629
641
|
if (readBinary) {
|
|
630
642
|
return readBinary(file);
|
|
631
643
|
}
|
|
@@ -708,18 +720,15 @@ async function createWasm() {
|
|
|
708
720
|
// Load the wasm module and create an instance of using native support in the JS engine.
|
|
709
721
|
// handle a generated wasm instance, receiving its exports and
|
|
710
722
|
// performing other necessary setup
|
|
711
|
-
|
|
712
|
-
function receiveInstance(instance, module) {
|
|
723
|
+
function receiveInstance(instance) {
|
|
713
724
|
wasmExports = instance.exports;
|
|
714
725
|
|
|
715
726
|
assignWasmExports(wasmExports);
|
|
716
727
|
|
|
717
728
|
updateMemoryViews();
|
|
718
729
|
|
|
719
|
-
removeRunDependency('wasm-instantiate');
|
|
720
730
|
return wasmExports;
|
|
721
731
|
}
|
|
722
|
-
addRunDependency('wasm-instantiate');
|
|
723
732
|
|
|
724
733
|
// Prefer streaming instantiation if available.
|
|
725
734
|
// Async compilation can be confusing when an error on the page overwrites Module
|
|
@@ -744,15 +753,14 @@ async function createWasm() {
|
|
|
744
753
|
// performing.
|
|
745
754
|
// Also pthreads and wasm workers initialize the wasm instance through this
|
|
746
755
|
// path.
|
|
747
|
-
|
|
748
|
-
|
|
756
|
+
var instantiateWasm = Module['instantiateWasm'];
|
|
757
|
+
if (instantiateWasm) {
|
|
758
|
+
return new Promise((resolve) => {
|
|
749
759
|
try {
|
|
750
|
-
|
|
751
|
-
resolve(receiveInstance(inst, mod));
|
|
752
|
-
});
|
|
760
|
+
instantiateWasm(info, (inst) => resolve(receiveInstance(inst)));
|
|
753
761
|
} catch(e) {
|
|
754
762
|
err(`Module.instantiateWasm callback failed with error: ${e}`);
|
|
755
|
-
|
|
763
|
+
throw e;
|
|
756
764
|
}
|
|
757
765
|
});
|
|
758
766
|
}
|
|
@@ -776,6 +784,15 @@ async function createWasm() {
|
|
|
776
784
|
}
|
|
777
785
|
}
|
|
778
786
|
|
|
787
|
+
/** @type {!Int32Array} */
|
|
788
|
+
var HEAP32;
|
|
789
|
+
|
|
790
|
+
/** @type {!Int8Array} */
|
|
791
|
+
var HEAP8;
|
|
792
|
+
|
|
793
|
+
/** @type {!Uint32Array} */
|
|
794
|
+
var HEAPU32;
|
|
795
|
+
|
|
779
796
|
var callRuntimeCallbacks = (callbacks) => {
|
|
780
797
|
while (callbacks.length > 0) {
|
|
781
798
|
// Pass the module as the first argument.
|
|
@@ -788,122 +805,15 @@ async function createWasm() {
|
|
|
788
805
|
var onPreRuns = [];
|
|
789
806
|
var addOnPreRun = (cb) => onPreRuns.push(cb);
|
|
790
807
|
|
|
791
|
-
var runDependencies = 0;
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
var dependenciesFulfilled = null;
|
|
795
|
-
|
|
796
|
-
var runDependencyTracking = {
|
|
797
|
-
};
|
|
798
|
-
|
|
799
|
-
var runDependencyWatcher = null;
|
|
800
|
-
var removeRunDependency = (id) => {
|
|
801
|
-
runDependencies--;
|
|
802
|
-
|
|
803
|
-
Module['monitorRunDependencies']?.(runDependencies);
|
|
804
|
-
|
|
805
|
-
assert(id, 'removeRunDependency requires an ID');
|
|
806
|
-
assert(runDependencyTracking[id]);
|
|
807
|
-
delete runDependencyTracking[id];
|
|
808
|
-
if (runDependencies == 0) {
|
|
809
|
-
if (runDependencyWatcher !== null) {
|
|
810
|
-
clearInterval(runDependencyWatcher);
|
|
811
|
-
runDependencyWatcher = null;
|
|
812
|
-
}
|
|
813
|
-
if (dependenciesFulfilled) {
|
|
814
|
-
var callback = dependenciesFulfilled;
|
|
815
|
-
dependenciesFulfilled = null;
|
|
816
|
-
callback(); // can add another dependenciesFulfilled
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
};
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
var addRunDependency = (id) => {
|
|
823
|
-
runDependencies++;
|
|
824
|
-
|
|
825
|
-
Module['monitorRunDependencies']?.(runDependencies);
|
|
826
|
-
|
|
827
|
-
assert(id, 'addRunDependency requires an ID')
|
|
828
|
-
assert(!runDependencyTracking[id]);
|
|
829
|
-
runDependencyTracking[id] = 1;
|
|
830
|
-
if (runDependencyWatcher === null && globalThis.setInterval) {
|
|
831
|
-
// Check for missing dependencies every few seconds
|
|
832
|
-
runDependencyWatcher = setInterval(() => {
|
|
833
|
-
if (ABORT) {
|
|
834
|
-
clearInterval(runDependencyWatcher);
|
|
835
|
-
runDependencyWatcher = null;
|
|
836
|
-
return;
|
|
837
|
-
}
|
|
838
|
-
var shown = false;
|
|
839
|
-
for (var dep in runDependencyTracking) {
|
|
840
|
-
if (!shown) {
|
|
841
|
-
shown = true;
|
|
842
|
-
err('still waiting on run dependencies:');
|
|
843
|
-
}
|
|
844
|
-
err(`dependency: ${dep}`);
|
|
845
|
-
}
|
|
846
|
-
if (shown) {
|
|
847
|
-
err('(end of list)');
|
|
848
|
-
}
|
|
849
|
-
}, 10000);
|
|
850
|
-
// Prevent this timer from keeping the runtime alive if nothing
|
|
851
|
-
// else is.
|
|
852
|
-
runDependencyWatcher.unref?.()
|
|
853
|
-
}
|
|
854
|
-
};
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
/**
|
|
859
|
-
* @param {number} ptr
|
|
860
|
-
* @param {string} type
|
|
861
|
-
*/
|
|
862
|
-
function getValue(ptr, type = 'i8') {
|
|
863
|
-
if (type.endsWith('*')) type = '*';
|
|
864
|
-
switch (type) {
|
|
865
|
-
case 'i1': return HEAP8[ptr];
|
|
866
|
-
case 'i8': return HEAP8[ptr];
|
|
867
|
-
case 'i16': return HEAP16[((ptr)>>1)];
|
|
868
|
-
case 'i32': return HEAP32[((ptr)>>2)];
|
|
869
|
-
case 'i64': return HEAP64[((ptr)>>3)];
|
|
870
|
-
case 'float': return HEAPF32[((ptr)>>2)];
|
|
871
|
-
case 'double': return HEAPF64[((ptr)>>3)];
|
|
872
|
-
case '*': return HEAPU32[((ptr)>>2)];
|
|
873
|
-
default: abort(`invalid type for getValue: ${type}`);
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
808
|
|
|
877
809
|
var noExitRuntime = false;
|
|
878
810
|
|
|
879
|
-
|
|
811
|
+
function ptrToString(ptr) {
|
|
880
812
|
assert(typeof ptr === 'number', `ptrToString expects a number, got ${typeof ptr}`);
|
|
881
813
|
// Convert to 32-bit unsigned value
|
|
882
814
|
ptr >>>= 0;
|
|
883
815
|
return '0x' + ptr.toString(16).padStart(8, '0');
|
|
884
|
-
};
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
/**
|
|
889
|
-
* @param {number} ptr
|
|
890
|
-
* @param {number} value
|
|
891
|
-
* @param {string} type
|
|
892
|
-
*/
|
|
893
|
-
function setValue(ptr, value, type = 'i8') {
|
|
894
|
-
if (type.endsWith('*')) type = '*';
|
|
895
|
-
switch (type) {
|
|
896
|
-
case 'i1': HEAP8[ptr] = value; break;
|
|
897
|
-
case 'i8': HEAP8[ptr] = value; break;
|
|
898
|
-
case 'i16': HEAP16[((ptr)>>1)] = value; break;
|
|
899
|
-
case 'i32': HEAP32[((ptr)>>2)] = value; break;
|
|
900
|
-
case 'i64': HEAP64[((ptr)>>3)] = BigInt(value); break;
|
|
901
|
-
case 'float': HEAPF32[((ptr)>>2)] = value; break;
|
|
902
|
-
case 'double': HEAPF64[((ptr)>>3)] = value; break;
|
|
903
|
-
case '*': HEAPU32[((ptr)>>2)] = value; break;
|
|
904
|
-
default: abort(`invalid type for setValue: ${type}`);
|
|
905
816
|
}
|
|
906
|
-
}
|
|
907
817
|
|
|
908
818
|
var stackRestore = (val) => __emscripten_stack_restore(val);
|
|
909
819
|
|
|
@@ -922,6 +832,14 @@ async function createWasm() {
|
|
|
922
832
|
|
|
923
833
|
var UTF8Decoder = globalThis.TextDecoder && new TextDecoder();
|
|
924
834
|
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* heapOrArray is either a regular array, or a JavaScript typed array view.
|
|
838
|
+
* @param {number} idx
|
|
839
|
+
* @param {number=} maxBytesToRead
|
|
840
|
+
* @param {boolean=} ignoreNul
|
|
841
|
+
* @return {number}
|
|
842
|
+
*/
|
|
925
843
|
var findStringEnd = (heapOrArray, idx, maxBytesToRead, ignoreNul) => {
|
|
926
844
|
var maxIdx = idx + maxBytesToRead;
|
|
927
845
|
if (ignoreNul) return maxIdx;
|
|
@@ -966,7 +884,7 @@ async function createWasm() {
|
|
|
966
884
|
if ((u0 & 0xF0) == 0xE0) {
|
|
967
885
|
u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
|
|
968
886
|
} else {
|
|
969
|
-
if ((u0 & 0xF8) != 0xF0) warnOnce(
|
|
887
|
+
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!`);
|
|
970
888
|
u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
|
|
971
889
|
}
|
|
972
890
|
|
|
@@ -980,6 +898,9 @@ async function createWasm() {
|
|
|
980
898
|
return str;
|
|
981
899
|
};
|
|
982
900
|
|
|
901
|
+
/** @type {!Uint8Array} */
|
|
902
|
+
var HEAPU8;
|
|
903
|
+
|
|
983
904
|
/**
|
|
984
905
|
* Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
|
|
985
906
|
* emscripten HEAP, returns a copy of that string as a Javascript String object.
|
|
@@ -1024,15 +945,12 @@ async function createWasm() {
|
|
|
1024
945
|
// This block is not needed on v19+ since crypto.getRandomValues is builtin
|
|
1025
946
|
if (ENVIRONMENT_IS_NODE) {
|
|
1026
947
|
var nodeCrypto = require('node:crypto');
|
|
1027
|
-
return (view) => nodeCrypto.randomFillSync(view);
|
|
948
|
+
return (view) => (nodeCrypto.randomFillSync(view), 0);
|
|
1028
949
|
}
|
|
1029
950
|
|
|
1030
|
-
return (view) => crypto.getRandomValues(view);
|
|
1031
|
-
};
|
|
1032
|
-
var randomFill = (view) => {
|
|
1033
|
-
// Lazily init on the first invocation.
|
|
1034
|
-
(randomFill = initRandomFill())(view);
|
|
951
|
+
return (view) => (crypto.getRandomValues(view), 0);
|
|
1035
952
|
};
|
|
953
|
+
var randomFill = (view) => (randomFill = initRandomFill())(view);
|
|
1036
954
|
|
|
1037
955
|
|
|
1038
956
|
|
|
@@ -1098,7 +1016,7 @@ async function createWasm() {
|
|
|
1098
1016
|
heap[outIdx++] = 0x80 | (u & 63);
|
|
1099
1017
|
} else {
|
|
1100
1018
|
if (outIdx + 3 >= endIdx) break;
|
|
1101
|
-
if (u > 0x10FFFF) warnOnce(
|
|
1019
|
+
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).`);
|
|
1102
1020
|
heap[outIdx++] = 0xF0 | (u >> 18);
|
|
1103
1021
|
heap[outIdx++] = 0x80 | ((u >> 12) & 63);
|
|
1104
1022
|
heap[outIdx++] = 0x80 | ((u >> 6) & 63);
|
|
@@ -1222,7 +1140,7 @@ async function createWasm() {
|
|
|
1222
1140
|
} catch (e) {
|
|
1223
1141
|
throw new FS.ErrnoError(29);
|
|
1224
1142
|
}
|
|
1225
|
-
if (result === undefined && bytesRead
|
|
1143
|
+
if (result === undefined && !bytesRead) {
|
|
1226
1144
|
throw new FS.ErrnoError(6);
|
|
1227
1145
|
}
|
|
1228
1146
|
if (result === null || result === undefined) break;
|
|
@@ -1313,7 +1231,7 @@ async function createWasm() {
|
|
|
1313
1231
|
var zeroMemory = (ptr, size) => HEAPU8.fill(0, ptr, ptr + size);
|
|
1314
1232
|
|
|
1315
1233
|
var alignMemory = (size, alignment) => {
|
|
1316
|
-
assert(alignment,
|
|
1234
|
+
assert(alignment, 'alignment argument is required');
|
|
1317
1235
|
return Math.ceil(size / alignment) * alignment;
|
|
1318
1236
|
};
|
|
1319
1237
|
var mmapAlloc = (size) => {
|
|
@@ -1322,6 +1240,7 @@ async function createWasm() {
|
|
|
1322
1240
|
if (ptr) zeroMemory(ptr, size);
|
|
1323
1241
|
return ptr;
|
|
1324
1242
|
};
|
|
1243
|
+
|
|
1325
1244
|
var MEMFS = {
|
|
1326
1245
|
ops_table:null,
|
|
1327
1246
|
mount(mount) {
|
|
@@ -1386,11 +1305,14 @@ async function createWasm() {
|
|
|
1386
1305
|
} else if (FS.isFile(node.mode)) {
|
|
1387
1306
|
node.node_ops = MEMFS.ops_table.file.node;
|
|
1388
1307
|
node.stream_ops = MEMFS.ops_table.file.stream;
|
|
1389
|
-
|
|
1390
|
-
//
|
|
1391
|
-
|
|
1392
|
-
//
|
|
1393
|
-
|
|
1308
|
+
// The actual number of bytes used in the typed array, as opposed to
|
|
1309
|
+
// contents.length which gives the whole capacity.
|
|
1310
|
+
node.usedBytes = 0;
|
|
1311
|
+
// The byte data of the file is stored in a typed array.
|
|
1312
|
+
// Note: typed arrays are not resizable like normal JS arrays are, so
|
|
1313
|
+
// there is a small penalty involved for appending file writes that
|
|
1314
|
+
// continuously grow a file similar to std::vector capacity vs used.
|
|
1315
|
+
node.contents = MEMFS.emptyFileContents ??= new Uint8Array(0);
|
|
1394
1316
|
} else if (FS.isLink(node.mode)) {
|
|
1395
1317
|
node.node_ops = MEMFS.ops_table.link.node;
|
|
1396
1318
|
node.stream_ops = MEMFS.ops_table.link.stream;
|
|
@@ -1407,36 +1329,30 @@ async function createWasm() {
|
|
|
1407
1329
|
return node;
|
|
1408
1330
|
},
|
|
1409
1331
|
getFileDataAsTypedArray(node) {
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
return new Uint8Array(node.contents);
|
|
1332
|
+
assert(FS.isFile(node.mode), 'getFileDataAsTypedArray called on non-file');
|
|
1333
|
+
return node.contents.subarray(0, node.usedBytes); // Make sure to not return excess unused bytes.
|
|
1413
1334
|
},
|
|
1414
1335
|
expandFileStorage(node, newCapacity) {
|
|
1415
|
-
var prevCapacity = node.contents
|
|
1336
|
+
var prevCapacity = node.contents.length;
|
|
1416
1337
|
if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough.
|
|
1417
|
-
// Don't expand strictly to the given requested limit if it's only a very
|
|
1418
|
-
//
|
|
1419
|
-
//
|
|
1338
|
+
// Don't expand strictly to the given requested limit if it's only a very
|
|
1339
|
+
// small increase, but instead geometrically grow capacity.
|
|
1340
|
+
// For small filesizes (<1MB), perform size*2 geometric increase, but for
|
|
1341
|
+
// large sizes, do a much more conservative size*1.125 increase to avoid
|
|
1342
|
+
// overshooting the allocation cap by a very large margin.
|
|
1420
1343
|
var CAPACITY_DOUBLING_MAX = 1024 * 1024;
|
|
1421
1344
|
newCapacity = Math.max(newCapacity, (prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2.0 : 1.125)) >>> 0);
|
|
1422
|
-
if (prevCapacity
|
|
1423
|
-
var oldContents = node
|
|
1345
|
+
if (prevCapacity) newCapacity = Math.max(newCapacity, 256); // At minimum allocate 256b for each file when expanding.
|
|
1346
|
+
var oldContents = MEMFS.getFileDataAsTypedArray(node);
|
|
1424
1347
|
node.contents = new Uint8Array(newCapacity); // Allocate new storage.
|
|
1425
|
-
|
|
1348
|
+
node.contents.set(oldContents);
|
|
1426
1349
|
},
|
|
1427
1350
|
resizeFileStorage(node, newSize) {
|
|
1428
1351
|
if (node.usedBytes == newSize) return;
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
var oldContents = node.contents;
|
|
1434
|
-
node.contents = new Uint8Array(newSize); // Allocate new storage.
|
|
1435
|
-
if (oldContents) {
|
|
1436
|
-
node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
|
|
1437
|
-
}
|
|
1438
|
-
node.usedBytes = newSize;
|
|
1439
|
-
}
|
|
1352
|
+
var oldContents = node.contents;
|
|
1353
|
+
node.contents = new Uint8Array(newSize); // Allocate new storage.
|
|
1354
|
+
node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); // Copy old data over to the new storage.
|
|
1355
|
+
node.usedBytes = newSize;
|
|
1440
1356
|
},
|
|
1441
1357
|
node_ops:{
|
|
1442
1358
|
getattr(node) {
|
|
@@ -1468,7 +1384,7 @@ async function createWasm() {
|
|
|
1468
1384
|
return attr;
|
|
1469
1385
|
},
|
|
1470
1386
|
setattr(node, attr) {
|
|
1471
|
-
for (const key of [
|
|
1387
|
+
for (const key of ['mode', 'atime', 'mtime', 'ctime']) {
|
|
1472
1388
|
if (attr[key] != null) {
|
|
1473
1389
|
node[key] = attr[key];
|
|
1474
1390
|
}
|
|
@@ -1536,16 +1452,11 @@ async function createWasm() {
|
|
|
1536
1452
|
if (position >= stream.node.usedBytes) return 0;
|
|
1537
1453
|
var size = Math.min(stream.node.usedBytes - position, length);
|
|
1538
1454
|
assert(size >= 0);
|
|
1539
|
-
|
|
1540
|
-
buffer.set(contents.subarray(position, position + size), offset);
|
|
1541
|
-
} else {
|
|
1542
|
-
for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i];
|
|
1543
|
-
}
|
|
1455
|
+
buffer.set(contents.subarray(position, position + size), offset);
|
|
1544
1456
|
return size;
|
|
1545
1457
|
},
|
|
1546
1458
|
write(stream, buffer, offset, length, position, canOwn) {
|
|
1547
|
-
|
|
1548
|
-
assert(!(buffer instanceof ArrayBuffer));
|
|
1459
|
+
assert(buffer.subarray, 'FS.write expects a TypedArray');
|
|
1549
1460
|
// If the buffer is located in main memory (HEAP), and if
|
|
1550
1461
|
// memory can grow, we can't hold on to references of the
|
|
1551
1462
|
// memory buffer, as they may get invalidated. That means we
|
|
@@ -1558,33 +1469,19 @@ async function createWasm() {
|
|
|
1558
1469
|
var node = stream.node;
|
|
1559
1470
|
node.mtime = node.ctime = Date.now();
|
|
1560
1471
|
|
|
1561
|
-
if (
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
return length;
|
|
1571
|
-
} else if (position + length <= node.usedBytes) { // Writing to an already allocated and used subrange of the file?
|
|
1572
|
-
node.contents.set(buffer.subarray(offset, offset + length), position);
|
|
1573
|
-
return length;
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
// Appending to an existing file and we need to reallocate, or source data did not come as a typed array.
|
|
1578
|
-
MEMFS.expandFileStorage(node, position+length);
|
|
1579
|
-
if (node.contents.subarray && buffer.subarray) {
|
|
1472
|
+
if (canOwn) {
|
|
1473
|
+
assert(!position, 'canOwn must imply no weird position inside the file');
|
|
1474
|
+
node.contents = buffer.subarray(offset, offset + length);
|
|
1475
|
+
node.usedBytes = length;
|
|
1476
|
+
} else if (!node.usedBytes && !position) { // 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.
|
|
1477
|
+
node.contents = buffer.slice(offset, offset + length);
|
|
1478
|
+
node.usedBytes = length;
|
|
1479
|
+
} else {
|
|
1480
|
+
MEMFS.expandFileStorage(node, position+length);
|
|
1580
1481
|
// Use typed array write which is available.
|
|
1581
1482
|
node.contents.set(buffer.subarray(offset, offset + length), position);
|
|
1582
|
-
|
|
1583
|
-
for (var i = 0; i < length; i++) {
|
|
1584
|
-
node.contents[position + i] = buffer[offset + i]; // Or fall back to manual write if not.
|
|
1585
|
-
}
|
|
1483
|
+
node.usedBytes = Math.max(node.usedBytes, position + length);
|
|
1586
1484
|
}
|
|
1587
|
-
node.usedBytes = Math.max(node.usedBytes, position + length);
|
|
1588
1485
|
return length;
|
|
1589
1486
|
},
|
|
1590
1487
|
llseek(stream, offset, whence) {
|
|
@@ -1609,7 +1506,7 @@ async function createWasm() {
|
|
|
1609
1506
|
var allocated;
|
|
1610
1507
|
var contents = stream.node.contents;
|
|
1611
1508
|
// Only make a new copy when MAP_PRIVATE is specified.
|
|
1612
|
-
if (!(flags & 2) && contents
|
|
1509
|
+
if (!(flags & 2) && contents.buffer === HEAP8.buffer) {
|
|
1613
1510
|
// We can't emulate MAP_SHARED when the file is not backed by the
|
|
1614
1511
|
// buffer we're mapping to (e.g. the HEAP buffer).
|
|
1615
1512
|
allocated = false;
|
|
@@ -1643,6 +1540,7 @@ async function createWasm() {
|
|
|
1643
1540
|
};
|
|
1644
1541
|
|
|
1645
1542
|
var FS_modeStringToFlags = (str) => {
|
|
1543
|
+
if (typeof str != 'string') return str;
|
|
1646
1544
|
var flagModes = {
|
|
1647
1545
|
'r': 0,
|
|
1648
1546
|
'r+': 2,
|
|
@@ -1658,6 +1556,16 @@ async function createWasm() {
|
|
|
1658
1556
|
return flags;
|
|
1659
1557
|
};
|
|
1660
1558
|
|
|
1559
|
+
var FS_fileDataToTypedArray = (data) => {
|
|
1560
|
+
if (typeof data == 'string') {
|
|
1561
|
+
data = intArrayFromString(data, true);
|
|
1562
|
+
}
|
|
1563
|
+
if (!data.subarray) {
|
|
1564
|
+
data = new Uint8Array(data);
|
|
1565
|
+
}
|
|
1566
|
+
return data;
|
|
1567
|
+
};
|
|
1568
|
+
|
|
1661
1569
|
var FS_getMode = (canRead, canWrite) => {
|
|
1662
1570
|
var mode = 0;
|
|
1663
1571
|
if (canRead) mode |= 292 | 73;
|
|
@@ -1792,26 +1700,27 @@ async function createWasm() {
|
|
|
1792
1700
|
'ESTRPIPE': 135,
|
|
1793
1701
|
};
|
|
1794
1702
|
|
|
1703
|
+
|
|
1795
1704
|
var NODEFS = {
|
|
1796
1705
|
isWindows:false,
|
|
1797
1706
|
staticInit() {
|
|
1798
1707
|
NODEFS.isWindows = !!process.platform.match(/^win/);
|
|
1799
|
-
var flags = process.binding(
|
|
1708
|
+
var flags = process.binding('constants')['fs'];
|
|
1800
1709
|
NODEFS.flagsForNodeMap = {
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1710
|
+
'1024': flags['O_APPEND'],
|
|
1711
|
+
'64': flags['O_CREAT'],
|
|
1712
|
+
'128': flags['O_EXCL'],
|
|
1713
|
+
'256': flags['O_NOCTTY'],
|
|
1714
|
+
'0': flags['O_RDONLY'],
|
|
1715
|
+
'2': flags['O_RDWR'],
|
|
1716
|
+
'4096': flags['O_SYNC'],
|
|
1717
|
+
'512': flags['O_TRUNC'],
|
|
1718
|
+
'1': flags['O_WRONLY'],
|
|
1719
|
+
'131072': flags['O_NOFOLLOW'],
|
|
1811
1720
|
};
|
|
1812
1721
|
// The 0 define must match on both sides, as otherwise we would not
|
|
1813
1722
|
// know to add it.
|
|
1814
|
-
assert(NODEFS.flagsForNodeMap[
|
|
1723
|
+
assert(NODEFS.flagsForNodeMap['0'] === 0);
|
|
1815
1724
|
},
|
|
1816
1725
|
convertNodeCode(e) {
|
|
1817
1726
|
var code = e.code;
|
|
@@ -1926,7 +1835,7 @@ async function createWasm() {
|
|
|
1926
1835
|
// update the common node structure mode as well
|
|
1927
1836
|
node.mode = attr.mode;
|
|
1928
1837
|
}
|
|
1929
|
-
if (typeof (attr.atime ?? attr.mtime) ===
|
|
1838
|
+
if (typeof (attr.atime ?? attr.mtime) === 'number') {
|
|
1930
1839
|
// Unfortunately, we have to stat the current value if we don't want
|
|
1931
1840
|
// to change it. On top of that, since the times don't round trip
|
|
1932
1841
|
// this will only keep the value nearly unchanged not exactly
|
|
@@ -1951,7 +1860,11 @@ async function createWasm() {
|
|
|
1951
1860
|
if (attr.mode != null && attr.dontFollow) {
|
|
1952
1861
|
throw new FS.ErrnoError(52);
|
|
1953
1862
|
}
|
|
1954
|
-
|
|
1863
|
+
// `dontFollow` (AT_SYMLINK_NOFOLLOW): use lutimes so the symlink's own
|
|
1864
|
+
// timestamps are set without the host resolving it, which would
|
|
1865
|
+
// otherwise escape the NODEFS mount root.
|
|
1866
|
+
var utimes = attr.dontFollow ? fs.lutimesSync : fs.utimesSync;
|
|
1867
|
+
NODEFS.setattr(path, node, attr, fs.chmodSync, utimes, fs.truncateSync, fs.lstatSync);
|
|
1955
1868
|
},
|
|
1956
1869
|
lookup(parent, name) {
|
|
1957
1870
|
var path = PATH.join2(NODEFS.realPath(parent), name);
|
|
@@ -2024,7 +1937,7 @@ async function createWasm() {
|
|
|
2024
1937
|
},
|
|
2025
1938
|
close(stream) {
|
|
2026
1939
|
NODEFS.tryFSOperation(() => {
|
|
2027
|
-
if (stream.nfd &&
|
|
1940
|
+
if (stream.nfd && !--stream.shared.refcount) {
|
|
2028
1941
|
fs.closeSync(stream.nfd);
|
|
2029
1942
|
}
|
|
2030
1943
|
});
|
|
@@ -2083,6 +1996,70 @@ async function createWasm() {
|
|
|
2083
1996
|
|
|
2084
1997
|
|
|
2085
1998
|
|
|
1999
|
+
|
|
2000
|
+
var NODERAWFS_stream_funcs = {
|
|
2001
|
+
close(stream) {
|
|
2002
|
+
VFS.closeStream(stream.fd);
|
|
2003
|
+
// Don't close stdin/stdout/stderr since they are used by node itself.
|
|
2004
|
+
if (--stream.shared.refcnt <= 0 && stream.nfd > 2) {
|
|
2005
|
+
// This stream is created by our Node.js filesystem, close the
|
|
2006
|
+
// native file descriptor when its reference count drops to 0.
|
|
2007
|
+
fs.closeSync(stream.nfd);
|
|
2008
|
+
}
|
|
2009
|
+
},
|
|
2010
|
+
llseek(stream, offset, whence) {
|
|
2011
|
+
var position = offset;
|
|
2012
|
+
if (whence === 1) {
|
|
2013
|
+
position += stream.position;
|
|
2014
|
+
} else if (whence === 2) {
|
|
2015
|
+
position += fs.fstatSync(stream.nfd).size;
|
|
2016
|
+
} else if (whence !== 0) {
|
|
2017
|
+
throw new FS.ErrnoError(28);
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
if (position < 0) {
|
|
2021
|
+
throw new FS.ErrnoError(28);
|
|
2022
|
+
}
|
|
2023
|
+
stream.position = position;
|
|
2024
|
+
return position;
|
|
2025
|
+
},
|
|
2026
|
+
read(stream, buffer, offset, length, position) {
|
|
2027
|
+
var seeking = typeof position != 'undefined';
|
|
2028
|
+
if (!seeking && stream.seekable) position = stream.position;
|
|
2029
|
+
var bytesRead = fs.readSync(stream.nfd, buffer, offset, length, position);
|
|
2030
|
+
// update position marker when non-seeking
|
|
2031
|
+
if (!seeking) stream.position += bytesRead;
|
|
2032
|
+
return bytesRead;
|
|
2033
|
+
},
|
|
2034
|
+
write(stream, buffer, offset, length, position) {
|
|
2035
|
+
if (stream.flags & 1024) {
|
|
2036
|
+
// seek to the end before writing in append mode
|
|
2037
|
+
FS.llseek(stream, 0, 2);
|
|
2038
|
+
}
|
|
2039
|
+
var seeking = typeof position != 'undefined';
|
|
2040
|
+
if (!seeking && stream.seekable) position = stream.position;
|
|
2041
|
+
var bytesWritten = fs.writeSync(stream.nfd, buffer, offset, length, position);
|
|
2042
|
+
// update position marker when non-seeking
|
|
2043
|
+
if (!seeking) stream.position += bytesWritten;
|
|
2044
|
+
return bytesWritten;
|
|
2045
|
+
},
|
|
2046
|
+
mmap(stream, length, position, prot, flags) {
|
|
2047
|
+
if (!length) {
|
|
2048
|
+
throw new FS.ErrnoError(28);
|
|
2049
|
+
}
|
|
2050
|
+
var ptr = mmapAlloc(length);
|
|
2051
|
+
FS.read(stream, HEAP8, ptr, length, position);
|
|
2052
|
+
return { ptr, allocated: true };
|
|
2053
|
+
},
|
|
2054
|
+
msync(stream, buffer, offset, length, mmapFlags) {
|
|
2055
|
+
FS.write(stream, buffer, 0, length, offset);
|
|
2056
|
+
// should we check if bytesWritten and length are the same?
|
|
2057
|
+
return 0;
|
|
2058
|
+
},
|
|
2059
|
+
ioctl(stream, cmd, arg) {
|
|
2060
|
+
throw new FS.ErrnoError(59);
|
|
2061
|
+
},
|
|
2062
|
+
};
|
|
2086
2063
|
var NODERAWFS = {
|
|
2087
2064
|
lookup(parent, name) {
|
|
2088
2065
|
assert(parent)
|
|
@@ -2098,11 +2075,10 @@ async function createWasm() {
|
|
|
2098
2075
|
return { path, node: { id: st.ino, mode, node_ops: NODERAWFS, path }};
|
|
2099
2076
|
},
|
|
2100
2077
|
createStandardStreams() {
|
|
2101
|
-
|
|
2102
|
-
FS.createStream({ nfd: 0, position: 0, path: '/dev/stdin', flags: 0, tty: true, seekable: false }, 0);
|
|
2078
|
+
FS.createStream({ nfd: 0, position: 0, path: '/dev/stdin', flags: 0, seekable: false }, 0);
|
|
2103
2079
|
var paths = [,'/dev/stdout', '/dev/stderr'];
|
|
2104
2080
|
for (var i = 1; i < 3; i++) {
|
|
2105
|
-
FS.createStream({ nfd: i, position: 0, path: paths[i], flags: 577,
|
|
2081
|
+
FS.createStream({ nfd: i, position: 0, path: paths[i], flags: 577, seekable: false }, i);
|
|
2106
2082
|
}
|
|
2107
2083
|
},
|
|
2108
2084
|
cwd() { return process.cwd(); },
|
|
@@ -2116,6 +2092,14 @@ async function createWasm() {
|
|
|
2116
2092
|
},
|
|
2117
2093
|
mkdir(...args) { fs.mkdirSync(...args); },
|
|
2118
2094
|
symlink(...args) { fs.symlinkSync(...args); },
|
|
2095
|
+
link(oldpath, newpath, flags) {
|
|
2096
|
+
// AT_SYMLINK_FOLLOW (0x400): dereference oldpath if it is a symlink,
|
|
2097
|
+
// since node's link(2) links to the symlink itself by default.
|
|
2098
|
+
if (flags & 0x400) {
|
|
2099
|
+
oldpath = fs.realpathSync(oldpath);
|
|
2100
|
+
}
|
|
2101
|
+
fs.linkSync(oldpath, newpath);
|
|
2102
|
+
},
|
|
2119
2103
|
rename(...args) { fs.renameSync(...args); },
|
|
2120
2104
|
rmdir(...args) { fs.rmdirSync(...args); },
|
|
2121
2105
|
readdir(...args) { return ['.', '..'].concat(fs.readdirSync(...args)); },
|
|
@@ -2132,6 +2116,12 @@ async function createWasm() {
|
|
|
2132
2116
|
},
|
|
2133
2117
|
fstat(fd) {
|
|
2134
2118
|
var stream = FS.getStreamChecked(fd);
|
|
2119
|
+
// Virtual streams (pipes, sockets) have no backing node fd; defer to their
|
|
2120
|
+
// own getattr rather than node's fs.fstatSync.
|
|
2121
|
+
var getattr = stream.stream_ops?.getattr ?? stream.node.node_ops?.getattr;
|
|
2122
|
+
if (getattr) {
|
|
2123
|
+
return getattr(stream.stream_ops?.getattr ? stream : stream.node);
|
|
2124
|
+
}
|
|
2135
2125
|
return fs.fstatSync(stream.nfd);
|
|
2136
2126
|
},
|
|
2137
2127
|
statfs(path) {
|
|
@@ -2185,21 +2175,23 @@ async function createWasm() {
|
|
|
2185
2175
|
var stream = FS.getStreamChecked(fd);
|
|
2186
2176
|
fs.ftruncateSync(stream.nfd, len);
|
|
2187
2177
|
},
|
|
2188
|
-
utime(path, atime, mtime) {
|
|
2178
|
+
utime(path, atime, mtime, dontFollow) {
|
|
2189
2179
|
// null here for atime or mtime means UTIME_OMIT was passed. Since node
|
|
2190
2180
|
// doesn't support this concept we need to first find the existing
|
|
2191
2181
|
// timestamps in order to preserve them.
|
|
2192
2182
|
if ((atime === null) || (mtime === null)) {
|
|
2193
|
-
var st = fs.statSync(path);
|
|
2183
|
+
var st = dontFollow ? fs.lstatSync(path) : fs.statSync(path);
|
|
2194
2184
|
atime ||= st.atimeMs;
|
|
2195
2185
|
mtime ||= st.mtimeMs;
|
|
2196
2186
|
}
|
|
2197
|
-
|
|
2187
|
+
if (dontFollow) {
|
|
2188
|
+
fs.lutimesSync(path, atime/1000, mtime/1000);
|
|
2189
|
+
} else {
|
|
2190
|
+
fs.utimesSync(path, atime/1000, mtime/1000);
|
|
2191
|
+
}
|
|
2198
2192
|
},
|
|
2199
2193
|
open(path, flags, mode) {
|
|
2200
|
-
|
|
2201
|
-
flags = FS_modeStringToFlags(flags)
|
|
2202
|
-
}
|
|
2194
|
+
flags = FS_modeStringToFlags(flags);
|
|
2203
2195
|
var pathTruncated = path.split('/').map((s) => s.slice(0, 255)).join('/');
|
|
2204
2196
|
var nfd = fs.openSync(pathTruncated, NODEFS.flagsForNode(flags), mode);
|
|
2205
2197
|
var st = fs.fstatSync(nfd);
|
|
@@ -2214,96 +2206,14 @@ async function createWasm() {
|
|
|
2214
2206
|
createStream(stream, fd) {
|
|
2215
2207
|
// Call the original FS.createStream
|
|
2216
2208
|
var rtn = VFS.createStream(stream, fd);
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2209
|
+
// Detect PIPEFS streams and skip the refcnt/tty initialization in that case.
|
|
2210
|
+
if (!stream.stream_ops) {
|
|
2211
|
+
rtn.shared.refcnt ??= 0;
|
|
2220
2212
|
rtn.shared.refcnt++;
|
|
2213
|
+
rtn.tty = nodeTTY.isatty(rtn.nfd);
|
|
2221
2214
|
}
|
|
2222
2215
|
return rtn;
|
|
2223
2216
|
},
|
|
2224
|
-
close(stream) {
|
|
2225
|
-
VFS.closeStream(stream.fd);
|
|
2226
|
-
// Don't close stdin/stdout/stderr since they are used by node itself.
|
|
2227
|
-
if (!stream.stream_ops && --stream.shared.refcnt <= 0 && stream.nfd > 2) {
|
|
2228
|
-
// This stream is created by our Node.js filesystem, close the
|
|
2229
|
-
// native file descriptor when its reference count drops to 0.
|
|
2230
|
-
fs.closeSync(stream.nfd);
|
|
2231
|
-
}
|
|
2232
|
-
},
|
|
2233
|
-
llseek(stream, offset, whence) {
|
|
2234
|
-
if (stream.stream_ops) {
|
|
2235
|
-
// this stream is created by in-memory filesystem
|
|
2236
|
-
return VFS.llseek(stream, offset, whence);
|
|
2237
|
-
}
|
|
2238
|
-
var position = offset;
|
|
2239
|
-
if (whence === 1) {
|
|
2240
|
-
position += stream.position;
|
|
2241
|
-
} else if (whence === 2) {
|
|
2242
|
-
position += fs.fstatSync(stream.nfd).size;
|
|
2243
|
-
} else if (whence !== 0) {
|
|
2244
|
-
throw new FS.ErrnoError(28);
|
|
2245
|
-
}
|
|
2246
|
-
|
|
2247
|
-
if (position < 0) {
|
|
2248
|
-
throw new FS.ErrnoError(28);
|
|
2249
|
-
}
|
|
2250
|
-
stream.position = position;
|
|
2251
|
-
return position;
|
|
2252
|
-
},
|
|
2253
|
-
read(stream, buffer, offset, length, position) {
|
|
2254
|
-
if (stream.stream_ops) {
|
|
2255
|
-
// this stream is created by in-memory filesystem
|
|
2256
|
-
return VFS.read(stream, buffer, offset, length, position);
|
|
2257
|
-
}
|
|
2258
|
-
var seeking = typeof position != 'undefined';
|
|
2259
|
-
if (!seeking && stream.seekable) position = stream.position;
|
|
2260
|
-
var bytesRead = fs.readSync(stream.nfd, buffer, offset, length, position);
|
|
2261
|
-
// update position marker when non-seeking
|
|
2262
|
-
if (!seeking) stream.position += bytesRead;
|
|
2263
|
-
return bytesRead;
|
|
2264
|
-
},
|
|
2265
|
-
write(stream, buffer, offset, length, position) {
|
|
2266
|
-
if (stream.stream_ops) {
|
|
2267
|
-
// this stream is created by in-memory filesystem
|
|
2268
|
-
return VFS.write(stream, buffer, offset, length, position);
|
|
2269
|
-
}
|
|
2270
|
-
if (stream.flags & +"1024") {
|
|
2271
|
-
// seek to the end before writing in append mode
|
|
2272
|
-
FS.llseek(stream, 0, +"2");
|
|
2273
|
-
}
|
|
2274
|
-
var seeking = typeof position != 'undefined';
|
|
2275
|
-
if (!seeking && stream.seekable) position = stream.position;
|
|
2276
|
-
var bytesWritten = fs.writeSync(stream.nfd, buffer, offset, length, position);
|
|
2277
|
-
// update position marker when non-seeking
|
|
2278
|
-
if (!seeking) stream.position += bytesWritten;
|
|
2279
|
-
return bytesWritten;
|
|
2280
|
-
},
|
|
2281
|
-
mmap(stream, length, position, prot, flags) {
|
|
2282
|
-
if (!length) {
|
|
2283
|
-
throw new FS.ErrnoError(28);
|
|
2284
|
-
}
|
|
2285
|
-
if (stream.stream_ops) {
|
|
2286
|
-
// this stream is created by in-memory filesystem
|
|
2287
|
-
return VFS.mmap(stream, length, position, prot, flags);
|
|
2288
|
-
}
|
|
2289
|
-
|
|
2290
|
-
var ptr = mmapAlloc(length);
|
|
2291
|
-
FS.read(stream, HEAP8, ptr, length, position);
|
|
2292
|
-
return { ptr, allocated: true };
|
|
2293
|
-
},
|
|
2294
|
-
msync(stream, buffer, offset, length, mmapFlags) {
|
|
2295
|
-
if (stream.stream_ops) {
|
|
2296
|
-
// this stream is created by in-memory filesystem
|
|
2297
|
-
return VFS.msync(stream, buffer, offset, length, mmapFlags);
|
|
2298
|
-
}
|
|
2299
|
-
|
|
2300
|
-
FS.write(stream, buffer, 0, length, offset);
|
|
2301
|
-
// should we check if bytesWritten and length are the same?
|
|
2302
|
-
return 0;
|
|
2303
|
-
},
|
|
2304
|
-
ioctl() {
|
|
2305
|
-
throw new FS.ErrnoError(59);
|
|
2306
|
-
},
|
|
2307
2217
|
};
|
|
2308
2218
|
|
|
2309
2219
|
|
|
@@ -2328,6 +2238,73 @@ async function createWasm() {
|
|
|
2328
2238
|
}
|
|
2329
2239
|
};
|
|
2330
2240
|
|
|
2241
|
+
var dependenciesPromise = null;
|
|
2242
|
+
var resolveRunDependencies = async () => dependenciesPromise;
|
|
2243
|
+
var runDependencies = 0;
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
var dependenciesPromiseResolve = null;
|
|
2247
|
+
|
|
2248
|
+
var runDependencyTracking = {
|
|
2249
|
+
};
|
|
2250
|
+
|
|
2251
|
+
var runDependencyWatcher = null;
|
|
2252
|
+
var removeRunDependency = (id) => {
|
|
2253
|
+
runDependencies--;
|
|
2254
|
+
|
|
2255
|
+
Module['monitorRunDependencies']?.(runDependencies);
|
|
2256
|
+
|
|
2257
|
+
assert(id, 'removeRunDependency requires an ID');
|
|
2258
|
+
assert(runDependencyTracking[id]);
|
|
2259
|
+
delete runDependencyTracking[id];
|
|
2260
|
+
if (!runDependencies) {
|
|
2261
|
+
if (runDependencyWatcher !== null) {
|
|
2262
|
+
clearInterval(runDependencyWatcher);
|
|
2263
|
+
runDependencyWatcher = null;
|
|
2264
|
+
}
|
|
2265
|
+
dependenciesPromiseResolve();
|
|
2266
|
+
}
|
|
2267
|
+
};
|
|
2268
|
+
|
|
2269
|
+
|
|
2270
|
+
|
|
2271
|
+
|
|
2272
|
+
var addRunDependency = (id) => {
|
|
2273
|
+
if (!runDependencies) {
|
|
2274
|
+
dependenciesPromise = new Promise((resolve) => dependenciesPromiseResolve = resolve);
|
|
2275
|
+
}
|
|
2276
|
+
runDependencies++;
|
|
2277
|
+
|
|
2278
|
+
Module['monitorRunDependencies']?.(runDependencies);
|
|
2279
|
+
|
|
2280
|
+
assert(id, 'addRunDependency requires an ID')
|
|
2281
|
+
assert(!runDependencyTracking[id]);
|
|
2282
|
+
runDependencyTracking[id] = 1;
|
|
2283
|
+
if (!runDependencyWatcher && globalThis.setInterval) {
|
|
2284
|
+
// Check for missing dependencies every few seconds
|
|
2285
|
+
runDependencyWatcher = setInterval(() => {
|
|
2286
|
+
if (ABORT) {
|
|
2287
|
+
clearInterval(runDependencyWatcher);
|
|
2288
|
+
runDependencyWatcher = null;
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
var shown = false;
|
|
2292
|
+
for (var dep in runDependencyTracking) {
|
|
2293
|
+
if (!shown) {
|
|
2294
|
+
shown = true;
|
|
2295
|
+
err('still waiting on run dependencies:');
|
|
2296
|
+
}
|
|
2297
|
+
err(`dependency: ${dep}`);
|
|
2298
|
+
}
|
|
2299
|
+
if (shown) {
|
|
2300
|
+
err('(end of list)');
|
|
2301
|
+
}
|
|
2302
|
+
}, 10000);
|
|
2303
|
+
// Prevent this timer from keeping the runtime alive if nothing
|
|
2304
|
+
// else is.
|
|
2305
|
+
runDependencyWatcher.unref?.()
|
|
2306
|
+
}
|
|
2307
|
+
};
|
|
2331
2308
|
|
|
2332
2309
|
|
|
2333
2310
|
var preloadPlugins = [];
|
|
@@ -2370,6 +2347,7 @@ async function createWasm() {
|
|
|
2370
2347
|
var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
|
|
2371
2348
|
FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror);
|
|
2372
2349
|
};
|
|
2350
|
+
|
|
2373
2351
|
var FS = {
|
|
2374
2352
|
root:null,
|
|
2375
2353
|
mounts:[],
|
|
@@ -2468,6 +2446,48 @@ async function createWasm() {
|
|
|
2468
2446
|
get isDevice() {
|
|
2469
2447
|
return FS.isChrdev(this.mode);
|
|
2470
2448
|
}
|
|
2449
|
+
// The per-inode readiness wait-queue. The node carries a Set of listener
|
|
2450
|
+
// entries {cb}; producers (SOCKFS, PIPEFS) call notifyListeners on a
|
|
2451
|
+
// readiness transition, and poll()/epoll consume it. It lives on the node
|
|
2452
|
+
// (not the fd) so dup'd fds share one queue. Only nodes that derive real
|
|
2453
|
+
// readiness (sockets, pipes, and an epoll's own node) ever use this -
|
|
2454
|
+
// always-ready types (regular files, ttys) never register or notify.
|
|
2455
|
+
addListener(cb, exclusive = false) {
|
|
2456
|
+
var entry = {cb, exclusive};
|
|
2457
|
+
var listeners = (this.listeners ??= new Set());
|
|
2458
|
+
listeners.add(entry);
|
|
2459
|
+
return {listeners, entry};
|
|
2460
|
+
}
|
|
2461
|
+
notifyListeners(flags) {
|
|
2462
|
+
// Iterates the set without copying, which is safe ONLY under a
|
|
2463
|
+
// load-bearing contract that every internal listener must honour:
|
|
2464
|
+
// 1. A listener must not run user code synchronously (a poll waiter only
|
|
2465
|
+
// resolves a Promise; an epoll registration only re-lists +
|
|
2466
|
+
// re-notifies; the epoll callback only schedules a tick). User code
|
|
2467
|
+
// runs on a later tick, never inside this loop.
|
|
2468
|
+
// 2. A listener may delete entries only from ITS OWN waiter, never from
|
|
2469
|
+
// a sibling node's set that may be mid-iteration. (Deleting an entry
|
|
2470
|
+
// of the set being iterated here is fine - a Set tolerates removal of
|
|
2471
|
+
// a not-yet-visited entry mid-iteration; mutating a *different* node's
|
|
2472
|
+
// set is fine because that set is not being iterated.)
|
|
2473
|
+
// Violating either gives silently skipped wakeups that are near-impossible
|
|
2474
|
+
// to reproduce. Any new producer/listener must preserve it.
|
|
2475
|
+
if (!this.listeners) return;
|
|
2476
|
+
// Fire every non-exclusive listener. Among EPOLLEXCLUSIVE registrations
|
|
2477
|
+
// (one fd watched by several epolls) wake only one, rotating round-robin
|
|
2478
|
+
// per node, to avoid a thundering herd. (Only epoll registrations are ever
|
|
2479
|
+
// exclusive; poll waiters and a node's own consumers are not.)
|
|
2480
|
+
var excl;
|
|
2481
|
+
for (var entry of this.listeners) {
|
|
2482
|
+
if (entry.exclusive) (excl ||= []).push(entry);
|
|
2483
|
+
else entry.cb(flags);
|
|
2484
|
+
}
|
|
2485
|
+
if (excl) {
|
|
2486
|
+
var i = (this.exclTurn || 0) % excl.length;
|
|
2487
|
+
this.exclTurn = i + 1;
|
|
2488
|
+
excl[i].cb(flags);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2471
2491
|
},
|
|
2472
2492
|
lookupPath(path, opts = {}) {
|
|
2473
2493
|
if (!path) {
|
|
@@ -2479,7 +2499,7 @@ async function createWasm() {
|
|
|
2479
2499
|
path = FS.cwd() + '/' + path;
|
|
2480
2500
|
}
|
|
2481
2501
|
|
|
2482
|
-
// limit max consecutive symlinks to
|
|
2502
|
+
// limit max consecutive symlinks to SYMLOOP_MAX.
|
|
2483
2503
|
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
|
|
2484
2504
|
// split the absolute path
|
|
2485
2505
|
var parts = path.split('/').filter((p) => !!p);
|
|
@@ -2771,7 +2791,14 @@ async function createWasm() {
|
|
|
2771
2791
|
var arg = setattr ? stream : node;
|
|
2772
2792
|
setattr ??= node.node_ops.setattr;
|
|
2773
2793
|
FS.checkOpExists(setattr, 63)
|
|
2774
|
-
|
|
2794
|
+
try {
|
|
2795
|
+
setattr(arg, attr);
|
|
2796
|
+
} catch (e) {
|
|
2797
|
+
if (e instanceof RangeError) {
|
|
2798
|
+
throw new FS.ErrnoError(22);
|
|
2799
|
+
}
|
|
2800
|
+
throw e;
|
|
2801
|
+
}
|
|
2775
2802
|
},
|
|
2776
2803
|
chrdev_stream_ops:{
|
|
2777
2804
|
open(stream) {
|
|
@@ -3038,6 +3065,25 @@ async function createWasm() {
|
|
|
3038
3065
|
}
|
|
3039
3066
|
return parent.node_ops.symlink(parent, newname, oldpath);
|
|
3040
3067
|
},
|
|
3068
|
+
link(oldpath, newpath, flags) {
|
|
3069
|
+
var lookup = FS.lookupPath(newpath, { parent: true });
|
|
3070
|
+
var parent = lookup.node;
|
|
3071
|
+
if (!parent) {
|
|
3072
|
+
throw new FS.ErrnoError(44);
|
|
3073
|
+
}
|
|
3074
|
+
var newname = PATH.basename(newpath);
|
|
3075
|
+
var errCode = FS.mayCreate(parent, newname);
|
|
3076
|
+
if (errCode) {
|
|
3077
|
+
throw new FS.ErrnoError(errCode);
|
|
3078
|
+
}
|
|
3079
|
+
// Hardlinks are only supported by filesystem backends that provide a
|
|
3080
|
+
// `link` node op (e.g. NODERAWFS backed by the host). NODEFS omits it:
|
|
3081
|
+
// a host hardlink cannot be confined to the mount root.
|
|
3082
|
+
if (!parent.node_ops.link) {
|
|
3083
|
+
throw new FS.ErrnoError(34);
|
|
3084
|
+
}
|
|
3085
|
+
return parent.node_ops.link(parent, newname, oldpath, flags);
|
|
3086
|
+
},
|
|
3041
3087
|
rename(old_path, new_path) {
|
|
3042
3088
|
var old_dirname = PATH.dirname(old_path);
|
|
3043
3089
|
var new_dirname = PATH.dirname(new_path);
|
|
@@ -3284,20 +3330,19 @@ async function createWasm() {
|
|
|
3284
3330
|
}
|
|
3285
3331
|
FS.doTruncate(stream, stream.node, len);
|
|
3286
3332
|
},
|
|
3287
|
-
utime(path, atime, mtime) {
|
|
3288
|
-
var lookup = FS.lookupPath(path, { follow:
|
|
3289
|
-
|
|
3290
|
-
var setattr = FS.checkOpExists(node.node_ops.setattr, 63);
|
|
3291
|
-
setattr(node, {
|
|
3333
|
+
utime(path, atime, mtime, dontFollow) {
|
|
3334
|
+
var lookup = FS.lookupPath(path, { follow: !dontFollow });
|
|
3335
|
+
FS.doSetAttr(null, lookup.node, {
|
|
3292
3336
|
atime: atime,
|
|
3293
|
-
mtime: mtime
|
|
3337
|
+
mtime: mtime,
|
|
3338
|
+
dontFollow
|
|
3294
3339
|
});
|
|
3295
3340
|
},
|
|
3296
3341
|
open(path, flags, mode = 0o666) {
|
|
3297
|
-
if (path ===
|
|
3342
|
+
if (path === '') {
|
|
3298
3343
|
throw new FS.ErrnoError(44);
|
|
3299
3344
|
}
|
|
3300
|
-
flags =
|
|
3345
|
+
flags = FS_modeStringToFlags(flags);
|
|
3301
3346
|
if ((flags & 64)) {
|
|
3302
3347
|
mode = (mode & 4095) | 32768;
|
|
3303
3348
|
} else {
|
|
@@ -3308,7 +3353,7 @@ async function createWasm() {
|
|
|
3308
3353
|
if (typeof path == 'object') {
|
|
3309
3354
|
node = path;
|
|
3310
3355
|
} else {
|
|
3311
|
-
isDirPath = path.endsWith(
|
|
3356
|
+
isDirPath = path.endsWith('/');
|
|
3312
3357
|
// noent_okay makes it so that if the final component of the path
|
|
3313
3358
|
// doesn't exist, lookupPath returns `node: undefined`. `path` will be
|
|
3314
3359
|
// updated to point to the target of all symlinks.
|
|
@@ -3391,6 +3436,11 @@ async function createWasm() {
|
|
|
3391
3436
|
throw new FS.ErrnoError(8);
|
|
3392
3437
|
}
|
|
3393
3438
|
if (stream.getdents) stream.getdents = null; // free readdir state
|
|
3439
|
+
// The fd is going away: wake anything waiting on it (poll/epoll) with
|
|
3440
|
+
// POLLNVAL so a blocking wait unblocks and an epoll registration is evicted
|
|
3441
|
+
// on its next derive. Only sockets/pipes/epoll ever carry a wait-queue, so
|
|
3442
|
+
// for every other stream (incl. nodeless noderawfs stdio) this is a no-op.
|
|
3443
|
+
stream.node?.notifyListeners(32);
|
|
3394
3444
|
try {
|
|
3395
3445
|
if (stream.stream_ops.close) {
|
|
3396
3446
|
stream.stream_ops.close(stream);
|
|
@@ -3448,6 +3498,7 @@ async function createWasm() {
|
|
|
3448
3498
|
},
|
|
3449
3499
|
write(stream, buffer, offset, length, position, canOwn) {
|
|
3450
3500
|
assert(offset >= 0);
|
|
3501
|
+
assert(buffer.subarray, 'FS.write expects a TypedArray');
|
|
3451
3502
|
if (length < 0 || position < 0) {
|
|
3452
3503
|
throw new FS.ErrnoError(28);
|
|
3453
3504
|
}
|
|
@@ -3484,8 +3535,8 @@ async function createWasm() {
|
|
|
3484
3535
|
// to write to file opened in read-only mode with MAP_PRIVATE flag,
|
|
3485
3536
|
// as all modifications will be visible only in the memory of
|
|
3486
3537
|
// the current process.
|
|
3487
|
-
if ((prot & 2)
|
|
3488
|
-
&& (flags & 2)
|
|
3538
|
+
if ((prot & 2)
|
|
3539
|
+
&& !(flags & 2)
|
|
3489
3540
|
&& (stream.flags & 2097155) !== 2) {
|
|
3490
3541
|
throw new FS.ErrnoError(2);
|
|
3491
3542
|
}
|
|
@@ -3514,8 +3565,8 @@ async function createWasm() {
|
|
|
3514
3565
|
return stream.stream_ops.ioctl(stream, cmd, arg);
|
|
3515
3566
|
},
|
|
3516
3567
|
readFile(path, opts = {}) {
|
|
3517
|
-
opts.flags = opts.flags
|
|
3518
|
-
opts.encoding = opts.encoding
|
|
3568
|
+
opts.flags = opts.flags ?? 0;
|
|
3569
|
+
opts.encoding = opts.encoding ?? 'binary';
|
|
3519
3570
|
if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
|
|
3520
3571
|
abort(`Invalid encoding type "${opts.encoding}"`);
|
|
3521
3572
|
}
|
|
@@ -3531,16 +3582,10 @@ async function createWasm() {
|
|
|
3531
3582
|
return buf;
|
|
3532
3583
|
},
|
|
3533
3584
|
writeFile(path, data, opts = {}) {
|
|
3534
|
-
opts.flags = opts.flags
|
|
3585
|
+
opts.flags = opts.flags ?? 577;
|
|
3535
3586
|
var stream = FS.open(path, opts.flags, opts.mode);
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
}
|
|
3539
|
-
if (ArrayBuffer.isView(data)) {
|
|
3540
|
-
FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
|
|
3541
|
-
} else {
|
|
3542
|
-
abort('Unsupported data type');
|
|
3543
|
-
}
|
|
3587
|
+
data = FS_fileDataToTypedArray(data);
|
|
3588
|
+
FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
|
|
3544
3589
|
FS.close(stream);
|
|
3545
3590
|
},
|
|
3546
3591
|
cwd:() => FS.currentPath,
|
|
@@ -3584,7 +3629,7 @@ async function createWasm() {
|
|
|
3584
3629
|
// use a buffer to avoid overhead of individual crypto calls per byte
|
|
3585
3630
|
var randomBuffer = new Uint8Array(1024), randomLeft = 0;
|
|
3586
3631
|
var randomByte = () => {
|
|
3587
|
-
if (randomLeft
|
|
3632
|
+
if (!randomLeft) {
|
|
3588
3633
|
randomFill(randomBuffer);
|
|
3589
3634
|
randomLeft = randomBuffer.byteLength;
|
|
3590
3635
|
}
|
|
@@ -3766,11 +3811,7 @@ async function createWasm() {
|
|
|
3766
3811
|
var mode = FS_getMode(canRead, canWrite);
|
|
3767
3812
|
var node = FS.create(path, mode);
|
|
3768
3813
|
if (data) {
|
|
3769
|
-
|
|
3770
|
-
var arr = new Array(data.length);
|
|
3771
|
-
for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
|
|
3772
|
-
data = arr;
|
|
3773
|
-
}
|
|
3814
|
+
data = FS_fileDataToTypedArray(data);
|
|
3774
3815
|
// make sure we can write to the file
|
|
3775
3816
|
FS.chmod(node, mode | 146);
|
|
3776
3817
|
var stream = FS.open(node, 577);
|
|
@@ -3805,7 +3846,7 @@ async function createWasm() {
|
|
|
3805
3846
|
} catch (e) {
|
|
3806
3847
|
throw new FS.ErrnoError(29);
|
|
3807
3848
|
}
|
|
3808
|
-
if (result === undefined && bytesRead
|
|
3849
|
+
if (result === undefined && !bytesRead) {
|
|
3809
3850
|
throw new FS.ErrnoError(6);
|
|
3810
3851
|
}
|
|
3811
3852
|
if (result === null || result === undefined) break;
|
|
@@ -3836,7 +3877,7 @@ async function createWasm() {
|
|
|
3836
3877
|
forceLoadFile(obj) {
|
|
3837
3878
|
if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
|
|
3838
3879
|
if (globalThis.XMLHttpRequest) {
|
|
3839
|
-
abort(
|
|
3880
|
+
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.');
|
|
3840
3881
|
} else { // Command-line.
|
|
3841
3882
|
try {
|
|
3842
3883
|
obj.contents = readBinary(obj.url);
|
|
@@ -3867,11 +3908,11 @@ async function createWasm() {
|
|
|
3867
3908
|
var xhr = new XMLHttpRequest();
|
|
3868
3909
|
xhr.open('HEAD', url, false);
|
|
3869
3910
|
xhr.send(null);
|
|
3870
|
-
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(
|
|
3871
|
-
var datalength = Number(xhr.getResponseHeader(
|
|
3911
|
+
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(`Couldn't load ${url}. Status: ${xhr.status}`);
|
|
3912
|
+
var datalength = Number(xhr.getResponseHeader('Content-length'));
|
|
3872
3913
|
var header;
|
|
3873
|
-
var hasByteServing = (header = xhr.getResponseHeader(
|
|
3874
|
-
var usesGzip = (header = xhr.getResponseHeader(
|
|
3914
|
+
var hasByteServing = (header = xhr.getResponseHeader('Accept-Ranges')) && header === 'bytes';
|
|
3915
|
+
var usesGzip = (header = xhr.getResponseHeader('Content-Encoding')) && header === 'gzip';
|
|
3875
3916
|
|
|
3876
3917
|
var chunkSize = 1024*1024; // Chunk size in bytes
|
|
3877
3918
|
|
|
@@ -3879,13 +3920,13 @@ async function createWasm() {
|
|
|
3879
3920
|
|
|
3880
3921
|
// Function to get a range from the remote URL.
|
|
3881
3922
|
var doXHR = (from, to) => {
|
|
3882
|
-
if (from > to) abort(
|
|
3883
|
-
if (to > datalength-1) abort(
|
|
3923
|
+
if (from > to) abort(`invalid range (${from}, ${to}) or no bytes requested!`);
|
|
3924
|
+
if (to > datalength-1) abort(`only ${datalength} bytes available! programmer error!`);
|
|
3884
3925
|
|
|
3885
3926
|
// TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
|
|
3886
3927
|
var xhr = new XMLHttpRequest();
|
|
3887
3928
|
xhr.open('GET', url, false);
|
|
3888
|
-
if (datalength !== chunkSize) xhr.setRequestHeader(
|
|
3929
|
+
if (datalength !== chunkSize) xhr.setRequestHeader('Range', `bytes=${from}-${to}`);
|
|
3889
3930
|
|
|
3890
3931
|
// Some hints to the browser that we want binary data.
|
|
3891
3932
|
xhr.responseType = 'arraybuffer';
|
|
@@ -3894,11 +3935,11 @@ async function createWasm() {
|
|
|
3894
3935
|
}
|
|
3895
3936
|
|
|
3896
3937
|
xhr.send(null);
|
|
3897
|
-
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(
|
|
3938
|
+
if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(`Couldn't load ${url}. Status: ${xhr.status}`);
|
|
3898
3939
|
if (xhr.response !== undefined) {
|
|
3899
3940
|
return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
|
|
3900
3941
|
}
|
|
3901
|
-
return intArrayFromString(xhr.responseText
|
|
3942
|
+
return intArrayFromString(xhr.responseText ?? '', true);
|
|
3902
3943
|
};
|
|
3903
3944
|
var lazyArray = this;
|
|
3904
3945
|
lazyArray.setDataGetter((chunkNum) => {
|
|
@@ -3917,7 +3958,7 @@ async function createWasm() {
|
|
|
3917
3958
|
chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
|
|
3918
3959
|
datalength = this.getter(0).length;
|
|
3919
3960
|
chunkSize = datalength;
|
|
3920
|
-
out(
|
|
3961
|
+
out('LazyFiles on gzip forces download of the whole file when length is accessed');
|
|
3921
3962
|
}
|
|
3922
3963
|
|
|
3923
3964
|
this._length = datalength;
|
|
@@ -4005,27 +4046,16 @@ async function createWasm() {
|
|
|
4005
4046
|
node.stream_ops = stream_ops;
|
|
4006
4047
|
return node;
|
|
4007
4048
|
},
|
|
4008
|
-
absolutePath() {
|
|
4009
|
-
abort('FS.absolutePath has been removed; use PATH_FS.resolve instead');
|
|
4010
|
-
},
|
|
4011
|
-
createFolder() {
|
|
4012
|
-
abort('FS.createFolder has been removed; use FS.mkdir instead');
|
|
4013
|
-
},
|
|
4014
|
-
createLink() {
|
|
4015
|
-
abort('FS.createLink has been removed; use FS.symlink instead');
|
|
4016
|
-
},
|
|
4017
|
-
joinPath() {
|
|
4018
|
-
abort('FS.joinPath has been removed; use PATH.join instead');
|
|
4019
|
-
},
|
|
4020
|
-
mmapAlloc() {
|
|
4021
|
-
abort('FS.mmapAlloc has been replaced by the top level function mmapAlloc');
|
|
4022
|
-
},
|
|
4023
|
-
standardizePath() {
|
|
4024
|
-
abort('FS.standardizePath has been removed; use PATH.normalize instead');
|
|
4025
|
-
},
|
|
4026
4049
|
};
|
|
4027
4050
|
|
|
4051
|
+
|
|
4052
|
+
|
|
4053
|
+
|
|
4054
|
+
|
|
4055
|
+
/** not-@type {!BigInt64Array} */
|
|
4056
|
+
var HEAP64;
|
|
4028
4057
|
var SYSCALLS = {
|
|
4058
|
+
currentUmask:18,
|
|
4029
4059
|
calculateAt(dirfd, path, allowEmpty) {
|
|
4030
4060
|
if (PATH.isAbs(path)) {
|
|
4031
4061
|
return path;
|
|
@@ -4088,7 +4118,7 @@ async function createWasm() {
|
|
|
4088
4118
|
// MAP_PRIVATE calls need not to be synced back to underlying fs
|
|
4089
4119
|
return 0;
|
|
4090
4120
|
}
|
|
4091
|
-
var buffer = HEAPU8.
|
|
4121
|
+
var buffer = HEAPU8.subarray(addr, addr + len);
|
|
4092
4122
|
FS.msync(stream, buffer, offset, len, flags);
|
|
4093
4123
|
},
|
|
4094
4124
|
getStreamFromFD(fd) {
|
|
@@ -4101,6 +4131,9 @@ async function createWasm() {
|
|
|
4101
4131
|
return ret;
|
|
4102
4132
|
},
|
|
4103
4133
|
};
|
|
4134
|
+
|
|
4135
|
+
/** @type {!Int16Array} */
|
|
4136
|
+
var HEAP16;
|
|
4104
4137
|
function ___syscall_fcntl64(fd, cmd, varargs) {
|
|
4105
4138
|
SYSCALLS.varargs = varargs;
|
|
4106
4139
|
try {
|
|
@@ -4126,7 +4159,8 @@ async function createWasm() {
|
|
|
4126
4159
|
return stream.flags;
|
|
4127
4160
|
case 4: {
|
|
4128
4161
|
var arg = syscallGetVarargI();
|
|
4129
|
-
|
|
4162
|
+
var mask = 289792;
|
|
4163
|
+
stream.flags = (stream.flags & ~mask) | (arg & mask);
|
|
4130
4164
|
return 0;
|
|
4131
4165
|
}
|
|
4132
4166
|
case 12: {
|
|
@@ -4150,8 +4184,12 @@ async function createWasm() {
|
|
|
4150
4184
|
return -e.errno;
|
|
4151
4185
|
}
|
|
4152
4186
|
}
|
|
4187
|
+
|
|
4153
4188
|
|
|
4154
4189
|
|
|
4190
|
+
|
|
4191
|
+
|
|
4192
|
+
|
|
4155
4193
|
function ___syscall_ioctl(fd, op, varargs) {
|
|
4156
4194
|
SYSCALLS.varargs = varargs;
|
|
4157
4195
|
try {
|
|
@@ -4247,6 +4285,7 @@ async function createWasm() {
|
|
|
4247
4285
|
return -e.errno;
|
|
4248
4286
|
}
|
|
4249
4287
|
}
|
|
4288
|
+
|
|
4250
4289
|
|
|
4251
4290
|
|
|
4252
4291
|
function ___syscall_openat(dirfd, path, flags, varargs) {
|
|
@@ -4256,18 +4295,22 @@ async function createWasm() {
|
|
|
4256
4295
|
path = SYSCALLS.getStr(path);
|
|
4257
4296
|
path = SYSCALLS.calculateAt(dirfd, path);
|
|
4258
4297
|
var mode = varargs ? syscallGetVarargI() : 0;
|
|
4298
|
+
if (flags & 64) {
|
|
4299
|
+
mode &= ~SYSCALLS.currentUmask;
|
|
4300
|
+
}
|
|
4259
4301
|
return FS.open(path, flags, mode).fd;
|
|
4260
4302
|
} catch (e) {
|
|
4261
4303
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
4262
4304
|
return -e.errno;
|
|
4263
4305
|
}
|
|
4264
4306
|
}
|
|
4307
|
+
|
|
4265
4308
|
|
|
4266
4309
|
var __abort_js = () =>
|
|
4267
4310
|
abort('native code called abort()');
|
|
4268
4311
|
|
|
4269
4312
|
var __emscripten_throw_longjmp = () => {
|
|
4270
|
-
throw
|
|
4313
|
+
throw new EmscriptenSjLj;
|
|
4271
4314
|
};
|
|
4272
4315
|
|
|
4273
4316
|
|
|
@@ -4311,9 +4354,10 @@ async function createWasm() {
|
|
|
4311
4354
|
} catch(e) {
|
|
4312
4355
|
err(`growMemory: Attempted to grow heap from ${oldHeapSize} bytes to ${size} bytes, but got error: ${e}`);
|
|
4313
4356
|
}
|
|
4314
|
-
// implicit 0 return to save code size (caller will cast
|
|
4357
|
+
// implicit 0 return to save code size (caller will cast 'undefined' into 0
|
|
4315
4358
|
// anyhow)
|
|
4316
4359
|
};
|
|
4360
|
+
|
|
4317
4361
|
var _emscripten_resize_heap = (requestedSize) => {
|
|
4318
4362
|
var oldSize = HEAPU8.length;
|
|
4319
4363
|
// With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
|
|
@@ -4409,7 +4453,9 @@ async function createWasm() {
|
|
|
4409
4453
|
return e.errno;
|
|
4410
4454
|
}
|
|
4411
4455
|
}
|
|
4456
|
+
|
|
4412
4457
|
|
|
4458
|
+
|
|
4413
4459
|
/** @param {number=} offset */
|
|
4414
4460
|
var doReadv = (stream, iov, iovcnt, offset) => {
|
|
4415
4461
|
var ret = 0;
|
|
@@ -4417,7 +4463,18 @@ async function createWasm() {
|
|
|
4417
4463
|
var ptr = HEAPU32[((iov)>>2)];
|
|
4418
4464
|
var len = HEAPU32[(((iov)+(4))>>2)];
|
|
4419
4465
|
iov += 8;
|
|
4420
|
-
|
|
4466
|
+
try {
|
|
4467
|
+
var curr = FS.read(stream, HEAP8, ptr, len, offset);
|
|
4468
|
+
} catch (e) {
|
|
4469
|
+
// On a non-blocking stream a subsequent read may would-block after we
|
|
4470
|
+
// already gathered data. POSIX readv is a single gather-read: return
|
|
4471
|
+
// what we have rather than failing the whole call.
|
|
4472
|
+
if (ret > 0 && e instanceof FS.ErrnoError &&
|
|
4473
|
+
(e.errno == 6 || e.errno == 6)) {
|
|
4474
|
+
break;
|
|
4475
|
+
}
|
|
4476
|
+
throw e;
|
|
4477
|
+
}
|
|
4421
4478
|
if (curr < 0) return -1;
|
|
4422
4479
|
ret += curr;
|
|
4423
4480
|
if (curr < len) break; // nothing more to read
|
|
@@ -4428,6 +4485,7 @@ async function createWasm() {
|
|
|
4428
4485
|
return ret;
|
|
4429
4486
|
};
|
|
4430
4487
|
|
|
4488
|
+
|
|
4431
4489
|
function _fd_read(fd, iov, iovcnt, pnum) {
|
|
4432
4490
|
try {
|
|
4433
4491
|
|
|
@@ -4440,19 +4498,21 @@ async function createWasm() {
|
|
|
4440
4498
|
return e.errno;
|
|
4441
4499
|
}
|
|
4442
4500
|
}
|
|
4501
|
+
|
|
4443
4502
|
|
|
4444
4503
|
|
|
4504
|
+
|
|
4445
4505
|
function _fd_seek(fd, offset, whence, newOffset) {
|
|
4446
4506
|
offset = bigintToI53Checked(offset);
|
|
4447
4507
|
|
|
4448
4508
|
|
|
4449
4509
|
try {
|
|
4450
4510
|
|
|
4451
|
-
if (isNaN(offset)) return
|
|
4511
|
+
if (isNaN(offset)) return 22;
|
|
4452
4512
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
4453
4513
|
FS.llseek(stream, offset, whence);
|
|
4454
4514
|
HEAP64[((newOffset)>>3)] = BigInt(stream.position);
|
|
4455
|
-
if (stream.getdents && offset
|
|
4515
|
+
if (stream.getdents && !offset && whence === 0) stream.getdents = null; // reset readdir state
|
|
4456
4516
|
return 0;
|
|
4457
4517
|
} catch (e) {
|
|
4458
4518
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
@@ -4461,27 +4521,34 @@ async function createWasm() {
|
|
|
4461
4521
|
;
|
|
4462
4522
|
}
|
|
4463
4523
|
|
|
4524
|
+
|
|
4525
|
+
|
|
4464
4526
|
/** @param {number=} offset */
|
|
4465
4527
|
var doWritev = (stream, iov, iovcnt, offset) => {
|
|
4466
|
-
|
|
4467
|
-
|
|
4528
|
+
// Gather all iovecs into one contiguous buffer and issue a single
|
|
4529
|
+
// FS.write, matching POSIX writev's single gather-write semantics (as
|
|
4530
|
+
// __syscall_sendmsg already does). Per-iovec writes fragment a stream
|
|
4531
|
+
// socket send into multiple segments, breaking stream byte semantics.
|
|
4532
|
+
if (iovcnt == 1) {
|
|
4533
|
+
// Single iovec: write directly from HEAP8, no gather buffer needed.
|
|
4534
|
+
return FS.write(stream, HEAP8, HEAPU32[((iov)>>2)], HEAPU32[(((iov)+(4))>>2)], offset);
|
|
4535
|
+
}
|
|
4536
|
+
var total = 0;
|
|
4537
|
+
for (var i = 0, p = iov; i < iovcnt; i++, p += 8) {
|
|
4538
|
+
total += HEAPU32[(((p)+(4))>>2)];
|
|
4539
|
+
}
|
|
4540
|
+
var view = new Uint8Array(total);
|
|
4541
|
+
var voff = 0;
|
|
4542
|
+
for (var i = 0; i < iovcnt; i++, iov += 8) {
|
|
4468
4543
|
var ptr = HEAPU32[((iov)>>2)];
|
|
4469
4544
|
var len = HEAPU32[(((iov)+(4))>>2)];
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
if (curr < 0) return -1;
|
|
4473
|
-
ret += curr;
|
|
4474
|
-
if (curr < len) {
|
|
4475
|
-
// No more space to write.
|
|
4476
|
-
break;
|
|
4477
|
-
}
|
|
4478
|
-
if (typeof offset != 'undefined') {
|
|
4479
|
-
offset += curr;
|
|
4480
|
-
}
|
|
4545
|
+
view.set(HEAPU8.subarray(ptr, ptr + len), voff);
|
|
4546
|
+
voff += len;
|
|
4481
4547
|
}
|
|
4482
|
-
return
|
|
4548
|
+
return FS.write(stream, view, 0, total, offset);
|
|
4483
4549
|
};
|
|
4484
4550
|
|
|
4551
|
+
|
|
4485
4552
|
function _fd_write(fd, iov, iovcnt, pnum) {
|
|
4486
4553
|
try {
|
|
4487
4554
|
|
|
@@ -4494,6 +4561,7 @@ async function createWasm() {
|
|
|
4494
4561
|
return e.errno;
|
|
4495
4562
|
}
|
|
4496
4563
|
}
|
|
4564
|
+
|
|
4497
4565
|
|
|
4498
4566
|
|
|
4499
4567
|
var handleException = (e) => {
|
|
@@ -4515,8 +4583,9 @@ async function createWasm() {
|
|
|
4515
4583
|
};
|
|
4516
4584
|
|
|
4517
4585
|
|
|
4586
|
+
|
|
4518
4587
|
var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
|
|
4519
|
-
assert(typeof maxBytesToWrite == 'number', 'stringToUTF8
|
|
4588
|
+
assert(typeof maxBytesToWrite == 'number', 'stringToUTF8 requires a third parameter that specifies the length of the output buffer');
|
|
4520
4589
|
return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
|
|
4521
4590
|
};
|
|
4522
4591
|
|
|
@@ -4528,6 +4597,7 @@ async function createWasm() {
|
|
|
4528
4597
|
return ret;
|
|
4529
4598
|
};
|
|
4530
4599
|
|
|
4600
|
+
|
|
4531
4601
|
var wasmTableMirror = [];
|
|
4532
4602
|
|
|
4533
4603
|
|
|
@@ -4538,7 +4608,7 @@ async function createWasm() {
|
|
|
4538
4608
|
wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
|
|
4539
4609
|
}
|
|
4540
4610
|
/** @suppress {checkTypes} */
|
|
4541
|
-
assert(wasmTable.get(funcPtr) == func, '
|
|
4611
|
+
assert(wasmTable.get(funcPtr) == func, 'table mirror is out of date');
|
|
4542
4612
|
return func;
|
|
4543
4613
|
};
|
|
4544
4614
|
|
|
@@ -4548,10 +4618,11 @@ async function createWasm() {
|
|
|
4548
4618
|
if (ENVIRONMENT_IS_NODE) { NODEFS.staticInit(); };
|
|
4549
4619
|
|
|
4550
4620
|
if (!ENVIRONMENT_IS_NODE) {
|
|
4551
|
-
throw new Error(
|
|
4621
|
+
throw new Error('NODERAWFS is currently only supported on Node.js environment.')
|
|
4552
4622
|
}
|
|
4553
|
-
var
|
|
4554
|
-
|
|
4623
|
+
var nodeTTY = require('node:tty');
|
|
4624
|
+
function _wrapNodeError(func) {
|
|
4625
|
+
return (...args) => {
|
|
4555
4626
|
try {
|
|
4556
4627
|
return func(...args)
|
|
4557
4628
|
} catch (e) {
|
|
@@ -4566,14 +4637,26 @@ if (ENVIRONMENT_IS_NODE) { NODEFS.staticInit(); };
|
|
|
4566
4637
|
throw e;
|
|
4567
4638
|
}
|
|
4568
4639
|
}
|
|
4569
|
-
}
|
|
4640
|
+
}
|
|
4641
|
+
function _wrapNodeStreamFunc(func, vfs_func) {
|
|
4642
|
+
return _wrapNodeError((stream, ...args) => {
|
|
4643
|
+
if (stream.stream_ops) {
|
|
4644
|
+
// this stream was created by some other FS. e.g: PIPEFS.
|
|
4645
|
+
return vfs_func(stream, ...args);
|
|
4646
|
+
}
|
|
4647
|
+
return func(stream, ...args);
|
|
4648
|
+
});
|
|
4649
|
+
}
|
|
4570
4650
|
// Use this to reference our in-memory filesystem
|
|
4571
4651
|
/** @suppress {partialAlias} */
|
|
4572
4652
|
var VFS = {...FS};
|
|
4573
4653
|
// Wrap the whole in-memory filesystem API with
|
|
4574
4654
|
// our Node.js based functions
|
|
4575
|
-
for (
|
|
4576
|
-
FS[
|
|
4655
|
+
for (const [key, value] of Object.entries(NODERAWFS)) {
|
|
4656
|
+
FS[key] = _wrapNodeError(value);
|
|
4657
|
+
}
|
|
4658
|
+
for (const [key, value] of Object.entries(NODERAWFS_stream_funcs)) {
|
|
4659
|
+
FS[key] = _wrapNodeStreamFunc(value, FS[key]);
|
|
4577
4660
|
};
|
|
4578
4661
|
// End JS library code
|
|
4579
4662
|
|
|
@@ -4585,15 +4668,14 @@ if (ENVIRONMENT_IS_NODE) { NODEFS.staticInit(); };
|
|
|
4585
4668
|
|
|
4586
4669
|
// Begin ATMODULES hooks
|
|
4587
4670
|
if (Module['noExitRuntime']) noExitRuntime = Module['noExitRuntime'];
|
|
4588
|
-
|
|
4671
|
+
|
|
4589
4672
|
if (Module['print']) out = Module['print'];
|
|
4590
4673
|
if (Module['printErr']) err = Module['printErr'];
|
|
4591
|
-
if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
4592
4674
|
// End ATMODULES hooks
|
|
4593
4675
|
|
|
4594
4676
|
checkIncomingModuleAPI();
|
|
4595
4677
|
|
|
4596
|
-
if (Module['arguments'])
|
|
4678
|
+
if (Module['arguments']) programArgs = Module['arguments'];
|
|
4597
4679
|
if (Module['thisProgram']) thisProgram = Module['thisProgram'];
|
|
4598
4680
|
|
|
4599
4681
|
// Assertions on removed incoming Module JS APIs.
|
|
@@ -4612,10 +4694,13 @@ if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
|
4612
4694
|
assert(typeof Module['wasmMemory'] == 'undefined', 'Use of `wasmMemory` detected. Use -sIMPORTED_MEMORY to define wasmMemory externally');
|
|
4613
4695
|
assert(typeof Module['INITIAL_MEMORY'] == 'undefined', 'Detected runtime INITIAL_MEMORY setting. Use -sIMPORTED_MEMORY to define wasmMemory dynamically');
|
|
4614
4696
|
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4697
|
+
var preInit = Module['preInit'];
|
|
4698
|
+
if (preInit) {
|
|
4699
|
+
if (typeof preInit == 'function') Module['preInit'] = preInit = [preInit];
|
|
4700
|
+
// Written as a loop so that preInit functions that themselves add more
|
|
4701
|
+
// preInit functions. Is this actually needed?
|
|
4702
|
+
while (preInit.length > 0) {
|
|
4703
|
+
preInit.shift()();
|
|
4619
4704
|
}
|
|
4620
4705
|
}
|
|
4621
4706
|
consumedModuleProp('preInit');
|
|
@@ -4672,6 +4757,8 @@ if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
|
4672
4757
|
'getFunctionAddress',
|
|
4673
4758
|
'addFunction',
|
|
4674
4759
|
'removeFunction',
|
|
4760
|
+
'setValue',
|
|
4761
|
+
'getValue',
|
|
4675
4762
|
'intArrayToString',
|
|
4676
4763
|
'AsciiToString',
|
|
4677
4764
|
'stringToAscii',
|
|
@@ -4701,12 +4788,14 @@ if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
|
4701
4788
|
'registerOrientationChangeEventCallback',
|
|
4702
4789
|
'fillFullscreenChangeEventData',
|
|
4703
4790
|
'registerFullscreenChangeEventCallback',
|
|
4791
|
+
'callCanvasResizedCallback',
|
|
4704
4792
|
'JSEvents_requestFullscreen',
|
|
4705
4793
|
'JSEvents_resizeCanvasForFullscreen',
|
|
4706
4794
|
'registerRestoreOldStyle',
|
|
4707
4795
|
'hideEverythingExceptGivenElement',
|
|
4708
4796
|
'restoreHiddenElements',
|
|
4709
4797
|
'setLetterbox',
|
|
4798
|
+
'currentFullscreenStrategy',
|
|
4710
4799
|
'softFullscreenResizeWebGLRenderTarget',
|
|
4711
4800
|
'doRequestFullscreen',
|
|
4712
4801
|
'fillPointerlockChangeEventData',
|
|
@@ -4738,10 +4827,9 @@ if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
|
4738
4827
|
'registerPreMainLoop',
|
|
4739
4828
|
'getPromise',
|
|
4740
4829
|
'makePromise',
|
|
4830
|
+
'addPromise',
|
|
4741
4831
|
'idsToPromises',
|
|
4742
4832
|
'makePromiseCallback',
|
|
4743
|
-
'ExceptionInfo',
|
|
4744
|
-
'findMatchingCatch',
|
|
4745
4833
|
'Browser_asyncPrepareDataCounter',
|
|
4746
4834
|
'isLeapYear',
|
|
4747
4835
|
'ydayFromDate',
|
|
@@ -4765,6 +4853,7 @@ if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
|
4765
4853
|
'colorChannelsInGlTextureFormat',
|
|
4766
4854
|
'emscriptenWebGLGetTexPixelData',
|
|
4767
4855
|
'emscriptenWebGLGetUniform',
|
|
4856
|
+
'webglGetProgramUniformLocation',
|
|
4768
4857
|
'webglGetUniformLocation',
|
|
4769
4858
|
'webglPrepareUniformLocationsBeforeFirstUse',
|
|
4770
4859
|
'webglGetLeftBracePos',
|
|
@@ -4773,14 +4862,10 @@ if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
|
|
|
4773
4862
|
'writeGLArray',
|
|
4774
4863
|
'registerWebGlEventCallback',
|
|
4775
4864
|
'runAndAbortIfError',
|
|
4776
|
-
'ALLOC_NORMAL',
|
|
4777
|
-
'ALLOC_STACK',
|
|
4778
|
-
'allocate',
|
|
4779
4865
|
'writeStringToMemory',
|
|
4780
4866
|
'writeAsciiToMemory',
|
|
4781
4867
|
'allocateUTF8',
|
|
4782
4868
|
'allocateUTF8OnStack',
|
|
4783
|
-
'demangle',
|
|
4784
4869
|
'stackTrace',
|
|
4785
4870
|
'getNativeTypeSize',
|
|
4786
4871
|
];
|
|
@@ -4792,21 +4877,21 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
|
|
|
4792
4877
|
'err',
|
|
4793
4878
|
'abort',
|
|
4794
4879
|
'wasmExports',
|
|
4795
|
-
'
|
|
4796
|
-
'
|
|
4880
|
+
'writeStackCookie',
|
|
4881
|
+
'checkStackCookie',
|
|
4882
|
+
'INT53_MAX',
|
|
4883
|
+
'INT53_MIN',
|
|
4884
|
+
'bigintToI53Checked',
|
|
4797
4885
|
'HEAP8',
|
|
4798
4886
|
'HEAPU8',
|
|
4799
4887
|
'HEAP16',
|
|
4800
4888
|
'HEAPU16',
|
|
4801
4889
|
'HEAP32',
|
|
4802
4890
|
'HEAPU32',
|
|
4891
|
+
'HEAPF32',
|
|
4892
|
+
'HEAPF64',
|
|
4803
4893
|
'HEAP64',
|
|
4804
4894
|
'HEAPU64',
|
|
4805
|
-
'writeStackCookie',
|
|
4806
|
-
'checkStackCookie',
|
|
4807
|
-
'INT53_MAX',
|
|
4808
|
-
'INT53_MIN',
|
|
4809
|
-
'bigintToI53Checked',
|
|
4810
4895
|
'stackSave',
|
|
4811
4896
|
'stackRestore',
|
|
4812
4897
|
'stackAlloc',
|
|
@@ -4839,8 +4924,6 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
|
|
|
4839
4924
|
'addOnPostRun',
|
|
4840
4925
|
'freeTableIndexes',
|
|
4841
4926
|
'functionsInTableMap',
|
|
4842
|
-
'setValue',
|
|
4843
|
-
'getValue',
|
|
4844
4927
|
'PATH',
|
|
4845
4928
|
'PATH_FS',
|
|
4846
4929
|
'UTF8Decoder',
|
|
@@ -4855,7 +4938,6 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
|
|
|
4855
4938
|
'JSEvents',
|
|
4856
4939
|
'specialHTMLTargets',
|
|
4857
4940
|
'findCanvasEventTarget',
|
|
4858
|
-
'currentFullscreenStrategy',
|
|
4859
4941
|
'restoreOldWindowedStyle',
|
|
4860
4942
|
'UNWIND_CACHE',
|
|
4861
4943
|
'ExitStatus',
|
|
@@ -4867,12 +4949,8 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
|
|
|
4867
4949
|
'emClearImmediate_deps',
|
|
4868
4950
|
'emClearImmediate',
|
|
4869
4951
|
'promiseMap',
|
|
4870
|
-
'uncaughtExceptionCount',
|
|
4871
|
-
'exceptionLast',
|
|
4872
|
-
'exceptionCaught',
|
|
4873
4952
|
'Browser',
|
|
4874
4953
|
'requestFullscreen',
|
|
4875
|
-
'requestFullScreen',
|
|
4876
4954
|
'setCanvasSize',
|
|
4877
4955
|
'getUserMedia',
|
|
4878
4956
|
'createContext',
|
|
@@ -4888,6 +4966,7 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
|
|
|
4888
4966
|
'FS_preloadFile',
|
|
4889
4967
|
'FS_modeStringToFlags',
|
|
4890
4968
|
'FS_getMode',
|
|
4969
|
+
'FS_fileDataToTypedArray',
|
|
4891
4970
|
'FS_stdin_getChar_buffer',
|
|
4892
4971
|
'FS_stdin_getChar',
|
|
4893
4972
|
'FS_unlink',
|
|
@@ -4956,6 +5035,7 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
|
|
|
4956
5035
|
'FS_mkdir',
|
|
4957
5036
|
'FS_mkdev',
|
|
4958
5037
|
'FS_symlink',
|
|
5038
|
+
'FS_link',
|
|
4959
5039
|
'FS_rename',
|
|
4960
5040
|
'FS_rmdir',
|
|
4961
5041
|
'FS_readdir',
|
|
@@ -5000,18 +5080,13 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
|
|
|
5000
5080
|
'FS_createDataFile',
|
|
5001
5081
|
'FS_forceLoadFile',
|
|
5002
5082
|
'FS_createLazyFile',
|
|
5003
|
-
'FS_absolutePath',
|
|
5004
|
-
'FS_createFolder',
|
|
5005
|
-
'FS_createLink',
|
|
5006
|
-
'FS_joinPath',
|
|
5007
|
-
'FS_mmapAlloc',
|
|
5008
|
-
'FS_standardizePath',
|
|
5009
5083
|
'MEMFS',
|
|
5010
5084
|
'TTY',
|
|
5011
5085
|
'PIPEFS',
|
|
5012
5086
|
'SOCKFS',
|
|
5013
5087
|
'NODEFS',
|
|
5014
5088
|
'NODERAWFS',
|
|
5089
|
+
'NODERAWFS_stream_funcs',
|
|
5015
5090
|
'nodePath',
|
|
5016
5091
|
'tempFixedLengthArray',
|
|
5017
5092
|
'miniTempWebGLFloatBuffers',
|
|
@@ -5040,6 +5115,30 @@ function checkIncomingModuleAPI() {
|
|
|
5040
5115
|
ignoredModuleProp('fetchSettings');
|
|
5041
5116
|
ignoredModuleProp('logReadFiles');
|
|
5042
5117
|
ignoredModuleProp('loadSplitModule');
|
|
5118
|
+
ignoredModuleProp('onMalloc');
|
|
5119
|
+
ignoredModuleProp('onRealloc');
|
|
5120
|
+
ignoredModuleProp('onFree');
|
|
5121
|
+
ignoredModuleProp('onSbrkGrow');
|
|
5122
|
+
ignoredModuleProp('onCOSCacheHit');
|
|
5123
|
+
ignoredModuleProp('onCOSCacheMiss');
|
|
5124
|
+
ignoredModuleProp('onCOSStore');
|
|
5125
|
+
ignoredModuleProp('GL_MAX_TEXTURE_IMAGE_UNITS');
|
|
5126
|
+
ignoredModuleProp('SDL_canPlayWithWebAudio');
|
|
5127
|
+
ignoredModuleProp('SDL_numSimultaneouslyQueuedBuffers');
|
|
5128
|
+
ignoredModuleProp('freePreloadedMediaOnUse');
|
|
5129
|
+
ignoredModuleProp('preinitializedWebGLContext');
|
|
5130
|
+
ignoredModuleProp('keyboardListeningElement');
|
|
5131
|
+
ignoredModuleProp('doNotCaptureKeyboard');
|
|
5132
|
+
ignoredModuleProp('extraStackTrace');
|
|
5133
|
+
ignoredModuleProp('preloadPlugins');
|
|
5134
|
+
ignoredModuleProp('preMainLoop');
|
|
5135
|
+
ignoredModuleProp('postMainLoop');
|
|
5136
|
+
ignoredModuleProp('forcedAspectRatio');
|
|
5137
|
+
ignoredModuleProp('mainScriptUrlOrBlob');
|
|
5138
|
+
ignoredModuleProp('onFullScreen');
|
|
5139
|
+
ignoredModuleProp('INITIAL_MEMORY');
|
|
5140
|
+
ignoredModuleProp('wasmMemory');
|
|
5141
|
+
ignoredModuleProp('wasmBinary');
|
|
5043
5142
|
}
|
|
5044
5143
|
|
|
5045
5144
|
// Imports from the Wasm binary.
|
|
@@ -5077,14 +5176,14 @@ function assignWasmExports(wasmExports) {
|
|
|
5077
5176
|
assert(typeof wasmExports['emscripten_stack_get_current'] != 'undefined', 'missing Wasm export: emscripten_stack_get_current');
|
|
5078
5177
|
assert(typeof wasmExports['memory'] != 'undefined', 'missing Wasm export: memory');
|
|
5079
5178
|
assert(typeof wasmExports['__indirect_function_table'] != 'undefined', 'missing Wasm export: __indirect_function_table');
|
|
5080
|
-
_main = Module['_main'] = createExportWrapper('__main_argc_argv', 2);
|
|
5081
|
-
_fflush = createExportWrapper('fflush', 1);
|
|
5082
|
-
___funcs_on_exit = createExportWrapper('__funcs_on_exit', 0);
|
|
5083
|
-
_emscripten_builtin_memalign = createExportWrapper('emscripten_builtin_memalign', 2);
|
|
5179
|
+
_main = Module['_main'] = createExportWrapper('__main_argc_argv', wasmExports['__main_argc_argv'], 2);
|
|
5180
|
+
_fflush = createExportWrapper('fflush', wasmExports['fflush'], 1);
|
|
5181
|
+
___funcs_on_exit = createExportWrapper('__funcs_on_exit', wasmExports['__funcs_on_exit'], 0);
|
|
5182
|
+
_emscripten_builtin_memalign = createExportWrapper('emscripten_builtin_memalign', wasmExports['emscripten_builtin_memalign'], 2);
|
|
5084
5183
|
_emscripten_stack_get_end = wasmExports['emscripten_stack_get_end'];
|
|
5085
5184
|
_emscripten_stack_get_base = wasmExports['emscripten_stack_get_base'];
|
|
5086
|
-
_strerror = createExportWrapper('strerror', 1);
|
|
5087
|
-
_setThrew = createExportWrapper('setThrew', 2);
|
|
5185
|
+
_strerror = createExportWrapper('strerror', wasmExports['strerror'], 1);
|
|
5186
|
+
_setThrew = createExportWrapper('setThrew', wasmExports['setThrew'], 2);
|
|
5088
5187
|
_emscripten_stack_init = wasmExports['emscripten_stack_init'];
|
|
5089
5188
|
_emscripten_stack_get_free = wasmExports['emscripten_stack_get_free'];
|
|
5090
5189
|
__emscripten_stack_restore = wasmExports['_emscripten_stack_restore'];
|
|
@@ -5139,7 +5238,7 @@ function invoke_ii(index,a1) {
|
|
|
5139
5238
|
return getWasmTableEntry(index)(a1);
|
|
5140
5239
|
} catch(e) {
|
|
5141
5240
|
stackRestore(sp);
|
|
5142
|
-
if (e
|
|
5241
|
+
if (!(e instanceof EmscriptenEH)) throw e;
|
|
5143
5242
|
_setThrew(1, 0);
|
|
5144
5243
|
}
|
|
5145
5244
|
}
|
|
@@ -5150,7 +5249,7 @@ function invoke_iii(index,a1,a2) {
|
|
|
5150
5249
|
return getWasmTableEntry(index)(a1,a2);
|
|
5151
5250
|
} catch(e) {
|
|
5152
5251
|
stackRestore(sp);
|
|
5153
|
-
if (e
|
|
5252
|
+
if (!(e instanceof EmscriptenEH)) throw e;
|
|
5154
5253
|
_setThrew(1, 0);
|
|
5155
5254
|
}
|
|
5156
5255
|
}
|
|
@@ -5161,7 +5260,7 @@ function invoke_viii(index,a1,a2,a3) {
|
|
|
5161
5260
|
getWasmTableEntry(index)(a1,a2,a3);
|
|
5162
5261
|
} catch(e) {
|
|
5163
5262
|
stackRestore(sp);
|
|
5164
|
-
if (e
|
|
5263
|
+
if (!(e instanceof EmscriptenEH)) throw e;
|
|
5165
5264
|
_setThrew(1, 0);
|
|
5166
5265
|
}
|
|
5167
5266
|
}
|
|
@@ -5172,7 +5271,7 @@ function invoke_vii(index,a1,a2) {
|
|
|
5172
5271
|
getWasmTableEntry(index)(a1,a2);
|
|
5173
5272
|
} catch(e) {
|
|
5174
5273
|
stackRestore(sp);
|
|
5175
|
-
if (e
|
|
5274
|
+
if (!(e instanceof EmscriptenEH)) throw e;
|
|
5176
5275
|
_setThrew(1, 0);
|
|
5177
5276
|
}
|
|
5178
5277
|
}
|
|
@@ -5183,7 +5282,7 @@ function invoke_vi(index,a1) {
|
|
|
5183
5282
|
getWasmTableEntry(index)(a1);
|
|
5184
5283
|
} catch(e) {
|
|
5185
5284
|
stackRestore(sp);
|
|
5186
|
-
if (e
|
|
5285
|
+
if (!(e instanceof EmscriptenEH)) throw e;
|
|
5187
5286
|
_setThrew(1, 0);
|
|
5188
5287
|
}
|
|
5189
5288
|
}
|
|
@@ -5232,65 +5331,47 @@ function stackCheckInit() {
|
|
|
5232
5331
|
writeStackCookie();
|
|
5233
5332
|
}
|
|
5234
5333
|
|
|
5235
|
-
function run(args =
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
dependenciesFulfilled = run;
|
|
5239
|
-
return;
|
|
5240
|
-
}
|
|
5334
|
+
async function run(args = programArgs) {
|
|
5335
|
+
assert(!calledRun);
|
|
5336
|
+
calledRun = true;
|
|
5241
5337
|
|
|
5242
5338
|
stackCheckInit();
|
|
5243
5339
|
|
|
5244
5340
|
preRun();
|
|
5245
5341
|
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
dependenciesFulfilled = run;
|
|
5249
|
-
return;
|
|
5342
|
+
if (runDependencies) {
|
|
5343
|
+
await resolveRunDependencies();
|
|
5250
5344
|
}
|
|
5251
5345
|
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5346
|
+
var setStatus = Module['setStatus'];
|
|
5347
|
+
if (setStatus) {
|
|
5348
|
+
setStatus('Running...');
|
|
5349
|
+
// Yield to the event loop to allow the browser to paint "Running..."
|
|
5350
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
5351
|
+
// Then we want to clear the status text, but only after the rest of this function runs.
|
|
5352
|
+
setTimeout(setStatus, 1, '');
|
|
5353
|
+
}
|
|
5260
5354
|
|
|
5261
|
-
|
|
5355
|
+
if (ABORT) return;
|
|
5262
5356
|
|
|
5263
|
-
|
|
5357
|
+
initRuntime();
|
|
5264
5358
|
|
|
5265
|
-
|
|
5266
|
-
consumedModuleProp('onRuntimeInitialized');
|
|
5359
|
+
// No ATMAINS hooks
|
|
5267
5360
|
|
|
5268
|
-
|
|
5269
|
-
|
|
5361
|
+
Module['onRuntimeInitialized']?.();
|
|
5362
|
+
consumedModuleProp('onRuntimeInitialized');
|
|
5270
5363
|
|
|
5271
|
-
|
|
5272
|
-
|
|
5364
|
+
var noInitialRun = Module['noInitialRun'] || false;
|
|
5365
|
+
if (!noInitialRun) callMain(args);
|
|
5273
5366
|
|
|
5274
|
-
|
|
5275
|
-
Module['setStatus']('Running...');
|
|
5276
|
-
setTimeout(() => {
|
|
5277
|
-
setTimeout(() => Module['setStatus'](''), 1);
|
|
5278
|
-
doRun();
|
|
5279
|
-
}, 1);
|
|
5280
|
-
} else
|
|
5281
|
-
{
|
|
5282
|
-
doRun();
|
|
5283
|
-
}
|
|
5284
|
-
checkStackCookie();
|
|
5367
|
+
postRun();
|
|
5285
5368
|
}
|
|
5286
5369
|
|
|
5287
5370
|
var wasmExports;
|
|
5288
5371
|
|
|
5289
5372
|
// With async instantation wasmExports is assigned asynchronously when the
|
|
5290
5373
|
// instance is received.
|
|
5291
|
-
createWasm();
|
|
5292
|
-
|
|
5293
|
-
run();
|
|
5374
|
+
createWasm().then(() => run());
|
|
5294
5375
|
|
|
5295
5376
|
// end include: postamble.js
|
|
5296
5377
|
|