@ai-ecoverse/slicc-kernel 1.51.1 → 1.53.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 +4 -4
- package/dist/kernel-worker.js +10 -7
- package/dist/kernel-worker.js.map +2 -2
- package/dist/node-process-worker.js +241 -23
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +10 -7
- package/dist/node.js.map +2 -2
- package/dist/process-worker.js +241 -6
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/process-worker.js
CHANGED
|
@@ -4770,6 +4770,10 @@ function kernelEntry2() {
|
|
|
4770
4770
|
function deviceEntry(meta) {
|
|
4771
4771
|
return { type: "device", device: meta.device, ...meta.access ? { access: meta.access } : {} };
|
|
4772
4772
|
}
|
|
4773
|
+
function refuseWrite(s, oflags, rights) {
|
|
4774
|
+
const writes = (rights & RIGHTS.FD_WRITE) !== 0n || (oflags & OFLAGS.TRUNC) !== 0;
|
|
4775
|
+
if (s?.readonly && writes) throw new WasiError("EROFS");
|
|
4776
|
+
}
|
|
4773
4777
|
function preopenOf(e) {
|
|
4774
4778
|
return {
|
|
4775
4779
|
...e.preopen ? { preopen: e.preopen } : {},
|
|
@@ -5237,6 +5241,7 @@ var init_wasi_fds = __esm({
|
|
|
5237
5241
|
return this.install({ type: "dir", path });
|
|
5238
5242
|
}
|
|
5239
5243
|
if (!s && !(oflags & OFLAGS.CREAT)) throw new WasiError("ENOENT");
|
|
5244
|
+
refuseWrite(s, oflags, rights);
|
|
5240
5245
|
if (this.shared) return this.kernelFile(path, s, oflags, rights, fdflags);
|
|
5241
5246
|
return this.install({ type: "file", file: this.file(path, s, oflags, rights, fdflags) });
|
|
5242
5247
|
}
|
|
@@ -6748,6 +6753,191 @@ var init_wasi_module = __esm({
|
|
|
6748
6753
|
}
|
|
6749
6754
|
});
|
|
6750
6755
|
|
|
6756
|
+
// src/process/wasi/wasi-procfs.ts
|
|
6757
|
+
function inProc(path) {
|
|
6758
|
+
return path === "/proc" || path.startsWith("/proc/");
|
|
6759
|
+
}
|
|
6760
|
+
function procfsBridge(fs, tree) {
|
|
6761
|
+
const over = {
|
|
6762
|
+
readFile: (p) => inProc(p) ? tree.read(p) : fs.readFile(p),
|
|
6763
|
+
stat: (p) => inProc(p) ? tree.stat(p) : fs.stat(p),
|
|
6764
|
+
lstat: (p) => inProc(p) ? tree.stat(p, false) : fs.lstat(p),
|
|
6765
|
+
readdir: (p) => {
|
|
6766
|
+
if (inProc(p)) return tree.readdir(p);
|
|
6767
|
+
const names = fs.readdir(p);
|
|
6768
|
+
return p === "/" && !names.includes("proc") ? [...names, "proc"] : names;
|
|
6769
|
+
},
|
|
6770
|
+
exists: (p) => inProc(p) ? tree.exists(p) : fs.exists(p),
|
|
6771
|
+
readlink: (p) => inProc(p) ? tree.readlink(p) : fs.readlink(p),
|
|
6772
|
+
readdirStat: (p) => {
|
|
6773
|
+
if (!inProc(p)) {
|
|
6774
|
+
const listed = fs.readdirStat(p);
|
|
6775
|
+
if (p !== "/" || listed.some(([name2]) => name2 === "proc")) return listed;
|
|
6776
|
+
return [...listed, ["proc", tree.stat("/proc")]];
|
|
6777
|
+
}
|
|
6778
|
+
return tree.readdir(p).map((name2) => {
|
|
6779
|
+
try {
|
|
6780
|
+
return [name2, tree.stat(`${p}/${name2}`, false)];
|
|
6781
|
+
} catch {
|
|
6782
|
+
return [name2, null];
|
|
6783
|
+
}
|
|
6784
|
+
});
|
|
6785
|
+
},
|
|
6786
|
+
rename: (from, to) => {
|
|
6787
|
+
if (inProc(from) || inProc(to)) throw syncError("EROFS", from);
|
|
6788
|
+
fs.rename(from, to);
|
|
6789
|
+
},
|
|
6790
|
+
hold: (p, ...rest2) => inProc(p) ? void 0 : fs.hold?.(p, ...rest2),
|
|
6791
|
+
...fs.pread ? {
|
|
6792
|
+
pread: (p, at, n, version) => inProc(p) ? tree.read(p).subarray(at, at + n) : fs.pread(p, at, n, version)
|
|
6793
|
+
} : {}
|
|
6794
|
+
};
|
|
6795
|
+
for (const name2 of READ_ONLY) {
|
|
6796
|
+
const fn = fs[name2];
|
|
6797
|
+
if (!fn) continue;
|
|
6798
|
+
over[name2] = (p, ...rest2) => {
|
|
6799
|
+
if (inProc(p)) throw syncError("EROFS", p);
|
|
6800
|
+
return fn.call(fs, p, ...rest2);
|
|
6801
|
+
};
|
|
6802
|
+
}
|
|
6803
|
+
return new Proxy(fs, {
|
|
6804
|
+
get: (target, key, receiver) => key in over ? over[key] : Reflect.get(target, key, receiver)
|
|
6805
|
+
});
|
|
6806
|
+
}
|
|
6807
|
+
var DIR_MODE3, FILE_MODE2, LINK_MODE3, PID_NAMES, SYSTEM_NAMES, ProcTree, READ_ONLY;
|
|
6808
|
+
var init_wasi_procfs = __esm({
|
|
6809
|
+
"src/process/wasi/wasi-procfs.ts"() {
|
|
6810
|
+
"use strict";
|
|
6811
|
+
init_sync_fs_wire();
|
|
6812
|
+
init_process_fds();
|
|
6813
|
+
init_procfs();
|
|
6814
|
+
DIR_MODE3 = 16749;
|
|
6815
|
+
FILE_MODE2 = 33060;
|
|
6816
|
+
LINK_MODE3 = 41471;
|
|
6817
|
+
PID_NAMES = PID_FILES;
|
|
6818
|
+
SYSTEM_NAMES = SYSTEM_FILES;
|
|
6819
|
+
ProcTree = class {
|
|
6820
|
+
source;
|
|
6821
|
+
pid;
|
|
6822
|
+
memory;
|
|
6823
|
+
constructor(source, pid, memory = memorySource()) {
|
|
6824
|
+
this.source = source;
|
|
6825
|
+
this.pid = pid;
|
|
6826
|
+
this.memory = memory;
|
|
6827
|
+
}
|
|
6828
|
+
listing() {
|
|
6829
|
+
return this.source.procList();
|
|
6830
|
+
}
|
|
6831
|
+
alive(pid) {
|
|
6832
|
+
return this.listing().processes.some((p) => p.pid === pid);
|
|
6833
|
+
}
|
|
6834
|
+
node(parts) {
|
|
6835
|
+
const [top, leaf, ...rest2] = parts;
|
|
6836
|
+
if (top === void 0) {
|
|
6837
|
+
return {
|
|
6838
|
+
kind: "dir",
|
|
6839
|
+
names: () => [
|
|
6840
|
+
...SYSTEM_NAMES,
|
|
6841
|
+
"mounts",
|
|
6842
|
+
"self",
|
|
6843
|
+
...this.listing().processes.map((p) => String(p.pid))
|
|
6844
|
+
]
|
|
6845
|
+
};
|
|
6846
|
+
}
|
|
6847
|
+
if (top === "self") {
|
|
6848
|
+
return leaf === void 0 ? { kind: "link", target: String(this.pid) } : void 0;
|
|
6849
|
+
}
|
|
6850
|
+
if (leaf === void 0 && top === "mounts") {
|
|
6851
|
+
return { kind: "file", content: () => mountTable(this.source.mountList()) };
|
|
6852
|
+
}
|
|
6853
|
+
if (leaf === void 0 && SYSTEM_NAMES.includes(top)) {
|
|
6854
|
+
return {
|
|
6855
|
+
kind: "file",
|
|
6856
|
+
content: () => systemFile(top, this.listing(), Date.now(), this.memory)
|
|
6857
|
+
};
|
|
6858
|
+
}
|
|
6859
|
+
if (!/^[1-9]\d*$/.test(top) || rest2.length > 0 || !this.alive(Number(top))) return void 0;
|
|
6860
|
+
if (leaf === void 0) return { kind: "dir", names: () => [...PID_NAMES] };
|
|
6861
|
+
if (!PID_NAMES.includes(leaf)) return void 0;
|
|
6862
|
+
return {
|
|
6863
|
+
kind: "file",
|
|
6864
|
+
content: () => {
|
|
6865
|
+
const listing = this.listing();
|
|
6866
|
+
const info = listing.processes.find((p) => p.pid === Number(top));
|
|
6867
|
+
if (!info) throw syncError("ENOENT", `/proc/${top}/${leaf}`);
|
|
6868
|
+
return pidFile(leaf, info, listing.boot);
|
|
6869
|
+
}
|
|
6870
|
+
};
|
|
6871
|
+
}
|
|
6872
|
+
parts(path, follow2) {
|
|
6873
|
+
const parts = path.split("/").filter((p) => p !== "").slice(1);
|
|
6874
|
+
if (parts[0] === "self" && (follow2 || parts.length > 1)) parts[0] = String(this.pid);
|
|
6875
|
+
return parts;
|
|
6876
|
+
}
|
|
6877
|
+
find(path, follow2) {
|
|
6878
|
+
const node = this.node(this.parts(path, follow2));
|
|
6879
|
+
if (!node) throw syncError("ENOENT", path);
|
|
6880
|
+
return node;
|
|
6881
|
+
}
|
|
6882
|
+
stat(path, follow2 = true) {
|
|
6883
|
+
const node = this.find(path, follow2);
|
|
6884
|
+
const base = {
|
|
6885
|
+
isFile: false,
|
|
6886
|
+
isDirectory: false,
|
|
6887
|
+
size: 0,
|
|
6888
|
+
mtimeMs: Date.now(),
|
|
6889
|
+
readonly: true
|
|
6890
|
+
};
|
|
6891
|
+
if (node.kind === "dir") return { ...base, isDirectory: true, mode: DIR_MODE3 };
|
|
6892
|
+
if (node.kind === "link") {
|
|
6893
|
+
return { ...base, isSymbolicLink: true, mode: LINK_MODE3, size: node.target.length };
|
|
6894
|
+
}
|
|
6895
|
+
return { ...base, isFile: true, mode: FILE_MODE2, size: this.bytes(node).length };
|
|
6896
|
+
}
|
|
6897
|
+
bytes(node) {
|
|
6898
|
+
return new TextEncoder().encode(node.kind === "file" ? node.content() : "");
|
|
6899
|
+
}
|
|
6900
|
+
read(path) {
|
|
6901
|
+
const node = this.find(path, true);
|
|
6902
|
+
if (node.kind !== "file") throw syncError("EISDIR", path);
|
|
6903
|
+
return this.bytes(node);
|
|
6904
|
+
}
|
|
6905
|
+
readdir(path) {
|
|
6906
|
+
const node = this.find(path, true);
|
|
6907
|
+
if (node.kind !== "dir") throw syncError("ENOTDIR", path);
|
|
6908
|
+
return node.names();
|
|
6909
|
+
}
|
|
6910
|
+
readlink(path) {
|
|
6911
|
+
const node = this.find(path, false);
|
|
6912
|
+
if (node.kind !== "link") throw syncError("EINVAL", path);
|
|
6913
|
+
return node.target;
|
|
6914
|
+
}
|
|
6915
|
+
exists(path) {
|
|
6916
|
+
try {
|
|
6917
|
+
this.find(path, true);
|
|
6918
|
+
return true;
|
|
6919
|
+
} catch {
|
|
6920
|
+
return false;
|
|
6921
|
+
}
|
|
6922
|
+
}
|
|
6923
|
+
};
|
|
6924
|
+
READ_ONLY = [
|
|
6925
|
+
"writeFile",
|
|
6926
|
+
"mkdir",
|
|
6927
|
+
"rm",
|
|
6928
|
+
"unlink",
|
|
6929
|
+
"rmdir",
|
|
6930
|
+
"symlink",
|
|
6931
|
+
"chmod",
|
|
6932
|
+
"utimes",
|
|
6933
|
+
"lutimes",
|
|
6934
|
+
"create",
|
|
6935
|
+
"pwrite",
|
|
6936
|
+
"truncate"
|
|
6937
|
+
];
|
|
6938
|
+
}
|
|
6939
|
+
});
|
|
6940
|
+
|
|
6751
6941
|
// src/process/wasi/wasi-signals.ts
|
|
6752
6942
|
var DELIVERED_MASK, KERNEL_DEFAULTS, LIBC_DEFAULT_EXIT, SA_RESTART, DISPOSITION_IGNORE, DISPOSITION_HANDLER, withBit, WASIX_LIBC_DEFAULT_LINE, WasiSignals;
|
|
6753
6943
|
var init_wasi_signals = __esm({
|
|
@@ -8891,6 +9081,15 @@ async function instantiate(host, module, memory, threads, {
|
|
|
8891
9081
|
}
|
|
8892
9082
|
return { instance, driver };
|
|
8893
9083
|
}
|
|
9084
|
+
function procTree(call2, pid) {
|
|
9085
|
+
return new ProcTree(
|
|
9086
|
+
{
|
|
9087
|
+
procList: () => call2({ op: "proc-list" }),
|
|
9088
|
+
mountList: () => call2({ op: "mount-list" })
|
|
9089
|
+
},
|
|
9090
|
+
pid
|
|
9091
|
+
);
|
|
9092
|
+
}
|
|
8894
9093
|
function exportedTable(instance) {
|
|
8895
9094
|
const table = instance.exports.__indirect_function_table;
|
|
8896
9095
|
return table instanceof WebAssembly.Table ? table : void 0;
|
|
@@ -8962,7 +9161,10 @@ async function runWasiProcess(init, port2) {
|
|
|
8962
9161
|
ppid: id.ppid,
|
|
8963
9162
|
parent: () => identify(transport, init).ppid,
|
|
8964
9163
|
kernel: { sys: traced(stats, "kernel", sys), call: call2 },
|
|
8965
|
-
fs:
|
|
9164
|
+
fs: procfsBridge(
|
|
9165
|
+
cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport))),
|
|
9166
|
+
procTree(call2, id.pid)
|
|
9167
|
+
),
|
|
8966
9168
|
...descriptors(init, fork, threads)
|
|
8967
9169
|
});
|
|
8968
9170
|
if (threads) {
|
|
@@ -9053,7 +9255,7 @@ async function runWasiThread(init, port2) {
|
|
|
9053
9255
|
ppid: id.ppid,
|
|
9054
9256
|
parent: () => identify(transport, init).ppid,
|
|
9055
9257
|
kernel: { sys, call: call2 },
|
|
9056
|
-
fs: cachingBridge(createSyncFsSabBridge(transport)),
|
|
9258
|
+
fs: procfsBridge(cachingBridge(createSyncFsSabBridge(transport)), procTree(call2, id.pid)),
|
|
9057
9259
|
shared: threads.ids
|
|
9058
9260
|
});
|
|
9059
9261
|
const program = await programImports(init.program, host, transport, thread.tid);
|
|
@@ -9108,6 +9310,7 @@ var init_wasi_runtime = __esm({
|
|
|
9108
9310
|
init_wasi_host();
|
|
9109
9311
|
init_wasi_imports();
|
|
9110
9312
|
init_wasi_module();
|
|
9313
|
+
init_wasi_procfs();
|
|
9111
9314
|
init_wasi_signals();
|
|
9112
9315
|
init_wasi_stats();
|
|
9113
9316
|
init_wasi_threads();
|
|
@@ -10370,10 +10573,25 @@ function ttyOps(kernel) {
|
|
|
10370
10573
|
await kernel.call({ op: "tty-pgrp-set", fd, pgrp });
|
|
10371
10574
|
}
|
|
10372
10575
|
};
|
|
10576
|
+
const openOn = async (terminal, fd) => {
|
|
10577
|
+
const open = await kernel.json({ op: "fd-list" });
|
|
10578
|
+
const on = open.filter((entry) => entry.terminal === terminal);
|
|
10579
|
+
return (on.find((entry) => entry.fd === fd) ?? on[0])?.fd;
|
|
10580
|
+
};
|
|
10581
|
+
const reopened = async (terminal, termios) => {
|
|
10582
|
+
const fd = await kernel.json({ op: "fd-open-tty", name: terminal });
|
|
10583
|
+
try {
|
|
10584
|
+
await setAttr(fd, termios);
|
|
10585
|
+
} finally {
|
|
10586
|
+
await kernel.call({ op: "fd-close", fd });
|
|
10587
|
+
}
|
|
10588
|
+
};
|
|
10373
10589
|
const restore = async () => {
|
|
10374
10590
|
for (const [terminal, { fd, termios }] of [...saved].reverse()) {
|
|
10375
10591
|
saved.delete(terminal);
|
|
10376
|
-
await
|
|
10592
|
+
const at = await openOn(terminal, fd).catch(() => void 0);
|
|
10593
|
+
const back = at === void 0 ? reopened(terminal, termios) : setAttr(at, termios);
|
|
10594
|
+
await back.catch(() => void 0);
|
|
10377
10595
|
}
|
|
10378
10596
|
};
|
|
10379
10597
|
return { tty, restore };
|
|
@@ -10910,19 +11128,35 @@ function hide(target, names) {
|
|
|
10910
11128
|
}
|
|
10911
11129
|
}
|
|
10912
11130
|
}
|
|
11131
|
+
function vacate(target, names) {
|
|
11132
|
+
for (const name2 of names) {
|
|
11133
|
+
for (let at = target; at && at !== Object.prototype; ) {
|
|
11134
|
+
if (Object.getOwnPropertyDescriptor(at, name2)?.configurable) Reflect.deleteProperty(at, name2);
|
|
11135
|
+
at = Object.getPrototypeOf(at);
|
|
11136
|
+
}
|
|
11137
|
+
Reflect.defineProperty(target, name2, {
|
|
11138
|
+
value: void 0,
|
|
11139
|
+
writable: true,
|
|
11140
|
+
enumerable: false,
|
|
11141
|
+
configurable: true
|
|
11142
|
+
});
|
|
11143
|
+
if (Reflect.get(target, name2) !== void 0) {
|
|
11144
|
+
throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
|
|
11145
|
+
}
|
|
11146
|
+
}
|
|
11147
|
+
}
|
|
10913
11148
|
function lockdown(scope2 = globalThis) {
|
|
10914
11149
|
hide(scope2, BLOCKED_GLOBALS);
|
|
11150
|
+
vacate(scope2, OPEN_SLOTS);
|
|
10915
11151
|
const navigator = scope2.navigator;
|
|
10916
11152
|
if (navigator && typeof navigator === "object") hide(navigator, BLOCKED_NAVIGATOR);
|
|
10917
11153
|
}
|
|
10918
|
-
var BLOCKED_GLOBALS, BLOCKED_NAVIGATOR;
|
|
11154
|
+
var BLOCKED_GLOBALS, BLOCKED_NAVIGATOR, OPEN_SLOTS;
|
|
10919
11155
|
var init_lockdown = __esm({
|
|
10920
11156
|
"src/process/js/lockdown.ts"() {
|
|
10921
11157
|
"use strict";
|
|
10922
11158
|
BLOCKED_GLOBALS = [
|
|
10923
|
-
"fetch",
|
|
10924
11159
|
"XMLHttpRequest",
|
|
10925
|
-
"WebSocket",
|
|
10926
11160
|
"WebSocketStream",
|
|
10927
11161
|
"WebTransport",
|
|
10928
11162
|
"EventSource",
|
|
@@ -10937,6 +11171,7 @@ var init_lockdown = __esm({
|
|
|
10937
11171
|
"close"
|
|
10938
11172
|
];
|
|
10939
11173
|
BLOCKED_NAVIGATOR = ["storage", "locks", "serviceWorker"];
|
|
11174
|
+
OPEN_SLOTS = ["fetch", "WebSocket"];
|
|
10940
11175
|
}
|
|
10941
11176
|
});
|
|
10942
11177
|
|