@ai-ecoverse/slicc-kernel 1.103.3 → 1.106.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/README.md +56 -15
- package/dist/driver-worker.js +36 -1
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +89 -5
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +783 -289
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +2 -2
- package/dist/node-driver-worker.js +36 -1
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +447 -224
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +831 -309
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +384 -161
- package/dist/process-worker.js.map +4 -4
- package/dist/types/commands.d.ts +6 -1
- package/dist/types/fs/command-stat.d.ts +3 -0
- package/dist/types/fs/commands.d.ts +7 -1
- package/dist/types/fs/engines.d.ts +5 -0
- package/dist/types/fs/types.d.ts +1 -0
- package/dist/types/kernel/host.d.ts +1 -0
- package/dist/types/kernel/net/http-syscalls.d.ts +10 -0
- package/dist/types/kernel/net/http1.d.ts +1 -0
- package/dist/types/kernel/net/remote-transport.d.ts +18 -0
- package/dist/types/kernel/net/transport.d.ts +2 -0
- package/dist/types/kernel/process.d.ts +8 -0
- package/dist/types/launcher.d.ts +4 -0
- package/dist/types/process/process-signals.d.ts +3 -0
- package/dist/types/process/wasi/wasi-cred.d.ts +11 -0
- package/dist/types/process/wasi/wasi-files.d.ts +1 -0
- package/dist/types/process/wasi/wasi-host.d.ts +9 -0
- package/dist/types/process/wasi/wasi-sigmask.d.ts +7 -1
- package/dist/types/process/wasi/wasix-epoll.d.ts +3 -0
- package/dist/types/refused-command.d.ts +4 -0
- package/dist/types/transport.d.ts +1 -0
- package/package.json +17 -12
package/dist/process-worker.js
CHANGED
|
@@ -2491,7 +2491,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
2491
2491
|
var init_version = __esm({
|
|
2492
2492
|
"src/version.ts"() {
|
|
2493
2493
|
"use strict";
|
|
2494
|
-
KERNEL_VERSION = true ? "1.
|
|
2494
|
+
KERNEL_VERSION = true ? "1.106.2" : "0.0.0-dev";
|
|
2495
2495
|
OS_RELEASE = "6.0.0-slicc";
|
|
2496
2496
|
}
|
|
2497
2497
|
});
|
|
@@ -4207,7 +4207,7 @@ function orphanContents(stream) {
|
|
|
4207
4207
|
if (live.ranged) return live.ranged.read(0, live.ranged.size());
|
|
4208
4208
|
return live.data?.slice(0, live.len ?? live.data.length) ?? new Uint8Array(0);
|
|
4209
4209
|
}
|
|
4210
|
-
function vfsPromoter(Fs, sys,
|
|
4210
|
+
function vfsPromoter(Fs, sys, streams2, livePath) {
|
|
4211
4211
|
const promoted = /* @__PURE__ */ new Map();
|
|
4212
4212
|
return (stream) => {
|
|
4213
4213
|
if (stream.sliccKernelFd !== void 0 || !isVfsFile(Fs, stream)) return;
|
|
@@ -4227,11 +4227,11 @@ function vfsPromoter(Fs, sys, streams, livePath) {
|
|
|
4227
4227
|
);
|
|
4228
4228
|
promoted.set(stream.shared, kfd);
|
|
4229
4229
|
}
|
|
4230
|
-
|
|
4230
|
+
streams2.attachFile(stream, kfd);
|
|
4231
4231
|
};
|
|
4232
4232
|
}
|
|
4233
|
-
function describeForFork(Fs, sys,
|
|
4234
|
-
const promote = vfsPromoter(Fs, sys,
|
|
4233
|
+
function describeForFork(Fs, sys, streams2, livePath) {
|
|
4234
|
+
const promote = vfsPromoter(Fs, sys, streams2, livePath);
|
|
4235
4235
|
const out = [];
|
|
4236
4236
|
for (const stream of Fs.streams) {
|
|
4237
4237
|
if (!stream) continue;
|
|
@@ -4255,7 +4255,7 @@ function kernelEntry(stream, kernel) {
|
|
|
4255
4255
|
const access = kind === "tty" ? O_RDWR : (stream.flags ?? O_RDWR) & O_ACCMODE4;
|
|
4256
4256
|
return { fd: stream.fd, kernel, kind, flags: access, ...cloexec };
|
|
4257
4257
|
}
|
|
4258
|
-
function describeInherited(Fs, sys,
|
|
4258
|
+
function describeInherited(Fs, sys, streams2, livePath, actions = []) {
|
|
4259
4259
|
const table = /* @__PURE__ */ new Map();
|
|
4260
4260
|
for (const stream of Fs.streams) {
|
|
4261
4261
|
if (stream) table.set(stream.fd, { stream, cloexec: closesOnExec(stream) });
|
|
@@ -4270,7 +4270,7 @@ function describeInherited(Fs, sys, streams, livePath, actions = []) {
|
|
|
4270
4270
|
for (const [fd, { stream, cloexec }] of table) {
|
|
4271
4271
|
if (fd > 2 && !cloexec) slots3.set(fd, stream);
|
|
4272
4272
|
}
|
|
4273
|
-
const promote = vfsPromoter(Fs, sys,
|
|
4273
|
+
const promote = vfsPromoter(Fs, sys, streams2, livePath);
|
|
4274
4274
|
const out = [];
|
|
4275
4275
|
for (const [fd, stream] of slots3) {
|
|
4276
4276
|
promote(stream);
|
|
@@ -4299,50 +4299,50 @@ function place(Fs, stream, fd) {
|
|
|
4299
4299
|
Fs.closeStream(stream.fd);
|
|
4300
4300
|
return moved;
|
|
4301
4301
|
}
|
|
4302
|
-
function placeholder(Fs,
|
|
4302
|
+
function placeholder(Fs, streams2, entry) {
|
|
4303
4303
|
const access = entry.flags ?? O_RDWR;
|
|
4304
|
-
if (entry.kind === "socket") return
|
|
4304
|
+
if (entry.kind === "socket") return streams2.socketStream(access);
|
|
4305
4305
|
if (entry.kind === "tty") return Fs.open("/dev/tty", O_RDWR);
|
|
4306
4306
|
if (entry.kind === "stream" || entry.kind === "clipboard" || entry.kind === "sealed")
|
|
4307
4307
|
return Fs.open("/dev/null", access);
|
|
4308
4308
|
Fs.mkdirTree(PLACEHOLDER_DIR);
|
|
4309
4309
|
return Fs.open(`${PLACEHOLDER_DIR}/${entry.fd}`, access | O_CREAT3);
|
|
4310
4310
|
}
|
|
4311
|
-
function asFifo(stream,
|
|
4312
|
-
const inos = streamInos.get(
|
|
4313
|
-
streamInos.set(
|
|
4311
|
+
function asFifo(stream, streams2, identity) {
|
|
4312
|
+
const inos = streamInos.get(streams2) ?? /* @__PURE__ */ new Map();
|
|
4313
|
+
streamInos.set(streams2, inos);
|
|
4314
4314
|
const fixed = inos.get(identity) ?? nextStreamIno++;
|
|
4315
4315
|
inos.set(identity, fixed);
|
|
4316
4316
|
const node = stream.node;
|
|
4317
|
-
|
|
4317
|
+
streams2.describe(stream, `pipe:[${fixed}]`, () => ({
|
|
4318
4318
|
...node.node_ops?.getattr?.(node),
|
|
4319
4319
|
mode: FIFO_MODE,
|
|
4320
4320
|
ino: fixed,
|
|
4321
4321
|
size: 0
|
|
4322
4322
|
}));
|
|
4323
4323
|
}
|
|
4324
|
-
function placeKernelStream(Fs,
|
|
4325
|
-
const stream = place(Fs, placeholder(Fs,
|
|
4324
|
+
function placeKernelStream(Fs, streams2, entry) {
|
|
4325
|
+
const stream = place(Fs, placeholder(Fs, streams2, entry), entry.fd);
|
|
4326
4326
|
if (entry.kind === "file") {
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
} else if (entry.kind === "socket")
|
|
4330
|
-
else
|
|
4331
|
-
if (entry.kind === "clipboard")
|
|
4332
|
-
if (entry.kind === "sealed" || entry.kind === "clipboard")
|
|
4333
|
-
if (entry.kind === "tty")
|
|
4327
|
+
streams2.attachFile(stream, entry.kernel);
|
|
4328
|
+
streams2.sizeFromKernel(stream, entry.kernel);
|
|
4329
|
+
} else if (entry.kind === "socket") streams2.attachSocket(stream, entry.kernel);
|
|
4330
|
+
else streams2.attach(stream, entry.kernel, entry.kind === "tty");
|
|
4331
|
+
if (entry.kind === "clipboard") streams2.reportClose(entry.kernel);
|
|
4332
|
+
if (entry.kind === "sealed" || entry.kind === "clipboard") streams2.nameDevice(stream, entry.kind);
|
|
4333
|
+
if (entry.kind === "tty") streams2.nameTerminal(stream);
|
|
4334
4334
|
if (entry.kind === "stream") {
|
|
4335
|
-
asFifo(stream,
|
|
4335
|
+
asFifo(stream, streams2, entry.desc !== void 0 ? `d${entry.desc}` : `k${entry.kernel}`);
|
|
4336
4336
|
}
|
|
4337
4337
|
setCloseOnExec(stream, entry.cloexec === true);
|
|
4338
4338
|
return stream;
|
|
4339
4339
|
}
|
|
4340
|
-
function restoreForkedStreams(Fs,
|
|
4340
|
+
function restoreForkedStreams(Fs, streams2, table) {
|
|
4341
4341
|
for (const stream of Fs.streams) if (stream) Fs.closeStream(stream.fd);
|
|
4342
4342
|
for (const entry of table) {
|
|
4343
4343
|
try {
|
|
4344
4344
|
if ("kernel" in entry) {
|
|
4345
|
-
placeKernelStream(Fs,
|
|
4345
|
+
placeKernelStream(Fs, streams2, entry);
|
|
4346
4346
|
} else {
|
|
4347
4347
|
const placed = place(
|
|
4348
4348
|
Fs,
|
|
@@ -4410,14 +4410,14 @@ function forkRestarted(deps, state, snapshotAt) {
|
|
|
4410
4410
|
let memory = state.memory;
|
|
4411
4411
|
let seen = snapshotAt;
|
|
4412
4412
|
return restarted(() => {
|
|
4413
|
-
const
|
|
4413
|
+
const streams2 = deps.describeFork();
|
|
4414
4414
|
const now = deps.deliveries?.();
|
|
4415
4415
|
if (now !== seen) {
|
|
4416
4416
|
seen = now;
|
|
4417
4417
|
const live = deps.memory?.();
|
|
4418
4418
|
if (live) memory = new Uint8Array(live.buffer).slice();
|
|
4419
4419
|
}
|
|
4420
|
-
const forked = { ...state, memory, streams, cwd: deps.Fs.cwd() };
|
|
4420
|
+
const forked = { ...state, memory, streams: streams2, cwd: deps.Fs.cwd() };
|
|
4421
4421
|
return deps.transport.call(
|
|
4422
4422
|
{ op: "proc-fork", state: forked, restart: true },
|
|
4423
4423
|
Infinity,
|
|
@@ -4729,6 +4729,8 @@ var init_process_signals = __esm({
|
|
|
4729
4729
|
unwinding = false;
|
|
4730
4730
|
quieted = 0;
|
|
4731
4731
|
delivered = 0;
|
|
4732
|
+
raised = 0;
|
|
4733
|
+
entering = 0;
|
|
4732
4734
|
raw;
|
|
4733
4735
|
header;
|
|
4734
4736
|
hooks;
|
|
@@ -4791,9 +4793,18 @@ var init_process_signals = __esm({
|
|
|
4791
4793
|
const header = this.header;
|
|
4792
4794
|
const pending = Atomics.load(header, SAB_I_SIGNALS) & ~Atomics.load(header, SAB_I_BLOCKED) | Atomics.load(header, SAB_I_TIMERS) | Atomics.load(header, SAB_I_KILLED);
|
|
4793
4795
|
if (pending === 0) return false;
|
|
4794
|
-
this.
|
|
4796
|
+
if (this.entering === 0) this.raised = this.quieted > 0 ? -1 : 0;
|
|
4797
|
+
this.entering++;
|
|
4798
|
+
try {
|
|
4799
|
+
this.deliver();
|
|
4800
|
+
} finally {
|
|
4801
|
+
this.entering--;
|
|
4802
|
+
}
|
|
4795
4803
|
return true;
|
|
4796
4804
|
}
|
|
4805
|
+
raisedOnEntry() {
|
|
4806
|
+
return this.raised;
|
|
4807
|
+
}
|
|
4797
4808
|
deliver() {
|
|
4798
4809
|
if (this.quieted > 0) return;
|
|
4799
4810
|
const killed = Atomics.load(this.header, SAB_I_KILLED);
|
|
@@ -4806,6 +4817,7 @@ var init_process_signals = __esm({
|
|
|
4806
4817
|
const pending = blocked === 0 ? Atomics.exchange(this.header, SAB_I_SIGNALS, 0) : Atomics.and(this.header, SAB_I_SIGNALS, blocked) & ~blocked;
|
|
4807
4818
|
if (this.depth <= 1) this.lastDelivered = pending | (timers & 1 ? sigbit(SIG.ALRM) : 0);
|
|
4808
4819
|
if (pending !== 0 || timers !== 0) this.delivered++;
|
|
4820
|
+
this.raised |= pending | (timers & 1 ? sigbit(SIG.ALRM) : 0) | (timers & ~1 ? -1 : 0);
|
|
4809
4821
|
for (let which = 0; which < 3; which++) {
|
|
4810
4822
|
if (timers & 1 << which) this.hooks.timer?.(which);
|
|
4811
4823
|
}
|
|
@@ -4828,7 +4840,7 @@ function resolved(Fs, addr) {
|
|
|
4828
4840
|
return { family: "unix", path: normalizePath(path) };
|
|
4829
4841
|
}
|
|
4830
4842
|
function createSocketKernel(deps) {
|
|
4831
|
-
const { transport, Fs, sys, streams } = deps;
|
|
4843
|
+
const { transport, Fs, sys, streams: streams2 } = deps;
|
|
4832
4844
|
const call2 = (req) => {
|
|
4833
4845
|
const r = transport.call(req, Number.POSITIVE_INFINITY, req.op);
|
|
4834
4846
|
if (!r.ok) throw new SyscallError(r.errno);
|
|
@@ -4864,12 +4876,12 @@ function createSocketKernel(deps) {
|
|
|
4864
4876
|
const install = (k, nonblock, cloexec = false) => {
|
|
4865
4877
|
let stream;
|
|
4866
4878
|
try {
|
|
4867
|
-
stream =
|
|
4879
|
+
stream = streams2.socketStream(O_RDWR2 | (nonblock ? O_NONBLOCK : 0));
|
|
4868
4880
|
} catch (e) {
|
|
4869
4881
|
sys.close(k);
|
|
4870
4882
|
throw e;
|
|
4871
4883
|
}
|
|
4872
|
-
|
|
4884
|
+
streams2.attachSocket(stream, k);
|
|
4873
4885
|
setCloseOnExec(stream, cloexec);
|
|
4874
4886
|
return stream.fd;
|
|
4875
4887
|
};
|
|
@@ -5562,9 +5574,9 @@ function kernelSys(transport) {
|
|
|
5562
5574
|
}
|
|
5563
5575
|
};
|
|
5564
5576
|
}
|
|
5565
|
-
function wireKernelFd(Fs,
|
|
5577
|
+
function wireKernelFd(Fs, streams2, entry) {
|
|
5566
5578
|
if (entry.device && openDevice(Fs, entry.fd, entry.device)) return;
|
|
5567
|
-
placeKernelStream(Fs,
|
|
5579
|
+
placeKernelStream(Fs, streams2, {
|
|
5568
5580
|
...entry,
|
|
5569
5581
|
kind: entry.device ? "stream" : entry.kind,
|
|
5570
5582
|
kernel: entry.fd
|
|
@@ -5589,7 +5601,7 @@ function openAt(Fs, fd, path, flags) {
|
|
|
5589
5601
|
}
|
|
5590
5602
|
return true;
|
|
5591
5603
|
}
|
|
5592
|
-
function wireKernelStdio(Fs,
|
|
5604
|
+
function wireKernelStdio(Fs, streams2, sys) {
|
|
5593
5605
|
for (const fd of [0, 1, 2]) {
|
|
5594
5606
|
const stream = Fs.getStream(fd);
|
|
5595
5607
|
if (!stream) continue;
|
|
@@ -5600,11 +5612,11 @@ function wireKernelStdio(Fs, streams, sys) {
|
|
|
5600
5612
|
const flags = sys?.access ? stream.flags & ~O_ACCMODE5 | accessMode(sys.access(fd)) : stream.flags;
|
|
5601
5613
|
Fs.closeStream(fd);
|
|
5602
5614
|
const kernel = { fd, kernel: fd, kind, flags };
|
|
5603
|
-
placeKernelStream(Fs,
|
|
5615
|
+
placeKernelStream(Fs, streams2, kernel).flags = flags;
|
|
5604
5616
|
continue;
|
|
5605
5617
|
}
|
|
5606
|
-
|
|
5607
|
-
|
|
5618
|
+
streams2.attach(stream, fd);
|
|
5619
|
+
streams2.nameTerminal(stream);
|
|
5608
5620
|
}
|
|
5609
5621
|
}
|
|
5610
5622
|
function glueBody(glue) {
|
|
@@ -5703,6 +5715,11 @@ function credSyncTransport(gated, early, cred) {
|
|
|
5703
5715
|
}
|
|
5704
5716
|
};
|
|
5705
5717
|
}
|
|
5718
|
+
function sigpipeSpared(transport) {
|
|
5719
|
+
const req = { op: "proc-kill-self", sig: SIG.PIPE, probe: true };
|
|
5720
|
+
const r = transport.call(req, Number.POSITIVE_INFINITY, "proc-kill-self");
|
|
5721
|
+
return r.ok && !(r.kind === "json" && r.json === "terminate");
|
|
5722
|
+
}
|
|
5706
5723
|
async function runWasmProcess(init, port2, deps = {}) {
|
|
5707
5724
|
const signals = new SignalGate(
|
|
5708
5725
|
createSyncSabTransport(init.sab, port2, {
|
|
@@ -5810,10 +5827,10 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5810
5827
|
});
|
|
5811
5828
|
early = () => signals.quiet(() => vfs.flushDirty());
|
|
5812
5829
|
closeDropsLocks(running.FS, sys);
|
|
5813
|
-
const sigpipe = () => running.sliccSigpipe?.() === 1;
|
|
5830
|
+
const sigpipe = () => running.sliccSigpipe?.() === 1 || sigpipeSpared(gated);
|
|
5814
5831
|
const restartable = () => signals.restartable();
|
|
5815
5832
|
const owners = init.owners ? { owners: true } : {};
|
|
5816
|
-
const
|
|
5833
|
+
const streams2 = new KernelStreams(running.FS, sys, {
|
|
5817
5834
|
sigpipe,
|
|
5818
5835
|
restartable,
|
|
5819
5836
|
...owners,
|
|
@@ -5821,21 +5838,21 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5821
5838
|
});
|
|
5822
5839
|
trackCloseOnExec(running.FS);
|
|
5823
5840
|
quietQuit(running.FS, (on) => {
|
|
5824
|
-
|
|
5841
|
+
streams2.quitting = on;
|
|
5825
5842
|
});
|
|
5826
|
-
atExit = () =>
|
|
5843
|
+
atExit = () => streams2.exiting();
|
|
5827
5844
|
useMounts(running.FS, init.env, true);
|
|
5828
5845
|
useZeroDevices(running.FS);
|
|
5829
5846
|
useProcfs(running.FS, sys, init.pid);
|
|
5830
|
-
if (init.fork) restoreForkedStreams(running.FS,
|
|
5847
|
+
if (init.fork) restoreForkedStreams(running.FS, streams2, init.fork.streams ?? []);
|
|
5831
5848
|
else {
|
|
5832
|
-
wireKernelStdio(running.FS,
|
|
5833
|
-
for (const entry of init.fds ?? []) wireKernelFd(running.FS,
|
|
5849
|
+
wireKernelStdio(running.FS, streams2, sys);
|
|
5850
|
+
for (const entry of init.fds ?? []) wireKernelFd(running.FS, streams2, entry);
|
|
5834
5851
|
}
|
|
5835
5852
|
const pipefs = ownValue(running, "PIPEFS");
|
|
5836
|
-
if (pipefs)
|
|
5837
|
-
|
|
5838
|
-
|
|
5853
|
+
if (pipefs) streams2.usePipes(pipefs);
|
|
5854
|
+
streams2.useControllingTerminal();
|
|
5855
|
+
streams2.useKernelFdMetadata();
|
|
5839
5856
|
useDevFd(running.FS);
|
|
5840
5857
|
useDevRemoval(running.FS);
|
|
5841
5858
|
useFileMmap(running.FS, {
|
|
@@ -5855,9 +5872,9 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5855
5872
|
restartable,
|
|
5856
5873
|
memory: () => memory,
|
|
5857
5874
|
deliveries: () => signals.deliveries(),
|
|
5858
|
-
describeFork: () => describeForFork(running.FS, sys,
|
|
5859
|
-
inherit: (actions) => describeInherited(running.FS, sys,
|
|
5860
|
-
stdioPromoter: () => vfsPromoter(running.FS, sys,
|
|
5875
|
+
describeFork: () => describeForFork(running.FS, sys, streams2, livePath),
|
|
5876
|
+
inherit: (actions) => describeInherited(running.FS, sys, streams2, livePath, actions),
|
|
5877
|
+
stdioPromoter: () => vfsPromoter(running.FS, sys, streams2, livePath),
|
|
5861
5878
|
...callerOwner(running.FS, init)
|
|
5862
5879
|
});
|
|
5863
5880
|
running.sliccKernel.http = createHttpKernel(transport);
|
|
@@ -5866,15 +5883,15 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5866
5883
|
transport,
|
|
5867
5884
|
Fs: running.FS,
|
|
5868
5885
|
sys,
|
|
5869
|
-
streams,
|
|
5886
|
+
streams: streams2,
|
|
5870
5887
|
sigpipe,
|
|
5871
5888
|
restartable
|
|
5872
5889
|
});
|
|
5873
|
-
return runWithFlush(running, init,
|
|
5890
|
+
return runWithFlush(running, init, streams2, vfs);
|
|
5874
5891
|
}
|
|
5875
|
-
function runWithFlush(running, init,
|
|
5892
|
+
function runWithFlush(running, init, streams2, vfs) {
|
|
5876
5893
|
try {
|
|
5877
|
-
return
|
|
5894
|
+
return streams2.exitStatus(runMain(running, init));
|
|
5878
5895
|
} finally {
|
|
5879
5896
|
try {
|
|
5880
5897
|
vfs.flush();
|
|
@@ -6419,7 +6436,7 @@ function pinnedIo2(bridge, handle, rewriting) {
|
|
|
6419
6436
|
} : {}
|
|
6420
6437
|
};
|
|
6421
6438
|
}
|
|
6422
|
-
var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, FS_GEN, RING2, RING_SIZE2, SLOT2, SHARED_IDS_BYTES, StatCache;
|
|
6439
|
+
var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, FS_GEN, CRED_GEN, RING2, RING_SIZE2, SLOT2, SHARED_IDS_BYTES, StatCache;
|
|
6423
6440
|
var init_wasi_files = __esm({
|
|
6424
6441
|
"src/process/wasi/wasi-files.ts"() {
|
|
6425
6442
|
"use strict";
|
|
@@ -6641,6 +6658,7 @@ var init_wasi_files = __esm({
|
|
|
6641
6658
|
MAX_LINKS = 40;
|
|
6642
6659
|
MISS_TTL_MS = 20;
|
|
6643
6660
|
FS_GEN = 4;
|
|
6661
|
+
CRED_GEN = 5;
|
|
6644
6662
|
RING2 = 8;
|
|
6645
6663
|
RING_SIZE2 = 64;
|
|
6646
6664
|
SLOT2 = 3;
|
|
@@ -6861,6 +6879,48 @@ var init_slicc_sem = __esm({
|
|
|
6861
6879
|
}
|
|
6862
6880
|
});
|
|
6863
6881
|
|
|
6882
|
+
// src/process/wasi/wasi-cred.ts
|
|
6883
|
+
var CredCache;
|
|
6884
|
+
var init_wasi_cred = __esm({
|
|
6885
|
+
"src/process/wasi/wasi-cred.ts"() {
|
|
6886
|
+
"use strict";
|
|
6887
|
+
init_wasi_files();
|
|
6888
|
+
CredCache = class {
|
|
6889
|
+
cred;
|
|
6890
|
+
stamp = 0;
|
|
6891
|
+
fetch;
|
|
6892
|
+
shared;
|
|
6893
|
+
constructor(fetch, shared) {
|
|
6894
|
+
this.fetch = fetch;
|
|
6895
|
+
this.shared = shared;
|
|
6896
|
+
}
|
|
6897
|
+
gen() {
|
|
6898
|
+
return this.shared ? Atomics.load(this.shared, CRED_GEN) : 0;
|
|
6899
|
+
}
|
|
6900
|
+
get() {
|
|
6901
|
+
const gen = this.gen();
|
|
6902
|
+
if (this.cred === void 0 || this.stamp !== gen) {
|
|
6903
|
+
this.cred = this.fetch();
|
|
6904
|
+
this.stamp = gen;
|
|
6905
|
+
}
|
|
6906
|
+
return this.cred;
|
|
6907
|
+
}
|
|
6908
|
+
change(apply2) {
|
|
6909
|
+
const seen = this.gen();
|
|
6910
|
+
const cred = apply2();
|
|
6911
|
+
if (!this.shared) {
|
|
6912
|
+
this.cred = cred;
|
|
6913
|
+
return cred;
|
|
6914
|
+
}
|
|
6915
|
+
const was = Atomics.add(this.shared, CRED_GEN, 1);
|
|
6916
|
+
this.cred = was === seen ? cred : void 0;
|
|
6917
|
+
this.stamp = was + 1;
|
|
6918
|
+
return cred;
|
|
6919
|
+
}
|
|
6920
|
+
};
|
|
6921
|
+
}
|
|
6922
|
+
});
|
|
6923
|
+
|
|
6864
6924
|
// src/kernel/pipe.ts
|
|
6865
6925
|
var PIPE_CAPACITY;
|
|
6866
6926
|
var init_pipe = __esm({
|
|
@@ -7949,6 +8009,92 @@ var init_wasi_termios = __esm({
|
|
|
7949
8009
|
}
|
|
7950
8010
|
});
|
|
7951
8011
|
|
|
8012
|
+
// src/process/wasi/wasix-epoll.ts
|
|
8013
|
+
function timeoutMs(ns) {
|
|
8014
|
+
const value2 = BigInt.asUintN(64, ns);
|
|
8015
|
+
if (value2 === FOREVER) return -1;
|
|
8016
|
+
const ms = (value2 + NS_PER_MS2 - 1n) / NS_PER_MS2;
|
|
8017
|
+
return ms > BigInt(MAX_TIMEOUT_MS) ? -1 : Number(ms);
|
|
8018
|
+
}
|
|
8019
|
+
function wasixEpollImports(host) {
|
|
8020
|
+
const { mem, fds, o } = host;
|
|
8021
|
+
const call2 = (req) => o.kernel.call(req);
|
|
8022
|
+
const kernelFd = (fd, refusal2) => {
|
|
8023
|
+
const e = fds.find(fd);
|
|
8024
|
+
if (!e) throw new WasiError("EBADF");
|
|
8025
|
+
if (e.type !== "kernel") throw new WasiError(refusal2);
|
|
8026
|
+
};
|
|
8027
|
+
const writeEvents2 = (ptr, events) => {
|
|
8028
|
+
const view = mem.view();
|
|
8029
|
+
events.forEach((ev, i) => {
|
|
8030
|
+
const at = ptr + i * EVENT_SIZE;
|
|
8031
|
+
mem.bytes(at, EVENT_SIZE).fill(0);
|
|
8032
|
+
view.setUint32(at, ev.events, true);
|
|
8033
|
+
mem.bytes(at + DATA_OFFSET, DATA_SIZE).set(ev.data);
|
|
8034
|
+
});
|
|
8035
|
+
};
|
|
8036
|
+
return {
|
|
8037
|
+
epoll_create: (out) => {
|
|
8038
|
+
const fd = call2({ op: "epoll-create" });
|
|
8039
|
+
fds.adopt(fd, "stream", false);
|
|
8040
|
+
mem.view().setUint32(out, fd, true);
|
|
8041
|
+
},
|
|
8042
|
+
epoll_ctl: (epfd, op, fd, event) => {
|
|
8043
|
+
const how = (host.strictEpoll ? WASIX_OPS : DUAL_OPS)[op];
|
|
8044
|
+
if (!how) throw new WasiError("EINVAL");
|
|
8045
|
+
kernelFd(epfd, "EINVAL");
|
|
8046
|
+
kernelFd(fd, "EPERM");
|
|
8047
|
+
if (how !== "del" && event === 0) throw new WasiError("EINVAL");
|
|
8048
|
+
const events = event === 0 ? 0 : mem.view().getUint32(event, true);
|
|
8049
|
+
const data = event === 0 ? [] : [...mem.bytes(event + DATA_OFFSET, DATA_SIZE)];
|
|
8050
|
+
call2({ op: "epoll-ctl", epfd, how, fd, events, data });
|
|
8051
|
+
},
|
|
8052
|
+
epoll_wait: (epfd, ptr, maxevents, timeout, out) => {
|
|
8053
|
+
mem.view().setUint32(out, 0, true);
|
|
8054
|
+
if ((maxevents | 0) <= 0) throw new WasiError("EINVAL");
|
|
8055
|
+
kernelFd(epfd, "EINVAL");
|
|
8056
|
+
const max = Math.min(maxevents | 0, MAX_EVENTS);
|
|
8057
|
+
const ms = host.entered ? 0 : timeoutMs(timeout);
|
|
8058
|
+
const events = call2({ op: "epoll-wait", epfd, max, timeoutMs: ms });
|
|
8059
|
+
if (host.entered && events.length === 0 && timeoutMs(timeout) !== 0) return E.INTR;
|
|
8060
|
+
writeEvents2(ptr, events);
|
|
8061
|
+
mem.view().setUint32(out, events.length, true);
|
|
8062
|
+
return E.SUCCESS;
|
|
8063
|
+
},
|
|
8064
|
+
fd_event: (initial, flags, out) => {
|
|
8065
|
+
const value2 = BigInt.asUintN(64, initial);
|
|
8066
|
+
if (value2 > EVENTFD_MAX) throw new WasiError("EINVAL");
|
|
8067
|
+
const fd = call2({
|
|
8068
|
+
op: "eventfd-open",
|
|
8069
|
+
initial: value2.toString(),
|
|
8070
|
+
semaphore: (flags & EVENTFD_SEMAPHORE) !== 0
|
|
8071
|
+
});
|
|
8072
|
+
fds.adopt(fd, "stream", (flags & EVENTFD_NONBLOCK) !== 0);
|
|
8073
|
+
mem.view().setUint32(out, fd, true);
|
|
8074
|
+
}
|
|
8075
|
+
};
|
|
8076
|
+
}
|
|
8077
|
+
var EVENT_SIZE, DATA_OFFSET, DATA_SIZE, MAX_EVENTS, FOREVER, MAX_TIMEOUT_MS, NS_PER_MS2, EVENTFD_SEMAPHORE, EVENTFD_NONBLOCK, EVENTFD_MAX, WASIX_OPS, DUAL_OPS;
|
|
8078
|
+
var init_wasix_epoll = __esm({
|
|
8079
|
+
"src/process/wasi/wasix-epoll.ts"() {
|
|
8080
|
+
"use strict";
|
|
8081
|
+
init_wasi_abi();
|
|
8082
|
+
init_wasi_files();
|
|
8083
|
+
EVENT_SIZE = 32;
|
|
8084
|
+
DATA_OFFSET = 8;
|
|
8085
|
+
DATA_SIZE = 24;
|
|
8086
|
+
MAX_EVENTS = 4096;
|
|
8087
|
+
FOREVER = 0xffffffffffffffffn;
|
|
8088
|
+
MAX_TIMEOUT_MS = 2147483647;
|
|
8089
|
+
NS_PER_MS2 = 1000000n;
|
|
8090
|
+
EVENTFD_SEMAPHORE = 1;
|
|
8091
|
+
EVENTFD_NONBLOCK = 4;
|
|
8092
|
+
EVENTFD_MAX = 0xfffffffffffffffen;
|
|
8093
|
+
WASIX_OPS = ["add", "mod", "del"];
|
|
8094
|
+
DUAL_OPS = ["add", "set", "del", "mod"];
|
|
8095
|
+
}
|
|
8096
|
+
});
|
|
8097
|
+
|
|
7952
8098
|
// src/kernel/net/datagram-wire.ts
|
|
7953
8099
|
function decodeReceived(raw) {
|
|
7954
8100
|
const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
@@ -8335,7 +8481,7 @@ function filestatOf(path, s) {
|
|
|
8335
8481
|
size: BigInt(s.size),
|
|
8336
8482
|
ino: s.ino !== void 0 ? BigInt(s.ino) : pathInode(path),
|
|
8337
8483
|
...s.nlink !== void 0 ? { nlink: BigInt(s.nlink) } : {},
|
|
8338
|
-
mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) *
|
|
8484
|
+
mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) * NS_PER_MS3
|
|
8339
8485
|
};
|
|
8340
8486
|
}
|
|
8341
8487
|
function kernelFiletype(kind) {
|
|
@@ -8385,7 +8531,7 @@ function wrap(table) {
|
|
|
8385
8531
|
}
|
|
8386
8532
|
return out;
|
|
8387
8533
|
}
|
|
8388
|
-
var WasiExit, IDS,
|
|
8534
|
+
var WasiExit, IDS, NS_PER_MS3, AT_SYMLINK_NOFOLLOW2, AT_EACCESS2, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, SIG_IGN, SEALED_MODE, WasiHost;
|
|
8389
8535
|
var init_wasi_host = __esm({
|
|
8390
8536
|
"src/process/wasi/wasi-host.ts"() {
|
|
8391
8537
|
"use strict";
|
|
@@ -8393,14 +8539,17 @@ var init_wasi_host = __esm({
|
|
|
8393
8539
|
init_physical_path();
|
|
8394
8540
|
init_cpu_clock();
|
|
8395
8541
|
init_cred();
|
|
8542
|
+
init_signals();
|
|
8396
8543
|
init_slicc_lock();
|
|
8397
8544
|
init_slicc_sem();
|
|
8398
8545
|
init_wasi_abi();
|
|
8546
|
+
init_wasi_cred();
|
|
8399
8547
|
init_wasi_fds();
|
|
8400
8548
|
init_wasi_files();
|
|
8401
8549
|
init_wasi_memory();
|
|
8402
8550
|
init_wasi_poll();
|
|
8403
8551
|
init_wasi_termios();
|
|
8552
|
+
init_wasix_epoll();
|
|
8404
8553
|
init_wasix_sockets();
|
|
8405
8554
|
WasiExit = class extends Error {
|
|
8406
8555
|
code;
|
|
@@ -8410,26 +8559,30 @@ var init_wasi_host = __esm({
|
|
|
8410
8559
|
}
|
|
8411
8560
|
};
|
|
8412
8561
|
IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
|
|
8413
|
-
|
|
8562
|
+
NS_PER_MS3 = 1000000n;
|
|
8414
8563
|
AT_SYMLINK_NOFOLLOW2 = 1;
|
|
8415
8564
|
AT_EACCESS2 = 2;
|
|
8416
8565
|
ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
|
|
8417
8566
|
GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
|
|
8418
8567
|
S_IFIFO = 4096;
|
|
8419
8568
|
DEFAULT_UMASK = 18;
|
|
8420
|
-
MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) *
|
|
8569
|
+
MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS3;
|
|
8421
8570
|
MAX_READ = 1024 * 1024;
|
|
8422
|
-
SIGPIPE_EXIT =
|
|
8571
|
+
SIGPIPE_EXIT = 128 + SIG.PIPE;
|
|
8423
8572
|
SIG_IGN = 1;
|
|
8424
8573
|
SEALED_MODE = 8630;
|
|
8425
8574
|
WasiHost = class {
|
|
8426
8575
|
mem = new WasiMemory();
|
|
8427
8576
|
fds;
|
|
8577
|
+
creds;
|
|
8428
8578
|
started = performance.now();
|
|
8429
8579
|
cache;
|
|
8430
8580
|
startCwd;
|
|
8431
8581
|
interruptWakes = false;
|
|
8582
|
+
strictEpoll = false;
|
|
8432
8583
|
entered = false;
|
|
8584
|
+
enteredSignals = 0;
|
|
8585
|
+
raisedOnEntry;
|
|
8433
8586
|
onRaise;
|
|
8434
8587
|
muted;
|
|
8435
8588
|
signals;
|
|
@@ -8460,6 +8613,10 @@ var init_wasi_host = __esm({
|
|
|
8460
8613
|
this.o = { ...o, kernel: { sys, call: call2 } };
|
|
8461
8614
|
this.startCwd = o.cwd;
|
|
8462
8615
|
this.fds = new WasiFds(this.o.kernel, o.fs);
|
|
8616
|
+
this.creds = new CredCache(
|
|
8617
|
+
() => this.o.kernel.call({ op: "proc-cred" }),
|
|
8618
|
+
o.credGen ?? o.shared
|
|
8619
|
+
);
|
|
8463
8620
|
if (o.shared) this.fds.share(o.shared, true);
|
|
8464
8621
|
else if (o.forked) this.fds.restore(o.forked.fds, o.forked.cloexec);
|
|
8465
8622
|
else this.fds.setup(o.cwd, o.inherited ?? [], o.preopenRoot === true);
|
|
@@ -8499,7 +8656,7 @@ var init_wasi_host = __esm({
|
|
|
8499
8656
|
own.call(this.o.fs, path, idOf3(uid), idOf3(gid), follow2, handle);
|
|
8500
8657
|
};
|
|
8501
8658
|
const caller = () => {
|
|
8502
|
-
const cred = this.
|
|
8659
|
+
const cred = this.creds.get();
|
|
8503
8660
|
return [cred.euid, cred.egid];
|
|
8504
8661
|
};
|
|
8505
8662
|
const owner = (st, out) => {
|
|
@@ -8604,7 +8761,7 @@ var init_wasi_host = __esm({
|
|
|
8604
8761
|
}),
|
|
8605
8762
|
umount2: (tp, tl, flags) => void this.o.kernel.call({ op: "umount", target: path(tp, tl), flags }),
|
|
8606
8763
|
cred_get: (out) => {
|
|
8607
|
-
const cred = this.
|
|
8764
|
+
const cred = this.creds.get();
|
|
8608
8765
|
const view = mem.view();
|
|
8609
8766
|
view.getUint32(out + 20, true);
|
|
8610
8767
|
IDS.forEach((key, i) => void view.setUint32(out + i * 4, cred[key], true));
|
|
@@ -8614,7 +8771,7 @@ var init_wasi_host = __esm({
|
|
|
8614
8771
|
IDS.forEach((key, i) => {
|
|
8615
8772
|
if (ids[i] !== -1) change[key] = ids[i] >>> 0;
|
|
8616
8773
|
});
|
|
8617
|
-
void this.o.kernel.call({ op: "proc-setcred", change });
|
|
8774
|
+
void this.creds.change(() => this.o.kernel.call({ op: "proc-setcred", change }));
|
|
8618
8775
|
},
|
|
8619
8776
|
...semImports(this),
|
|
8620
8777
|
...lockImports({
|
|
@@ -8638,7 +8795,7 @@ var init_wasi_host = __esm({
|
|
|
8638
8795
|
}
|
|
8639
8796
|
}),
|
|
8640
8797
|
groups_get: (buf, cap, count) => {
|
|
8641
|
-
const { groups } = this.
|
|
8798
|
+
const { groups } = this.creds.get();
|
|
8642
8799
|
if (cap !== 0 && cap < groups.length) throw new WasiError("EINVAL");
|
|
8643
8800
|
const shown = cap === 0 ? [] : groups;
|
|
8644
8801
|
const view = mem.view();
|
|
@@ -8651,7 +8808,9 @@ var init_wasi_host = __esm({
|
|
|
8651
8808
|
if (n < 0 || n > MAX_GROUPS) throw new WasiError("EINVAL");
|
|
8652
8809
|
const view = mem.view();
|
|
8653
8810
|
const groups = Array.from({ length: n }, (_, i) => view.getUint32(buf + i * 4, true));
|
|
8654
|
-
void this.
|
|
8811
|
+
void this.creds.change(
|
|
8812
|
+
() => this.o.kernel.call({ op: "proc-setcred", change: { groups } })
|
|
8813
|
+
);
|
|
8655
8814
|
},
|
|
8656
8815
|
sigaction_set: (sig, disposition, flags) => {
|
|
8657
8816
|
if (!this.signals) return E.NOSYS;
|
|
@@ -8666,6 +8825,24 @@ var init_wasi_host = __esm({
|
|
|
8666
8825
|
view.setUint32(old + 4, oldHi, true);
|
|
8667
8826
|
}) : E.NOSYS,
|
|
8668
8827
|
sigmask_poll: (lo, hi, inPtr, outPtr, n, nevents) => this.sigmask ? this.maskedPoll(this.sigmask, [lo, hi], [inPtr, outPtr, n, nevents]) : E.NOSYS,
|
|
8828
|
+
sigmask_epoll_wait: (lo, hi, epfd, events, max, timeout, nevents) => this.sigmask ? this.maskedEpoll(
|
|
8829
|
+
this.sigmask,
|
|
8830
|
+
[lo, hi],
|
|
8831
|
+
nevents,
|
|
8832
|
+
(epoll) => epoll(epfd, events, max, timeout, nevents)
|
|
8833
|
+
) : E.NOSYS,
|
|
8834
|
+
sigwait: (lo, _hi, timeout, out) => {
|
|
8835
|
+
const mask = this.sigmask;
|
|
8836
|
+
if (!mask) return E.NOSYS;
|
|
8837
|
+
mem.view().setUint32(out, 0, true);
|
|
8838
|
+
return mask.sigwait(
|
|
8839
|
+
lo,
|
|
8840
|
+
timeout,
|
|
8841
|
+
(set) => void this.o.kernel.call({ op: "sig-waiting", tid: mask.tid, set }),
|
|
8842
|
+
(sig) => void mem.view().setUint32(out, sig, true),
|
|
8843
|
+
this.entered
|
|
8844
|
+
);
|
|
8845
|
+
},
|
|
8669
8846
|
sigpending_get: (out) => {
|
|
8670
8847
|
if (!this.sigmask) return E.NOSYS;
|
|
8671
8848
|
mem.view().setBigUint64(out, BigInt(this.sigmask.pending()), true);
|
|
@@ -8698,6 +8875,7 @@ var init_wasi_host = __esm({
|
|
|
8698
8875
|
try {
|
|
8699
8876
|
this.mem.view().setUint32(nevents, 0, true);
|
|
8700
8877
|
if (mask.deliverUnblocked()) return E.INTR;
|
|
8878
|
+
this.settleEntry(mask);
|
|
8701
8879
|
if (n > 0) return this.poll(inPtr, outPtr, n, nevents);
|
|
8702
8880
|
return this.entered ? E.INTR : this.suspend();
|
|
8703
8881
|
} finally {
|
|
@@ -8705,6 +8883,23 @@ var init_wasi_host = __esm({
|
|
|
8705
8883
|
mask.restore(old);
|
|
8706
8884
|
}
|
|
8707
8885
|
}
|
|
8886
|
+
epollWait;
|
|
8887
|
+
settleEntry(mask) {
|
|
8888
|
+
if (this.entered && (this.enteredSignals & ~mask.blockedBits()) === 0) this.entered = false;
|
|
8889
|
+
}
|
|
8890
|
+
maskedEpoll(mask, set, nevents, wait2) {
|
|
8891
|
+
const old = mask.swap(set[0], set[1]);
|
|
8892
|
+
try {
|
|
8893
|
+
this.mem.view().setUint32(nevents, 0, true);
|
|
8894
|
+
if (mask.deliverUnblocked()) return E.INTR;
|
|
8895
|
+
this.settleEntry(mask);
|
|
8896
|
+
this.epollWait ??= wasixEpollImports(this).epoll_wait;
|
|
8897
|
+
return wait2(this.epollWait) ?? E.SUCCESS;
|
|
8898
|
+
} finally {
|
|
8899
|
+
mask.deliverUnblocked();
|
|
8900
|
+
mask.restore(old);
|
|
8901
|
+
}
|
|
8902
|
+
}
|
|
8708
8903
|
suspend() {
|
|
8709
8904
|
for (; ; ) {
|
|
8710
8905
|
try {
|
|
@@ -8727,7 +8922,7 @@ var init_wasi_host = __esm({
|
|
|
8727
8922
|
return this.cache;
|
|
8728
8923
|
}
|
|
8729
8924
|
now(id) {
|
|
8730
|
-
if (id === CLOCK.REALTIME) return BigInt(Date.now()) *
|
|
8925
|
+
if (id === CLOCK.REALTIME) return BigInt(Date.now()) * NS_PER_MS3;
|
|
8731
8926
|
if (id === CLOCK.MONOTONIC) {
|
|
8732
8927
|
return MONOTONIC_BASE + BigInt(Math.round(performance.now() * 1e6));
|
|
8733
8928
|
}
|
|
@@ -9061,7 +9256,7 @@ var init_wasi_host = __esm({
|
|
|
9061
9256
|
return this.fds.kind(fd, e) === "file" ? this.changed(fd, e, n) : n;
|
|
9062
9257
|
} catch (err) {
|
|
9063
9258
|
const broken = err.code === "EPIPE";
|
|
9064
|
-
if (broken && this.fds.kind(fd, e) !== "socket")
|
|
9259
|
+
if (broken && this.fds.kind(fd, e) !== "socket") this.brokenPipe();
|
|
9065
9260
|
throw err;
|
|
9066
9261
|
}
|
|
9067
9262
|
}
|
|
@@ -9073,6 +9268,18 @@ var init_wasi_host = __esm({
|
|
|
9073
9268
|
}
|
|
9074
9269
|
return this.file(fd, "write").write(data);
|
|
9075
9270
|
}
|
|
9271
|
+
brokenPipe() {
|
|
9272
|
+
let action;
|
|
9273
|
+
try {
|
|
9274
|
+
action = this.o.kernel.call({ op: "proc-kill-self", sig: SIG.PIPE, probe: true });
|
|
9275
|
+
} catch {
|
|
9276
|
+
action = "terminate";
|
|
9277
|
+
}
|
|
9278
|
+
if (action !== "terminate") return;
|
|
9279
|
+
const mask = this.sigmask;
|
|
9280
|
+
if (!mask?.blocks(SIG.PIPE)) throw new WasiExit(SIGPIPE_EXIT);
|
|
9281
|
+
this.o.kernel.call({ op: "thread-kill", tid: mask.tid, sig: SIG.PIPE });
|
|
9282
|
+
}
|
|
9076
9283
|
read(fd, max) {
|
|
9077
9284
|
const e = this.fds.get(fd);
|
|
9078
9285
|
if (e.type === "kernel") {
|
|
@@ -9256,7 +9463,7 @@ var init_wasi_host = __esm({
|
|
|
9256
9463
|
current ??= statOf(path);
|
|
9257
9464
|
return current[field2] ?? current.mtimeMs ?? now;
|
|
9258
9465
|
};
|
|
9259
|
-
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 /
|
|
9466
|
+
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS3) : kept(field2);
|
|
9260
9467
|
(follow2 ? this.o.fs.utimes : this.o.fs.lutimes).call(
|
|
9261
9468
|
this.o.fs,
|
|
9262
9469
|
path,
|
|
@@ -10257,7 +10464,7 @@ var init_wasi_procfs = __esm({
|
|
|
10257
10464
|
});
|
|
10258
10465
|
|
|
10259
10466
|
// src/process/wasi/wasi-sigmask.ts
|
|
10260
|
-
var UNBLOCKABLE, LIBC_UNBLOCKABLE, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK, kernelBits, libcBits, apply, WasiSigmask;
|
|
10467
|
+
var UNBLOCKABLE, LIBC_UNBLOCKABLE, FOREVER2, NS_PER_MS4, POLL_MS, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK, kernelBits, libcBits, apply, WasiSigmask;
|
|
10261
10468
|
var init_wasi_sigmask = __esm({
|
|
10262
10469
|
"src/process/wasi/wasi-sigmask.ts"() {
|
|
10263
10470
|
"use strict";
|
|
@@ -10266,6 +10473,9 @@ var init_wasi_sigmask = __esm({
|
|
|
10266
10473
|
init_wasi_abi();
|
|
10267
10474
|
UNBLOCKABLE = sigbit(SIG.KILL) | sigbit(SIG.STOP);
|
|
10268
10475
|
LIBC_UNBLOCKABLE = 1 << SIG.KILL - 1 | 1 << SIG.STOP - 1;
|
|
10476
|
+
FOREVER2 = 0xffffffffffffffffn;
|
|
10477
|
+
NS_PER_MS4 = 1000000n;
|
|
10478
|
+
POLL_MS = 50;
|
|
10269
10479
|
SIG_BLOCK = 0;
|
|
10270
10480
|
SIG_UNBLOCK = 1;
|
|
10271
10481
|
SIG_SETMASK = 2;
|
|
@@ -10282,10 +10492,12 @@ var init_wasi_sigmask = __esm({
|
|
|
10282
10492
|
header;
|
|
10283
10493
|
deliver;
|
|
10284
10494
|
process;
|
|
10285
|
-
|
|
10495
|
+
tid;
|
|
10496
|
+
constructor(header, deliver, process, tid = 1) {
|
|
10286
10497
|
this.header = header;
|
|
10287
10498
|
this.deliver = deliver;
|
|
10288
10499
|
this.process = process;
|
|
10500
|
+
this.tid = tid;
|
|
10289
10501
|
this.lo = libcBits(Atomics.load(header, SAB_I_BLOCKED));
|
|
10290
10502
|
this.hi = Atomics.load(header, SAB_I_BLOCKED_HI);
|
|
10291
10503
|
}
|
|
@@ -10319,6 +10531,12 @@ var init_wasi_sigmask = __esm({
|
|
|
10319
10531
|
this.set(SIG_SETMASK, lo, hi, () => {
|
|
10320
10532
|
});
|
|
10321
10533
|
}
|
|
10534
|
+
blockedBits() {
|
|
10535
|
+
return Atomics.load(this.header, SAB_I_BLOCKED);
|
|
10536
|
+
}
|
|
10537
|
+
blocks(sig) {
|
|
10538
|
+
return (Atomics.load(this.header, SAB_I_BLOCKED) & sigbit(sig)) !== 0;
|
|
10539
|
+
}
|
|
10322
10540
|
inherited() {
|
|
10323
10541
|
return [kernelBits(this.lo), this.hi];
|
|
10324
10542
|
}
|
|
@@ -10326,6 +10544,47 @@ var init_wasi_sigmask = __esm({
|
|
|
10326
10544
|
Atomics.and(this.header, SAB_I_SIGNALS, ~sigbit(sig));
|
|
10327
10545
|
if (this.process) Atomics.and(this.process, SAB_I_SIGNALS, ~sigbit(sig));
|
|
10328
10546
|
}
|
|
10547
|
+
sigwait(setLo, timeoutNs, publish, took, entered = false) {
|
|
10548
|
+
const set = kernelBits(setLo | 0);
|
|
10549
|
+
const value2 = BigInt.asUintN(64, timeoutNs);
|
|
10550
|
+
const deadline = value2 === FOREVER2 ? Number.POSITIVE_INFINITY : performance.now() + Number((value2 + NS_PER_MS4 - 1n) / NS_PER_MS4);
|
|
10551
|
+
publish(set);
|
|
10552
|
+
try {
|
|
10553
|
+
for (; ; ) {
|
|
10554
|
+
const seen = Atomics.load(this.header, SAB_I_SIGNALS);
|
|
10555
|
+
const sig = this.take(set);
|
|
10556
|
+
if (sig !== 0) {
|
|
10557
|
+
took(sig);
|
|
10558
|
+
return E.SUCCESS;
|
|
10559
|
+
}
|
|
10560
|
+
if (entered || this.deliverUnblocked() || this.interrupted()) return E.INTR;
|
|
10561
|
+
const left = deadline - performance.now();
|
|
10562
|
+
if (left <= 0) return E.AGAIN;
|
|
10563
|
+
Atomics.wait(this.header, SAB_I_SIGNALS, seen, Math.min(left, POLL_MS));
|
|
10564
|
+
}
|
|
10565
|
+
} finally {
|
|
10566
|
+
publish(0);
|
|
10567
|
+
}
|
|
10568
|
+
}
|
|
10569
|
+
take(set) {
|
|
10570
|
+
for (const header of this.process ? [this.header, this.process] : [this.header]) {
|
|
10571
|
+
const ready = Atomics.load(header, SAB_I_SIGNALS) & set;
|
|
10572
|
+
if (ready === 0) continue;
|
|
10573
|
+
const bit = ready & -ready;
|
|
10574
|
+
if ((Atomics.and(header, SAB_I_SIGNALS, ~bit) & bit) !== 0) return 31 - Math.clz32(bit);
|
|
10575
|
+
}
|
|
10576
|
+
return 0;
|
|
10577
|
+
}
|
|
10578
|
+
interrupted() {
|
|
10579
|
+
const killed = this.process ?? this.header;
|
|
10580
|
+
if (Atomics.load(killed, SAB_I_KILLED) !== 0) {
|
|
10581
|
+
this.deliver();
|
|
10582
|
+
return true;
|
|
10583
|
+
}
|
|
10584
|
+
if (Atomics.load(killed, SAB_I_STOP) !== 1) return false;
|
|
10585
|
+
while (Atomics.load(killed, SAB_I_STOP) === 1) Atomics.wait(killed, SAB_I_STOP, 1);
|
|
10586
|
+
return true;
|
|
10587
|
+
}
|
|
10329
10588
|
pending() {
|
|
10330
10589
|
const own = Atomics.load(this.header, SAB_I_SIGNALS);
|
|
10331
10590
|
return libcBits(own | (this.process ? Atomics.load(this.process, SAB_I_SIGNALS) : 0));
|
|
@@ -10684,91 +10943,6 @@ var init_wasix_fork = __esm({
|
|
|
10684
10943
|
}
|
|
10685
10944
|
});
|
|
10686
10945
|
|
|
10687
|
-
// src/process/wasi/wasix-epoll.ts
|
|
10688
|
-
function timeoutMs(ns) {
|
|
10689
|
-
const value2 = BigInt.asUintN(64, ns);
|
|
10690
|
-
if (value2 === FOREVER) return -1;
|
|
10691
|
-
const ms = (value2 + NS_PER_MS3 - 1n) / NS_PER_MS3;
|
|
10692
|
-
return ms > BigInt(MAX_TIMEOUT_MS) ? -1 : Number(ms);
|
|
10693
|
-
}
|
|
10694
|
-
function wasixEpollImports(host) {
|
|
10695
|
-
const { mem, fds, o } = host;
|
|
10696
|
-
const call2 = (req) => o.kernel.call(req);
|
|
10697
|
-
const kernelFd = (fd, refusal2) => {
|
|
10698
|
-
const e = fds.find(fd);
|
|
10699
|
-
if (!e) throw new WasiError("EBADF");
|
|
10700
|
-
if (e.type !== "kernel") throw new WasiError(refusal2);
|
|
10701
|
-
};
|
|
10702
|
-
const writeEvents2 = (ptr, events) => {
|
|
10703
|
-
const view = mem.view();
|
|
10704
|
-
events.forEach((ev, i) => {
|
|
10705
|
-
const at = ptr + i * EVENT_SIZE;
|
|
10706
|
-
mem.bytes(at, EVENT_SIZE).fill(0);
|
|
10707
|
-
view.setUint32(at, ev.events, true);
|
|
10708
|
-
mem.bytes(at + DATA_OFFSET, DATA_SIZE).set(ev.data);
|
|
10709
|
-
});
|
|
10710
|
-
};
|
|
10711
|
-
return {
|
|
10712
|
-
epoll_create: (out) => {
|
|
10713
|
-
const fd = call2({ op: "epoll-create" });
|
|
10714
|
-
fds.adopt(fd, "stream", false);
|
|
10715
|
-
mem.view().setUint32(out, fd, true);
|
|
10716
|
-
},
|
|
10717
|
-
epoll_ctl: (epfd, op, fd, event) => {
|
|
10718
|
-
const how = OPS[op];
|
|
10719
|
-
if (!how) throw new WasiError("EINVAL");
|
|
10720
|
-
kernelFd(epfd, "EINVAL");
|
|
10721
|
-
kernelFd(fd, "EPERM");
|
|
10722
|
-
if (how !== "del" && event === 0) throw new WasiError("EINVAL");
|
|
10723
|
-
const events = event === 0 ? 0 : mem.view().getUint32(event, true);
|
|
10724
|
-
const data = event === 0 ? [] : [...mem.bytes(event + DATA_OFFSET, DATA_SIZE)];
|
|
10725
|
-
call2({ op: "epoll-ctl", epfd, how, fd, events, data });
|
|
10726
|
-
},
|
|
10727
|
-
epoll_wait: (epfd, ptr, maxevents, timeout, out) => {
|
|
10728
|
-
mem.view().setUint32(out, 0, true);
|
|
10729
|
-
if ((maxevents | 0) <= 0) throw new WasiError("EINVAL");
|
|
10730
|
-
kernelFd(epfd, "EINVAL");
|
|
10731
|
-
const max = Math.min(maxevents | 0, MAX_EVENTS);
|
|
10732
|
-
const ms = host.entered ? 0 : timeoutMs(timeout);
|
|
10733
|
-
const events = call2({ op: "epoll-wait", epfd, max, timeoutMs: ms });
|
|
10734
|
-
if (host.entered && events.length === 0 && timeoutMs(timeout) !== 0) return E.INTR;
|
|
10735
|
-
writeEvents2(ptr, events);
|
|
10736
|
-
mem.view().setUint32(out, events.length, true);
|
|
10737
|
-
return E.SUCCESS;
|
|
10738
|
-
},
|
|
10739
|
-
fd_event: (initial, flags, out) => {
|
|
10740
|
-
const value2 = BigInt.asUintN(64, initial);
|
|
10741
|
-
if (value2 > EVENTFD_MAX) throw new WasiError("EINVAL");
|
|
10742
|
-
const fd = call2({
|
|
10743
|
-
op: "eventfd-open",
|
|
10744
|
-
initial: value2.toString(),
|
|
10745
|
-
semaphore: (flags & EVENTFD_SEMAPHORE) !== 0
|
|
10746
|
-
});
|
|
10747
|
-
fds.adopt(fd, "stream", (flags & EVENTFD_NONBLOCK) !== 0);
|
|
10748
|
-
mem.view().setUint32(out, fd, true);
|
|
10749
|
-
}
|
|
10750
|
-
};
|
|
10751
|
-
}
|
|
10752
|
-
var EVENT_SIZE, DATA_OFFSET, DATA_SIZE, MAX_EVENTS, FOREVER, MAX_TIMEOUT_MS, NS_PER_MS3, EVENTFD_SEMAPHORE, EVENTFD_NONBLOCK, EVENTFD_MAX, OPS;
|
|
10753
|
-
var init_wasix_epoll = __esm({
|
|
10754
|
-
"src/process/wasi/wasix-epoll.ts"() {
|
|
10755
|
-
"use strict";
|
|
10756
|
-
init_wasi_abi();
|
|
10757
|
-
init_wasi_files();
|
|
10758
|
-
EVENT_SIZE = 32;
|
|
10759
|
-
DATA_OFFSET = 8;
|
|
10760
|
-
DATA_SIZE = 24;
|
|
10761
|
-
MAX_EVENTS = 4096;
|
|
10762
|
-
FOREVER = 0xffffffffffffffffn;
|
|
10763
|
-
MAX_TIMEOUT_MS = 2147483647;
|
|
10764
|
-
NS_PER_MS3 = 1000000n;
|
|
10765
|
-
EVENTFD_SEMAPHORE = 1;
|
|
10766
|
-
EVENTFD_NONBLOCK = 4;
|
|
10767
|
-
EVENTFD_MAX = 0xfffffffffffffffen;
|
|
10768
|
-
OPS = ["add", "set", "del", "mod"];
|
|
10769
|
-
}
|
|
10770
|
-
});
|
|
10771
|
-
|
|
10772
10946
|
// src/process/wasi/wasix-ffi.ts
|
|
10773
10947
|
function read(view, at, type) {
|
|
10774
10948
|
if (type === "i32") return view.getInt32(at, true);
|
|
@@ -11675,7 +11849,7 @@ function posixSignal(sig) {
|
|
|
11675
11849
|
function nsToMs(ns) {
|
|
11676
11850
|
return Math.ceil(Number(ns) / 1e6);
|
|
11677
11851
|
}
|
|
11678
|
-
var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON, ECHO, FUTEX_SLICE_MS, EINTR_LIBC, MAIN_HANDLE, WasixHost;
|
|
11852
|
+
var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON, ECHO, FUTEX_SLICE_MS, EINTR_LIBC, STRICT_EPOLL_LIBC, MAIN_HANDLE, WasixHost;
|
|
11679
11853
|
var init_wasix_host = __esm({
|
|
11680
11854
|
"src/process/wasi/wasix-host.ts"() {
|
|
11681
11855
|
"use strict";
|
|
@@ -11699,6 +11873,7 @@ var init_wasix_host = __esm({
|
|
|
11699
11873
|
ECHO = 8;
|
|
11700
11874
|
FUTEX_SLICE_MS = 50;
|
|
11701
11875
|
EINTR_LIBC = 22;
|
|
11876
|
+
STRICT_EPOLL_LIBC = 29;
|
|
11702
11877
|
MAIN_HANDLE = 2147483647;
|
|
11703
11878
|
WasixHost = class _WasixHost {
|
|
11704
11879
|
process;
|
|
@@ -11717,6 +11892,7 @@ var init_wasix_host = __esm({
|
|
|
11717
11892
|
driver,
|
|
11718
11893
|
() => (this.threads?.tid ?? MAIN_TID) !== MAIN_TID
|
|
11719
11894
|
);
|
|
11895
|
+
if (module) host.strictEpoll = (libcVersion(module) ?? 0) >= STRICT_EPOLL_LIBC;
|
|
11720
11896
|
if (module && !WebAssembly.Module.imports(module).some((i) => i.name === "fd_fdflags_set")) {
|
|
11721
11897
|
host.fds.implicitCloexec = true;
|
|
11722
11898
|
host.interruptWakes = (libcVersion(module) ?? 0) < EINTR_LIBC;
|
|
@@ -12177,6 +12353,7 @@ __export(wasi_runtime_exports, {
|
|
|
12177
12353
|
});
|
|
12178
12354
|
function wireSignals(host, gate) {
|
|
12179
12355
|
host.interrupted = () => gate.interrupt();
|
|
12356
|
+
host.raisedOnEntry = () => gate.raisedOnEntry();
|
|
12180
12357
|
host.quietly = (fn) => gate.quiet(fn);
|
|
12181
12358
|
}
|
|
12182
12359
|
function catchUpFirst(host, sync) {
|
|
@@ -12202,6 +12379,7 @@ function delivering(ns, table, host, driver, before) {
|
|
|
12202
12379
|
if (driver.idle) {
|
|
12203
12380
|
before?.();
|
|
12204
12381
|
host.entered = host.interrupted?.() === true;
|
|
12382
|
+
host.enteredSignals = host.entered ? host.raisedOnEntry?.() ?? -1 : 0;
|
|
12205
12383
|
}
|
|
12206
12384
|
return fn(...args);
|
|
12207
12385
|
};
|
|
@@ -12216,7 +12394,7 @@ function sigmaskOf(module, sab, gate, threads, process) {
|
|
|
12216
12394
|
}
|
|
12217
12395
|
if (threads) threads.blocked = () => loadBlocked(header);
|
|
12218
12396
|
const shared = process && new Int32Array(process, 0, SAB_HEADER_I32);
|
|
12219
|
-
return new WasiSigmask(header, () => gate.deliver(), shared);
|
|
12397
|
+
return new WasiSigmask(header, () => gate.deliver(), shared, threads?.tid ?? MAIN_TID);
|
|
12220
12398
|
}
|
|
12221
12399
|
function enosys(module, name2, foreign) {
|
|
12222
12400
|
const type = foreign?.[module]?.[name2];
|
|
@@ -12570,7 +12748,8 @@ async function runWasiProcess(init, port2) {
|
|
|
12570
12748
|
),
|
|
12571
12749
|
procTree(call2, id.pid)
|
|
12572
12750
|
),
|
|
12573
|
-
...descriptors(init, fork, threads)
|
|
12751
|
+
...descriptors(init, fork, threads),
|
|
12752
|
+
...threads ? { credGen: threads.ids } : {}
|
|
12574
12753
|
});
|
|
12575
12754
|
host.sigmask = sigmaskOf(module, init.sab, gate, threads);
|
|
12576
12755
|
if (threads) {
|
|
@@ -13935,6 +14114,9 @@ function rewrite(hop, status2, location) {
|
|
|
13935
14114
|
);
|
|
13936
14115
|
}
|
|
13937
14116
|
const toGet = (status2 === 301 || status2 === 302) && hop.method === "POST" || status2 === 303 && hop.method !== "GET" && hop.method !== "HEAD";
|
|
14117
|
+
if (hop.stream && !toGet) {
|
|
14118
|
+
throw failed3(new JsCallError("EIO", `a ${status2} redirect would send a streamed body again`));
|
|
14119
|
+
}
|
|
13938
14120
|
const crossOrigin = next2.origin !== new URL(hop.url).origin;
|
|
13939
14121
|
const headers = hop.headers.filter(
|
|
13940
14122
|
([name2]) => !(toGet && BODY_HEADERS.has(name2.toLowerCase())) && !(crossOrigin && CREDENTIALS.has(name2.toLowerCase()))
|
|
@@ -14101,6 +14283,44 @@ async function bodyOf(request, cap, signal) {
|
|
|
14101
14283
|
}
|
|
14102
14284
|
return out;
|
|
14103
14285
|
}
|
|
14286
|
+
function streams(known, request, init, url) {
|
|
14287
|
+
if (known.streamingBodies !== true || !(init?.body instanceof ReadableStream)) return false;
|
|
14288
|
+
return request.method !== "GET" && request.method !== "HEAD" && !local2(url);
|
|
14289
|
+
}
|
|
14290
|
+
async function pump(kernel, handle, stream, signal) {
|
|
14291
|
+
const reader = stream.getReader();
|
|
14292
|
+
const stop = () => void reader.cancel(signal.reason).catch(() => void 0);
|
|
14293
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
14294
|
+
try {
|
|
14295
|
+
await pumpFrom(kernel, handle, reader, signal);
|
|
14296
|
+
} finally {
|
|
14297
|
+
signal.removeEventListener("abort", stop);
|
|
14298
|
+
}
|
|
14299
|
+
}
|
|
14300
|
+
async function pumpFrom(kernel, handle, reader, signal) {
|
|
14301
|
+
for (; ; ) {
|
|
14302
|
+
let bytes;
|
|
14303
|
+
try {
|
|
14304
|
+
const next2 = await reader.read();
|
|
14305
|
+
if (next2.done) break;
|
|
14306
|
+
bytes = bytesOf(next2.value);
|
|
14307
|
+
} catch (err) {
|
|
14308
|
+
await reader.cancel(err).catch(() => void 0);
|
|
14309
|
+
await kernel.raw({ op: "net-close", handle });
|
|
14310
|
+
return;
|
|
14311
|
+
}
|
|
14312
|
+
if (bytes.length === 0) continue;
|
|
14313
|
+
const taken = await kernel.blocking({ op: "net-write", handle, bytes }, signal).then(
|
|
14314
|
+
() => true,
|
|
14315
|
+
() => false
|
|
14316
|
+
);
|
|
14317
|
+
if (!taken) {
|
|
14318
|
+
await reader.cancel().catch(() => void 0);
|
|
14319
|
+
return;
|
|
14320
|
+
}
|
|
14321
|
+
}
|
|
14322
|
+
await kernel.raw({ op: "net-end", handle });
|
|
14323
|
+
}
|
|
14104
14324
|
function fetchOp(kernel) {
|
|
14105
14325
|
const traits = /* @__PURE__ */ new Map();
|
|
14106
14326
|
const traitsOf = (url) => {
|
|
@@ -14120,8 +14340,9 @@ function fetchOp(kernel) {
|
|
|
14120
14340
|
url: hop.url,
|
|
14121
14341
|
method: hop.method,
|
|
14122
14342
|
headers: hop.headers,
|
|
14123
|
-
...hop.body ? { body: hop.body } : {}
|
|
14343
|
+
...hop.stream ? { stream: true } : hop.body ? { body: hop.body } : {}
|
|
14124
14344
|
});
|
|
14345
|
+
if (hop.stream) void pump(kernel, handle, hop.stream, signal);
|
|
14125
14346
|
try {
|
|
14126
14347
|
const r = await kernel.blocking({ op: "net-head", handle }, signal);
|
|
14127
14348
|
signal.throwIfAborted();
|
|
@@ -14215,7 +14436,8 @@ function fetchOp(kernel) {
|
|
|
14215
14436
|
throw failed3(new JsCallError("ENOTSUP", `redirect: ${request.redirect}`));
|
|
14216
14437
|
}
|
|
14217
14438
|
const url = withoutFragment(new URL(request.url));
|
|
14218
|
-
const
|
|
14439
|
+
const streamed = streams(known, request, init, url);
|
|
14440
|
+
const bytes = streamed ? void 0 : await bodyOf(request, known.maxRequestBody, signal);
|
|
14219
14441
|
if (bytes === OVER) {
|
|
14220
14442
|
return withMeta(plain(413, `request body over ${known.maxRequestBody} bytes`), url, false);
|
|
14221
14443
|
}
|
|
@@ -14223,7 +14445,8 @@ function fetchOp(kernel) {
|
|
|
14223
14445
|
url,
|
|
14224
14446
|
method: request.method,
|
|
14225
14447
|
headers: [...request.headers],
|
|
14226
|
-
body: bytes
|
|
14448
|
+
body: bytes,
|
|
14449
|
+
...streamed && request.body ? { stream: request.body } : {}
|
|
14227
14450
|
};
|
|
14228
14451
|
for (let hops = 0; ; hops++) {
|
|
14229
14452
|
const head = await send(hop, signal);
|