@ai-ecoverse/slicc-kernel 1.136.1 → 1.136.3
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 +1 -1
- package/dist/kernel-worker.js +56 -6
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +56 -6
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +1 -1
- package/dist/types/kernel/process.d.ts +1 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -327,7 +327,7 @@ On top of preview1 a WASI program gets:
|
|
|
327
327
|
A kernel without the imports answers `ENOSYS`, and the libc reports `SI_USER` with pid and uid 0, as before. **SIGCHLD:** with `SIGCHLD` set to `SIG_IGN` (by the program, or inherited), or with `SA_NOCLDWAIT` in the flags `slicc.sigaction_set` gets for `SIGCHLD`, an exited child is reaped at once and never stays a zombie: `waitpid` for it is `ECHILD`, and `wait` blocks until every child has exited, then fails with `ECHILD`, as on Linux. `SIGCHLD` is still sent. An explicit `SIG_DFL` turns it back off. A child that a process waits on for `exec`, or that `kernel.run` and the run calls collect, is never reaped that way.
|
|
328
328
|
- **Pipes** have no file type for WASI and WASIX programs' `fstat` (`st_mode` type 0), because WASI has no FIFO file type. A socket type, as kernels 1.47.3 to 1.48.1 gave them, made Ruby treat a `popen` pipe as a socket (`close_write` then never ends the child's input). The kernel's `slicc_fs.fd_mode` answers `S_IFIFO | 0600` (Linux numbering) for a pipe, and wasix-sysroot 2025.9.30-21 and later take the type from it, so programs built on it see a FIFO (`S_ISFIFO`); older libcs keep only the permission bits. Until then Python's asyncio refuses a pipe for a subprocess (`Pipe transport is only for pipes, sockets and character devices`). They are read and written as pipes; socket calls on them fail with `ENOTSOCK`, and `isatty()` is false. Emscripten programs, bash included, see a FIFO. The same holds for any kernel descriptor that is neither seekable nor a terminal or device, such as captured output.
|
|
329
329
|
- **Sockets**: the WASIX socket calls (`sock_open`, `sock_pair` for an `AF_UNIX` stream or datagram pair, `bind`, `listen`, `connect`, `accept`, options, local and peer names) are the kernel's loopback sockets, and preview1's `sock_recv` / `sock_send` / `sock_shutdown` work on them and on inherited ones. Writing to a socket whose peer is gone fails with `EPIPE`, through `fd_write` as through `sock_send`, as if `MSG_NOSIGNAL` were set. A write to a pipe, FIFO or terminal whose reader is gone follows the program's `SIGPIPE` disposition, as the kernel knows it (#810): at the default it ends the program with status 141; ignored (also an ignore inherited across `exec` and spawn, as bash's `trap '' PIPE` passes on), the write fails with `EPIPE`; with a handler, the handler runs on the thread that wrote and then the write fails with `EPIPE` (#820); blocked, `SIGPIPE` stays pending and the write fails with `EPIPE`. An Emscripten program's write to a pipe, and its `send` without `MSG_NOSIGNAL`, follow the same rules, except that the kernel doesn't see an Emscripten program's signal mask, so a blocked `SIGPIPE` there still ends it. A WASIX program's libc reads an inherited ignore back through `slicc.sigaction_inherited` (wasix-sysroot -32 and later; see below). An Emscripten program's shim reads it from `Module.sliccKernel.sigInherited()` (#965, homescoop#973). That's a mask with bit n set for signal n (not bit n-1, as the WASIX import has it) holding only inherited `SIG_IGN`s, never `SIGKILL` or `SIGSTOP`. The shim seeds its `sigaction` table from it in a constructor that runs before any user constructor. The kernel puts the function on `Module.sliccKernel` before the glue runs constructors, ahead of the rest of `sliccKernel`. On a kernel without the function it is undefined, and the shim keeps the defaults. HTTP and HTTPS leave through the realm proxy that `https_proxy` names, as for any other program; `resolve` answers `/etc/hosts` names and literal addresses, and the [uplink](#uplink)'s names. `sock_open(SOCK_DGRAM)` on `AF_INET`/`AF_INET6` gives a [datagram socket](#datagram-sockets-udp); `sock_send_to` and `sock_recv_from` carry its addresses, and `RECV_DATA_TRUNCATED` is set in `ro_flags` when a datagram did not fit.
|
|
330
|
-
- **Diagnostics**: a trap ends the program with 134 and its message on stderr; with `SLICC_WASM_BACKTRACE=1` the wasm frames follow, named from the module's name section, or from a sidecar for a module shipped without one (`<module>.names` beside it, or the same path in a `<package>-names` package). `SLICC_WASI_STATS=1` makes a program print its calls, counted and timed, as it ends.
|
|
330
|
+
- **Diagnostics**: a trap ends the program with 134 and its message on stderr; a program that crashes its worker otherwise (a JS stack overflow, `RangeError: Maximum call stack size exceeded`, or any other uncaught error) ends with 70, and its message goes to the process's own fd 2 too, so `2>` catches it (#1237), or to the session's stderr when it has no fd 2 to write; with `SLICC_WASM_BACKTRACE=1` the wasm frames follow, named from the module's name section, or from a sidecar for a module shipped without one (`<module>.names` beside it, or the same path in a `<package>-names` package). `SLICC_WASI_STATS=1` makes a program print its calls, counted and timed, as it ends.
|
|
331
331
|
|
|
332
332
|
### Program imports
|
|
333
333
|
|
package/dist/kernel-worker.js
CHANGED
|
@@ -7098,7 +7098,7 @@ function satisfies(version, range2) {
|
|
|
7098
7098
|
}
|
|
7099
7099
|
|
|
7100
7100
|
// src/version.ts
|
|
7101
|
-
var KERNEL_VERSION = true ? "1.136.
|
|
7101
|
+
var KERNEL_VERSION = true ? "1.136.3" : "0.0.0-dev";
|
|
7102
7102
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7103
7103
|
function procVersion() {
|
|
7104
7104
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -20104,7 +20104,20 @@ var KEY_PARSE_RANGES = [
|
|
|
20104
20104
|
[-28671, -24576],
|
|
20105
20105
|
[-127, -96]
|
|
20106
20106
|
];
|
|
20107
|
-
var
|
|
20107
|
+
var BEFORE_DECRYPT = /* @__PURE__ */ new Set([
|
|
20108
|
+
-15360,
|
|
20109
|
+
-15488,
|
|
20110
|
+
-16256,
|
|
20111
|
+
-14720,
|
|
20112
|
+
-4480,
|
|
20113
|
+
-4608,
|
|
20114
|
+
-4736,
|
|
20115
|
+
-5120,
|
|
20116
|
+
-24704,
|
|
20117
|
+
-24960,
|
|
20118
|
+
-106
|
|
20119
|
+
]);
|
|
20120
|
+
var keyParse = (code) => !BEFORE_DECRYPT.has(code) && KEY_PARSE_RANGES.some(([lo, hi]) => code >= lo && code <= hi);
|
|
20108
20121
|
function keyRefused(err, locked) {
|
|
20109
20122
|
const raw2 = err instanceof TlsError ? err.code : 0;
|
|
20110
20123
|
const code = locked && keyParse(raw2) ? -15232 : raw2;
|
|
@@ -22278,6 +22291,18 @@ var WasmProcess = class {
|
|
|
22278
22291
|
throw err;
|
|
22279
22292
|
}
|
|
22280
22293
|
}
|
|
22294
|
+
async complain(line) {
|
|
22295
|
+
const stderr = this.fds.has(2) ? this.fds.get(2).file : void 0;
|
|
22296
|
+
if (!stderr?.write || stderr.sealed || stderr.clipboard) return false;
|
|
22297
|
+
const bytes = new TextEncoder().encode(`${line}
|
|
22298
|
+
`);
|
|
22299
|
+
const timeout = new Promise((r) => setTimeout(() => r(0), 1e3));
|
|
22300
|
+
const sent = await Promise.race([stderr.write(bytes, AbortSignal.timeout(1e3)), timeout]).then(
|
|
22301
|
+
(n) => n,
|
|
22302
|
+
() => 0
|
|
22303
|
+
);
|
|
22304
|
+
return sent > 0;
|
|
22305
|
+
}
|
|
22281
22306
|
async clipboardComplaint(err) {
|
|
22282
22307
|
const name2 = this.options.clipboardName;
|
|
22283
22308
|
if (name2 === void 0 || !(err instanceof KernelError) || err.detail === void 0) return;
|
|
@@ -23753,6 +23778,29 @@ function outOfMemory(opts, data) {
|
|
|
23753
23778
|
}
|
|
23754
23779
|
return true;
|
|
23755
23780
|
}
|
|
23781
|
+
function workerError(event) {
|
|
23782
|
+
return String(event.message ?? "worker error");
|
|
23783
|
+
}
|
|
23784
|
+
var CrashSlot = class {
|
|
23785
|
+
status;
|
|
23786
|
+
reported = false;
|
|
23787
|
+
report;
|
|
23788
|
+
constructor(report) {
|
|
23789
|
+
this.report = report;
|
|
23790
|
+
}
|
|
23791
|
+
take(status, message3, finish) {
|
|
23792
|
+
if (this.status) return;
|
|
23793
|
+
this.status = status;
|
|
23794
|
+
const done5 = () => {
|
|
23795
|
+
this.reported = true;
|
|
23796
|
+
finish(...status);
|
|
23797
|
+
};
|
|
23798
|
+
void this.report(message3).then(done5, done5);
|
|
23799
|
+
}
|
|
23800
|
+
};
|
|
23801
|
+
async function crashReport(process, onError, message3) {
|
|
23802
|
+
if (!await process.complain(message3)) onError?.(message3);
|
|
23803
|
+
}
|
|
23756
23804
|
function spawnWasmProcess(opts) {
|
|
23757
23805
|
const { promise: ready2, resolve: started } = readiness(opts.program.abi);
|
|
23758
23806
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
@@ -23803,9 +23851,11 @@ function spawnWasmProcess(opts) {
|
|
|
23803
23851
|
const jsThreads = jsThreadsOf(opts, process, token, dispatch2, clocks, header3);
|
|
23804
23852
|
const { promise: exited, resolve: settle3 } = Promise.withResolvers();
|
|
23805
23853
|
let done5 = false;
|
|
23854
|
+
const crash = new CrashSlot((message3) => crashReport(process, opts.onError, message3));
|
|
23806
23855
|
let endedBy;
|
|
23807
23856
|
const finish = (code, sig) => {
|
|
23808
23857
|
if (done5) return;
|
|
23858
|
+
if (crash.status && !crash.reported) return;
|
|
23809
23859
|
done5 = true;
|
|
23810
23860
|
started(true);
|
|
23811
23861
|
clocks.freeze();
|
|
@@ -23834,8 +23884,9 @@ function spawnWasmProcess(opts) {
|
|
|
23834
23884
|
} else if (data?.type === WASM_PROCESS_EXIT) {
|
|
23835
23885
|
finish(...dying.status(data.code));
|
|
23836
23886
|
} else if (data?.type === WASM_PROCESS_ERROR) {
|
|
23837
|
-
|
|
23838
|
-
finish(...
|
|
23887
|
+
const status = dying.status(data.code);
|
|
23888
|
+
if (dying.ending) finish(...status);
|
|
23889
|
+
else crash.take(status, String(data.message), finish);
|
|
23839
23890
|
} else if (data?.type === WASM_THREAD_SPAWN && data.thread) {
|
|
23840
23891
|
spawnThread(data.thread);
|
|
23841
23892
|
} else if (data?.type === JS_THREAD_SPAWN && jsThreads) {
|
|
@@ -23845,8 +23896,7 @@ function spawnWasmProcess(opts) {
|
|
|
23845
23896
|
const onMessage = (event) => handle(event.data);
|
|
23846
23897
|
const onError = (event) => {
|
|
23847
23898
|
event.preventDefault();
|
|
23848
|
-
|
|
23849
|
-
finish(CRASHED);
|
|
23899
|
+
crash.take([CRASHED], workerError(event), finish);
|
|
23850
23900
|
};
|
|
23851
23901
|
worker.addEventListener("message", onMessage);
|
|
23852
23902
|
worker.addEventListener("error", onError);
|