@ai-ecoverse/slicc-kernel 1.41.0 → 1.41.2
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/dist/kernel-worker.js +233 -130
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +185 -64
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +255 -152
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +185 -64
- package/dist/process-worker.js.map +4 -4
- package/package.json +3 -3
|
@@ -166,7 +166,7 @@ var init_pages = __esm({
|
|
|
166
166
|
}
|
|
167
167
|
const last = runs[runs.length - 1];
|
|
168
168
|
if (last) last[1] = Math.max(last[1], Math.min(READAHEAD, this.stored - last[0]));
|
|
169
|
-
return runs.map(([
|
|
169
|
+
return runs.map(([start2, n]) => [start2, Math.min(n, this.stored - start2)]);
|
|
170
170
|
}
|
|
171
171
|
partial(at, length) {
|
|
172
172
|
if (length === 0) return [];
|
|
@@ -174,16 +174,16 @@ var init_pages = __esm({
|
|
|
174
174
|
const edges = /* @__PURE__ */ new Set([Math.floor(at / PAGE), Math.floor((at + length - 1) / PAGE)]);
|
|
175
175
|
const runs = [];
|
|
176
176
|
for (const page of edges) {
|
|
177
|
-
const
|
|
178
|
-
const covered = at <=
|
|
179
|
-
if (covered || this.pages.has(page) ||
|
|
180
|
-
runs.push([
|
|
177
|
+
const start2 = page * PAGE;
|
|
178
|
+
const covered = at <= start2 && at + length >= start2 + PAGE;
|
|
179
|
+
if (covered || this.pages.has(page) || start2 >= this.stored) continue;
|
|
180
|
+
runs.push([start2, Math.min(PAGE, this.stored - start2)]);
|
|
181
181
|
}
|
|
182
182
|
return runs;
|
|
183
183
|
}
|
|
184
|
-
fill(
|
|
184
|
+
fill(start2, bytes) {
|
|
185
185
|
for (let at = 0; at < bytes.length; at += PAGE) {
|
|
186
|
-
const page = (
|
|
186
|
+
const page = (start2 + at) / PAGE;
|
|
187
187
|
if (this.pages.has(page)) continue;
|
|
188
188
|
const part = bytes.subarray(at, Math.min(at + PAGE, bytes.length));
|
|
189
189
|
const fresh = this.take(part.length);
|
|
@@ -249,14 +249,14 @@ var init_pages = __esm({
|
|
|
249
249
|
while (j < sorted.length && sorted[j] === first + (j - i) && sorted[j] * PAGE % RUN !== 0) {
|
|
250
250
|
j++;
|
|
251
251
|
}
|
|
252
|
-
const
|
|
252
|
+
const start2 = first * PAGE;
|
|
253
253
|
const end = Math.min(this.length, (first + (j - i)) * PAGE);
|
|
254
|
-
const bytes = new Uint8Array(end -
|
|
254
|
+
const bytes = new Uint8Array(end - start2);
|
|
255
255
|
for (let k = i; k < j; k++) {
|
|
256
256
|
const page = this.pages.get(sorted[k]);
|
|
257
|
-
bytes.set(page.subarray(0, Math.min(PAGE, end - (k - i) * PAGE -
|
|
257
|
+
bytes.set(page.subarray(0, Math.min(PAGE, end - (k - i) * PAGE - start2)), (k - i) * PAGE);
|
|
258
258
|
}
|
|
259
|
-
runs.push({ offset:
|
|
259
|
+
runs.push({ offset: start2, bytes });
|
|
260
260
|
i = j;
|
|
261
261
|
}
|
|
262
262
|
const written2 = Math.max(this.stored, ...runs.map((r) => r.offset + r.bytes.length));
|
|
@@ -339,8 +339,8 @@ var init_ranged = __esm({
|
|
|
339
339
|
return this.pages.length;
|
|
340
340
|
}
|
|
341
341
|
fetch(runs) {
|
|
342
|
-
for (const [
|
|
343
|
-
this.pages.fill(
|
|
342
|
+
for (const [start2, n] of runs) {
|
|
343
|
+
this.pages.fill(start2, this.io.pread(this.path, start2, n, this.version));
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
346
|
read(at, length) {
|
|
@@ -594,7 +594,9 @@ function toMs(v) {
|
|
|
594
594
|
}
|
|
595
595
|
function createHelpers(Fs, ops) {
|
|
596
596
|
const bridgeOf = (node) => node.mount.opts.bridge;
|
|
597
|
+
const fileIo = (node) => pinnedIo(bridgeOf(node), node.live.handle);
|
|
597
598
|
const dirty = /* @__PURE__ */ new Set();
|
|
599
|
+
const handled = /* @__PURE__ */ new Set();
|
|
598
600
|
function markDirty(node) {
|
|
599
601
|
node.live.dirty = true;
|
|
600
602
|
dirty.add(node);
|
|
@@ -657,7 +659,7 @@ function createHelpers(Fs, ops) {
|
|
|
657
659
|
function ensureLoaded(node) {
|
|
658
660
|
const s = node.live;
|
|
659
661
|
if (s.loaded) return;
|
|
660
|
-
const bytes = call2(() =>
|
|
662
|
+
const bytes = call2(() => fileIo(node).readFile(liveNodePath(node)));
|
|
661
663
|
s.data = bytes;
|
|
662
664
|
s.len = bytes.length;
|
|
663
665
|
s.loaded = true;
|
|
@@ -667,10 +669,11 @@ function createHelpers(Fs, ops) {
|
|
|
667
669
|
if (s.ranged || !s.ranges) return s.ranged;
|
|
668
670
|
const bridge = bridgeOf(node);
|
|
669
671
|
const path = () => liveNodePath(node);
|
|
672
|
+
const file = () => fileIo(node);
|
|
670
673
|
const io = {
|
|
671
|
-
pread: (_, at, n, version) =>
|
|
672
|
-
pwrite: (_, at, bytes, transfer) =>
|
|
673
|
-
truncate: (_, size) =>
|
|
674
|
+
pread: (_, at, n, version) => file().pread(path(), at, n, version),
|
|
675
|
+
pwrite: (_, at, bytes, transfer) => file().pwrite(path(), at, bytes, transfer),
|
|
676
|
+
truncate: (_, size) => file().truncate(path(), size)
|
|
674
677
|
};
|
|
675
678
|
const st = call2(() => bridge.stat(path()));
|
|
676
679
|
s.ranged = new RangedFile(io, path(), st.size, st.version);
|
|
@@ -691,7 +694,7 @@ function createHelpers(Fs, ops) {
|
|
|
691
694
|
if (s.ranged) call2(() => s.ranged?.flush());
|
|
692
695
|
else {
|
|
693
696
|
const bytes = s.data.slice(0, s.len);
|
|
694
|
-
call2(() =>
|
|
697
|
+
call2(() => fileIo(node).writeFile(liveNodePath(node), bytes, true));
|
|
695
698
|
}
|
|
696
699
|
s.dirty = false;
|
|
697
700
|
s.stat = void 0;
|
|
@@ -738,6 +741,7 @@ function createHelpers(Fs, ops) {
|
|
|
738
741
|
return {
|
|
739
742
|
Fs,
|
|
740
743
|
bridgeOf,
|
|
744
|
+
handled,
|
|
741
745
|
call: call2,
|
|
742
746
|
metadataCall,
|
|
743
747
|
makeNode,
|
|
@@ -924,8 +928,12 @@ function createStreamOps(h) {
|
|
|
924
928
|
}
|
|
925
929
|
};
|
|
926
930
|
const opened = (node, on) => {
|
|
931
|
+
const s = node.live;
|
|
927
932
|
try {
|
|
928
|
-
bridgeOf(node).hold?.(liveNodePath(node), on, true);
|
|
933
|
+
const handle = bridgeOf(node).hold?.(liveNodePath(node), on, true, s.handle);
|
|
934
|
+
s.handle = on ? handle : void 0;
|
|
935
|
+
if (s.handle === void 0) h.handled.delete(node);
|
|
936
|
+
else h.handled.add(node);
|
|
929
937
|
} catch {
|
|
930
938
|
}
|
|
931
939
|
};
|
|
@@ -1043,6 +1051,7 @@ function createLiveVfsPlugin(Fs) {
|
|
|
1043
1051
|
mounts,
|
|
1044
1052
|
node_ops: nodeOps,
|
|
1045
1053
|
stream_ops: streamOps,
|
|
1054
|
+
handled: h.handled,
|
|
1046
1055
|
flushDirty: () => h.flushDirty(),
|
|
1047
1056
|
mount(mount) {
|
|
1048
1057
|
const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
|
|
@@ -1065,7 +1074,7 @@ function flushLiveVfs(Fs, plugin) {
|
|
|
1065
1074
|
if (s.ranged) s.ranged.flush();
|
|
1066
1075
|
else {
|
|
1067
1076
|
const bytes = s.data.slice(0, s.len);
|
|
1068
|
-
node.mount.opts.bridge.writeFile(liveNodePath(node), bytes, true);
|
|
1077
|
+
pinnedIo(node.mount.opts.bridge, s.handle).writeFile(liveNodePath(node), bytes, true);
|
|
1069
1078
|
}
|
|
1070
1079
|
s.dirty = false;
|
|
1071
1080
|
} catch (err) {
|
|
@@ -1143,6 +1152,7 @@ function liveRoot(Fs, bridge) {
|
|
|
1143
1152
|
plugin.mounts.add(root.mount);
|
|
1144
1153
|
invalidateLiveVfs(Fs, plugin);
|
|
1145
1154
|
guardRenames(Fs);
|
|
1155
|
+
guardKeptNodes(Fs, plugin.handled);
|
|
1146
1156
|
guardStatfs(Fs);
|
|
1147
1157
|
const memfs = root.memfs ?? root.node_ops;
|
|
1148
1158
|
const live = plugin.node_ops;
|
|
@@ -1199,6 +1209,28 @@ function guardStatfs(Fs) {
|
|
|
1199
1209
|
};
|
|
1200
1210
|
};
|
|
1201
1211
|
}
|
|
1212
|
+
function pinnedIo(bridge, handle) {
|
|
1213
|
+
return handle !== void 0 && bridge.pinned ? bridge.pinned(handle) : bridge;
|
|
1214
|
+
}
|
|
1215
|
+
function guardKeptNodes(Fs, handled) {
|
|
1216
|
+
const open = Fs.open?.bind(Fs);
|
|
1217
|
+
const forget = Fs.hashRemoveNode?.bind(Fs);
|
|
1218
|
+
if (!open || !forget || !Fs.lookupPath || !handled || Fs.sliccKept) return;
|
|
1219
|
+
Fs.sliccKept = true;
|
|
1220
|
+
const lookupPath = Fs.lookupPath.bind(Fs);
|
|
1221
|
+
Fs.open = (path, flags, mode) => {
|
|
1222
|
+
const name = path.slice(path.lastIndexOf("/") + 1);
|
|
1223
|
+
if (![...handled].some((held) => held.name === name)) return open(path, flags, mode);
|
|
1224
|
+
let node;
|
|
1225
|
+
try {
|
|
1226
|
+
node = lookupPath(path, { follow: true }).node;
|
|
1227
|
+
} catch {
|
|
1228
|
+
}
|
|
1229
|
+
const handle = node?.live?.openCount ? node.live.handle : void 0;
|
|
1230
|
+
if (node && handle !== void 0 && node.mount.opts.bridge.kept?.(handle)) forget(node);
|
|
1231
|
+
return open(path, flags, mode);
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1202
1234
|
function guardRenames(Fs) {
|
|
1203
1235
|
const rename = Fs.rename?.bind(Fs);
|
|
1204
1236
|
if (!rename || Fs.sliccRename) return;
|
|
@@ -1330,6 +1362,7 @@ var init_sync_fs_wire = __esm({
|
|
|
1330
1362
|
"statfs",
|
|
1331
1363
|
"hold",
|
|
1332
1364
|
"create",
|
|
1365
|
+
"kept",
|
|
1333
1366
|
"pread",
|
|
1334
1367
|
"pwrite",
|
|
1335
1368
|
"truncate"
|
|
@@ -1501,11 +1534,26 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
1501
1534
|
if (r.ok && r.kind === "json") return r.json;
|
|
1502
1535
|
throw errnoError("EIO", path);
|
|
1503
1536
|
}
|
|
1504
|
-
|
|
1505
|
-
readFile: (path) => bytes({ op: "read", path }, path),
|
|
1537
|
+
const io = (id) => ({
|
|
1538
|
+
readFile: (path) => bytes({ op: "read", path, ...id }, path),
|
|
1506
1539
|
writeFile: (path, data, open) => {
|
|
1507
|
-
run({ op: "write", path, body: data, ...open ? { mode: 1 } : {} }, path);
|
|
1540
|
+
run({ op: "write", path, body: data, ...open ? { mode: 1 } : {}, ...id }, path);
|
|
1541
|
+
},
|
|
1542
|
+
pread: (path, offset, length, version) => bytes({ op: "pread", path, offset, length, ...version ? { version } : {}, ...id }, path),
|
|
1543
|
+
pwrite: (path, offset, body, transfer) => {
|
|
1544
|
+
const whole = body.byteOffset === 0 && body.byteLength === body.buffer.byteLength;
|
|
1545
|
+
const owned = transfer && whole && body.buffer instanceof ArrayBuffer;
|
|
1546
|
+
const transferred = owned ? [body.buffer] : [];
|
|
1547
|
+
run({ op: "pwrite", path, offset, body, ...id }, path, transferred);
|
|
1508
1548
|
},
|
|
1549
|
+
truncate: (path, length) => {
|
|
1550
|
+
run({ op: "truncate", path, length, ...id }, path);
|
|
1551
|
+
}
|
|
1552
|
+
});
|
|
1553
|
+
return {
|
|
1554
|
+
...io({}),
|
|
1555
|
+
pinned: (handle) => io({ handle }),
|
|
1556
|
+
kept: (handle) => json({ op: "kept", path: "/", handle }, "/") === true,
|
|
1509
1557
|
stat: (path) => {
|
|
1510
1558
|
const s = parseSyncFsStat(json({ op: "stat", path }, path));
|
|
1511
1559
|
if (!s) throw errnoError("EIO", path);
|
|
@@ -1574,19 +1622,13 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
1574
1622
|
create: (path) => {
|
|
1575
1623
|
run({ op: "create", path }, path);
|
|
1576
1624
|
},
|
|
1577
|
-
hold: (path, held, open) => {
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
pwrite: (path, offset, body, transfer) => {
|
|
1583
|
-
const whole = body.byteOffset === 0 && body.byteLength === body.buffer.byteLength;
|
|
1584
|
-
const owned = transfer && whole && body.buffer instanceof ArrayBuffer;
|
|
1585
|
-
run({ op: "pwrite", path, offset, body }, path, owned ? [body.buffer] : []);
|
|
1625
|
+
hold: (path, held, open, handle) => {
|
|
1626
|
+
const mode = (held ? 1 : 0) | (open ? 2 : 0);
|
|
1627
|
+
if (mode === 3) return json({ op: "hold", path, mode }, path);
|
|
1628
|
+
run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
|
|
1629
|
+
return void 0;
|
|
1586
1630
|
},
|
|
1587
|
-
|
|
1588
|
-
run({ op: "truncate", path, length }, path);
|
|
1589
|
-
}
|
|
1631
|
+
statfs: (path = "/") => parseSyncFsUsage(json({ op: "statfs", path }, path))
|
|
1590
1632
|
};
|
|
1591
1633
|
}
|
|
1592
1634
|
var init_sync_sab_bridge = __esm({
|
|
@@ -1794,9 +1836,9 @@ var init_kernel_streams = __esm({
|
|
|
1794
1836
|
for (const name of ["stat", "lstat"]) {
|
|
1795
1837
|
const original = fs[name];
|
|
1796
1838
|
if (typeof original !== "function") continue;
|
|
1797
|
-
fs[name] = (path, ...
|
|
1839
|
+
fs[name] = (path, ...rest2) => {
|
|
1798
1840
|
const getattr = this.descriptions.get(path);
|
|
1799
|
-
return getattr ? getattr() : original.call(fs, path, ...
|
|
1841
|
+
return getattr ? getattr() : original.call(fs, path, ...rest2);
|
|
1800
1842
|
};
|
|
1801
1843
|
}
|
|
1802
1844
|
}
|
|
@@ -1884,13 +1926,13 @@ var init_kernel_streams = __esm({
|
|
|
1884
1926
|
for (const name of ["chown", "lchown", "chmod", "lchmod"]) {
|
|
1885
1927
|
const original = fs[name];
|
|
1886
1928
|
if (typeof original !== "function") continue;
|
|
1887
|
-
fs[name] = (path, ...
|
|
1929
|
+
fs[name] = (path, ...rest2) => isPtyPath(path) ? this.existingPty(path) : original.call(fs, path, ...rest2);
|
|
1888
1930
|
}
|
|
1889
1931
|
for (const name of ["stat", "lstat"]) {
|
|
1890
1932
|
const original = fs[name];
|
|
1891
1933
|
if (typeof original !== "function") continue;
|
|
1892
|
-
fs[name] = (path, ...
|
|
1893
|
-
if (!isPtyPath(path)) return original.call(fs, path, ...
|
|
1934
|
+
fs[name] = (path, ...rest2) => {
|
|
1935
|
+
if (!isPtyPath(path)) return original.call(fs, path, ...rest2);
|
|
1894
1936
|
this.existingPty(path);
|
|
1895
1937
|
return ptyStat(path);
|
|
1896
1938
|
};
|
|
@@ -2165,7 +2207,7 @@ function cloexecPipe2(pipe2, deps) {
|
|
|
2165
2207
|
};
|
|
2166
2208
|
}
|
|
2167
2209
|
function quietTarget(dup3, deps) {
|
|
2168
|
-
return (fd = -1, newfd = -1, flags = 0, ...
|
|
2210
|
+
return (fd = -1, newfd = -1, flags = 0, ...rest2) => {
|
|
2169
2211
|
const Fs = deps.fs();
|
|
2170
2212
|
const target = fd === newfd || flags !== 0 ? void 0 : Fs?.getStream(newfd);
|
|
2171
2213
|
if (target && Fs?.getStream(fd)) {
|
|
@@ -2174,7 +2216,7 @@ function quietTarget(dup3, deps) {
|
|
|
2174
2216
|
} catch {
|
|
2175
2217
|
}
|
|
2176
2218
|
}
|
|
2177
|
-
return dup3(fd, newfd, flags, ...
|
|
2219
|
+
return dup3(fd, newfd, flags, ...rest2);
|
|
2178
2220
|
};
|
|
2179
2221
|
}
|
|
2180
2222
|
function cloexecByFlag(syscall, flagArg, deps) {
|
|
@@ -2329,8 +2371,8 @@ function syncFsync(imports, fs, glue) {
|
|
|
2329
2371
|
};
|
|
2330
2372
|
}
|
|
2331
2373
|
}
|
|
2332
|
-
function offsetOf(
|
|
2333
|
-
const at =
|
|
2374
|
+
function offsetOf(rest2) {
|
|
2375
|
+
const at = rest2.length >= 3 ? Number(rest2[1]) * 2 ** 32 + (Number(rest2[0]) >>> 0) : Number(BigInt.asIntN(64, BigInt(rest2[0])));
|
|
2334
2376
|
return at >= 0 && Number.isSafeInteger(at) ? at : void 0;
|
|
2335
2377
|
}
|
|
2336
2378
|
function readInto(sys, kfd, target, at) {
|
|
@@ -2344,14 +2386,14 @@ function readInto(sys, kfd, target, at) {
|
|
|
2344
2386
|
return done;
|
|
2345
2387
|
}
|
|
2346
2388
|
function positioned(original, write, deps) {
|
|
2347
|
-
return (fd, iov, iovcnt, ...
|
|
2389
|
+
return (fd, iov, iovcnt, ...rest2) => {
|
|
2348
2390
|
const stream = deps.fs()?.getStream(Number(fd));
|
|
2349
2391
|
const memory = deps.memory();
|
|
2350
2392
|
const kfd = stream?.sliccKernelFile ? stream.sliccKernelFd : void 0;
|
|
2351
2393
|
if (kfd === void 0 || !memory || !(write ? deps.sys.pwrite : deps.sys.pread)) {
|
|
2352
|
-
return original(fd, iov, iovcnt, ...
|
|
2394
|
+
return original(fd, iov, iovcnt, ...rest2);
|
|
2353
2395
|
}
|
|
2354
|
-
const at = offsetOf(
|
|
2396
|
+
const at = offsetOf(rest2);
|
|
2355
2397
|
if (at === void 0) return wasiErrno("EINVAL");
|
|
2356
2398
|
const view = new DataView(memory.buffer);
|
|
2357
2399
|
let done = 0;
|
|
@@ -2367,7 +2409,7 @@ function positioned(original, write, deps) {
|
|
|
2367
2409
|
} catch (err) {
|
|
2368
2410
|
return errnoOf(err);
|
|
2369
2411
|
}
|
|
2370
|
-
view.setUint32(Number(
|
|
2412
|
+
view.setUint32(Number(rest2[rest2.length - 1]), done, true);
|
|
2371
2413
|
return 0;
|
|
2372
2414
|
};
|
|
2373
2415
|
}
|
|
@@ -4357,6 +4399,8 @@ function cachingBridge(bridge, now = () => performance.now()) {
|
|
|
4357
4399
|
utimes: (p, a, m) => mutating(() => bridge.utimes(p, a, m)),
|
|
4358
4400
|
lutimes: (p, a, m) => mutating(() => bridge.lutimes(p, a, m)),
|
|
4359
4401
|
...bridge.hold ? { hold: bridge.hold.bind(bridge) } : {},
|
|
4402
|
+
...bridge.kept ? { kept: bridge.kept.bind(bridge) } : {},
|
|
4403
|
+
...bridge.pinned ? { pinned: (handle) => pinnedIo2(bridge, handle, mutating) } : {},
|
|
4360
4404
|
...bridge.create ? { create: (p) => mutating(() => bridge.create?.(p)) } : {},
|
|
4361
4405
|
...bridge.pread && bridge.pwrite && bridge.truncate ? {
|
|
4362
4406
|
pread: bridge.pread.bind(bridge),
|
|
@@ -4366,6 +4410,17 @@ function cachingBridge(bridge, now = () => performance.now()) {
|
|
|
4366
4410
|
invalidate
|
|
4367
4411
|
};
|
|
4368
4412
|
}
|
|
4413
|
+
function pinnedIo2(bridge, handle, mutating) {
|
|
4414
|
+
const io = bridge.pinned(handle);
|
|
4415
|
+
const { pread, pwrite, truncate } = io;
|
|
4416
|
+
return {
|
|
4417
|
+
readFile: (p) => io.readFile(p),
|
|
4418
|
+
writeFile: (p, bytes, open) => mutating(() => io.writeFile(p, bytes, open)),
|
|
4419
|
+
pread: (p, at, n, version) => pread(p, at, n, version),
|
|
4420
|
+
pwrite: (p, at, bytes, transfer) => mutating(() => pwrite(p, at, bytes, transfer)),
|
|
4421
|
+
truncate: (p, size) => mutating(() => truncate(p, size))
|
|
4422
|
+
};
|
|
4423
|
+
}
|
|
4369
4424
|
var WasiError, FileBuffer, LocalFile, MISS_TTL_MS;
|
|
4370
4425
|
var init_wasi_files = __esm({
|
|
4371
4426
|
"src/process/wasi/wasi-files.ts"() {
|
|
@@ -4391,6 +4446,7 @@ var init_wasi_files = __esm({
|
|
|
4391
4446
|
where;
|
|
4392
4447
|
ranged;
|
|
4393
4448
|
maxFile;
|
|
4449
|
+
handle;
|
|
4394
4450
|
constructor(fs, path, empty, maxFile, size, version) {
|
|
4395
4451
|
this.fs = fs;
|
|
4396
4452
|
this.where = path;
|
|
@@ -4960,7 +5016,7 @@ var init_wasi_fds = __esm({
|
|
|
4960
5016
|
this.letGo(buffer);
|
|
4961
5017
|
}
|
|
4962
5018
|
letGo(buffer) {
|
|
4963
|
-
this.fs.hold?.(buffer.path, false, true);
|
|
5019
|
+
this.fs.hold?.(buffer.path, false, true, buffer.handle);
|
|
4964
5020
|
}
|
|
4965
5021
|
kind(fd, e) {
|
|
4966
5022
|
if (!e.kind) {
|
|
@@ -5047,6 +5103,10 @@ var init_wasi_fds = __esm({
|
|
|
5047
5103
|
file(path, existing, oflags, rights, fdflags) {
|
|
5048
5104
|
const { readable: readable2, writable: writable2 } = openAccess(existing, oflags, rights);
|
|
5049
5105
|
let buffer = this.buffers.get(path);
|
|
5106
|
+
if (buffer?.handle !== void 0 && this.fs.kept?.(buffer.handle)) {
|
|
5107
|
+
this.buffers.delete(path);
|
|
5108
|
+
buffer = void 0;
|
|
5109
|
+
}
|
|
5050
5110
|
if (buffer) {
|
|
5051
5111
|
if (oflags & OFLAGS.TRUNC) buffer.truncate(0);
|
|
5052
5112
|
} else {
|
|
@@ -5055,9 +5115,11 @@ var init_wasi_fds = __esm({
|
|
|
5055
5115
|
if (existing?.ranged) this.fs.invalidate?.();
|
|
5056
5116
|
const st = existing?.ranged || !existing ? this.fs.stat(path) : existing;
|
|
5057
5117
|
const ranged = st.ranged ? st.size : void 0;
|
|
5058
|
-
|
|
5118
|
+
const handle = this.fs.hold?.(path, true, true);
|
|
5119
|
+
const io = handle !== void 0 && this.fs.pinned ? this.fs.pinned(handle) : this.fs;
|
|
5120
|
+
buffer = new FileBuffer(io, path, empty, st.maxFile, ranged, st.version);
|
|
5121
|
+
buffer.handle = handle;
|
|
5059
5122
|
this.buffers.set(path, buffer);
|
|
5060
|
-
this.fs.hold?.(path, true, true);
|
|
5061
5123
|
}
|
|
5062
5124
|
buffer.opens++;
|
|
5063
5125
|
return new LocalFile(buffer, readable2, writable2, (fdflags & FDFLAGS.APPEND) !== 0);
|
|
@@ -5343,11 +5405,11 @@ function kernelFiletype(kind) {
|
|
|
5343
5405
|
return { filetype: FILETYPE.UNKNOWN, seeks: false };
|
|
5344
5406
|
}
|
|
5345
5407
|
}
|
|
5346
|
-
function direntRecord(
|
|
5408
|
+
function direntRecord(next2, ino, name, filetype) {
|
|
5347
5409
|
const nameBytes = new TextEncoder().encode(name);
|
|
5348
5410
|
const record = new Uint8Array(SIZE.DIRENT + nameBytes.length);
|
|
5349
5411
|
const v = new DataView(record.buffer);
|
|
5350
|
-
v.setBigUint64(0, BigInt(
|
|
5412
|
+
v.setBigUint64(0, BigInt(next2), true);
|
|
5351
5413
|
v.setBigUint64(8, ino, true);
|
|
5352
5414
|
v.setUint32(16, nameBytes.length, true);
|
|
5353
5415
|
v.setUint8(20, filetype);
|
|
@@ -5861,19 +5923,19 @@ var init_wasi_host = __esm({
|
|
|
5861
5923
|
return { filetype: FILETYPE.CHARACTER_DEVICE, size: 0n, ino: pathInode(path), mtimeNs: 0n };
|
|
5862
5924
|
}
|
|
5863
5925
|
this.fds.flushPath(path);
|
|
5864
|
-
const
|
|
5865
|
-
return filestatOf(path,
|
|
5926
|
+
const follow2 = (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
5927
|
+
return filestatOf(path, follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path));
|
|
5866
5928
|
}
|
|
5867
|
-
setTimes(path, atim, mtim, flags,
|
|
5929
|
+
setTimes(path, atim, mtim, flags, follow2 = true) {
|
|
5868
5930
|
const now = Date.now();
|
|
5869
5931
|
let current;
|
|
5870
|
-
const statOf =
|
|
5932
|
+
const statOf = follow2 ? this.o.fs.stat.bind(this.o.fs) : this.o.fs.lstat.bind(this.o.fs);
|
|
5871
5933
|
const kept = (field2) => {
|
|
5872
5934
|
current ??= statOf(path);
|
|
5873
5935
|
return current[field2] ?? current.mtimeMs ?? now;
|
|
5874
5936
|
};
|
|
5875
5937
|
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS) : kept(field2);
|
|
5876
|
-
(
|
|
5938
|
+
(follow2 ? this.o.fs.utimes : this.o.fs.lutimes).call(
|
|
5877
5939
|
this.o.fs,
|
|
5878
5940
|
path,
|
|
5879
5941
|
pick(FSTFLAGS.ATIM, FSTFLAGS.ATIM_NOW, atim, "atimeMs"),
|
|
@@ -6779,6 +6841,61 @@ var init_wasix_linker = __esm({
|
|
|
6779
6841
|
}
|
|
6780
6842
|
});
|
|
6781
6843
|
|
|
6844
|
+
// src/fs/physical-path.ts
|
|
6845
|
+
function start(path) {
|
|
6846
|
+
return { done: [], todo: path.split("/").filter((p) => p !== ""), hops: 0 };
|
|
6847
|
+
}
|
|
6848
|
+
function next(walk) {
|
|
6849
|
+
while (walk.todo.length > 0) {
|
|
6850
|
+
const part = walk.todo.shift();
|
|
6851
|
+
if (part === ".") continue;
|
|
6852
|
+
if (part === "..") {
|
|
6853
|
+
walk.done.pop();
|
|
6854
|
+
continue;
|
|
6855
|
+
}
|
|
6856
|
+
return part;
|
|
6857
|
+
}
|
|
6858
|
+
return void 0;
|
|
6859
|
+
}
|
|
6860
|
+
function lexical(path) {
|
|
6861
|
+
const walk = start(path);
|
|
6862
|
+
for (let part = next(walk); part !== void 0; part = next(walk)) walk.done.push(part);
|
|
6863
|
+
return `/${walk.done.join("/")}`;
|
|
6864
|
+
}
|
|
6865
|
+
function rest(walk, part) {
|
|
6866
|
+
return lexical(`/${[...walk.done, part, ...walk.todo].join("/")}`);
|
|
6867
|
+
}
|
|
6868
|
+
function follow(walk, target) {
|
|
6869
|
+
if (++walk.hops > MAX_HOPS) return false;
|
|
6870
|
+
if (target.startsWith("/")) walk.done.length = 0;
|
|
6871
|
+
walk.todo = [...target.split("/").filter((p) => p !== ""), ...walk.todo];
|
|
6872
|
+
return true;
|
|
6873
|
+
}
|
|
6874
|
+
function physicalPath(fs, path) {
|
|
6875
|
+
const walk = start(path);
|
|
6876
|
+
for (let part = next(walk); part !== void 0; part = next(walk)) {
|
|
6877
|
+
const at = `/${[...walk.done, part].join("/")}`;
|
|
6878
|
+
let target;
|
|
6879
|
+
try {
|
|
6880
|
+
target = fs.lstat(at).isSymbolicLink ? fs.readlink(at) : void 0;
|
|
6881
|
+
} catch {
|
|
6882
|
+
return rest(walk, part);
|
|
6883
|
+
}
|
|
6884
|
+
if (target === void 0) walk.done.push(part);
|
|
6885
|
+
else if (!follow(walk, target)) {
|
|
6886
|
+
throw Object.assign(new Error("too many levels of symbolic links"), { code: "ELOOP" });
|
|
6887
|
+
}
|
|
6888
|
+
}
|
|
6889
|
+
return `/${walk.done.join("/")}`;
|
|
6890
|
+
}
|
|
6891
|
+
var MAX_HOPS;
|
|
6892
|
+
var init_physical_path = __esm({
|
|
6893
|
+
"src/fs/physical-path.ts"() {
|
|
6894
|
+
"use strict";
|
|
6895
|
+
MAX_HOPS = 40;
|
|
6896
|
+
}
|
|
6897
|
+
});
|
|
6898
|
+
|
|
6782
6899
|
// src/process/wasi/wasix-process.ts
|
|
6783
6900
|
function resolveFrom(cwd, path) {
|
|
6784
6901
|
return normalize(path.startsWith("/") ? path : `${cwd}/${path}`);
|
|
@@ -6787,6 +6904,7 @@ var POSIX_TO_WASI_SIGNAL, O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUN
|
|
|
6787
6904
|
var init_wasix_process = __esm({
|
|
6788
6905
|
"src/process/wasi/wasix-process.ts"() {
|
|
6789
6906
|
"use strict";
|
|
6907
|
+
init_physical_path();
|
|
6790
6908
|
init_wasi_abi();
|
|
6791
6909
|
init_wasi_files();
|
|
6792
6910
|
init_wasi_host();
|
|
@@ -6873,10 +6991,13 @@ var init_wasix_process = __esm({
|
|
|
6873
6991
|
const kfd = this.openFor(op, cwd);
|
|
6874
6992
|
opened.push(kfd);
|
|
6875
6993
|
point(op.fd, kfd);
|
|
6876
|
-
} else if (op.cmd === "chdir") return
|
|
6877
|
-
else return fds.dir(op.fd).path;
|
|
6994
|
+
} else if (op.cmd === "chdir") return this.physicalFrom(cwd, op.path);
|
|
6995
|
+
else return physicalPath(this.host.o.fs, fds.dir(op.fd).path);
|
|
6878
6996
|
return cwd;
|
|
6879
6997
|
}
|
|
6998
|
+
physicalFrom(cwd, path) {
|
|
6999
|
+
return physicalPath(this.host.o.fs, path.startsWith("/") ? path : `${cwd}/${path}`);
|
|
7000
|
+
}
|
|
6880
7001
|
openFor(op, cwd) {
|
|
6881
7002
|
const path = resolveFrom(cwd, op.path);
|
|
6882
7003
|
const create = (op.oflags & OFLAG_CREAT) !== 0;
|
|
@@ -7910,8 +8031,8 @@ function linkerHost(host, imports) {
|
|
|
7910
8031
|
}
|
|
7911
8032
|
},
|
|
7912
8033
|
hostImports: () => {
|
|
7913
|
-
const { env: _env, "GOT.mem": _mem, "GOT.func": _func, ...
|
|
7914
|
-
return
|
|
8034
|
+
const { env: _env, "GOT.mem": _mem, "GOT.func": _func, ...rest2 } = imports();
|
|
8035
|
+
return rest2;
|
|
7915
8036
|
}
|
|
7916
8037
|
};
|
|
7917
8038
|
}
|
|
@@ -8053,9 +8174,9 @@ async function runWasiThread(init, port2) {
|
|
|
8053
8174
|
foreign: init.program.foreign,
|
|
8054
8175
|
...program ? { program } : {}
|
|
8055
8176
|
});
|
|
8056
|
-
const
|
|
8177
|
+
const start2 = instance.exports.wasi_thread_start;
|
|
8057
8178
|
try {
|
|
8058
|
-
|
|
8179
|
+
start2(thread.tid, thread.arg);
|
|
8059
8180
|
threads.exited();
|
|
8060
8181
|
} catch (e) {
|
|
8061
8182
|
if (e instanceof ThreadExit) {
|