@ai-ecoverse/slicc-kernel 1.108.0 → 1.108.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 +4 -4
- package/dist/kernel-worker.js +1 -1
- package/dist/node-process-worker.js +23 -18
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +1 -1
- package/dist/process-worker.js +23 -18
- package/dist/process-worker.js.map +2 -2
- package/dist/types/process/wasi/wasi-fds.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -322,7 +322,7 @@ A WASI command can name an ES module of its package that provides imports of its
|
|
|
322
322
|
|
|
323
323
|
- `memory()`, `instance()` (after instantiation), `tid` (1 for the main thread), `argv`, `env`, `cwd()`;
|
|
324
324
|
- `fs`: the synchronous filesystem the WASI calls use (absolute paths);
|
|
325
|
-
- `fds`: `open(path, { read, write, append, create, exclusive, truncate, directory, nofollow, mode })` returns a WASI descriptor of the program; `close`, `fstat` (`{ kind, path, mode, uid, gid, size, ino, mtimeMs }`), `fchmod`, and `tryLock(fd, exclusive)` / `unlock(fd)`: advisory locks held by the kernel across processes and threads, keyed by path, released on unlock, on closing the descriptor and at exit (`tryLock` returns 0, or 6 when another process holds the lock);
|
|
325
|
+
- `fds`: `open(path, { read, write, append, create, exclusive, truncate, directory, nofollow, mode })` returns a WASI descriptor of the program; `mode` is a new file's mode. With `create` and `exclusive` under users `report` or `enforce`, the file is created with it, less the umask, as `open(2)` does, and the name is only checked by the create itself (a symlink there is `EEXIST`). Otherwise the mode is set exactly once the file is open; `close`, `fstat` (`{ kind, path, mode, uid, gid, size, ino, mtimeMs }`), `fchmod`, and `tryLock(fd, exclusive)` / `unlock(fd)`: advisory locks held by the kernel across processes and threads, keyed by path, released on unlock, on closing the descriptor and at exit (`tryLock` returns 0, or 6 when another process holds the lock);
|
|
326
326
|
- `syscall(req)`: a kernel syscall, synchronously;
|
|
327
327
|
- `net.connect({ host, port, nonblock })` connects a TCP socket to the kernel's loopback and returns its kernel descriptor. `host` is `localhost` or `127.x.y.z`; anything else, or a port outside 1–65535, is `EINVAL`. A refused connection throws `ECONNREFUSED`. The connection carries the program's own identity, as any connect from its process does, so a [page facade](#page-facades) such as `SLICC_LINK_URL` sees the program's stamp. With `nonblock` it returns at once, and `net.ready(fd)` answers 0 once a connect is complete, `EINPROGRESS` (26) while it isn't, or the connect's WASI errno (`SO_ERROR`). On the loopback a connect completes at once, so `ready` is 0 straight away. `ready` is meant for a descriptor from `net.connect`. The descriptor is read and written with `fd-read` and `fd-write` and closed with `fd-close`, as below, and `fd-select` (`{ op: 'fd-select', read: [fds], write: [fds], timeoutMs }`, answering `{ read, write }` with the ready ones; `timeoutMs: -1` waits without a limit) waits until it's readable or writable;
|
|
328
328
|
- `spawn({ argv, env, cwd, stdin, stdout, stderr })` starts a command (resolved like `kernel.run`) as a child and returns `{ pid, stdin, stdout, stderr }`. `env` is the child's whole environment (the program's own by default), `cwd` the program's by default. Each stdio is `'inherit'` (the default: the program's own), `'null'`, or `'pipe'`: a kernel pipe whose end the result holds as a descriptor, read and written with `fd-read` (`{ op: 'fd-read', fd, max }`, an empty read at the end), `fd-write` (`{ op: 'fd-write', fd, body }`) and `fd-close`, through `syscall` or `async.submit`; the child's ends are closed in the program. A command that does not exist throws `ENOENT`;
|
|
@@ -922,7 +922,7 @@ The Biome, TypeScript, lefthook, Renovate and CI configuration comes from [slicc
|
|
|
922
922
|
|
|
923
923
|
`tools/big-file.mjs [bytes]` is a manual check, not part of any suite. It writes a file of that size (64 MiB by default) through a tmpfs mount with the unit-test launcher, reads it back, and prints the peak RSS and its ratio to the file size. A 256 MiB file peaks at about 1.8 times its size. Before ranged I/O (#127), a 1.1 GiB file peaked at 18 GB of RSS. **Do not run it past 1 GiB on a workstation.** It refuses anything over 256 MiB unless `SLICC_BIG_FILE_I_HAVE_THE_RAM=1` is set. Measure a small file and extrapolate instead. The unit suite checks a 32 MiB file the same way, and allows a fixed 192 MiB for garbage V8 has yet to collect, which dominates at that size.
|
|
924
924
|
|
|
925
|
-
Releases are cut by semantic-release on every push to `main`, in two jobs, and only on `main`. The first job runs on the bench pool, so it starts within a minute of the push, before `main` has moved on. It computes the version, tags the commit and creates the GitHub release, with `npmPublish: false`. A run that starts after `main` has moved skips; the run for the newer commit releases it. The second job runs on a GitHub-hosted runner, because npm's trusted publishing and provenance accept no self-hosted runner. It publishes the tagged commit with `tools/release-recover.mjs`. However long it waits for a runner, it publishes exactly the commit the run started on, so the provenance, the tag and the package's `gitHead` agree. For any version tagged at HEAD, `tools/release-recover.mjs` pushes the tag if origin lacks it, publishes the version if npm lacks it (with retries), and creates its GitHub release if that is missing too. So a failure after the version is tagged (a rejected push, a failed `npm publish`) doesn't strand it, and re-running the Release workflow completes it the same way.
|
|
925
|
+
Releases are cut by semantic-release on every push to `main`, in two jobs, and only on `main`. The first job runs on the bench pool, so it starts within a minute of the push, before `main` has moved on. It computes the version, tags the commit and creates the GitHub release, with `npmPublish: false`. A run that starts after `main` has moved skips; the run for the newer commit releases it. The second job runs on a GitHub-hosted runner, because npm's trusted publishing and provenance accept no self-hosted runner. It publishes the tagged commit with `tools/release-recover.mjs`. However long it waits for a runner, it publishes exactly the commit the run started on, so the provenance, the tag and the package's `gitHead` agree. For any version tagged at HEAD, `tools/release-recover.mjs` pushes the tag if origin lacks it, publishes the version if npm lacks it (with retries) and it is newer than npm's `latest` (an older one stays unpublished, so `latest` never moves back to it, and an `npm view` error fails the job instead of guessing; #837), and creates its GitHub release if that is missing too. So a failure after the version is tagged (a rejected push, a failed `npm publish`) doesn't strand it, and re-running the Release workflow completes it the same way.
|
|
926
926
|
|
|
927
927
|
### Certification (`cert-review`)
|
|
928
928
|
|
|
@@ -1084,9 +1084,9 @@ A threaded WASIX C program for `test/integration/thread-signal.test.mjs` (#520).
|
|
|
1084
1084
|
|
|
1085
1085
|
A WASIX C program for `test/integration/long-timers.test.mjs` (#767).
|
|
1086
1086
|
- `longwait alarm` sets `alarm(3000000)` (about 35 days), sleeps 0.5 s, and prints how many alarms came and how many seconds were left.
|
|
1087
|
-
- `longwait select|ppoll|nanosleep` waits 3,000,000 s on a pipe that never gets data, until a 300 ms interval timer interrupts the wait.
|
|
1087
|
+
- `longwait select|ppoll|nanosleep` waits 3,000,000 s on a pipe that never gets data, until a 300 ms interval timer interrupts the wait, and prints `not before it` when the wait lasted at least 300 ms (`early` otherwise). It sets no upper bound, so a loaded CI host can't fail the row; a wait that never ends times the test out.
|
|
1088
1088
|
|
|
1089
|
-
**Build:** `WASIX_SYSROOT_28=/path/to/wasix-sysroot ./build.sh`, with `wasixcc` 0.4.7 and binaryen's `wasm-opt` on `PATH`. `bin/longwait.wasm` is 44,
|
|
1089
|
+
**Build:** `WASIX_SYSROOT_28=/path/to/wasix-sysroot ./build.sh`, with `wasixcc` 0.4.7 and binaryen's `wasm-opt` on `PATH`. `bin/longwait.wasm` is 44,004 bytes, sha256 `e69d03f01479693666078297e781f5373719700c8534d1f2933749f5b3cee903`.
|
|
1090
1090
|
|
|
1091
1091
|
### `epollmask`
|
|
1092
1092
|
|
package/dist/kernel-worker.js
CHANGED
|
@@ -7985,7 +7985,7 @@ function satisfies(version, range2) {
|
|
|
7985
7985
|
}
|
|
7986
7986
|
|
|
7987
7987
|
// src/version.ts
|
|
7988
|
-
var KERNEL_VERSION = true ? "1.108.
|
|
7988
|
+
var KERNEL_VERSION = true ? "1.108.2" : "0.0.0-dev";
|
|
7989
7989
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7990
7990
|
function procVersion() {
|
|
7991
7991
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -2497,7 +2497,7 @@ var init_wasi_fds = __esm({
|
|
|
2497
2497
|
const flags = want === 6 ? O_RDWR : want === 2 ? O_WRONLY : 0;
|
|
2498
2498
|
return openDevice2.call(this.kernel.sys, flags);
|
|
2499
2499
|
}
|
|
2500
|
-
open(path, oflags, rights, fdflags) {
|
|
2500
|
+
open(path, oflags, rights, fdflags, mode) {
|
|
2501
2501
|
const device2 = deviceOf(path);
|
|
2502
2502
|
if (device2) return this.install({ type: "device", device: device2 });
|
|
2503
2503
|
const kernelDevice = this.openKernelDevice(path, oflags, fdflags, rights);
|
|
@@ -2518,13 +2518,16 @@ var init_wasi_fds = __esm({
|
|
|
2518
2518
|
}
|
|
2519
2519
|
if (!s && !(oflags & OFLAGS.CREAT)) throw new WasiError("ENOENT");
|
|
2520
2520
|
refuseWrite(s, oflags, rights);
|
|
2521
|
-
return this.regular(path, s, oflags, rights, fdflags);
|
|
2521
|
+
return this.regular(path, s, oflags, rights, fdflags, mode);
|
|
2522
2522
|
}
|
|
2523
|
-
regular(path, s, oflags, rights, fdflags) {
|
|
2523
|
+
regular(path, s, oflags, rights, fdflags, mode) {
|
|
2524
2524
|
if (this.shared || this.kernelHolds(path, s)) {
|
|
2525
|
-
return this.kernelFile(path, s, oflags, rights, fdflags);
|
|
2525
|
+
return this.kernelFile(path, s, oflags, rights, fdflags, mode);
|
|
2526
2526
|
}
|
|
2527
|
-
return this.install({
|
|
2527
|
+
return this.install({
|
|
2528
|
+
type: "file",
|
|
2529
|
+
file: this.file(path, s, oflags, rights, fdflags, mode)
|
|
2530
|
+
});
|
|
2528
2531
|
}
|
|
2529
2532
|
kernelHolds(path, st) {
|
|
2530
2533
|
for (const [fd, e] of this.table) {
|
|
@@ -2546,7 +2549,7 @@ var init_wasi_fds = __esm({
|
|
|
2546
2549
|
} catch {
|
|
2547
2550
|
}
|
|
2548
2551
|
}
|
|
2549
|
-
file(path, existing, oflags, rights, fdflags) {
|
|
2552
|
+
file(path, existing, oflags, rights, fdflags, mode) {
|
|
2550
2553
|
const { readable: readable3, writable: writable2 } = openAccess(existing, oflags, rights);
|
|
2551
2554
|
let buffer = this.buffers.get(path);
|
|
2552
2555
|
if (buffer?.handle !== void 0 && this.fs.kept?.(buffer.handle)) {
|
|
@@ -2559,13 +2562,13 @@ var init_wasi_fds = __esm({
|
|
|
2559
2562
|
if (this.fs.owners) this.fs.access?.(path, want, "open");
|
|
2560
2563
|
if (oflags & OFLAGS.TRUNC) buffer.truncate(0);
|
|
2561
2564
|
} else {
|
|
2562
|
-
buffer = this.freshBuffer(path, existing, oflags, want);
|
|
2565
|
+
buffer = this.freshBuffer(path, existing, oflags, want, mode);
|
|
2563
2566
|
}
|
|
2564
2567
|
buffer.opens++;
|
|
2565
2568
|
return new LocalFile(buffer, readable3, writable2, (fdflags & FDFLAGS.APPEND) !== 0);
|
|
2566
2569
|
}
|
|
2567
|
-
freshBuffer(path, existing, oflags, want) {
|
|
2568
|
-
const made = !existing && this.createNew(path, oflags);
|
|
2570
|
+
freshBuffer(path, existing, oflags, want, mode) {
|
|
2571
|
+
const made = !existing && this.createNew(path, oflags, mode);
|
|
2569
2572
|
const empty = made || (oflags & OFLAGS.TRUNC) !== 0;
|
|
2570
2573
|
if (existing?.ranged) this.fs.invalidate?.();
|
|
2571
2574
|
const seen = this.fs.changes?.now();
|
|
@@ -2595,11 +2598,11 @@ var init_wasi_fds = __esm({
|
|
|
2595
2598
|
if (id !== void 0) this.know(buffer, id);
|
|
2596
2599
|
return buffer;
|
|
2597
2600
|
}
|
|
2598
|
-
kernelFile(path, existing, oflags, rights, fdflags) {
|
|
2601
|
+
kernelFile(path, existing, oflags, rights, fdflags, mode) {
|
|
2599
2602
|
const { readable: readable3, writable: writable2 } = openAccess(existing, oflags, rights);
|
|
2600
2603
|
const append = (fdflags & FDFLAGS.APPEND) !== 0;
|
|
2601
2604
|
const flags = (writable2 ? readable3 ? O_RDWR : O_WRONLY : 0) | (append ? O_APPEND : 0);
|
|
2602
|
-
const made = !existing && this.createNew(path, oflags);
|
|
2605
|
+
const made = !existing && this.createNew(path, oflags, mode);
|
|
2603
2606
|
const truncate = made || (oflags & OFLAGS.TRUNC) !== 0;
|
|
2604
2607
|
const fd = this.kernel.sys.openVfs(path, flags, 0, {
|
|
2605
2608
|
...truncate ? { truncate } : {},
|
|
@@ -2612,13 +2615,13 @@ var init_wasi_fds = __esm({
|
|
|
2612
2615
|
this.bump();
|
|
2613
2616
|
return fd;
|
|
2614
2617
|
}
|
|
2615
|
-
createNew(path, oflags) {
|
|
2618
|
+
createNew(path, oflags, mode) {
|
|
2616
2619
|
if (!this.fs.create) {
|
|
2617
2620
|
this.fs.writeFile(path, new Uint8Array(0));
|
|
2618
2621
|
return true;
|
|
2619
2622
|
}
|
|
2620
2623
|
try {
|
|
2621
|
-
this.fs.create(path,
|
|
2624
|
+
this.fs.create(path, mode, true);
|
|
2622
2625
|
return true;
|
|
2623
2626
|
} catch (err) {
|
|
2624
2627
|
if (oflags & OFLAGS.EXCL || err.code !== "EEXIST") throw err;
|
|
@@ -4897,13 +4900,15 @@ function importsContext({
|
|
|
4897
4900
|
const fds = {
|
|
4898
4901
|
open(path, o = {}) {
|
|
4899
4902
|
const abs = host.fds.resolve(3, path);
|
|
4900
|
-
|
|
4903
|
+
const fresh = o.create === true && o.exclusive === true && owners && fs.create !== void 0;
|
|
4904
|
+
if (!fresh && o.nofollow && fs.exists(abs) && fs.lstat(abs).isSymbolicLink)
|
|
4901
4905
|
throw new WasiError("ELOOP");
|
|
4902
|
-
const existed = fs.exists(abs);
|
|
4906
|
+
const existed = !fresh && fs.exists(abs);
|
|
4903
4907
|
const oflags = (o.create ? OFLAGS.CREAT : 0) | (o.exclusive ? OFLAGS.EXCL : 0) | (o.truncate ? OFLAGS.TRUNC : 0) | (o.directory ? OFLAGS.DIRECTORY : 0);
|
|
4904
4908
|
const rights = (o.write ? RIGHTS.FD_WRITE : 0n) | (o.read || !o.write ? RIGHTS.FD_READ : 0n);
|
|
4905
|
-
const
|
|
4906
|
-
|
|
4909
|
+
const flags = o.append ? FDFLAGS.APPEND : 0;
|
|
4910
|
+
const fd = host.fds.open(abs, oflags, rights, flags, fresh ? o.mode : void 0);
|
|
4911
|
+
if (o.mode !== void 0 && !existed && !fresh) fs.chmod(abs, o.mode);
|
|
4907
4912
|
return fd;
|
|
4908
4913
|
},
|
|
4909
4914
|
close(fd) {
|
|
@@ -5167,7 +5172,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
5167
5172
|
var init_version = __esm({
|
|
5168
5173
|
"src/version.ts"() {
|
|
5169
5174
|
"use strict";
|
|
5170
|
-
KERNEL_VERSION = true ? "1.108.
|
|
5175
|
+
KERNEL_VERSION = true ? "1.108.2" : "0.0.0-dev";
|
|
5171
5176
|
OS_RELEASE = "6.0.0-slicc";
|
|
5172
5177
|
}
|
|
5173
5178
|
});
|