@ai-ecoverse/slicc-kernel 1.133.3 → 1.133.5
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 +26 -2
- package/dist/kernel-worker.js +208 -17
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +2 -2
- package/dist/node-process-worker.js +238 -131
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +208 -17
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +226 -119
- package/dist/process-worker.js.map +4 -4
- package/dist/types/fs/changes.d.ts +1 -0
- package/dist/types/fs/meta.d.ts +7 -0
- package/dist/types/fs/opfs.d.ts +3 -0
- package/dist/types/fs/remote.d.ts +1 -0
- package/dist/types/kernel/held-cwd.d.ts +65 -0
- package/dist/types/kernel/host.d.ts +9 -0
- package/dist/types/kernel/process.d.ts +8 -0
- package/dist/types/kernel/protocol.d.ts +7 -0
- package/dist/types/launcher.d.ts +5 -0
- package/dist/types/process/wasi/wasi-fds.d.ts +7 -0
- package/dist/types/process/wasi/wasi-files.d.ts +2 -1
- package/dist/types/process/wasi/wasi-host.d.ts +2 -0
- package/dist/types/realm/live-vfs-fs.d.ts +4 -0
- package/package.json +2 -2
package/dist/process-worker.js
CHANGED
|
@@ -458,6 +458,70 @@ var init_access = __esm({
|
|
|
458
458
|
}
|
|
459
459
|
});
|
|
460
460
|
|
|
461
|
+
// src/fs/changes.ts
|
|
462
|
+
function changeHash(path) {
|
|
463
|
+
let h = 2166136261;
|
|
464
|
+
for (let i = 0; i < path.length; i++) {
|
|
465
|
+
h ^= path.charCodeAt(i);
|
|
466
|
+
h = Math.imul(h, 16777619);
|
|
467
|
+
}
|
|
468
|
+
return h === 0 ? 1 : h;
|
|
469
|
+
}
|
|
470
|
+
function normal(path) {
|
|
471
|
+
const parts = [];
|
|
472
|
+
for (const part of path.split("/")) {
|
|
473
|
+
if (part === "" || part === ".") continue;
|
|
474
|
+
if (part === "..") parts.pop();
|
|
475
|
+
else parts.push(part);
|
|
476
|
+
}
|
|
477
|
+
return `/${parts.join("/")}`;
|
|
478
|
+
}
|
|
479
|
+
var GEN, RING, RING_SIZE, SLOT, SHARED_TTL_MS, DIRTY, FOREIGN, CHANGES_BYTES, ChangeView;
|
|
480
|
+
var init_changes = __esm({
|
|
481
|
+
"src/fs/changes.ts"() {
|
|
482
|
+
"use strict";
|
|
483
|
+
GEN = 0;
|
|
484
|
+
RING = 1;
|
|
485
|
+
RING_SIZE = 4096;
|
|
486
|
+
SLOT = 2;
|
|
487
|
+
SHARED_TTL_MS = 100;
|
|
488
|
+
DIRTY = RING + RING_SIZE * SLOT;
|
|
489
|
+
FOREIGN = DIRTY + 1;
|
|
490
|
+
CHANGES_BYTES = (FOREIGN + 1) * 4;
|
|
491
|
+
ChangeView = class {
|
|
492
|
+
view;
|
|
493
|
+
constructor(sab) {
|
|
494
|
+
this.view = new Int32Array(sab);
|
|
495
|
+
}
|
|
496
|
+
now() {
|
|
497
|
+
return Atomics.load(this.view, GEN);
|
|
498
|
+
}
|
|
499
|
+
clean() {
|
|
500
|
+
return this.view.length > DIRTY && Atomics.load(this.view, DIRTY) === 0;
|
|
501
|
+
}
|
|
502
|
+
foreign() {
|
|
503
|
+
return this.view.length > FOREIGN && Atomics.load(this.view, FOREIGN) === 1;
|
|
504
|
+
}
|
|
505
|
+
changedSince(seen, path) {
|
|
506
|
+
const now = Atomics.load(this.view, GEN);
|
|
507
|
+
const distance = now - seen >>> 0;
|
|
508
|
+
if (distance === 0) return { now, changed: false };
|
|
509
|
+
if (distance > RING_SIZE) return { now, changed: true };
|
|
510
|
+
const hash = changeHash(normal(path));
|
|
511
|
+
for (let i = 1; i <= distance; i++) {
|
|
512
|
+
const g = seen + i | 0;
|
|
513
|
+
const at = RING + (g & RING_SIZE - 1) * SLOT;
|
|
514
|
+
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
515
|
+
const hit = Atomics.load(this.view, at + 1) === hash;
|
|
516
|
+
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
517
|
+
if (hit) return { now, changed: true };
|
|
518
|
+
}
|
|
519
|
+
return { now, changed: false };
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
|
|
461
525
|
// src/fs/pages.ts
|
|
462
526
|
var PAGE, READAHEAD, CLEAN_LIMIT, WRITEBACK, RUN, Pages;
|
|
463
527
|
var init_pages = __esm({
|
|
@@ -1036,69 +1100,6 @@ var init_sync_fs_wire = __esm({
|
|
|
1036
1100
|
}
|
|
1037
1101
|
});
|
|
1038
1102
|
|
|
1039
|
-
// src/fs/changes.ts
|
|
1040
|
-
function changeHash(path) {
|
|
1041
|
-
let h = 2166136261;
|
|
1042
|
-
for (let i = 0; i < path.length; i++) {
|
|
1043
|
-
h ^= path.charCodeAt(i);
|
|
1044
|
-
h = Math.imul(h, 16777619);
|
|
1045
|
-
}
|
|
1046
|
-
return h === 0 ? 1 : h;
|
|
1047
|
-
}
|
|
1048
|
-
function normal(path) {
|
|
1049
|
-
const parts = [];
|
|
1050
|
-
for (const part of path.split("/")) {
|
|
1051
|
-
if (part === "" || part === ".") continue;
|
|
1052
|
-
if (part === "..") parts.pop();
|
|
1053
|
-
else parts.push(part);
|
|
1054
|
-
}
|
|
1055
|
-
return `/${parts.join("/")}`;
|
|
1056
|
-
}
|
|
1057
|
-
var GEN, RING, RING_SIZE, SLOT, DIRTY, FOREIGN, CHANGES_BYTES, ChangeView;
|
|
1058
|
-
var init_changes = __esm({
|
|
1059
|
-
"src/fs/changes.ts"() {
|
|
1060
|
-
"use strict";
|
|
1061
|
-
GEN = 0;
|
|
1062
|
-
RING = 1;
|
|
1063
|
-
RING_SIZE = 4096;
|
|
1064
|
-
SLOT = 2;
|
|
1065
|
-
DIRTY = RING + RING_SIZE * SLOT;
|
|
1066
|
-
FOREIGN = DIRTY + 1;
|
|
1067
|
-
CHANGES_BYTES = (FOREIGN + 1) * 4;
|
|
1068
|
-
ChangeView = class {
|
|
1069
|
-
view;
|
|
1070
|
-
constructor(sab) {
|
|
1071
|
-
this.view = new Int32Array(sab);
|
|
1072
|
-
}
|
|
1073
|
-
now() {
|
|
1074
|
-
return Atomics.load(this.view, GEN);
|
|
1075
|
-
}
|
|
1076
|
-
clean() {
|
|
1077
|
-
return this.view.length > DIRTY && Atomics.load(this.view, DIRTY) === 0;
|
|
1078
|
-
}
|
|
1079
|
-
foreign() {
|
|
1080
|
-
return this.view.length > FOREIGN && Atomics.load(this.view, FOREIGN) === 1;
|
|
1081
|
-
}
|
|
1082
|
-
changedSince(seen, path) {
|
|
1083
|
-
const now = Atomics.load(this.view, GEN);
|
|
1084
|
-
const distance = now - seen >>> 0;
|
|
1085
|
-
if (distance === 0) return { now, changed: false };
|
|
1086
|
-
if (distance > RING_SIZE) return { now, changed: true };
|
|
1087
|
-
const hash = changeHash(normal(path));
|
|
1088
|
-
for (let i = 1; i <= distance; i++) {
|
|
1089
|
-
const g = seen + i | 0;
|
|
1090
|
-
const at = RING + (g & RING_SIZE - 1) * SLOT;
|
|
1091
|
-
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
1092
|
-
const hit = Atomics.load(this.view, at + 1) === hash;
|
|
1093
|
-
if (Atomics.load(this.view, at) !== g) return { now, changed: true };
|
|
1094
|
-
if (hit) return { now, changed: true };
|
|
1095
|
-
}
|
|
1096
|
-
return { now, changed: false };
|
|
1097
|
-
}
|
|
1098
|
-
};
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
1101
|
-
|
|
1102
1103
|
// src/realm/sync-sab-bridge.ts
|
|
1103
1104
|
function syncCallCount() {
|
|
1104
1105
|
return calls;
|
|
@@ -1469,8 +1470,16 @@ function refusal(err) {
|
|
|
1469
1470
|
const code2 = err?.code;
|
|
1470
1471
|
return code2 === "EACCES" || code2 === "EPERM";
|
|
1471
1472
|
}
|
|
1472
|
-
function
|
|
1473
|
-
|
|
1473
|
+
function young(s) {
|
|
1474
|
+
return performance.now() - (s.filledAt ?? Number.NEGATIVE_INFINITY) < SHARED_TTL_MS;
|
|
1475
|
+
}
|
|
1476
|
+
function cachedStat(node, dir, view) {
|
|
1477
|
+
const s = node.live;
|
|
1478
|
+
if (view?.foreign() && !s.dirty) {
|
|
1479
|
+
const gen = s.statGen ?? s.named;
|
|
1480
|
+
if (s.openCount > 0 || !young(s) || gen === void 0) return false;
|
|
1481
|
+
if (view.changedSince(gen, liveNodePath(node)).changed) return false;
|
|
1482
|
+
}
|
|
1474
1483
|
return s.stat !== void 0 && (!dir || s.statAt === syncCallCount());
|
|
1475
1484
|
}
|
|
1476
1485
|
function searchParents(Fs, node, bridge, call2) {
|
|
@@ -1536,9 +1545,22 @@ function linkedStates(bridgeOf) {
|
|
|
1536
1545
|
const holder = (node) => opens.get(node.live) ?? node;
|
|
1537
1546
|
return { opening: opening2, sharedWith, know, idOf: idOf4, holder };
|
|
1538
1547
|
}
|
|
1548
|
+
function filled(s, stat, asked) {
|
|
1549
|
+
Object.assign(s, { stat, statAt: syncCallCount(), seenAt: syncEpoch(), ...asked });
|
|
1550
|
+
}
|
|
1551
|
+
function asking(bridge) {
|
|
1552
|
+
return { filledAt: performance.now(), statGen: bridge.changes?.now() };
|
|
1553
|
+
}
|
|
1554
|
+
function listing(s) {
|
|
1555
|
+
return { filledAt: s.listedAt ?? Number.NEGATIVE_INFINITY, statGen: s.listedGen };
|
|
1556
|
+
}
|
|
1557
|
+
function answeredAt(node, asked) {
|
|
1558
|
+
Object.assign(node.live, asked);
|
|
1559
|
+
return node;
|
|
1560
|
+
}
|
|
1539
1561
|
function freshState(stat) {
|
|
1540
1562
|
const base = { len: 0, loaded: false, dirty: false, openCount: 0 };
|
|
1541
|
-
return stat ? { stat, statAt: syncCallCount(), seenAt: syncEpoch(), ...base } : base;
|
|
1563
|
+
return stat ? { stat, statAt: syncCallCount(), filledAt: performance.now(), seenAt: syncEpoch(), ...base } : base;
|
|
1542
1564
|
}
|
|
1543
1565
|
function createHelpers(Fs, ops) {
|
|
1544
1566
|
const bridgeOf = (node) => node.mount.opts.bridge;
|
|
@@ -1591,9 +1613,11 @@ function createHelpers(Fs, ops) {
|
|
|
1591
1613
|
const size = node.live.ranged?.size() ?? node.live.len;
|
|
1592
1614
|
return { ...node.live.stat, size };
|
|
1593
1615
|
}
|
|
1594
|
-
|
|
1616
|
+
const view = bridgeOf(node).changes;
|
|
1617
|
+
if (!cachedStat(node, Fs.isDir(node.mode), view)) {
|
|
1618
|
+
const asked = { statGen: view?.now(), filledAt: performance.now() };
|
|
1595
1619
|
const st = call2(() => bridgeOf(node).lstat(liveNodePath(linked.holder(node))));
|
|
1596
|
-
|
|
1620
|
+
filled(node.live, st, asked);
|
|
1597
1621
|
node.mode = modeFromStat(st, exactIn(node));
|
|
1598
1622
|
}
|
|
1599
1623
|
return node.live.stat;
|
|
@@ -1755,7 +1779,7 @@ function createNodeOps(h) {
|
|
|
1755
1779
|
const owned = bridgeOf(node).owners === true;
|
|
1756
1780
|
if (owned && Fs.isLink(node.mode) && statOf(node).uid === void 0)
|
|
1757
1781
|
node.live.stat = void 0;
|
|
1758
|
-
const cached = owned && cachedStat(node
|
|
1782
|
+
const cached = owned && cachedStat(node, Fs.isDir(node.mode), bridgeOf(node).changes);
|
|
1759
1783
|
const st = statOf(node);
|
|
1760
1784
|
if (cached) searchParents(Fs, node, bridgeOf(node), call2);
|
|
1761
1785
|
const s = node.live;
|
|
@@ -1804,8 +1828,9 @@ function createNodeOps(h) {
|
|
|
1804
1828
|
lookup(parent, name2) {
|
|
1805
1829
|
const listed2 = parent.live.listed?.get(name2);
|
|
1806
1830
|
parent.live.listed?.delete(name2);
|
|
1831
|
+
const asked = listed2 ? listing(parent.live) : asking(bridgeOf(parent));
|
|
1807
1832
|
const st = listed2 ?? call2(() => bridgeOf(parent).lstat(childPath(parent, name2)));
|
|
1808
|
-
return makeNode(parent, name2, st);
|
|
1833
|
+
return answeredAt(makeNode(parent, name2, st), asked);
|
|
1809
1834
|
},
|
|
1810
1835
|
mknod(parent, name2, mode) {
|
|
1811
1836
|
parent.live.listed = void 0;
|
|
@@ -1878,8 +1903,11 @@ function createNodeOps(h) {
|
|
|
1878
1903
|
call2(() => bridgeOf(parent).rmdir(childPath(parent, name2)));
|
|
1879
1904
|
},
|
|
1880
1905
|
readdir(node) {
|
|
1906
|
+
const listedAt = performance.now();
|
|
1907
|
+
const listedGen = bridgeOf(node).changes?.now();
|
|
1881
1908
|
const listed2 = call2(() => bridgeOf(node).readdirStat(liveNodePath(node)));
|
|
1882
1909
|
node.live.listed = /* @__PURE__ */ new Map();
|
|
1910
|
+
Object.assign(node.live, { listedAt, listedGen });
|
|
1883
1911
|
for (const [name2, st] of listed2) if (st) node.live.listed.set(name2, st);
|
|
1884
1912
|
return [".", "..", ...listed2.map(([name2]) => name2)];
|
|
1885
1913
|
},
|
|
@@ -2511,6 +2539,7 @@ var init_live_vfs_fs = __esm({
|
|
|
2511
2539
|
"src/realm/live-vfs-fs.ts"() {
|
|
2512
2540
|
"use strict";
|
|
2513
2541
|
init_access();
|
|
2542
|
+
init_changes();
|
|
2514
2543
|
init_ranged();
|
|
2515
2544
|
init_types();
|
|
2516
2545
|
init_wasi_errno();
|
|
@@ -2664,7 +2693,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
2664
2693
|
var init_version = __esm({
|
|
2665
2694
|
"src/version.ts"() {
|
|
2666
2695
|
"use strict";
|
|
2667
|
-
KERNEL_VERSION = true ? "1.133.
|
|
2696
|
+
KERNEL_VERSION = true ? "1.133.5" : "0.0.0-dev";
|
|
2668
2697
|
OS_RELEASE = "6.0.0-slicc";
|
|
2669
2698
|
}
|
|
2670
2699
|
});
|
|
@@ -5366,8 +5395,8 @@ function sysEntry(parts) {
|
|
|
5366
5395
|
}
|
|
5367
5396
|
return at;
|
|
5368
5397
|
}
|
|
5369
|
-
function sysText(file,
|
|
5370
|
-
return typeof file === "string" ? file : file(
|
|
5398
|
+
function sysText(file, listing2) {
|
|
5399
|
+
return typeof file === "string" ? file : file(listing2());
|
|
5371
5400
|
}
|
|
5372
5401
|
function commOf(info) {
|
|
5373
5402
|
const name2 = info.argv[0] ?? "";
|
|
@@ -5495,35 +5524,35 @@ function memoryInfo(source, used = 0) {
|
|
|
5495
5524
|
["SwapFree", kb(0)]
|
|
5496
5525
|
].map(([key, value2]) => `${`${key}:`.padEnd(16)}${value2.padStart(12)}`).concat("").join("\n");
|
|
5497
5526
|
}
|
|
5498
|
-
function systemFile(name2,
|
|
5527
|
+
function systemFile(name2, listing2, now, memory) {
|
|
5499
5528
|
if (name2 === "version") return procVersion();
|
|
5500
|
-
const up = Math.max(0, now -
|
|
5529
|
+
const up = Math.max(0, now - listing2.boot) / 1e3;
|
|
5501
5530
|
if (name2 === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
|
|
5502
5531
|
`;
|
|
5503
5532
|
if (name2 === "meminfo") {
|
|
5504
5533
|
return memoryInfo(
|
|
5505
5534
|
memory,
|
|
5506
|
-
|
|
5535
|
+
listing2.processes.reduce((sum2, p) => sum2 + p.memory, 0)
|
|
5507
5536
|
);
|
|
5508
5537
|
}
|
|
5509
|
-
const live =
|
|
5538
|
+
const live = listing2.processes.filter((p) => p.state !== "Z");
|
|
5510
5539
|
if (name2 === "loadavg") {
|
|
5511
|
-
const last = Math.max(0, ...
|
|
5512
|
-
const [one, five, fifteen] = (
|
|
5540
|
+
const last = Math.max(0, ...listing2.processes.map((p) => p.pid));
|
|
5541
|
+
const [one, five, fifteen] = (listing2.load ?? [0, 0, 0]).map((n) => n.toFixed(2));
|
|
5513
5542
|
return `${one} ${five} ${fifteen} 1/${live.length} ${last}
|
|
5514
5543
|
`;
|
|
5515
5544
|
}
|
|
5516
|
-
const sum = (key) =>
|
|
5545
|
+
const sum = (key) => listing2.cpu?.[key] ?? listing2.processes.reduce((n, p) => n + (p[key] ?? 0), 0);
|
|
5517
5546
|
const user = ticks(sum("utime"));
|
|
5518
5547
|
const system = ticks(sum("stime"));
|
|
5519
|
-
const idle =
|
|
5548
|
+
const idle = listing2.cpu ? ticks(listing2.cpu.idle) : Math.max(0, ticks(now - listing2.boot) - user - system);
|
|
5520
5549
|
return [
|
|
5521
5550
|
`cpu ${user} 0 ${system} ${idle} 0 0 0 0 0 0`,
|
|
5522
5551
|
`cpu0 ${user} 0 ${system} ${idle} 0 0 0 0 0 0`,
|
|
5523
5552
|
"intr 0",
|
|
5524
5553
|
"ctxt 0",
|
|
5525
|
-
`btime ${Math.floor(
|
|
5526
|
-
`processes ${
|
|
5554
|
+
`btime ${Math.floor(listing2.boot / 1e3)}`,
|
|
5555
|
+
`processes ${listing2.processes.length}`,
|
|
5527
5556
|
"procs_running 1",
|
|
5528
5557
|
"procs_blocked 0",
|
|
5529
5558
|
""
|
|
@@ -5608,10 +5637,10 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
|
|
|
5608
5637
|
const find = (processes2, target, own) => (own ? processes2.find((p) => p.tid === target) : void 0) ?? processes2.find((p) => p.pid === target || p.tid === target);
|
|
5609
5638
|
const infoOf = (target) => find(procList().processes, target, false);
|
|
5610
5639
|
const pidContent = (target, name2, own = false) => () => {
|
|
5611
|
-
const
|
|
5612
|
-
const info = find(
|
|
5640
|
+
const listing2 = procList();
|
|
5641
|
+
const info = find(listing2.processes, target, own);
|
|
5613
5642
|
if (!info) throw error();
|
|
5614
|
-
return pidFile(name2, info,
|
|
5643
|
+
return pidFile(name2, info, listing2.boot);
|
|
5615
5644
|
};
|
|
5616
5645
|
const sysDir = (parent, name2, tree) => {
|
|
5617
5646
|
const dir = fresh(parent, name2, DIR_MODE2);
|
|
@@ -5746,15 +5775,15 @@ var init_procfs = __esm({
|
|
|
5746
5775
|
osrelease: `${OS_RELEASE}
|
|
5747
5776
|
`,
|
|
5748
5777
|
ostype: "Linux\n",
|
|
5749
|
-
slicc_wasm_memories: (
|
|
5778
|
+
slicc_wasm_memories: (listing2) => `${listing2.wasm?.live ?? 0} ${listing2.wasm?.ceiling ?? 0} ${listing2.wasm?.source ?? "none"}
|
|
5750
5779
|
`,
|
|
5751
|
-
slicc_shared_root: (
|
|
5780
|
+
slicc_shared_root: (listing2) => `${listing2.peers ?? 0}
|
|
5752
5781
|
`,
|
|
5753
|
-
slicc_fs_calls: (
|
|
5782
|
+
slicc_fs_calls: (listing2) => `${listing2.fsCalls ?? 0}
|
|
5754
5783
|
`,
|
|
5755
|
-
slicc_opfs_calls: (
|
|
5784
|
+
slicc_opfs_calls: (listing2) => `${listing2.opfsCalls ?? 0}
|
|
5756
5785
|
`,
|
|
5757
|
-
slicc_opfs_ops: (
|
|
5786
|
+
slicc_opfs_ops: (listing2) => `${listing2.opfsOps ?? 0}
|
|
5758
5787
|
`
|
|
5759
5788
|
}
|
|
5760
5789
|
};
|
|
@@ -6579,6 +6608,59 @@ var init_physical_path = __esm({
|
|
|
6579
6608
|
}
|
|
6580
6609
|
});
|
|
6581
6610
|
|
|
6611
|
+
// src/kernel/held-cwd.ts
|
|
6612
|
+
var CWD_SLOTS, UNTRACKED, HeldCwd;
|
|
6613
|
+
var init_held_cwd = __esm({
|
|
6614
|
+
"src/kernel/held-cwd.ts"() {
|
|
6615
|
+
"use strict";
|
|
6616
|
+
CWD_SLOTS = 1024;
|
|
6617
|
+
UNTRACKED = CWD_SLOTS - 1;
|
|
6618
|
+
HeldCwd = class {
|
|
6619
|
+
view;
|
|
6620
|
+
seen;
|
|
6621
|
+
dead = false;
|
|
6622
|
+
slot;
|
|
6623
|
+
at;
|
|
6624
|
+
ask;
|
|
6625
|
+
constructor(sab, slot2, ask, state) {
|
|
6626
|
+
this.view = new Int32Array(sab);
|
|
6627
|
+
this.slot = slot2;
|
|
6628
|
+
this.ask = ask;
|
|
6629
|
+
this.seen = state.seen;
|
|
6630
|
+
this.dead = state.dead;
|
|
6631
|
+
this.at = state.path;
|
|
6632
|
+
}
|
|
6633
|
+
moved(reply, path) {
|
|
6634
|
+
if (reply.slot === void 0) return false;
|
|
6635
|
+
this.slot = reply.slot;
|
|
6636
|
+
this.seen = reply.seen ?? Atomics.load(this.view, reply.slot);
|
|
6637
|
+
this.dead = reply.dead === true;
|
|
6638
|
+
this.at = path;
|
|
6639
|
+
return true;
|
|
6640
|
+
}
|
|
6641
|
+
follow() {
|
|
6642
|
+
const answer2 = this.ask();
|
|
6643
|
+
if (answer2.slot !== void 0) this.slot = answer2.slot;
|
|
6644
|
+
this.seen = answer2.gen;
|
|
6645
|
+
this.dead = !answer2.alive;
|
|
6646
|
+
return answer2.alive;
|
|
6647
|
+
}
|
|
6648
|
+
alive(path) {
|
|
6649
|
+
if (path !== void 0 && this.at !== void 0 && path !== this.at) {
|
|
6650
|
+
this.at = path;
|
|
6651
|
+
return this.follow();
|
|
6652
|
+
}
|
|
6653
|
+
if (this.dead) return false;
|
|
6654
|
+
if (Atomics.load(this.view, this.slot) === this.seen) return true;
|
|
6655
|
+
return this.follow();
|
|
6656
|
+
}
|
|
6657
|
+
get current() {
|
|
6658
|
+
return this.slot;
|
|
6659
|
+
}
|
|
6660
|
+
};
|
|
6661
|
+
}
|
|
6662
|
+
});
|
|
6663
|
+
|
|
6582
6664
|
// src/process/wasi/dylink.ts
|
|
6583
6665
|
function dylinkInfo(module) {
|
|
6584
6666
|
const [section2] = WebAssembly.Module.customSections(module, "dylink.0");
|
|
@@ -6741,11 +6823,11 @@ function copying(bridge, mutating, entry) {
|
|
|
6741
6823
|
copy: (from, to, mode, exclusive) => mutating(() => copy2.call(bridge, from, to, mode, exclusive), ...entry(to))
|
|
6742
6824
|
};
|
|
6743
6825
|
}
|
|
6744
|
-
function listed({ cache, seen, filled }, p, list, gen, asked) {
|
|
6826
|
+
function listed({ cache, seen, filled: filled2 }, p, list, gen, asked) {
|
|
6745
6827
|
const base = p === "/" ? "" : p;
|
|
6746
6828
|
for (const [name2, st] of list) {
|
|
6747
6829
|
if (!st) continue;
|
|
6748
|
-
|
|
6830
|
+
filled2.set(st, asked);
|
|
6749
6831
|
const at = `${base}/${name2}`;
|
|
6750
6832
|
cache.put(cache.lstats, at, st);
|
|
6751
6833
|
if (gen !== void 0) seen.saw(cache.lstats, at, gen);
|
|
@@ -6758,7 +6840,7 @@ function fetched({
|
|
|
6758
6840
|
view,
|
|
6759
6841
|
now,
|
|
6760
6842
|
seen,
|
|
6761
|
-
filled,
|
|
6843
|
+
filled: filled2,
|
|
6762
6844
|
cache
|
|
6763
6845
|
}, map, path, get) {
|
|
6764
6846
|
const gen = view?.now();
|
|
@@ -6770,7 +6852,7 @@ function fetched({
|
|
|
6770
6852
|
} catch (e) {
|
|
6771
6853
|
hit = { error: e, until: asked + MISS_TTL_MS, ...gen !== void 0 ? { gen } : {} };
|
|
6772
6854
|
}
|
|
6773
|
-
|
|
6855
|
+
filled2.set(hit, asked);
|
|
6774
6856
|
cache.put(map, path, hit);
|
|
6775
6857
|
return hit;
|
|
6776
6858
|
}
|
|
@@ -6779,17 +6861,17 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
6779
6861
|
const cache = new StatCache(blind ? void 0 : shared);
|
|
6780
6862
|
const { stats, lstats } = cache;
|
|
6781
6863
|
const view = bridge.changes;
|
|
6782
|
-
const
|
|
6783
|
-
const
|
|
6784
|
-
const live = (miss, path) => miss.until > now() &&
|
|
6864
|
+
const filled2 = new Fills(view, now);
|
|
6865
|
+
const young2 = (entry2) => filled2.young(entry2);
|
|
6866
|
+
const live = (miss, path) => miss.until > now() && young2(miss) && (view === void 0 || miss.gen === void 0 || !view.changedSince(miss.gen, path).changed);
|
|
6785
6867
|
const seen = new SeenAt(view, lstats);
|
|
6786
|
-
const kept = remember(cache, seen, blind, (entry2) =>
|
|
6868
|
+
const kept = remember(cache, seen, blind, (entry2) => filled2.set(entry2));
|
|
6787
6869
|
const gone = (path) => goneAbove([lstats, stats], live, path);
|
|
6788
6870
|
const usable = (map, path) => {
|
|
6789
6871
|
const hit = map.get(path);
|
|
6790
6872
|
if (hit === void 0) return void 0;
|
|
6791
6873
|
if ("until" in hit) return live(hit, path) ? hit : void 0;
|
|
6792
|
-
return
|
|
6874
|
+
return young2(hit) && !seen.changed(map, path) ? hit : void 0;
|
|
6793
6875
|
};
|
|
6794
6876
|
const cached = (map, path, get) => {
|
|
6795
6877
|
if (blind) return get();
|
|
@@ -6798,7 +6880,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
6798
6880
|
if (hit === void 0) {
|
|
6799
6881
|
const missing2 = gone(path);
|
|
6800
6882
|
if (missing2) throw missing2.error;
|
|
6801
|
-
hit = fetched({ view, now, seen, filled, cache }, map, path, get);
|
|
6883
|
+
hit = fetched({ view, now, seen, filled: filled2, cache }, map, path, get);
|
|
6802
6884
|
}
|
|
6803
6885
|
if ("until" in hit) throw hit.error;
|
|
6804
6886
|
return hit;
|
|
@@ -6857,14 +6939,14 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
6857
6939
|
const gen = view?.now();
|
|
6858
6940
|
const asked = now();
|
|
6859
6941
|
const list = bridge.readdirStat(p);
|
|
6860
|
-
if (!blind) listed({ cache, seen, filled }, p, list, gen, asked);
|
|
6942
|
+
if (!blind) listed({ cache, seen, filled: filled2 }, p, list, gen, asked);
|
|
6861
6943
|
return list;
|
|
6862
6944
|
},
|
|
6863
6945
|
readlink: (p) => {
|
|
6864
6946
|
const known = blind ? void 0 : (cache.fresh(), lstats.get(p));
|
|
6865
6947
|
const gen = seen.lstat(p);
|
|
6866
6948
|
const current = view !== void 0 && gen !== void 0 && !view.changedSince(gen, p).changed;
|
|
6867
|
-
if (known && current && !("until" in known) &&
|
|
6949
|
+
if (known && current && !("until" in known) && young2(known) && !known.isSymbolicLink) {
|
|
6868
6950
|
throw syncError("EINVAL", `'${p}' is not a symbolic link`);
|
|
6869
6951
|
}
|
|
6870
6952
|
return bridge.readlink(p);
|
|
@@ -6937,10 +7019,11 @@ function pinnedIo2(bridge, handle, rewriting) {
|
|
|
6937
7019
|
} : {}
|
|
6938
7020
|
};
|
|
6939
7021
|
}
|
|
6940
|
-
var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS,
|
|
7022
|
+
var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, CACHE_CAP, FS_GEN, CRED_GEN, UMASK2, RING2, RING_SIZE2, SLOT2, FD_RING, FD_RING_SIZE, SHARED_IDS_BYTES, StatCache, SEEN_CAP, SeenAt, remember, Fills;
|
|
6941
7023
|
var init_wasi_files = __esm({
|
|
6942
7024
|
"src/process/wasi/wasi-files.ts"() {
|
|
6943
7025
|
"use strict";
|
|
7026
|
+
init_changes();
|
|
6944
7027
|
init_ranged();
|
|
6945
7028
|
init_sync_fs_wire();
|
|
6946
7029
|
WasiError = class extends Error {
|
|
@@ -7164,7 +7247,6 @@ var init_wasi_files = __esm({
|
|
|
7164
7247
|
};
|
|
7165
7248
|
MAX_LINKS = 40;
|
|
7166
7249
|
MISS_TTL_MS = 20;
|
|
7167
|
-
SHARED_TTL_MS = 100;
|
|
7168
7250
|
CACHE_CAP = 8192;
|
|
7169
7251
|
FS_GEN = 4;
|
|
7170
7252
|
CRED_GEN = 5;
|
|
@@ -8770,6 +8852,7 @@ var init_wasi_fds = __esm({
|
|
|
8770
8852
|
e.path = path;
|
|
8771
8853
|
this.kernel.call({ op: "fd-meta", fd, meta: metaOf(e) });
|
|
8772
8854
|
}
|
|
8855
|
+
this.held?.moved(this.kernel.call({ op: "cwd-chdir", path }), path);
|
|
8773
8856
|
this.bump();
|
|
8774
8857
|
}
|
|
8775
8858
|
promote(fd, moved = false) {
|
|
@@ -9056,9 +9139,21 @@ var init_wasi_fds = __esm({
|
|
|
9056
9139
|
this.buffers.set(next2, buffer);
|
|
9057
9140
|
}
|
|
9058
9141
|
}
|
|
9142
|
+
held;
|
|
9143
|
+
cwdEntry(dir) {
|
|
9144
|
+
return dir.preopen === "." || dir.preopen === "./";
|
|
9145
|
+
}
|
|
9146
|
+
goneCwd(dir) {
|
|
9147
|
+
return this.held !== void 0 && this.cwdEntry(dir) && !this.held.alive(dir.path);
|
|
9148
|
+
}
|
|
9059
9149
|
resolve(dirfd, path) {
|
|
9060
9150
|
if (path === "") throw new WasiError("ENOENT");
|
|
9061
|
-
|
|
9151
|
+
if (path.startsWith("/")) return this.joined(path);
|
|
9152
|
+
const dir = this.dir(dirfd);
|
|
9153
|
+
if (path.split("/")[0] !== ".." && this.goneCwd(dir)) throw new WasiError("ENOENT");
|
|
9154
|
+
return this.joined(`${dir.path}/${path}`);
|
|
9155
|
+
}
|
|
9156
|
+
joined(joined2) {
|
|
9062
9157
|
return joined2.split("/").includes("..") ? physical(this.fs, joined2) : normalize(joined2);
|
|
9063
9158
|
}
|
|
9064
9159
|
openKernelDevice(path, oflags, fdflags, rights) {
|
|
@@ -10355,6 +10450,7 @@ var init_wasi_host = __esm({
|
|
|
10355
10450
|
this.o = { ...o, kernel: { sys, call: call2 } };
|
|
10356
10451
|
this.startCwd = o.cwd;
|
|
10357
10452
|
this.fds = new WasiFds(this.o.kernel, o.fs);
|
|
10453
|
+
if (o.held) this.fds.held = o.held;
|
|
10358
10454
|
this.creds = new CredCache(
|
|
10359
10455
|
() => this.o.kernel.call({ op: "proc-cred" }),
|
|
10360
10456
|
o.credGen ?? o.shared
|
|
@@ -11318,13 +11414,13 @@ var init_wasi_host = __esm({
|
|
|
11318
11414
|
const view = this.mem.view();
|
|
11319
11415
|
const size = Math.min(view.getUint32(at, true), SIGINFO_BYTES);
|
|
11320
11416
|
const fields = [sig, info.code, info.pid, info.uid, info.status];
|
|
11321
|
-
let
|
|
11417
|
+
let filled2 = 4;
|
|
11322
11418
|
for (const [i, value2] of fields.entries()) {
|
|
11323
11419
|
if (4 + (i + 1) * 4 > size) break;
|
|
11324
11420
|
view.setInt32(4 + at + i * 4, value2, true);
|
|
11325
|
-
|
|
11421
|
+
filled2 = 4 + (i + 1) * 4;
|
|
11326
11422
|
}
|
|
11327
|
-
view.setUint32(at,
|
|
11423
|
+
view.setUint32(at, filled2, true);
|
|
11328
11424
|
return true;
|
|
11329
11425
|
}
|
|
11330
11426
|
fdAlias(path) {
|
|
@@ -11436,7 +11532,9 @@ var init_wasi_host = __esm({
|
|
|
11436
11532
|
}
|
|
11437
11533
|
readdir(fd, buf, len, cookie, usedPtr) {
|
|
11438
11534
|
const dir = this.fds.dir(fd);
|
|
11439
|
-
if (cookie === 0 || !dir.listing)
|
|
11535
|
+
if (cookie === 0 || !dir.listing) {
|
|
11536
|
+
dir.listing = this.fds.goneCwd(dir) ? { names: [], stats: /* @__PURE__ */ new Map() } : this.list(dir.path);
|
|
11537
|
+
}
|
|
11440
11538
|
const { names, stats } = dir.listing;
|
|
11441
11539
|
let at = 0;
|
|
11442
11540
|
for (let i = cookie; i < names.length && at < len; i++) {
|
|
@@ -12389,10 +12487,10 @@ var init_wasi_procfs = __esm({
|
|
|
12389
12487
|
return {
|
|
12390
12488
|
kind: "file",
|
|
12391
12489
|
content: () => {
|
|
12392
|
-
const
|
|
12393
|
-
const info =
|
|
12490
|
+
const listing2 = this.listing();
|
|
12491
|
+
const info = listing2.processes.find((p) => p.pid === Number(top));
|
|
12394
12492
|
if (!info) throw syncError("ENOENT", `/proc/${top}/${leaf}`);
|
|
12395
|
-
return pidFile(leaf, info,
|
|
12493
|
+
return pidFile(leaf, info, listing2.boot);
|
|
12396
12494
|
}
|
|
12397
12495
|
};
|
|
12398
12496
|
}
|
|
@@ -12410,9 +12508,9 @@ var init_wasi_procfs = __esm({
|
|
|
12410
12508
|
return {
|
|
12411
12509
|
kind: "file",
|
|
12412
12510
|
content: () => {
|
|
12413
|
-
const
|
|
12414
|
-
const info =
|
|
12415
|
-
const line = info && taskStat(info, Number(tid),
|
|
12511
|
+
const listing2 = this.listing();
|
|
12512
|
+
const info = listing2.processes.find((p) => p.pid === pid);
|
|
12513
|
+
const line = info && taskStat(info, Number(tid), listing2.boot);
|
|
12416
12514
|
if (line === void 0) throw syncError("ENOENT", `/proc/${pid}/task/${tid}/stat`);
|
|
12417
12515
|
return line;
|
|
12418
12516
|
}
|
|
@@ -14675,6 +14773,12 @@ function ownersOf(init) {
|
|
|
14675
14773
|
...init.changes ? { changes: init.changes } : {}
|
|
14676
14774
|
};
|
|
14677
14775
|
}
|
|
14776
|
+
function heldOf2(init, call2) {
|
|
14777
|
+
const { held: held2 } = init;
|
|
14778
|
+
if (!held2) return {};
|
|
14779
|
+
const ask = () => call2({ op: "cwd-check" });
|
|
14780
|
+
return { held: new HeldCwd(held2.sab, held2.slot, ask, { ...held2, path: init.cwd }) };
|
|
14781
|
+
}
|
|
14678
14782
|
async function runWasiProcess(init, port2) {
|
|
14679
14783
|
captureBacktraces(init.env);
|
|
14680
14784
|
const signals = new WasiSignals(
|
|
@@ -14732,6 +14836,7 @@ async function runWasiProcess(init, port2) {
|
|
|
14732
14836
|
call2
|
|
14733
14837
|
),
|
|
14734
14838
|
...descriptors(init, fork, threads),
|
|
14839
|
+
...heldOf2(init, call2),
|
|
14735
14840
|
...threads ? { credGen: threads.ids } : {}
|
|
14736
14841
|
});
|
|
14737
14842
|
host.sigmask = sigmaskOf(module, init.sab, gate, threads);
|
|
@@ -14840,7 +14945,8 @@ async function runWasiThread(init, port2) {
|
|
|
14840
14945
|
),
|
|
14841
14946
|
call2
|
|
14842
14947
|
),
|
|
14843
|
-
shared: threads.ids
|
|
14948
|
+
shared: threads.ids,
|
|
14949
|
+
...heldOf2(init, call2)
|
|
14844
14950
|
});
|
|
14845
14951
|
host.tid = thread.tid;
|
|
14846
14952
|
host.sigmask = sigmaskOf(init.program.module, init.sab, gate, threads, init.signals);
|
|
@@ -14891,6 +14997,7 @@ var init_wasi_runtime = __esm({
|
|
|
14891
14997
|
"src/process/wasi/wasi-runtime.ts"() {
|
|
14892
14998
|
"use strict";
|
|
14893
14999
|
init_physical_path();
|
|
15000
|
+
init_held_cwd();
|
|
14894
15001
|
init_protocol();
|
|
14895
15002
|
init_signals();
|
|
14896
15003
|
init_sync_sab_bridge();
|
|
@@ -16117,10 +16224,10 @@ var init_js_net = __esm({
|
|
|
16117
16224
|
|
|
16118
16225
|
// src/process/js/js-proc.ts
|
|
16119
16226
|
function* procStep(abs, pid, run) {
|
|
16120
|
-
const
|
|
16227
|
+
const listing2 = yield { op: "proc-list" };
|
|
16121
16228
|
const mounts = abs === "/proc/mounts" ? yield { op: "mount-list" } : [];
|
|
16122
16229
|
const tree = new ProcTree(
|
|
16123
|
-
{ procList: () =>
|
|
16230
|
+
{ procList: () => listing2, mountList: () => mounts },
|
|
16124
16231
|
pid,
|
|
16125
16232
|
memorySource()
|
|
16126
16233
|
);
|