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