@ai-ecoverse/slicc-kernel 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/dist/index.js +2 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +26 -4
- package/dist/kernel-worker.js.map +4 -4
- package/dist/process-worker.js +143 -9
- package/dist/process-worker.js.map +3 -3
- package/package.json +3 -2
package/dist/process-worker.js
CHANGED
|
@@ -14,7 +14,7 @@ var __export = (target, all) => {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
// src/kernel/protocol.ts
|
|
17
|
-
var WASM_PROCESS_INIT, WASM_PROCESS_EXIT, WASM_PROCESS_ERROR, WASM_THREAD_SPAWN, WASM_THREAD_INIT, WASM_THREAD_EXIT, WASM_MAX_THREADS;
|
|
17
|
+
var WASM_PROCESS_INIT, WASM_PROCESS_EXIT, WASM_PROCESS_ERROR, WASM_THREAD_SPAWN, WASM_THREAD_INIT, WASM_THREAD_EXIT, WASM_MAX_THREADS, WASM_DEFAULT_THREADS;
|
|
18
18
|
var init_protocol = __esm({
|
|
19
19
|
"src/kernel/protocol.ts"() {
|
|
20
20
|
"use strict";
|
|
@@ -24,7 +24,8 @@ var init_protocol = __esm({
|
|
|
24
24
|
WASM_THREAD_SPAWN = "wasm-thread-spawn";
|
|
25
25
|
WASM_THREAD_INIT = "wasm-thread-init";
|
|
26
26
|
WASM_THREAD_EXIT = "wasm-thread-exit";
|
|
27
|
-
WASM_MAX_THREADS =
|
|
27
|
+
WASM_MAX_THREADS = 256;
|
|
28
|
+
WASM_DEFAULT_THREADS = 64;
|
|
28
29
|
}
|
|
29
30
|
});
|
|
30
31
|
|
|
@@ -468,7 +469,7 @@ function createLiveVfsPlugin(Fs) {
|
|
|
468
469
|
};
|
|
469
470
|
}
|
|
470
471
|
function ownedBy(plugin, node) {
|
|
471
|
-
return !!node && plugin.mounts.has(node.mount);
|
|
472
|
+
return !!node?.live && plugin.mounts.has(node.mount);
|
|
472
473
|
}
|
|
473
474
|
function flushLiveVfs(Fs, plugin) {
|
|
474
475
|
for (const head of Fs.nameTable ?? []) {
|
|
@@ -494,7 +495,7 @@ function invalidateLiveVfs(Fs, plugin) {
|
|
|
494
495
|
s.stat = void 0;
|
|
495
496
|
s.listed = void 0;
|
|
496
497
|
if (s.openCount === 0) {
|
|
497
|
-
if (node !== node.mount.root) drop.push(node);
|
|
498
|
+
if (node !== node.mount.root && !node.mounted) drop.push(node);
|
|
498
499
|
} else if (s.loaded && !s.dirty) {
|
|
499
500
|
s.data = void 0;
|
|
500
501
|
s.len = 0;
|
|
@@ -515,6 +516,7 @@ function describeMountError(err) {
|
|
|
515
516
|
return typeof errno2 === "number" ? `errno ${errno2}` : String(err);
|
|
516
517
|
}
|
|
517
518
|
function mountLiveVfsDirs(Fs, bridge, dirs, warn) {
|
|
519
|
+
if (Fs.root?.memfs) Fs.root.node_ops = Fs.root.memfs;
|
|
518
520
|
if (typeof Fs.filesystems !== "object" || !Fs.filesystems) {
|
|
519
521
|
throw new Error(
|
|
520
522
|
"the module was linked without filesystem support, so the VFS cannot be mounted (link it with -sFORCE_FILESYSTEM=1)"
|
|
@@ -535,6 +537,55 @@ function mountLiveVfsDirs(Fs, bridge, dirs, warn) {
|
|
|
535
537
|
}
|
|
536
538
|
return { plugin, mounted };
|
|
537
539
|
}
|
|
540
|
+
function liveRoot(Fs, bridge) {
|
|
541
|
+
const root = Fs.root;
|
|
542
|
+
const plugin = Fs.filesystems.SLICC_LIVE_FS;
|
|
543
|
+
if (!root || !plugin) return;
|
|
544
|
+
root.mount.opts = { root: "/", bridge };
|
|
545
|
+
root.live = { len: 0, loaded: false, dirty: false, openCount: 0 };
|
|
546
|
+
plugin.mounts.add(root.mount);
|
|
547
|
+
invalidateLiveVfs(Fs, plugin);
|
|
548
|
+
guardRenames(Fs);
|
|
549
|
+
const memfs = root.memfs ?? root.node_ops;
|
|
550
|
+
const live = plugin.node_ops;
|
|
551
|
+
root.memfs = memfs;
|
|
552
|
+
const own = (name) => Object.hasOwn(root.contents ?? {}, name);
|
|
553
|
+
root.node_ops = {
|
|
554
|
+
...memfs,
|
|
555
|
+
lookup: (parent, name) => live.lookup(parent, name),
|
|
556
|
+
mknod: (parent, name, mode, dev) => live.mknod(parent, name, mode, dev),
|
|
557
|
+
unlink: (parent, name) => live.unlink(parent, name),
|
|
558
|
+
rmdir: (parent, name) => (own(name) ? memfs : live).rmdir(parent, name),
|
|
559
|
+
symlink: (parent, name, target) => live.symlink(parent, name, target),
|
|
560
|
+
rename: (node, dir, name) => (node.live ? live : memfs).rename(node, dir, name),
|
|
561
|
+
readdir(node) {
|
|
562
|
+
const names = new Set(memfs.readdir(node));
|
|
563
|
+
for (const name of live.readdir(node)) names.add(name);
|
|
564
|
+
return [...names];
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
function crosses(Fs, from, to) {
|
|
569
|
+
const parentOf = (path) => Fs.lookupPath?.(path, { parent: true }).node;
|
|
570
|
+
const name = from.replace(/\/+$/, "").split("/").pop() ?? "";
|
|
571
|
+
try {
|
|
572
|
+
const fromDir = parentOf(from);
|
|
573
|
+
const node = fromDir && Fs.lookupNode?.(fromDir, name);
|
|
574
|
+
const dir = parentOf(to);
|
|
575
|
+
return !!node && !!dir && !!node.live !== !!dir.live;
|
|
576
|
+
} catch {
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
function guardRenames(Fs) {
|
|
581
|
+
const rename = Fs.rename?.bind(Fs);
|
|
582
|
+
if (!rename || Fs.sliccRename) return;
|
|
583
|
+
Fs.sliccRename = true;
|
|
584
|
+
Fs.rename = (from, to) => {
|
|
585
|
+
if (crosses(Fs, from, to)) throw new Fs.ErrnoError(ERRNO_BY_CODE.EXDEV);
|
|
586
|
+
rename(from, to);
|
|
587
|
+
};
|
|
588
|
+
}
|
|
538
589
|
var ERRNO_BY_CODE, EIO, S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END;
|
|
539
590
|
var init_live_vfs_fs = __esm({
|
|
540
591
|
"src/realm/live-vfs-fs.ts"() {
|
|
@@ -579,7 +630,7 @@ function topLevelDirs(bridge, warn) {
|
|
|
579
630
|
names = bridge.readdir("/");
|
|
580
631
|
} catch (err) {
|
|
581
632
|
warn(`cannot list the VFS root, nothing mounted: ${String(err)}`);
|
|
582
|
-
return
|
|
633
|
+
return void 0;
|
|
583
634
|
}
|
|
584
635
|
const candidates = names.filter((name) => name && !name.includes("/") && !MODULE_OWNED_DIRS.has(name)).map((name) => `/${name}`);
|
|
585
636
|
for (const dir of SYNTHETIC_DIRS) if (!candidates.includes(dir)) candidates.push(dir);
|
|
@@ -594,7 +645,9 @@ function topLevelDirs(bridge, warn) {
|
|
|
594
645
|
}
|
|
595
646
|
function mountVfsIntoEmscripten(Fs, deps) {
|
|
596
647
|
const { bridge, warn } = deps;
|
|
597
|
-
const
|
|
648
|
+
const dirs = topLevelDirs(bridge, warn);
|
|
649
|
+
const { plugin, mounted } = mountLiveVfsDirs(Fs, bridge, dirs ?? [], warn);
|
|
650
|
+
if (dirs) liveRoot(Fs, bridge);
|
|
598
651
|
try {
|
|
599
652
|
Fs.chdir(deps.cwd);
|
|
600
653
|
} catch (err) {
|
|
@@ -1625,6 +1678,28 @@ function wrapCloexecSyscalls(imports, glue, deps) {
|
|
|
1625
1678
|
}
|
|
1626
1679
|
}
|
|
1627
1680
|
}
|
|
1681
|
+
function persistsItself(stream) {
|
|
1682
|
+
const type = stream.node.mount?.type;
|
|
1683
|
+
return typeof type?.syncfs === "function";
|
|
1684
|
+
}
|
|
1685
|
+
function syncFsync(imports, fs) {
|
|
1686
|
+
for (const namespace of Object.values(imports)) {
|
|
1687
|
+
const original = namespace?.fd_sync;
|
|
1688
|
+
if (typeof original !== "function" || !original.isAsync) continue;
|
|
1689
|
+
namespace.fd_sync = (fd) => {
|
|
1690
|
+
const stream = fs()?.getStream(fd);
|
|
1691
|
+
if (!stream) return EBADF;
|
|
1692
|
+
if (persistsItself(stream)) return original(fd);
|
|
1693
|
+
try {
|
|
1694
|
+
const result = stream.stream_ops.fsync?.(stream);
|
|
1695
|
+
return typeof result === "number" ? result : 0;
|
|
1696
|
+
} catch (err) {
|
|
1697
|
+
const { errno: errno2, code: code2 } = err;
|
|
1698
|
+
return typeof errno2 === "number" ? errno2 : wasiErrno(String(code2));
|
|
1699
|
+
}
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1628
1703
|
function wasmMemory(instance, imports) {
|
|
1629
1704
|
const isMemory = (v) => v instanceof WebAssembly.Memory;
|
|
1630
1705
|
const exported = Object.values(instance.exports).find(isMemory);
|
|
@@ -1719,7 +1794,7 @@ function useDevFd(Fs) {
|
|
|
1719
1794
|
return fstat.call(Fs, fd);
|
|
1720
1795
|
};
|
|
1721
1796
|
}
|
|
1722
|
-
var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, DIR_MODE, LINK_MODE;
|
|
1797
|
+
var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, DIR_MODE, LINK_MODE;
|
|
1723
1798
|
var init_process_fds = __esm({
|
|
1724
1799
|
"src/process/process-fds.ts"() {
|
|
1725
1800
|
"use strict";
|
|
@@ -1742,6 +1817,7 @@ var init_process_fds = __esm({
|
|
|
1742
1817
|
ioctl: "__syscall_ioctl",
|
|
1743
1818
|
setitimer: "_setitimer_js"
|
|
1744
1819
|
};
|
|
1820
|
+
EBADF = 8;
|
|
1745
1821
|
DIR_MODE = 16749;
|
|
1746
1822
|
LINK_MODE = 41408;
|
|
1747
1823
|
}
|
|
@@ -2402,6 +2478,7 @@ async function runWasmProcess(init, port, deps = {}) {
|
|
|
2402
2478
|
}
|
|
2403
2479
|
}
|
|
2404
2480
|
});
|
|
2481
|
+
syncFsync(imports, () => ownValue(module, "FS"));
|
|
2405
2482
|
return WebAssembly.instantiate(init.program.module, imports);
|
|
2406
2483
|
}).then((instance) => {
|
|
2407
2484
|
memory = wasmMemory(instance, imports);
|
|
@@ -4255,6 +4332,7 @@ function importsContext({
|
|
|
4255
4332
|
fs,
|
|
4256
4333
|
fds,
|
|
4257
4334
|
syscall: call2,
|
|
4335
|
+
...processes(host, call2),
|
|
4258
4336
|
async: {
|
|
4259
4337
|
submit: (req) => call2({ op: "async-submit", req }),
|
|
4260
4338
|
wait(timeoutMs) {
|
|
@@ -4284,13 +4362,69 @@ function importsContext({
|
|
|
4284
4362
|
errno: (err) => wasiErrnoOf(code(err))
|
|
4285
4363
|
};
|
|
4286
4364
|
}
|
|
4287
|
-
|
|
4365
|
+
function processes(host, call2) {
|
|
4366
|
+
const close = (fd) => void call2({ op: "fd-close", fd });
|
|
4367
|
+
const slot = (n, how, mine, theirs) => {
|
|
4368
|
+
if (how === "inherit") return { fd: n };
|
|
4369
|
+
if (how === "null") return { none: true };
|
|
4370
|
+
const [read, write] = call2({ op: "fd-pipe" });
|
|
4371
|
+
mine[n] = n === 0 ? write : read;
|
|
4372
|
+
theirs.push(n === 0 ? read : write);
|
|
4373
|
+
return { fd: n === 0 ? read : write };
|
|
4374
|
+
};
|
|
4375
|
+
return {
|
|
4376
|
+
spawn(o) {
|
|
4377
|
+
const mine = [];
|
|
4378
|
+
const theirs = [];
|
|
4379
|
+
host.fds.promoteFiles();
|
|
4380
|
+
try {
|
|
4381
|
+
const stdio = STDIO.map((name, n) => slot(n, o[name] ?? "inherit", mine, theirs));
|
|
4382
|
+
const pid = call2({
|
|
4383
|
+
op: "proc-spawn",
|
|
4384
|
+
file: o.argv[0],
|
|
4385
|
+
argv: o.argv,
|
|
4386
|
+
env: o.env ?? { ...host.o.env },
|
|
4387
|
+
cwd: o.cwd ?? host.cwd,
|
|
4388
|
+
stdio
|
|
4389
|
+
});
|
|
4390
|
+
const out = { pid };
|
|
4391
|
+
STDIO.forEach((name, n) => {
|
|
4392
|
+
if (mine[n] !== void 0) out[name] = mine[n];
|
|
4393
|
+
});
|
|
4394
|
+
return out;
|
|
4395
|
+
} catch (err) {
|
|
4396
|
+
for (const fd of mine) if (fd !== void 0) close(fd);
|
|
4397
|
+
throw err;
|
|
4398
|
+
} finally {
|
|
4399
|
+
for (const fd of theirs) close(fd);
|
|
4400
|
+
host.o.fs.invalidate?.();
|
|
4401
|
+
}
|
|
4402
|
+
},
|
|
4403
|
+
wait(pid) {
|
|
4404
|
+
for (; ; ) {
|
|
4405
|
+
try {
|
|
4406
|
+
const [, status2] = call2({ op: "proc-wait", pid, nohang: false });
|
|
4407
|
+
host.o.fs.invalidate?.();
|
|
4408
|
+
const signal = status2 & 127;
|
|
4409
|
+
return signal ? { status: 128 + signal, signal } : { status: status2 >> 8 & 255 };
|
|
4410
|
+
} catch (err) {
|
|
4411
|
+
if (code(err) !== "EINTR") throw err;
|
|
4412
|
+
}
|
|
4413
|
+
}
|
|
4414
|
+
},
|
|
4415
|
+
kill(pid, sig) {
|
|
4416
|
+
call2({ op: "proc-kill", pid, sig });
|
|
4417
|
+
}
|
|
4418
|
+
};
|
|
4419
|
+
}
|
|
4420
|
+
var UID, STDIO;
|
|
4288
4421
|
var init_wasi_imports = __esm({
|
|
4289
4422
|
"src/process/wasi/wasi-imports.ts"() {
|
|
4290
4423
|
"use strict";
|
|
4291
4424
|
init_wasi_abi();
|
|
4292
4425
|
init_wasi_files();
|
|
4293
4426
|
UID = 1e3;
|
|
4427
|
+
STDIO = ["stdin", "stdout", "stderr"];
|
|
4294
4428
|
}
|
|
4295
4429
|
});
|
|
4296
4430
|
|
|
@@ -4409,7 +4543,7 @@ var init_wasi_stats = __esm({
|
|
|
4409
4543
|
// src/process/wasi/wasi-threads.ts
|
|
4410
4544
|
function threadCap(env) {
|
|
4411
4545
|
const asked = Number.parseInt(env.SLICC_WASM_THREADS ?? "", 10);
|
|
4412
|
-
return asked >= 1 ? Math.min(asked, WASM_MAX_THREADS) :
|
|
4546
|
+
return asked >= 1 ? Math.min(asked, WASM_MAX_THREADS) : WASM_DEFAULT_THREADS;
|
|
4413
4547
|
}
|
|
4414
4548
|
var LAST_TID, RUNNING, MAIN_TID, ThreadExit, WasiThreads;
|
|
4415
4549
|
var init_wasi_threads = __esm({
|