@ai-ecoverse/slicc-kernel 1.48.1 → 1.49.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 +10 -6
- package/dist/kernel-worker.js +43 -4
- package/dist/kernel-worker.js.map +2 -2
- package/dist/node-process-worker.js +10014 -9581
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +53 -6
- package/dist/node.js.map +2 -2
- package/dist/process-worker.js +443 -74
- package/dist/process-worker.js.map +4 -4
- package/package.json +4 -4
package/dist/process-worker.js
CHANGED
|
@@ -1991,12 +1991,12 @@ var init_kernel_streams = __esm({
|
|
|
1991
1991
|
usePipes(pipefs) {
|
|
1992
1992
|
const createPipe = pipefs.createPipe.bind(pipefs);
|
|
1993
1993
|
pipefs.createPipe = () => {
|
|
1994
|
-
const [
|
|
1994
|
+
const [read2, write2] = this.call(() => this.sys.pipe());
|
|
1995
1995
|
let fds;
|
|
1996
1996
|
try {
|
|
1997
1997
|
fds = createPipe();
|
|
1998
1998
|
} catch (e) {
|
|
1999
|
-
for (const kfd of [
|
|
1999
|
+
for (const kfd of [read2, write2]) {
|
|
2000
2000
|
try {
|
|
2001
2001
|
this.sys.close(kfd);
|
|
2002
2002
|
} catch {
|
|
@@ -2004,8 +2004,8 @@ var init_kernel_streams = __esm({
|
|
|
2004
2004
|
}
|
|
2005
2005
|
throw e;
|
|
2006
2006
|
}
|
|
2007
|
-
this.attach(this.Fs.getStream(fds.readable_fd),
|
|
2008
|
-
this.attach(this.Fs.getStream(fds.writable_fd),
|
|
2007
|
+
this.attach(this.Fs.getStream(fds.readable_fd), read2, false);
|
|
2008
|
+
this.attach(this.Fs.getStream(fds.writable_fd), write2, false);
|
|
2009
2009
|
return fds;
|
|
2010
2010
|
};
|
|
2011
2011
|
}
|
|
@@ -2394,12 +2394,12 @@ function readInto(sys, kfd, target, at) {
|
|
|
2394
2394
|
}
|
|
2395
2395
|
return done;
|
|
2396
2396
|
}
|
|
2397
|
-
function positioned(original,
|
|
2397
|
+
function positioned(original, write2, deps) {
|
|
2398
2398
|
return (fd, iov, iovcnt, ...rest2) => {
|
|
2399
2399
|
const stream = deps.fs()?.getStream(Number(fd));
|
|
2400
2400
|
const memory = deps.memory();
|
|
2401
2401
|
const kfd = stream?.sliccKernelFile ? stream.sliccKernelFd : void 0;
|
|
2402
|
-
if (kfd === void 0 || !memory || !(
|
|
2402
|
+
if (kfd === void 0 || !memory || !(write2 ? deps.sys.pwrite : deps.sys.pread)) {
|
|
2403
2403
|
return original(fd, iov, iovcnt, ...rest2);
|
|
2404
2404
|
}
|
|
2405
2405
|
const at = offsetOf(rest2);
|
|
@@ -2411,7 +2411,7 @@ function positioned(original, write, deps) {
|
|
|
2411
2411
|
const ptr = view.getUint32(Number(iov) + i * 8, true);
|
|
2412
2412
|
const len = view.getUint32(Number(iov) + i * 8 + 4, true);
|
|
2413
2413
|
const part = new Uint8Array(memory.buffer, ptr, len);
|
|
2414
|
-
const moved =
|
|
2414
|
+
const moved = write2 ? deps.sys.pwrite?.(kfd, part.slice(), at + done) ?? 0 : readInto(deps.sys, kfd, part, at + done);
|
|
2415
2415
|
done += moved;
|
|
2416
2416
|
if (moved < len) break;
|
|
2417
2417
|
}
|
|
@@ -2424,13 +2424,13 @@ function positioned(original, write, deps) {
|
|
|
2424
2424
|
}
|
|
2425
2425
|
function positionalIo(imports, deps) {
|
|
2426
2426
|
for (const namespace of namespaces(imports)) {
|
|
2427
|
-
for (const [name,
|
|
2427
|
+
for (const [name, write2] of [
|
|
2428
2428
|
["fd_pread", false],
|
|
2429
2429
|
["fd_pwrite", true]
|
|
2430
2430
|
]) {
|
|
2431
2431
|
const key = keyOf(namespace, name, deps.glue);
|
|
2432
2432
|
if (key !== void 0) {
|
|
2433
|
-
namespace[key] = positioned(namespace[key],
|
|
2433
|
+
namespace[key] = positioned(namespace[key], write2, deps);
|
|
2434
2434
|
}
|
|
2435
2435
|
}
|
|
2436
2436
|
}
|
|
@@ -2558,10 +2558,10 @@ function useZeroDevices(Fs) {
|
|
|
2558
2558
|
}
|
|
2559
2559
|
]
|
|
2560
2560
|
];
|
|
2561
|
-
for (const [path, minor,
|
|
2561
|
+
for (const [path, minor, write2] of devices) {
|
|
2562
2562
|
if (analyzePath.call(Fs, path).exists) continue;
|
|
2563
2563
|
const dev = makedev.call(Fs, 1, minor);
|
|
2564
|
-
registerDevice.call(Fs, dev, { read: zeros, write, llseek: () => 0 });
|
|
2564
|
+
registerDevice.call(Fs, dev, { read: zeros, write: write2, llseek: () => 0 });
|
|
2565
2565
|
mkdev.call(Fs, path, CHAR_DEVICE, dev);
|
|
2566
2566
|
}
|
|
2567
2567
|
}
|
|
@@ -2957,38 +2957,38 @@ function drain(Fs, stream) {
|
|
|
2957
2957
|
}
|
|
2958
2958
|
return out;
|
|
2959
2959
|
}
|
|
2960
|
-
function kernelSelect(Fs, transport,
|
|
2960
|
+
function kernelSelect(Fs, transport, read2, write2, timeoutMs) {
|
|
2961
2961
|
const kernel = (fd) => Fs.getStream(fd)?.sliccKernelFd;
|
|
2962
|
-
const kr =
|
|
2963
|
-
const kw =
|
|
2962
|
+
const kr = read2.map(kernel);
|
|
2963
|
+
const kw = write2.map(kernel);
|
|
2964
2964
|
const r = transport.call({ op: "fd-select", read: kr, write: kw, timeoutMs }, Infinity, "select");
|
|
2965
2965
|
if (!r.ok) return -wasiErrno(r.errno);
|
|
2966
2966
|
const got = r.kind === "json" ? r.json : { read: [], write: [] };
|
|
2967
2967
|
return {
|
|
2968
|
-
read:
|
|
2969
|
-
write:
|
|
2968
|
+
read: read2.filter((_, i) => got.read.includes(kr[i])),
|
|
2969
|
+
write: write2.filter((_, i) => got.write.includes(kw[i]))
|
|
2970
2970
|
};
|
|
2971
2971
|
}
|
|
2972
|
-
function ownReady(Fs,
|
|
2972
|
+
function ownReady(Fs, read2, write2) {
|
|
2973
2973
|
const flags = (fd) => {
|
|
2974
2974
|
const stream = Fs.getStream(fd);
|
|
2975
2975
|
if (!stream) return POLLNVAL;
|
|
2976
2976
|
return stream.stream_ops.poll ? stream.stream_ops.poll(stream) : POLLIN2 | POLLOUT2;
|
|
2977
2977
|
};
|
|
2978
2978
|
return {
|
|
2979
|
-
read:
|
|
2980
|
-
write:
|
|
2979
|
+
read: read2.filter((fd) => flags(fd) & (POLLIN2 | POLLHUP2 | POLLERR2 | POLLNVAL)),
|
|
2980
|
+
write: write2.filter((fd) => flags(fd) & (POLLOUT2 | POLLERR2 | POLLNVAL))
|
|
2981
2981
|
};
|
|
2982
2982
|
}
|
|
2983
|
-
function anySelect(Fs, transport,
|
|
2983
|
+
function anySelect(Fs, transport, read2, write2, timeoutMs) {
|
|
2984
2984
|
const kernel = (fd) => Fs.getStream(fd)?.sliccKernelFd;
|
|
2985
2985
|
const own = (fd) => kernel(fd) === void 0;
|
|
2986
|
-
if (![...
|
|
2986
|
+
if (![...read2, ...write2].some(own)) return kernelSelect(Fs, transport, read2, write2, timeoutMs);
|
|
2987
2987
|
const deadline = timeoutMs < 0 ? Number.POSITIVE_INFINITY : Date.now() + timeoutMs;
|
|
2988
|
-
const kernelRead =
|
|
2989
|
-
const kernelWrite =
|
|
2988
|
+
const kernelRead = read2.filter((fd) => !own(fd));
|
|
2989
|
+
const kernelWrite = write2.filter((fd) => !own(fd));
|
|
2990
2990
|
for (; ; ) {
|
|
2991
|
-
const local = ownReady(Fs,
|
|
2991
|
+
const local = ownReady(Fs, read2.filter(own), write2.filter(own));
|
|
2992
2992
|
const pending = local.read.length > 0 || local.write.length > 0;
|
|
2993
2993
|
const slice = pending ? 0 : Math.min(SELECT_SLICE_MS, Math.max(0, deadline - Date.now()));
|
|
2994
2994
|
const got = kernelSelect(Fs, transport, kernelRead, kernelWrite, slice);
|
|
@@ -3095,7 +3095,7 @@ function createProcessKernel(deps) {
|
|
|
3095
3095
|
if (!r.ok) return -wasiErrno(r.errno);
|
|
3096
3096
|
return r.kind === "json" ? r.json : -wasiErrno("EIO");
|
|
3097
3097
|
},
|
|
3098
|
-
select: (
|
|
3098
|
+
select: (read2, write2, timeoutMs) => anySelect(Fs, transport, read2, write2, timeoutMs),
|
|
3099
3099
|
execWait,
|
|
3100
3100
|
execve(file, argv, env, cwd) {
|
|
3101
3101
|
const pid = spawnChild(file, argv, env, cwd, [0, 1, 2], void 0, true);
|
|
@@ -5393,17 +5393,17 @@ function writeEvents(mem, ptr, events) {
|
|
|
5393
5393
|
}
|
|
5394
5394
|
function classify(fds, subs) {
|
|
5395
5395
|
const events = [];
|
|
5396
|
-
const
|
|
5397
|
-
const
|
|
5396
|
+
const read2 = [];
|
|
5397
|
+
const write2 = [];
|
|
5398
5398
|
for (const s of subs) {
|
|
5399
5399
|
if (s.type === EVENTTYPE.CLOCK) continue;
|
|
5400
5400
|
const e = fds.find(s.fd);
|
|
5401
5401
|
if (!e) events.push({ userdata: s.userdata, error: E.BADF, type: s.type });
|
|
5402
5402
|
else if (e.type !== "kernel")
|
|
5403
5403
|
events.push({ userdata: s.userdata, error: E.SUCCESS, type: s.type });
|
|
5404
|
-
else (s.type === EVENTTYPE.FD_READ ?
|
|
5404
|
+
else (s.type === EVENTTYPE.FD_READ ? read2 : write2).push(s.fd);
|
|
5405
5405
|
}
|
|
5406
|
-
return { events, read, write };
|
|
5406
|
+
return { events, read: read2, write: write2 };
|
|
5407
5407
|
}
|
|
5408
5408
|
function readyEvents(subs, ready) {
|
|
5409
5409
|
return subs.filter(
|
|
@@ -5419,11 +5419,11 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
|
|
|
5419
5419
|
if (nsubs === 0) return E.INVAL;
|
|
5420
5420
|
const { mem, kernel } = deps;
|
|
5421
5421
|
const subs = readSubscriptions(mem, inPtr, nsubs, deps.now);
|
|
5422
|
-
const { events, read, write } = classify(deps.fds, subs);
|
|
5422
|
+
const { events, read: read2, write: write2 } = classify(deps.fds, subs);
|
|
5423
5423
|
let interrupted = false;
|
|
5424
5424
|
const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
|
|
5425
5425
|
const expired = () => performance.now() + CLOCK_SLACK_MS >= earliest;
|
|
5426
|
-
if (
|
|
5426
|
+
if (read2.length > 0 || write2.length > 0 || events.length === 0) {
|
|
5427
5427
|
do {
|
|
5428
5428
|
let timeoutMs = -1;
|
|
5429
5429
|
if (events.length > 0) timeoutMs = 0;
|
|
@@ -5431,7 +5431,7 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
|
|
|
5431
5431
|
timeoutMs = Math.max(0, Math.ceil(earliest - performance.now()));
|
|
5432
5432
|
let ready;
|
|
5433
5433
|
try {
|
|
5434
|
-
ready = kernel.call({ op: "fd-select", read, write, timeoutMs });
|
|
5434
|
+
ready = kernel.call({ op: "fd-select", read: read2, write: write2, timeoutMs });
|
|
5435
5435
|
} catch (e) {
|
|
5436
5436
|
if (!deps.interruptWakes || e.code !== "EINTR") throw e;
|
|
5437
5437
|
interrupted = true;
|
|
@@ -5552,7 +5552,6 @@ function kernelFiletype(kind) {
|
|
|
5552
5552
|
case "device":
|
|
5553
5553
|
return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
|
|
5554
5554
|
case "socket":
|
|
5555
|
-
case "stream":
|
|
5556
5555
|
return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
|
|
5557
5556
|
case "file":
|
|
5558
5557
|
return { filetype: FILETYPE.REGULAR_FILE, seeks: true };
|
|
@@ -5589,7 +5588,7 @@ function wrap(table) {
|
|
|
5589
5588
|
}
|
|
5590
5589
|
return out;
|
|
5591
5590
|
}
|
|
5592
|
-
var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
|
|
5591
|
+
var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
|
|
5593
5592
|
var init_wasi_host = __esm({
|
|
5594
5593
|
"src/process/wasi/wasi-host.ts"() {
|
|
5595
5594
|
"use strict";
|
|
@@ -5610,6 +5609,7 @@ var init_wasi_host = __esm({
|
|
|
5610
5609
|
IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
|
|
5611
5610
|
NS_PER_MS = 1000000n;
|
|
5612
5611
|
AT_SYMLINK_NOFOLLOW2 = 1;
|
|
5612
|
+
S_IFIFO = 4096;
|
|
5613
5613
|
DEFAULT_UMASK = 18;
|
|
5614
5614
|
MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
|
|
5615
5615
|
MAX_READ = 1024 * 1024;
|
|
@@ -5686,7 +5686,12 @@ var init_wasi_host = __esm({
|
|
|
5686
5686
|
const old = this.o.kernel.call({ op: "proc-umask", mask });
|
|
5687
5687
|
mem.view().setUint32(out, old, true);
|
|
5688
5688
|
},
|
|
5689
|
-
fd_mode: (fd, out) =>
|
|
5689
|
+
fd_mode: (fd, out) => {
|
|
5690
|
+
const e = fds.get(fd);
|
|
5691
|
+
const pipe = e.type === "kernel" && fds.kind(fd, e) === "stream";
|
|
5692
|
+
const mode = pipe ? S_IFIFO | 384 : modeOf(this.o.fs.stat(pathOf(fd)));
|
|
5693
|
+
mem.view().setUint32(out, mode, true);
|
|
5694
|
+
},
|
|
5690
5695
|
path_mode: (dirfd, p, l, flags, out) => {
|
|
5691
5696
|
const path = at(dirfd, p, l);
|
|
5692
5697
|
const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
|
|
@@ -5779,8 +5784,8 @@ var init_wasi_host = __esm({
|
|
|
5779
5784
|
return BigInt(Math.round((performance.now() - this.started) * 1e6)) + 1n;
|
|
5780
5785
|
}
|
|
5781
5786
|
environ() {
|
|
5782
|
-
const
|
|
5783
|
-
const env = { PWD: this.cwd, ...this.o.env, ...
|
|
5787
|
+
const listen2 = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
|
|
5788
|
+
const env = { PWD: this.cwd, ...this.o.env, ...listen2 };
|
|
5784
5789
|
return Object.entries(env).map(([k, v]) => `${k}=${v}`);
|
|
5785
5790
|
}
|
|
5786
5791
|
processImports() {
|
|
@@ -6664,10 +6669,10 @@ function processes(host, call2, inThread) {
|
|
|
6664
6669
|
const slot = (n, how, mine, theirs) => {
|
|
6665
6670
|
if (how === "inherit") return { fd: n };
|
|
6666
6671
|
if (how === "null") return { none: true };
|
|
6667
|
-
const [
|
|
6668
|
-
mine[n] = n === 0 ?
|
|
6669
|
-
theirs.push(n === 0 ?
|
|
6670
|
-
return { fd: n === 0 ?
|
|
6672
|
+
const [read2, write2] = call2({ op: "fd-pipe" });
|
|
6673
|
+
mine[n] = n === 0 ? write2 : read2;
|
|
6674
|
+
theirs.push(n === 0 ? read2 : write2);
|
|
6675
|
+
return { fd: n === 0 ? read2 : write2 };
|
|
6671
6676
|
};
|
|
6672
6677
|
return {
|
|
6673
6678
|
spawn(o) {
|
|
@@ -7051,6 +7056,289 @@ var init_wasix_fork = __esm({
|
|
|
7051
7056
|
}
|
|
7052
7057
|
});
|
|
7053
7058
|
|
|
7059
|
+
// src/process/wasi/wasix-ffi.ts
|
|
7060
|
+
function read(view, at, type) {
|
|
7061
|
+
if (type === "i32") return view.getInt32(at, true);
|
|
7062
|
+
if (type === "i64") return view.getBigInt64(at, true);
|
|
7063
|
+
if (type === "f32") return view.getFloat32(at, true);
|
|
7064
|
+
return view.getFloat64(at, true);
|
|
7065
|
+
}
|
|
7066
|
+
function write(view, at, type, value2) {
|
|
7067
|
+
if (type === "i32") view.setInt32(at, Number(value2), true);
|
|
7068
|
+
else if (type === "i64") view.setBigInt64(at, BigInt(value2), true);
|
|
7069
|
+
else if (type === "f32") view.setFloat32(at, Number(value2), true);
|
|
7070
|
+
else view.setFloat64(at, Number(value2), true);
|
|
7071
|
+
}
|
|
7072
|
+
function scalars(types) {
|
|
7073
|
+
if (types.includes("other")) throw new WasiError("EINVAL");
|
|
7074
|
+
return types;
|
|
7075
|
+
}
|
|
7076
|
+
function callDynamic(ctx, id, values, valuesLen, results, resultsLen, strict) {
|
|
7077
|
+
const table = ctx.table();
|
|
7078
|
+
if (!table) throw new WasiError("ENOTSUP");
|
|
7079
|
+
const fn = id < table.length ? table.get(id) : null;
|
|
7080
|
+
const sig = fn ? ctx.types.of(fn) : void 0;
|
|
7081
|
+
if (!fn || !sig) throw new WasiError("EINVAL");
|
|
7082
|
+
const params = scalars(sig.params);
|
|
7083
|
+
const outs = scalars(sig.results);
|
|
7084
|
+
const view = ctx.mem.view();
|
|
7085
|
+
const end = values + valuesLen;
|
|
7086
|
+
let at = values;
|
|
7087
|
+
const args = params.map((type) => {
|
|
7088
|
+
if (at + SIZE2[type] > end) {
|
|
7089
|
+
if (strict) throw new WasiError("EINVAL");
|
|
7090
|
+
return type === "i64" ? 0n : 0;
|
|
7091
|
+
}
|
|
7092
|
+
const v = read(view, at, type);
|
|
7093
|
+
at += SIZE2[type];
|
|
7094
|
+
return v;
|
|
7095
|
+
});
|
|
7096
|
+
if (strict && at !== end) throw new WasiError("EINVAL");
|
|
7097
|
+
const returned = fn(...args);
|
|
7098
|
+
const got = outs.length === 1 ? [returned] : returned ?? [];
|
|
7099
|
+
const after = ctx.mem.view();
|
|
7100
|
+
const stop = results + resultsLen;
|
|
7101
|
+
let out = results;
|
|
7102
|
+
outs.forEach((type, i) => {
|
|
7103
|
+
if (out + SIZE2[type] > stop) {
|
|
7104
|
+
if (strict) throw new WasiError("EINVAL");
|
|
7105
|
+
return;
|
|
7106
|
+
}
|
|
7107
|
+
write(after, out, type, got[i]);
|
|
7108
|
+
out += SIZE2[type];
|
|
7109
|
+
});
|
|
7110
|
+
if (strict && out !== stop) throw new WasiError("EINVAL");
|
|
7111
|
+
}
|
|
7112
|
+
var SIZE2;
|
|
7113
|
+
var init_wasix_ffi = __esm({
|
|
7114
|
+
"src/process/wasi/wasix-ffi.ts"() {
|
|
7115
|
+
"use strict";
|
|
7116
|
+
init_wasi_files();
|
|
7117
|
+
SIZE2 = { i32: 4, i64: 8, f32: 4, f64: 8 };
|
|
7118
|
+
}
|
|
7119
|
+
});
|
|
7120
|
+
|
|
7121
|
+
// src/process/wasi/wasm-functypes.ts
|
|
7122
|
+
function readTypes(r, s) {
|
|
7123
|
+
for (let i = r.u32(); i > 0; i--) {
|
|
7124
|
+
r.byte();
|
|
7125
|
+
const params = [];
|
|
7126
|
+
for (let n = r.u32(); n > 0; n--) params.push(r.valtype());
|
|
7127
|
+
const results = [];
|
|
7128
|
+
for (let n = r.u32(); n > 0; n--) results.push(r.valtype());
|
|
7129
|
+
s.info.sigs.push({ params, results });
|
|
7130
|
+
}
|
|
7131
|
+
}
|
|
7132
|
+
function readImports(r, s) {
|
|
7133
|
+
for (let i = r.u32(); i > 0; i--) {
|
|
7134
|
+
r.name();
|
|
7135
|
+
const field2 = r.name();
|
|
7136
|
+
const kind = r.byte();
|
|
7137
|
+
if (kind === 0) s.info.funcs.push(r.u32());
|
|
7138
|
+
else if (kind === 1) {
|
|
7139
|
+
r.valtype();
|
|
7140
|
+
r.limits();
|
|
7141
|
+
} else if (kind === 2) r.limits();
|
|
7142
|
+
else if (kind === 3) {
|
|
7143
|
+
r.valtype();
|
|
7144
|
+
r.byte();
|
|
7145
|
+
s.globals.push(field2);
|
|
7146
|
+
} else {
|
|
7147
|
+
r.byte();
|
|
7148
|
+
r.u32();
|
|
7149
|
+
}
|
|
7150
|
+
}
|
|
7151
|
+
}
|
|
7152
|
+
function readFunctions(r, s) {
|
|
7153
|
+
for (let i = r.u32(); i > 0; i--) s.info.funcs.push(r.u32());
|
|
7154
|
+
}
|
|
7155
|
+
function constExpr(r, s) {
|
|
7156
|
+
let value2 = 0;
|
|
7157
|
+
let tableBase = false;
|
|
7158
|
+
let known = true;
|
|
7159
|
+
for (; ; ) {
|
|
7160
|
+
const op = r.byte();
|
|
7161
|
+
if (op === 11) return known ? { value: value2, tableBase } : void 0;
|
|
7162
|
+
if (op === 65) value2 += r.s32();
|
|
7163
|
+
else if (op === 35) {
|
|
7164
|
+
const g = s.globals[r.u32()];
|
|
7165
|
+
if (g === TABLE_BASE) tableBase = true;
|
|
7166
|
+
else if (typeof g === "number") value2 += g;
|
|
7167
|
+
else known = false;
|
|
7168
|
+
} else if (op === 210) {
|
|
7169
|
+
value2 = r.u32();
|
|
7170
|
+
} else if (op in SKIP) {
|
|
7171
|
+
SKIP[op]?.(r);
|
|
7172
|
+
known = false;
|
|
7173
|
+
} else if (op !== 106) {
|
|
7174
|
+
r.at = r.bytes.length;
|
|
7175
|
+
return void 0;
|
|
7176
|
+
}
|
|
7177
|
+
}
|
|
7178
|
+
}
|
|
7179
|
+
function readGlobals(r, s) {
|
|
7180
|
+
for (let i = r.u32(); i > 0; i--) {
|
|
7181
|
+
r.valtype();
|
|
7182
|
+
r.byte();
|
|
7183
|
+
const init = constExpr(r, s);
|
|
7184
|
+
s.globals.push(init && !init.tableBase ? init.value : void 0);
|
|
7185
|
+
}
|
|
7186
|
+
}
|
|
7187
|
+
function readExports(r, s) {
|
|
7188
|
+
for (let i = r.u32(); i > 0; i--) {
|
|
7189
|
+
const name = r.name();
|
|
7190
|
+
const kind = r.byte();
|
|
7191
|
+
const index2 = r.u32();
|
|
7192
|
+
if (kind === 0) s.info.exports[name] = index2;
|
|
7193
|
+
}
|
|
7194
|
+
}
|
|
7195
|
+
function readElems(r, s) {
|
|
7196
|
+
for (let i = r.u32(); i > 0; i--) {
|
|
7197
|
+
const flags = r.u32();
|
|
7198
|
+
const active = (flags & 1) === 0;
|
|
7199
|
+
const table = flags & 2 ? active ? r.u32() : 0 : 0;
|
|
7200
|
+
const offset = active ? constExpr(r, s) : void 0;
|
|
7201
|
+
if (flags & 3) r.valtype();
|
|
7202
|
+
const funcs = [];
|
|
7203
|
+
for (let n = r.u32(); n > 0; n--) {
|
|
7204
|
+
if (flags & 4) {
|
|
7205
|
+
const ref = constExpr(r, s);
|
|
7206
|
+
funcs.push(ref ? ref.value : -1);
|
|
7207
|
+
} else funcs.push(r.u32());
|
|
7208
|
+
}
|
|
7209
|
+
if (offset && table === 0) {
|
|
7210
|
+
s.info.elems.push({ offset: offset.value, tableBase: offset.tableBase, funcs });
|
|
7211
|
+
}
|
|
7212
|
+
}
|
|
7213
|
+
}
|
|
7214
|
+
function funcTypeInfo(bytes) {
|
|
7215
|
+
const r = new Reader(bytes);
|
|
7216
|
+
const s = { info: { sigs: [], funcs: [], exports: {}, elems: [] }, globals: [] };
|
|
7217
|
+
while (r.at < bytes.length) {
|
|
7218
|
+
const id = r.byte();
|
|
7219
|
+
const end = r.u32() + r.at;
|
|
7220
|
+
SECTIONS[id]?.(r, s);
|
|
7221
|
+
r.at = end;
|
|
7222
|
+
}
|
|
7223
|
+
return s.info;
|
|
7224
|
+
}
|
|
7225
|
+
var VALTYPES, TABLE_BASE, Reader, SKIP, SECTIONS, FuncTypes;
|
|
7226
|
+
var init_wasm_functypes = __esm({
|
|
7227
|
+
"src/process/wasi/wasm-functypes.ts"() {
|
|
7228
|
+
"use strict";
|
|
7229
|
+
VALTYPES = {
|
|
7230
|
+
127: "i32",
|
|
7231
|
+
126: "i64",
|
|
7232
|
+
125: "f32",
|
|
7233
|
+
124: "f64"
|
|
7234
|
+
};
|
|
7235
|
+
TABLE_BASE = "__table_base";
|
|
7236
|
+
Reader = class {
|
|
7237
|
+
at = 8;
|
|
7238
|
+
bytes;
|
|
7239
|
+
constructor(bytes) {
|
|
7240
|
+
this.bytes = bytes;
|
|
7241
|
+
}
|
|
7242
|
+
byte() {
|
|
7243
|
+
return this.bytes[this.at++] ?? 0;
|
|
7244
|
+
}
|
|
7245
|
+
u32() {
|
|
7246
|
+
let result = 0;
|
|
7247
|
+
let shift = 0;
|
|
7248
|
+
for (; ; ) {
|
|
7249
|
+
const b = this.byte();
|
|
7250
|
+
result |= (b & 127) << shift;
|
|
7251
|
+
if (!(b & 128)) return result >>> 0;
|
|
7252
|
+
shift += 7;
|
|
7253
|
+
}
|
|
7254
|
+
}
|
|
7255
|
+
s32() {
|
|
7256
|
+
let result = 0;
|
|
7257
|
+
let shift = 0;
|
|
7258
|
+
let b;
|
|
7259
|
+
do {
|
|
7260
|
+
b = this.byte();
|
|
7261
|
+
result |= (b & 127) << shift;
|
|
7262
|
+
shift += 7;
|
|
7263
|
+
} while (b & 128);
|
|
7264
|
+
return shift < 32 && b & 64 ? result | -1 << shift : result;
|
|
7265
|
+
}
|
|
7266
|
+
name() {
|
|
7267
|
+
const len = this.u32();
|
|
7268
|
+
const s = new TextDecoder().decode(this.bytes.subarray(this.at, this.at + len));
|
|
7269
|
+
this.at += len;
|
|
7270
|
+
return s;
|
|
7271
|
+
}
|
|
7272
|
+
valtype() {
|
|
7273
|
+
const code2 = this.byte();
|
|
7274
|
+
if (code2 === 99 || code2 === 100) this.s32();
|
|
7275
|
+
return VALTYPES[code2] ?? "other";
|
|
7276
|
+
}
|
|
7277
|
+
limits() {
|
|
7278
|
+
const flags = this.byte();
|
|
7279
|
+
this.u32();
|
|
7280
|
+
if (flags & 1) this.u32();
|
|
7281
|
+
}
|
|
7282
|
+
};
|
|
7283
|
+
SKIP = {
|
|
7284
|
+
66: (r) => r.s32(),
|
|
7285
|
+
67: (r) => {
|
|
7286
|
+
r.at += 4;
|
|
7287
|
+
},
|
|
7288
|
+
68: (r) => {
|
|
7289
|
+
r.at += 8;
|
|
7290
|
+
},
|
|
7291
|
+
208: (r) => r.valtype()
|
|
7292
|
+
};
|
|
7293
|
+
SECTIONS = {
|
|
7294
|
+
1: readTypes,
|
|
7295
|
+
2: readImports,
|
|
7296
|
+
3: readFunctions,
|
|
7297
|
+
6: readGlobals,
|
|
7298
|
+
7: readExports,
|
|
7299
|
+
9: readElems
|
|
7300
|
+
};
|
|
7301
|
+
FuncTypes = class {
|
|
7302
|
+
known = /* @__PURE__ */ new WeakMap();
|
|
7303
|
+
pending = [];
|
|
7304
|
+
register(read2, instance, table, tableBase) {
|
|
7305
|
+
this.pending.push(() => {
|
|
7306
|
+
const bytes = read2();
|
|
7307
|
+
if (bytes) this.add(funcTypeInfo(bytes), instance, table, tableBase);
|
|
7308
|
+
});
|
|
7309
|
+
}
|
|
7310
|
+
add(info, instance, table, tableBase) {
|
|
7311
|
+
const sig = (func) => info.sigs[info.funcs[func] ?? -1];
|
|
7312
|
+
for (const [name, func] of Object.entries(info.exports)) {
|
|
7313
|
+
const fn = instance.exports[name];
|
|
7314
|
+
const type = sig(func);
|
|
7315
|
+
if (typeof fn === "function" && type) this.known.set(fn, type);
|
|
7316
|
+
}
|
|
7317
|
+
if (!table) return;
|
|
7318
|
+
for (const seg of info.elems) {
|
|
7319
|
+
const start2 = seg.offset + (seg.tableBase ? tableBase : 0);
|
|
7320
|
+
seg.funcs.forEach((func, i) => {
|
|
7321
|
+
const type = sig(func);
|
|
7322
|
+
const fn = start2 + i < table.length ? table.get(start2 + i) : null;
|
|
7323
|
+
if (fn && type) this.known.set(fn, type);
|
|
7324
|
+
});
|
|
7325
|
+
}
|
|
7326
|
+
}
|
|
7327
|
+
set(fn, sig) {
|
|
7328
|
+
this.known.set(fn, sig);
|
|
7329
|
+
}
|
|
7330
|
+
of(fn) {
|
|
7331
|
+
const known = this.known.get(fn);
|
|
7332
|
+
if (known || this.pending.length === 0) return known;
|
|
7333
|
+
const pending = this.pending;
|
|
7334
|
+
this.pending = [];
|
|
7335
|
+
for (const run of pending) run();
|
|
7336
|
+
return this.known.get(fn);
|
|
7337
|
+
}
|
|
7338
|
+
};
|
|
7339
|
+
}
|
|
7340
|
+
});
|
|
7341
|
+
|
|
7054
7342
|
// src/process/wasi/wasix-linker.ts
|
|
7055
7343
|
function expandOrigin(entry, dir) {
|
|
7056
7344
|
return entry.replace(/\$(?:ORIGIN\b|\{ORIGIN\})/g, dir);
|
|
@@ -7069,13 +7357,14 @@ function call(instance, name) {
|
|
|
7069
7357
|
const fn = instance.exports[name];
|
|
7070
7358
|
if (typeof fn === "function") fn();
|
|
7071
7359
|
}
|
|
7072
|
-
var
|
|
7360
|
+
var TABLE_BASE2, PAGE2, STACK_SIZE, LIBRARY_DIRS, DlError, WasixLinker;
|
|
7073
7361
|
var init_wasix_linker = __esm({
|
|
7074
7362
|
"src/process/wasi/wasix-linker.ts"() {
|
|
7075
7363
|
"use strict";
|
|
7076
7364
|
init_dylink();
|
|
7077
7365
|
init_wasi_files();
|
|
7078
|
-
|
|
7366
|
+
init_wasm_functypes();
|
|
7367
|
+
TABLE_BASE2 = 1;
|
|
7079
7368
|
PAGE2 = 65536;
|
|
7080
7369
|
STACK_SIZE = 8 * 1024 * 1024;
|
|
7081
7370
|
LIBRARY_DIRS = ["/lib", "/usr/lib", "/usr/local/lib"];
|
|
@@ -7096,6 +7385,8 @@ var init_wasix_linker = __esm({
|
|
|
7096
7385
|
slots = /* @__PURE__ */ new Map();
|
|
7097
7386
|
nextHandle = 1;
|
|
7098
7387
|
publisher;
|
|
7388
|
+
closures;
|
|
7389
|
+
types = new FuncTypes();
|
|
7099
7390
|
memory;
|
|
7100
7391
|
host;
|
|
7101
7392
|
constructor(memory, mainInfo, host, thread = false) {
|
|
@@ -7107,7 +7398,7 @@ var init_wasix_linker = __esm({
|
|
|
7107
7398
|
if (!thread) growTo(memory, this.stackHigh);
|
|
7108
7399
|
this.table = new WebAssembly.Table({
|
|
7109
7400
|
element: "anyfunc",
|
|
7110
|
-
initial:
|
|
7401
|
+
initial: TABLE_BASE2 + mainInfo.tableSize
|
|
7111
7402
|
});
|
|
7112
7403
|
this.stackPointer = new WebAssembly.Global(
|
|
7113
7404
|
{ value: "i32", mutable: true },
|
|
@@ -7127,7 +7418,7 @@ var init_wasix_linker = __esm({
|
|
|
7127
7418
|
__indirect_function_table: this.table,
|
|
7128
7419
|
__stack_pointer: this.stackPointer,
|
|
7129
7420
|
__memory_base: i32(this.memoryBase),
|
|
7130
|
-
__table_base: i32(
|
|
7421
|
+
__table_base: i32(TABLE_BASE2),
|
|
7131
7422
|
__c_longjmp: this.cLongjmp,
|
|
7132
7423
|
__cpp_exception: this.cppException
|
|
7133
7424
|
};
|
|
@@ -7179,7 +7470,22 @@ var init_wasix_linker = __esm({
|
|
|
7179
7470
|
for (const [path, linked] of this.byPath) out[path] = linked.module;
|
|
7180
7471
|
return out;
|
|
7181
7472
|
}
|
|
7473
|
+
allocateClosure() {
|
|
7474
|
+
const index2 = this.closures.allocate(
|
|
7475
|
+
this.table.length
|
|
7476
|
+
);
|
|
7477
|
+
growTable(this.table, index2 + 1);
|
|
7478
|
+
return index2;
|
|
7479
|
+
}
|
|
7480
|
+
freeClosure(index2) {
|
|
7481
|
+
this.closures?.free(index2);
|
|
7482
|
+
this.table.set(index2, null);
|
|
7483
|
+
}
|
|
7182
7484
|
replay(record) {
|
|
7485
|
+
if (record.kind === "closure") {
|
|
7486
|
+
growTable(this.table, record.index + 1);
|
|
7487
|
+
return;
|
|
7488
|
+
}
|
|
7183
7489
|
if (record.kind === "load") {
|
|
7184
7490
|
if (this.modules.has(record.handle)) return;
|
|
7185
7491
|
this.instantiate(record.path, this.moduleAt(record.path), record, false);
|
|
@@ -7294,6 +7600,7 @@ var init_wasix_linker = __esm({
|
|
|
7294
7600
|
"GOT.func": gotFunc
|
|
7295
7601
|
};
|
|
7296
7602
|
linked.instance = new WebAssembly.Instance(module, imports);
|
|
7603
|
+
this.types.register(() => this.host.read(path), linked.instance, this.table, at.tableBase);
|
|
7297
7604
|
this.modules.set(at.handle, linked);
|
|
7298
7605
|
this.byPath.set(path, linked);
|
|
7299
7606
|
for (const resolve of pending) resolve();
|
|
@@ -7671,9 +7978,11 @@ var init_wasix_host = __esm({
|
|
|
7671
7978
|
init_wasi_files();
|
|
7672
7979
|
init_wasi_host();
|
|
7673
7980
|
init_wasi_threads();
|
|
7981
|
+
init_wasix_ffi();
|
|
7674
7982
|
init_wasix_linker();
|
|
7675
7983
|
init_wasix_process();
|
|
7676
7984
|
init_wasix_sockets();
|
|
7985
|
+
init_wasm_functypes();
|
|
7677
7986
|
FDFLAGSEXT_CLOEXEC = 1;
|
|
7678
7987
|
SPAWN_OP_SIZE = 56;
|
|
7679
7988
|
SPAWN_OPS = ["close", "dup2", "open", "chdir", "fchdir"];
|
|
@@ -7685,6 +7994,8 @@ var init_wasix_host = __esm({
|
|
|
7685
7994
|
process;
|
|
7686
7995
|
threads;
|
|
7687
7996
|
linker;
|
|
7997
|
+
types = new FuncTypes();
|
|
7998
|
+
table;
|
|
7688
7999
|
signals;
|
|
7689
8000
|
host;
|
|
7690
8001
|
driver;
|
|
@@ -7766,6 +8077,18 @@ var init_wasix_host = __esm({
|
|
|
7766
8077
|
...this.processImports(),
|
|
7767
8078
|
...this.threadImports(),
|
|
7768
8079
|
...this.dlImports(),
|
|
8080
|
+
closure_allocate: (out) => {
|
|
8081
|
+
if (!this.linker) throw new WasiError("ENOTSUP");
|
|
8082
|
+
this.mem.view().setUint32(out, this.linker.allocateClosure(), true);
|
|
8083
|
+
},
|
|
8084
|
+
closure_free: (index2) => {
|
|
8085
|
+
if (!this.linker) throw new WasiError("ENOTSUP");
|
|
8086
|
+
this.linker.freeClosure(index2);
|
|
8087
|
+
},
|
|
8088
|
+
call_dynamic: (...a) => void callDynamic(
|
|
8089
|
+
{ mem: this.mem, table: () => this.table, types: this.types },
|
|
8090
|
+
...a
|
|
8091
|
+
),
|
|
7769
8092
|
...wasixSocketImports(this.host, this.host.imports())
|
|
7770
8093
|
});
|
|
7771
8094
|
}
|
|
@@ -8087,12 +8410,12 @@ function nameFrame(line, module, name) {
|
|
|
8087
8410
|
const found = name(Number(m[4]));
|
|
8088
8411
|
return found === void 0 ? line : `${m[1]}${found} (${m[2]})`;
|
|
8089
8412
|
}
|
|
8090
|
-
function sidecarNames(
|
|
8413
|
+
function sidecarNames(read2, path) {
|
|
8091
8414
|
let names;
|
|
8092
8415
|
return (index2) => {
|
|
8093
8416
|
if (!names) {
|
|
8094
8417
|
try {
|
|
8095
|
-
names = parseFunctionNames(
|
|
8418
|
+
names = parseFunctionNames(read2(path));
|
|
8096
8419
|
} catch {
|
|
8097
8420
|
names = /* @__PURE__ */ new Map();
|
|
8098
8421
|
}
|
|
@@ -8262,7 +8585,8 @@ async function instantiate(host, module, memory, threads, {
|
|
|
8262
8585
|
stats,
|
|
8263
8586
|
signals,
|
|
8264
8587
|
program,
|
|
8265
|
-
foreign
|
|
8588
|
+
foreign,
|
|
8589
|
+
path
|
|
8266
8590
|
} = {}) {
|
|
8267
8591
|
const driver = new AsyncifyDriver(host.mem);
|
|
8268
8592
|
const wasixHost = WebAssembly.Module.imports(module).some((i) => i.module === WASIX) ? new WasixHost(host, driver, module) : void 0;
|
|
@@ -8288,7 +8612,10 @@ async function instantiate(host, module, memory, threads, {
|
|
|
8288
8612
|
) : void 0;
|
|
8289
8613
|
if (sync) {
|
|
8290
8614
|
({ preview1, wasix } = sync.guard(preview1, wasix));
|
|
8291
|
-
if (wasixHost)
|
|
8615
|
+
if (wasixHost) {
|
|
8616
|
+
wasixHost.linker = sync.linker;
|
|
8617
|
+
wasixHost.types = sync.linker.types;
|
|
8618
|
+
}
|
|
8292
8619
|
if (threads) {
|
|
8293
8620
|
sync.linker.cache = threads.received;
|
|
8294
8621
|
threads.modules = () => sync.linker.compiled();
|
|
@@ -8319,6 +8646,14 @@ async function instantiate(host, module, memory, threads, {
|
|
|
8319
8646
|
stats?.phase("instantiate");
|
|
8320
8647
|
const exports = instance.exports;
|
|
8321
8648
|
host.mem.bind(memory ?? exports.memory);
|
|
8649
|
+
if (wasixHost) {
|
|
8650
|
+
const table = sync?.linker.table ?? exportedTable(instance);
|
|
8651
|
+
wasixHost.table = table;
|
|
8652
|
+
if (path !== void 0) {
|
|
8653
|
+
const read2 = linkerHost(host, () => ({})).read;
|
|
8654
|
+
wasixHost.types.register(() => read2(path), instance, table, sync ? TABLE_BASE2 : 0);
|
|
8655
|
+
}
|
|
8656
|
+
}
|
|
8322
8657
|
if (sync) {
|
|
8323
8658
|
sync.linker.bindMain(instance, !thread);
|
|
8324
8659
|
if (thread) sync.catchUp();
|
|
@@ -8326,6 +8661,10 @@ async function instantiate(host, module, memory, threads, {
|
|
|
8326
8661
|
}
|
|
8327
8662
|
return { instance, driver };
|
|
8328
8663
|
}
|
|
8664
|
+
function exportedTable(instance) {
|
|
8665
|
+
const table = instance.exports.__indirect_function_table;
|
|
8666
|
+
return table instanceof WebAssembly.Table ? table : void 0;
|
|
8667
|
+
}
|
|
8329
8668
|
function linkerHost(host, imports) {
|
|
8330
8669
|
return {
|
|
8331
8670
|
read: (path) => {
|
|
@@ -8405,6 +8744,7 @@ async function runWasiProcess(init, port2) {
|
|
|
8405
8744
|
stats,
|
|
8406
8745
|
signals,
|
|
8407
8746
|
foreign: init.program.foreign,
|
|
8747
|
+
path: init.program.path,
|
|
8408
8748
|
...program ? { program } : {}
|
|
8409
8749
|
});
|
|
8410
8750
|
restoreExportedMemory(instance, memory, init);
|
|
@@ -8489,6 +8829,7 @@ async function runWasiThread(init, port2) {
|
|
|
8489
8829
|
const { instance } = await instantiate(host, init.program.module, thread.memory, threads, {
|
|
8490
8830
|
thread: true,
|
|
8491
8831
|
foreign: init.program.foreign,
|
|
8832
|
+
path: init.program.path,
|
|
8492
8833
|
...program ? { program } : {}
|
|
8493
8834
|
});
|
|
8494
8835
|
signals.bind(instance.exports);
|
|
@@ -8568,6 +8909,14 @@ var init_wasi_runtime = __esm({
|
|
|
8568
8909
|
this.call = call2;
|
|
8569
8910
|
this.ids = ids;
|
|
8570
8911
|
linker.publisher = (record) => this.publish(record);
|
|
8912
|
+
linker.closures = {
|
|
8913
|
+
allocate: (floor) => {
|
|
8914
|
+
const index2 = this.call({ op: "dl-closure", floor });
|
|
8915
|
+
this.catchUp();
|
|
8916
|
+
return index2;
|
|
8917
|
+
},
|
|
8918
|
+
free: (index2) => void this.call({ op: "dl-closure-free", index: index2 })
|
|
8919
|
+
};
|
|
8571
8920
|
}
|
|
8572
8921
|
publish(record) {
|
|
8573
8922
|
const since = this.call({ op: "dl-log", append: record, from: this.count });
|
|
@@ -8926,10 +9275,10 @@ async function slots(kernel, o, mine, theirs) {
|
|
|
8926
9275
|
else if (how === "null") stdio.push({ none: true });
|
|
8927
9276
|
else if (typeof how === "number") stdio.push({ fd: how });
|
|
8928
9277
|
else {
|
|
8929
|
-
const [
|
|
8930
|
-
mine[n] = n === 0 ?
|
|
8931
|
-
theirs.push(n === 0 ?
|
|
8932
|
-
stdio.push({ fd: n === 0 ?
|
|
9278
|
+
const [read2, write2] = await kernel.json({ op: "fd-pipe" });
|
|
9279
|
+
mine[n] = n === 0 ? write2 : read2;
|
|
9280
|
+
theirs.push(n === 0 ? read2 : write2);
|
|
9281
|
+
stdio.push({ fd: n === 0 ? read2 : write2 });
|
|
8933
9282
|
}
|
|
8934
9283
|
}
|
|
8935
9284
|
return stdio;
|
|
@@ -9349,8 +9698,8 @@ function checkOpen(abs, o, existing) {
|
|
|
9349
9698
|
if (existing?.isDirectory) throw new JsCallError("EISDIR", abs);
|
|
9350
9699
|
}
|
|
9351
9700
|
function flagsOf(o) {
|
|
9352
|
-
const
|
|
9353
|
-
const access =
|
|
9701
|
+
const write2 = o.write || o.append || o.truncate;
|
|
9702
|
+
const access = write2 ? o.read ? O_RDWR6 : O_WRONLY6 : 0;
|
|
9354
9703
|
return access | (o.append ? O_APPEND3 : 0);
|
|
9355
9704
|
}
|
|
9356
9705
|
function openRequest(abs, o) {
|
|
@@ -9535,14 +9884,14 @@ function syncOps(kernel, shared) {
|
|
|
9535
9884
|
infos.set(fd, got);
|
|
9536
9885
|
return got;
|
|
9537
9886
|
};
|
|
9538
|
-
const
|
|
9887
|
+
const read2 = (fd, max = CHUNK2) => {
|
|
9539
9888
|
index(max, "read");
|
|
9540
9889
|
const emulated = readDevice(info(fd), max, shared.random);
|
|
9541
9890
|
if (emulated) return emulated;
|
|
9542
9891
|
const r = kernel.blocking({ op: "fd-read", fd, max: Math.min(max, MAX_IO) });
|
|
9543
9892
|
return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
|
|
9544
9893
|
};
|
|
9545
|
-
const
|
|
9894
|
+
const write2 = (fd, data) => {
|
|
9546
9895
|
const bytes = typeof data === "string" ? encoder2.encode(data) : data;
|
|
9547
9896
|
const i = info(fd);
|
|
9548
9897
|
if (writeDevice(i)) return;
|
|
@@ -9589,8 +9938,8 @@ function syncOps(kernel, shared) {
|
|
|
9589
9938
|
return handle.file;
|
|
9590
9939
|
};
|
|
9591
9940
|
return {
|
|
9592
|
-
read,
|
|
9593
|
-
write,
|
|
9941
|
+
read: read2,
|
|
9942
|
+
write: write2,
|
|
9594
9943
|
close(fd) {
|
|
9595
9944
|
handles.get(fd)?.();
|
|
9596
9945
|
handles.delete(fd);
|
|
@@ -9970,6 +10319,11 @@ var init_js_websocket = __esm({
|
|
|
9970
10319
|
});
|
|
9971
10320
|
|
|
9972
10321
|
// src/process/js/js-context.ts
|
|
10322
|
+
function listen(listeners, listener) {
|
|
10323
|
+
const own = (error, promise) => listener(error, promise);
|
|
10324
|
+
listeners.add(own);
|
|
10325
|
+
return () => void listeners.delete(own);
|
|
10326
|
+
}
|
|
9973
10327
|
function identityOf(answer2, fallback) {
|
|
9974
10328
|
const id = answer2;
|
|
9975
10329
|
return {
|
|
@@ -10019,7 +10373,7 @@ function createContext(o) {
|
|
|
10019
10373
|
infos.set(fd, got);
|
|
10020
10374
|
return got;
|
|
10021
10375
|
};
|
|
10022
|
-
const
|
|
10376
|
+
const read2 = async (fd, max = CHUNK2, signal) => {
|
|
10023
10377
|
index(max, "read");
|
|
10024
10378
|
const emulated = readDevice(await info(fd), max, random);
|
|
10025
10379
|
if (emulated) return emulated;
|
|
@@ -10039,7 +10393,7 @@ function createContext(o) {
|
|
|
10039
10393
|
}
|
|
10040
10394
|
}
|
|
10041
10395
|
};
|
|
10042
|
-
const
|
|
10396
|
+
const write2 = (fd, data) => {
|
|
10043
10397
|
const bytes = typeof data === "string" ? encoder3.encode(data) : data;
|
|
10044
10398
|
let settle;
|
|
10045
10399
|
const settled = new Promise((resolve2) => settle = resolve2);
|
|
@@ -10053,7 +10407,7 @@ function createContext(o) {
|
|
|
10053
10407
|
}
|
|
10054
10408
|
})();
|
|
10055
10409
|
};
|
|
10056
|
-
const writable2 = (fd) => new WritableStream({ write: (chunk) =>
|
|
10410
|
+
const writable2 = (fd) => new WritableStream({ write: (chunk) => write2(fd, chunk) });
|
|
10057
10411
|
const statOf = async (op, path) => {
|
|
10058
10412
|
const abs = resolve(path);
|
|
10059
10413
|
await kernel.call({ op: "fd-path-flush", path: abs });
|
|
@@ -10089,8 +10443,9 @@ function createContext(o) {
|
|
|
10089
10443
|
handles
|
|
10090
10444
|
});
|
|
10091
10445
|
const terminal = ttyOps(kernel);
|
|
10092
|
-
const io = { read, send: writeAll, close: (fd) => ctx.close(fd) };
|
|
10446
|
+
const io = { read: read2, send: writeAll, close: (fd) => ctx.close(fd) };
|
|
10093
10447
|
const children = childOps(kernel, io, { env: o.env, cwd: o.cwd, signal: signalNumber });
|
|
10448
|
+
const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
|
|
10094
10449
|
const ctx = {
|
|
10095
10450
|
argv: o.argv,
|
|
10096
10451
|
env: o.env,
|
|
@@ -10102,7 +10457,7 @@ function createContext(o) {
|
|
|
10102
10457
|
stdin: new ReadableStream(
|
|
10103
10458
|
{
|
|
10104
10459
|
async pull(controller) {
|
|
10105
|
-
const chunk = await
|
|
10460
|
+
const chunk = await read2(0);
|
|
10106
10461
|
if (chunk.length === 0) controller.close();
|
|
10107
10462
|
else controller.enqueue(chunk);
|
|
10108
10463
|
}
|
|
@@ -10111,8 +10466,8 @@ function createContext(o) {
|
|
|
10111
10466
|
),
|
|
10112
10467
|
stdout: writable2(1),
|
|
10113
10468
|
stderr: writable2(2),
|
|
10114
|
-
read,
|
|
10115
|
-
write,
|
|
10469
|
+
read: read2,
|
|
10470
|
+
write: write2,
|
|
10116
10471
|
async close(fd) {
|
|
10117
10472
|
handles.get(fd)?.();
|
|
10118
10473
|
handles.delete(fd);
|
|
@@ -10138,7 +10493,9 @@ function createContext(o) {
|
|
|
10138
10493
|
net: netOps(kernel, io),
|
|
10139
10494
|
websocket: websocketOp(kernel),
|
|
10140
10495
|
tty: terminal.tty,
|
|
10141
|
-
exit
|
|
10496
|
+
exit,
|
|
10497
|
+
onUncaught: (listener) => listen(strays.exception, listener),
|
|
10498
|
+
onUnhandledRejection: (listener) => listen(strays.rejection, listener)
|
|
10142
10499
|
};
|
|
10143
10500
|
const drain2 = async () => {
|
|
10144
10501
|
for (; ; ) {
|
|
@@ -10357,19 +10714,19 @@ __export(js_runtime_exports, {
|
|
|
10357
10714
|
runJsProcess: () => runJsProcess,
|
|
10358
10715
|
trapStrays: () => trapStrays
|
|
10359
10716
|
});
|
|
10360
|
-
function trapStrays(scope2,
|
|
10717
|
+
function trapStrays(scope2, stray) {
|
|
10361
10718
|
if (typeof scope2.process?.on === "function") {
|
|
10362
|
-
scope2.process.on("unhandledRejection",
|
|
10363
|
-
scope2.process.on("uncaughtException",
|
|
10719
|
+
scope2.process.on("unhandledRejection", (err, promise) => stray("rejection", err, promise));
|
|
10720
|
+
scope2.process.on("uncaughtException", (err) => stray("exception", err));
|
|
10364
10721
|
return;
|
|
10365
10722
|
}
|
|
10366
10723
|
scope2.addEventListener?.("unhandledrejection", (event) => {
|
|
10367
10724
|
event.preventDefault();
|
|
10368
|
-
|
|
10725
|
+
stray("rejection", event.reason, event.promise);
|
|
10369
10726
|
});
|
|
10370
10727
|
scope2.addEventListener?.("error", (event) => {
|
|
10371
10728
|
event.preventDefault();
|
|
10372
|
-
|
|
10729
|
+
stray("exception", event.error);
|
|
10373
10730
|
});
|
|
10374
10731
|
}
|
|
10375
10732
|
async function settledStrays() {
|
|
@@ -10406,6 +10763,7 @@ async function runJsProcess(init, port2, deps = {}) {
|
|
|
10406
10763
|
waitAsync: deps.waitAsync
|
|
10407
10764
|
});
|
|
10408
10765
|
void kernel.watchStops();
|
|
10766
|
+
const strays = { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
|
|
10409
10767
|
const id = identityOf(await kernel.json({ op: "proc-identity" }), init);
|
|
10410
10768
|
kernel.pid = id.pid;
|
|
10411
10769
|
const { ctx, drain: drain2 } = createContext({
|
|
@@ -10416,12 +10774,23 @@ async function runJsProcess(init, port2, deps = {}) {
|
|
|
10416
10774
|
ppid: id.ppid,
|
|
10417
10775
|
cwd: init.cwd,
|
|
10418
10776
|
exit: (status3) => exited(statusOf(status3)),
|
|
10419
|
-
lane: laneOf(init.lane)
|
|
10777
|
+
lane: laneOf(init.lane),
|
|
10778
|
+
strays
|
|
10420
10779
|
});
|
|
10421
10780
|
const say = (text) => ctx.write(2, `${init.argv0}: ${text}
|
|
10422
10781
|
`).catch(() => void 0);
|
|
10423
10782
|
let main;
|
|
10424
|
-
trapStrays(deps.scope ?? globalThis,
|
|
10783
|
+
trapStrays(deps.scope ?? globalThis, (kind, err, promise) => {
|
|
10784
|
+
const listeners = [...strays[kind]];
|
|
10785
|
+
if (listeners.length === 0) return fail(err);
|
|
10786
|
+
for (const listener of listeners) {
|
|
10787
|
+
try {
|
|
10788
|
+
listener(err, promise);
|
|
10789
|
+
} catch (thrown) {
|
|
10790
|
+
fail(thrown);
|
|
10791
|
+
}
|
|
10792
|
+
}
|
|
10793
|
+
});
|
|
10425
10794
|
try {
|
|
10426
10795
|
(deps.lockdown ?? lockdown)();
|
|
10427
10796
|
main = mainOf(await (deps.load ?? importSource)(init.program.glue));
|