@ai-ecoverse/slicc-kernel 1.17.0 → 1.17.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 +7 -0
- package/dist/kernel-worker.js +63 -23
- package/dist/kernel-worker.js.map +2 -2
- package/dist/node-process-worker.js +123 -90
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +63 -23
- package/dist/node.js.map +2 -2
- package/dist/process-worker.js +123 -90
- package/dist/process-worker.js.map +2 -2
- package/package.json +1 -1
package/dist/process-worker.js
CHANGED
|
@@ -1446,6 +1446,25 @@ function ownReady(Fs, read, write) {
|
|
|
1446
1446
|
write: write.filter((fd) => flags(fd) & (POLLOUT2 | POLLERR2 | POLLNVAL))
|
|
1447
1447
|
};
|
|
1448
1448
|
}
|
|
1449
|
+
function anySelect(Fs, transport, read, write, timeoutMs) {
|
|
1450
|
+
const kernel = (fd) => Fs.getStream(fd)?.sliccKernelFd;
|
|
1451
|
+
const own = (fd) => kernel(fd) === void 0;
|
|
1452
|
+
if (![...read, ...write].some(own)) return kernelSelect(Fs, transport, read, write, timeoutMs);
|
|
1453
|
+
const deadline = timeoutMs < 0 ? Number.POSITIVE_INFINITY : Date.now() + timeoutMs;
|
|
1454
|
+
const kernelRead = read.filter((fd) => !own(fd));
|
|
1455
|
+
const kernelWrite = write.filter((fd) => !own(fd));
|
|
1456
|
+
for (; ; ) {
|
|
1457
|
+
const local = ownReady(Fs, read.filter(own), write.filter(own));
|
|
1458
|
+
const pending = local.read.length > 0 || local.write.length > 0;
|
|
1459
|
+
const slice = pending ? 0 : Math.min(SELECT_SLICE_MS, Math.max(0, deadline - Date.now()));
|
|
1460
|
+
const got = kernelSelect(Fs, transport, kernelRead, kernelWrite, slice);
|
|
1461
|
+
if (typeof got === "number") return got;
|
|
1462
|
+
const ready = { read: [...local.read, ...got.read], write: [...local.write, ...got.write] };
|
|
1463
|
+
if (ready.read.length > 0 || ready.write.length > 0 || Date.now() >= deadline) {
|
|
1464
|
+
return ready;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1449
1468
|
function createProcessKernel(deps) {
|
|
1450
1469
|
const { transport, Fs } = deps;
|
|
1451
1470
|
const reaped = /* @__PURE__ */ new Map();
|
|
@@ -1487,35 +1506,52 @@ function createProcessKernel(deps) {
|
|
|
1487
1506
|
Fs.write(stream, r.bytes, 0, r.bytes.length);
|
|
1488
1507
|
}
|
|
1489
1508
|
};
|
|
1509
|
+
const execCaptures = /* @__PURE__ */ new Map();
|
|
1510
|
+
const execWait = (pid) => {
|
|
1511
|
+
const r = transport.call({ op: "proc-exec", pid }, Infinity, `exec ${pid}`);
|
|
1512
|
+
if (!r.ok) return -wasiErrno(r.errno);
|
|
1513
|
+
deps.afterChild();
|
|
1514
|
+
return r.kind === "json" ? r.json[1] : 0;
|
|
1515
|
+
};
|
|
1516
|
+
const spawnChild = (file, argv, env, cwd, fds, actions, exec) => {
|
|
1517
|
+
const unflushed = flushed(deps.beforeSpawn);
|
|
1518
|
+
if (unflushed < 0) return unflushed;
|
|
1519
|
+
const promote = deps.stdioPromoter?.();
|
|
1520
|
+
const stdio = [0, 1, 2].map((n) => slot(fds[n] ?? -1, n, promote));
|
|
1521
|
+
const inherit = deps.inherit?.(actions) ?? [];
|
|
1522
|
+
const r = transport.call(
|
|
1523
|
+
{
|
|
1524
|
+
op: "proc-spawn",
|
|
1525
|
+
file,
|
|
1526
|
+
argv,
|
|
1527
|
+
env: env ?? deps.env,
|
|
1528
|
+
cwd: cwd ?? Fs.cwd(),
|
|
1529
|
+
stdio,
|
|
1530
|
+
...inherit.length > 0 ? { inherit } : {},
|
|
1531
|
+
...exec ? { exec } : {}
|
|
1532
|
+
},
|
|
1533
|
+
Infinity,
|
|
1534
|
+
`proc-spawn ${file}`
|
|
1535
|
+
);
|
|
1536
|
+
if (!r.ok) return -wasiErrno(r.errno);
|
|
1537
|
+
const pid = r.kind === "json" ? r.json : 0;
|
|
1538
|
+
const captures = [1, 2].filter((n) => "capture" in stdio[n]);
|
|
1539
|
+
if (captures.length === 0) return pid;
|
|
1540
|
+
if (exec) {
|
|
1541
|
+
execCaptures.set(pid, () => {
|
|
1542
|
+
for (const n of captures) deliver(pid, n, fds[n]);
|
|
1543
|
+
});
|
|
1544
|
+
return pid;
|
|
1545
|
+
}
|
|
1546
|
+
const waited = kernelWait(pid, false);
|
|
1547
|
+
if (typeof waited === "number") return waited;
|
|
1548
|
+
for (const n of captures) deliver(pid, n, fds[n]);
|
|
1549
|
+
reaped.set(pid, waited[1]);
|
|
1550
|
+
return pid;
|
|
1551
|
+
};
|
|
1490
1552
|
return {
|
|
1491
1553
|
spawn(file, argv, env, cwd, fds, actions) {
|
|
1492
|
-
|
|
1493
|
-
if (unflushed < 0) return unflushed;
|
|
1494
|
-
const promote = deps.stdioPromoter?.();
|
|
1495
|
-
const stdio = [0, 1, 2].map((n) => slot(fds[n] ?? -1, n, promote));
|
|
1496
|
-
const inherit = deps.inherit?.(actions) ?? [];
|
|
1497
|
-
const r = transport.call(
|
|
1498
|
-
{
|
|
1499
|
-
op: "proc-spawn",
|
|
1500
|
-
file,
|
|
1501
|
-
argv,
|
|
1502
|
-
env: env ?? deps.env,
|
|
1503
|
-
cwd: cwd ?? Fs.cwd(),
|
|
1504
|
-
stdio,
|
|
1505
|
-
...inherit.length > 0 ? { inherit } : {}
|
|
1506
|
-
},
|
|
1507
|
-
Infinity,
|
|
1508
|
-
`proc-spawn ${file}`
|
|
1509
|
-
);
|
|
1510
|
-
if (!r.ok) return -wasiErrno(r.errno);
|
|
1511
|
-
const pid = r.kind === "json" ? r.json : 0;
|
|
1512
|
-
const captures = [1, 2].filter((n) => "capture" in stdio[n]);
|
|
1513
|
-
if (captures.length === 0) return pid;
|
|
1514
|
-
const waited = kernelWait(pid, false);
|
|
1515
|
-
if (typeof waited === "number") return waited;
|
|
1516
|
-
for (const n of captures) deliver(pid, n, fds[n]);
|
|
1517
|
-
reaped.set(pid, waited[1]);
|
|
1518
|
-
return pid;
|
|
1554
|
+
return spawnChild(file, argv, env, cwd, fds, actions, false);
|
|
1519
1555
|
},
|
|
1520
1556
|
fork(state) {
|
|
1521
1557
|
const unflushed = flushed(deps.beforeSpawn);
|
|
@@ -1529,31 +1565,15 @@ function createProcessKernel(deps) {
|
|
|
1529
1565
|
if (!r.ok) return -wasiErrno(r.errno);
|
|
1530
1566
|
return r.kind === "json" ? r.json : -wasiErrno("EIO");
|
|
1531
1567
|
},
|
|
1532
|
-
select(read, write, timeoutMs)
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
const
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
const local = ownReady(Fs, read.filter(own), write.filter(own));
|
|
1542
|
-
const pending = local.read.length > 0 || local.write.length > 0;
|
|
1543
|
-
const slice = pending ? 0 : Math.min(SELECT_SLICE_MS, Math.max(0, deadline - Date.now()));
|
|
1544
|
-
const got = kernelSelect(Fs, transport, kernelRead, kernelWrite, slice);
|
|
1545
|
-
if (typeof got === "number") return got;
|
|
1546
|
-
const ready = { read: [...local.read, ...got.read], write: [...local.write, ...got.write] };
|
|
1547
|
-
if (ready.read.length > 0 || ready.write.length > 0 || Date.now() >= deadline) {
|
|
1548
|
-
return ready;
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
},
|
|
1552
|
-
execWait(pid) {
|
|
1553
|
-
const r = transport.call({ op: "proc-exec", pid }, Infinity, `exec ${pid}`);
|
|
1554
|
-
if (!r.ok) return -wasiErrno(r.errno);
|
|
1555
|
-
deps.afterChild();
|
|
1556
|
-
return r.kind === "json" ? r.json[1] : 0;
|
|
1568
|
+
select: (read, write, timeoutMs) => anySelect(Fs, transport, read, write, timeoutMs),
|
|
1569
|
+
execWait,
|
|
1570
|
+
execve(file, argv, env, cwd) {
|
|
1571
|
+
const pid = spawnChild(file, argv, env, cwd, [0, 1, 2], void 0, true);
|
|
1572
|
+
if (pid < 0) return pid;
|
|
1573
|
+
const status2 = execWait(pid);
|
|
1574
|
+
execCaptures.get(pid)?.();
|
|
1575
|
+
execCaptures.delete(pid);
|
|
1576
|
+
return status2;
|
|
1557
1577
|
},
|
|
1558
1578
|
pause() {
|
|
1559
1579
|
return status(call2({ op: "sig-pause" }, "pause"));
|
|
@@ -3338,20 +3358,20 @@ function pathInode(path) {
|
|
|
3338
3358
|
}
|
|
3339
3359
|
return h;
|
|
3340
3360
|
}
|
|
3341
|
-
function cachingBridge(bridge) {
|
|
3361
|
+
function cachingBridge(bridge, now = () => performance.now()) {
|
|
3342
3362
|
const stats = /* @__PURE__ */ new Map();
|
|
3343
3363
|
const lstats = /* @__PURE__ */ new Map();
|
|
3344
3364
|
const cached = (map, path, get) => {
|
|
3345
3365
|
let hit = map.get(path);
|
|
3346
|
-
if (hit === void 0) {
|
|
3366
|
+
if (hit === void 0 || "until" in hit && hit.until <= now()) {
|
|
3347
3367
|
try {
|
|
3348
3368
|
hit = get();
|
|
3349
3369
|
} catch (e) {
|
|
3350
|
-
hit = e;
|
|
3370
|
+
hit = { error: e, until: now() + MISS_TTL_MS };
|
|
3351
3371
|
}
|
|
3352
3372
|
map.set(path, hit);
|
|
3353
3373
|
}
|
|
3354
|
-
if (
|
|
3374
|
+
if ("until" in hit) throw hit.error;
|
|
3355
3375
|
return hit;
|
|
3356
3376
|
};
|
|
3357
3377
|
const invalidate = () => {
|
|
@@ -3401,7 +3421,7 @@ function cachingBridge(bridge) {
|
|
|
3401
3421
|
invalidate
|
|
3402
3422
|
};
|
|
3403
3423
|
}
|
|
3404
|
-
var WasiError, FileBuffer, LocalFile;
|
|
3424
|
+
var WasiError, FileBuffer, LocalFile, MISS_TTL_MS;
|
|
3405
3425
|
var init_wasi_files = __esm({
|
|
3406
3426
|
"src/process/wasi/wasi-files.ts"() {
|
|
3407
3427
|
"use strict";
|
|
@@ -3530,6 +3550,7 @@ var init_wasi_files = __esm({
|
|
|
3530
3550
|
this.buffer.flush();
|
|
3531
3551
|
}
|
|
3532
3552
|
};
|
|
3553
|
+
MISS_TTL_MS = 20;
|
|
3533
3554
|
}
|
|
3534
3555
|
});
|
|
3535
3556
|
|
|
@@ -4292,27 +4313,30 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
|
|
|
4292
4313
|
const subs = readSubscriptions(mem, inPtr, nsubs, deps.now);
|
|
4293
4314
|
const { events, read, write } = classify(deps.fds, subs);
|
|
4294
4315
|
let interrupted = false;
|
|
4316
|
+
const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
|
|
4317
|
+
const expired = () => performance.now() + CLOCK_SLACK_MS >= earliest;
|
|
4295
4318
|
if (read.length > 0 || write.length > 0 || events.length === 0) {
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4319
|
+
do {
|
|
4320
|
+
let timeoutMs = -1;
|
|
4321
|
+
if (events.length > 0) timeoutMs = 0;
|
|
4322
|
+
else if (earliest !== Infinity)
|
|
4323
|
+
timeoutMs = Math.max(0, Math.ceil(earliest - performance.now()));
|
|
4324
|
+
let ready;
|
|
4325
|
+
try {
|
|
4326
|
+
ready = kernel.call({ op: "fd-select", read, write, timeoutMs });
|
|
4327
|
+
} catch (e) {
|
|
4328
|
+
if (!deps.interruptWakes || e.code !== "EINTR") throw e;
|
|
4329
|
+
interrupted = true;
|
|
4330
|
+
ready = { read: [], write: [] };
|
|
4331
|
+
}
|
|
4332
|
+
events.push(
|
|
4333
|
+
...readyEvents(subs, ready)
|
|
4334
|
+
);
|
|
4335
|
+
} while (events.length === 0 && !interrupted && earliest !== Infinity && !expired());
|
|
4312
4336
|
}
|
|
4313
4337
|
const after = performance.now();
|
|
4314
4338
|
for (const s of subs) {
|
|
4315
|
-
if (s.type === EVENTTYPE.CLOCK && (interrupted || s.deadline <= after +
|
|
4339
|
+
if (s.type === EVENTTYPE.CLOCK && (interrupted || s.deadline <= after + CLOCK_SLACK_MS)) {
|
|
4316
4340
|
events.push({ userdata: s.userdata, error: E.SUCCESS, type: s.type });
|
|
4317
4341
|
}
|
|
4318
4342
|
}
|
|
@@ -4320,10 +4344,12 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
|
|
|
4320
4344
|
mem.view().setUint32(neventsPtr, events.length, true);
|
|
4321
4345
|
return E.SUCCESS;
|
|
4322
4346
|
}
|
|
4347
|
+
var CLOCK_SLACK_MS;
|
|
4323
4348
|
var init_wasi_poll = __esm({
|
|
4324
4349
|
"src/process/wasi/wasi-poll.ts"() {
|
|
4325
4350
|
"use strict";
|
|
4326
4351
|
init_wasi_abi();
|
|
4352
|
+
CLOCK_SLACK_MS = 0.5;
|
|
4327
4353
|
}
|
|
4328
4354
|
});
|
|
4329
4355
|
|
|
@@ -4451,19 +4477,25 @@ var init_wasi_host = __esm({
|
|
|
4451
4477
|
...this.statImports(),
|
|
4452
4478
|
...this.pathImports(),
|
|
4453
4479
|
...this.socketImports(),
|
|
4454
|
-
poll_oneoff: (inPtr, outPtr, n, nevents) =>
|
|
4455
|
-
{
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4480
|
+
poll_oneoff: (inPtr, outPtr, n, nevents) => {
|
|
4481
|
+
try {
|
|
4482
|
+
return pollOneoff(
|
|
4483
|
+
{
|
|
4484
|
+
mem: this.mem,
|
|
4485
|
+
fds: this.fds,
|
|
4486
|
+
kernel: this.o.kernel,
|
|
4487
|
+
now: (id) => this.now(id),
|
|
4488
|
+
interruptWakes: this.interruptWakes
|
|
4489
|
+
},
|
|
4490
|
+
inPtr,
|
|
4491
|
+
outPtr,
|
|
4492
|
+
n,
|
|
4493
|
+
nevents
|
|
4494
|
+
);
|
|
4495
|
+
} finally {
|
|
4496
|
+
this.o.fs.invalidate?.();
|
|
4497
|
+
}
|
|
4498
|
+
}
|
|
4467
4499
|
});
|
|
4468
4500
|
return this.cache;
|
|
4469
4501
|
}
|
|
@@ -5818,7 +5850,7 @@ var init_wasix_process = __esm({
|
|
|
5818
5850
|
...op.oflags & OFLAG_TRUNC ? { truncate: true } : {}
|
|
5819
5851
|
});
|
|
5820
5852
|
}
|
|
5821
|
-
spawn(req) {
|
|
5853
|
+
spawn(req, exec = false) {
|
|
5822
5854
|
const { stdio, inherit, cwd, opened } = this.childFds(req.ops ?? []);
|
|
5823
5855
|
try {
|
|
5824
5856
|
return this.call({
|
|
@@ -5828,7 +5860,8 @@ var init_wasix_process = __esm({
|
|
|
5828
5860
|
env: req.env ?? this.environment(),
|
|
5829
5861
|
cwd,
|
|
5830
5862
|
stdio,
|
|
5831
|
-
inherit
|
|
5863
|
+
inherit,
|
|
5864
|
+
...exec ? { exec } : {}
|
|
5832
5865
|
});
|
|
5833
5866
|
} finally {
|
|
5834
5867
|
for (const kfd of opened) this.host.o.kernel.sys.close(kfd);
|
|
@@ -5836,7 +5869,7 @@ var init_wasix_process = __esm({
|
|
|
5836
5869
|
}
|
|
5837
5870
|
}
|
|
5838
5871
|
exec(req) {
|
|
5839
|
-
const pid = this.spawn(req);
|
|
5872
|
+
const pid = this.spawn(req, true);
|
|
5840
5873
|
const [, status2] = this.call({ op: "proc-exec", pid });
|
|
5841
5874
|
const sig = status2 & 127;
|
|
5842
5875
|
throw new WasiExit(sig ? 128 + sig : status2 >> 8 & 255);
|