@ai-ecoverse/slicc-kernel 1.39.3 → 1.40.1

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.
@@ -2730,13 +2730,13 @@ function describeInherited(Fs, sys, streams, livePath, actions = []) {
2730
2730
  if (from) table.set(target, { stream: from.stream, cloexec: false });
2731
2731
  else table.delete(target);
2732
2732
  }
2733
- const slots = /* @__PURE__ */ new Map();
2733
+ const slots2 = /* @__PURE__ */ new Map();
2734
2734
  for (const [fd, { stream, cloexec }] of table) {
2735
- if (fd > 2 && !cloexec) slots.set(fd, stream);
2735
+ if (fd > 2 && !cloexec) slots2.set(fd, stream);
2736
2736
  }
2737
2737
  const promote = vfsPromoter(Fs, sys, streams, livePath);
2738
2738
  const out = [];
2739
- for (const [fd, stream] of slots) {
2739
+ for (const [fd, stream] of slots2) {
2740
2740
  promote(stream);
2741
2741
  const slot = inheritedSlot(fd, stream);
2742
2742
  if (slot) out.push(slot);
@@ -4517,10 +4517,10 @@ var init_wasi_files = __esm({
4517
4517
  readable;
4518
4518
  writable;
4519
4519
  append;
4520
- constructor(buffer, readable, writable, append) {
4520
+ constructor(buffer, readable2, writable2, append) {
4521
4521
  this.buffer = buffer;
4522
- this.readable = readable;
4523
- this.writable = writable;
4522
+ this.readable = readable2;
4523
+ this.writable = writable2;
4524
4524
  this.append = append;
4525
4525
  }
4526
4526
  get path() {
@@ -4602,9 +4602,9 @@ function entryOf(info) {
4602
4602
  function openAccess(existing, oflags, rights) {
4603
4603
  const readonly = existing?.readonly === true;
4604
4604
  const mutating = readonly ? OFLAGS.TRUNC : OFLAGS.CREAT | OFLAGS.TRUNC;
4605
- const writable = (rights & RIGHTS.FD_WRITE) !== 0n || (oflags & mutating) !== 0;
4606
- if (writable && readonly) throw new WasiError("EROFS");
4607
- return { readable: (rights & RIGHTS.FD_READ) !== 0n || !writable, writable };
4605
+ const writable2 = (rights & RIGHTS.FD_WRITE) !== 0n || (oflags & mutating) !== 0;
4606
+ if (writable2 && readonly) throw new WasiError("EROFS");
4607
+ return { readable: (rights & RIGHTS.FD_READ) !== 0n || !writable2, writable: writable2 };
4608
4608
  }
4609
4609
  function promoteRequest(fd, f, handed) {
4610
4610
  const orphan = f.buffer.isOrphan();
@@ -5035,13 +5035,17 @@ var init_wasi_fds = __esm({
5035
5035
  if (oflags & OFLAGS.DIRECTORY && !s?.isDirectory) {
5036
5036
  throw new WasiError(s ? "ENOTDIR" : "ENOENT");
5037
5037
  }
5038
- if (s?.isDirectory) return this.install({ type: "dir", path });
5038
+ if (s?.isDirectory) {
5039
+ const asked = (oflags & OFLAGS.DIRECTORY) === 0 && (rights & RIGHTS.FD_WRITE) !== 0n;
5040
+ if (asked || (oflags & (OFLAGS.CREAT | OFLAGS.TRUNC)) !== 0) throw new WasiError("EISDIR");
5041
+ return this.install({ type: "dir", path });
5042
+ }
5039
5043
  if (!s && !(oflags & OFLAGS.CREAT)) throw new WasiError("ENOENT");
5040
5044
  if (this.shared) return this.kernelFile(path, s, oflags, rights, fdflags);
5041
5045
  return this.install({ type: "file", file: this.file(path, s, oflags, rights, fdflags) });
5042
5046
  }
5043
5047
  file(path, existing, oflags, rights, fdflags) {
5044
- const { readable, writable } = openAccess(existing, oflags, rights);
5048
+ const { readable: readable2, writable: writable2 } = openAccess(existing, oflags, rights);
5045
5049
  let buffer = this.buffers.get(path);
5046
5050
  if (buffer) {
5047
5051
  if (oflags & OFLAGS.TRUNC) buffer.truncate(0);
@@ -5056,12 +5060,12 @@ var init_wasi_fds = __esm({
5056
5060
  this.fs.hold?.(path, true, true);
5057
5061
  }
5058
5062
  buffer.opens++;
5059
- return new LocalFile(buffer, readable, writable, (fdflags & FDFLAGS.APPEND) !== 0);
5063
+ return new LocalFile(buffer, readable2, writable2, (fdflags & FDFLAGS.APPEND) !== 0);
5060
5064
  }
5061
5065
  kernelFile(path, existing, oflags, rights, fdflags) {
5062
- const { readable, writable } = openAccess(existing, oflags, rights);
5066
+ const { readable: readable2, writable: writable2 } = openAccess(existing, oflags, rights);
5063
5067
  const append = (fdflags & FDFLAGS.APPEND) !== 0;
5064
- const flags = (writable ? readable ? O_RDWR4 : O_WRONLY4 : 0) | (append ? O_APPEND : 0);
5068
+ const flags = (writable2 ? readable2 ? O_RDWR4 : O_WRONLY4 : 0) | (append ? O_APPEND : 0);
5065
5069
  const made = !existing && this.createNew(path, oflags);
5066
5070
  const truncate = made || (oflags & OFLAGS.TRUNC) !== 0;
5067
5071
  const fd = this.kernel.sys.openVfs(path, flags, 0, truncate ? { truncate } : {});
@@ -6843,8 +6847,8 @@ var init_wasix_process = __esm({
6843
6847
  ];
6844
6848
  return { stdio, inherit, cwd, opened };
6845
6849
  }
6846
- applyFdOp(op, slots, cwd) {
6847
- const { map, nulls, opened } = slots;
6850
+ applyFdOp(op, slots2, cwd) {
6851
+ const { map, nulls, opened } = slots2;
6848
6852
  const { fds } = this.host;
6849
6853
  const point = (fd, kfd) => {
6850
6854
  if (kfd === void 0) {
@@ -8207,6 +8211,17 @@ var init_async_sab = __esm({
8207
8211
  });
8208
8212
 
8209
8213
  // src/process/js/js-kernel.ts
8214
+ function untilAborted(work, signal) {
8215
+ if (!signal) return work;
8216
+ return new Promise((resolve) => {
8217
+ const done = () => {
8218
+ signal.removeEventListener("abort", done);
8219
+ resolve();
8220
+ };
8221
+ signal.addEventListener("abort", done, { once: true });
8222
+ work.then(done, done);
8223
+ });
8224
+ }
8210
8225
  var JsCallError, JsKernel;
8211
8226
  var init_js_kernel = __esm({
8212
8227
  "src/process/js/js-kernel.ts"() {
@@ -8258,20 +8273,24 @@ var init_js_kernel = __esm({
8258
8273
  const result = await this.call(req);
8259
8274
  return result.ok && result.kind === "bytes" ? result.bytes : new Uint8Array(0);
8260
8275
  }
8261
- async blocking(req) {
8276
+ async blocking(req, signal) {
8262
8277
  for (; ; ) {
8263
8278
  const id = await this.json({ op: "async-submit", req });
8264
- const result = await this.settled(id);
8279
+ const result = await this.settled(id, signal);
8265
8280
  if (result.ok) return result;
8266
8281
  if (result.errno !== "EINTR") throw new JsCallError(result.errno, req.op);
8267
8282
  }
8268
8283
  }
8269
- async settled(id) {
8284
+ async settled(id, signal) {
8270
8285
  for (; ; ) {
8271
8286
  const seen = Atomics.load(this.header, SAB_I_ASYNC);
8272
8287
  const taken = await this.raw({ op: "async-take", id });
8273
8288
  if (taken.ok || taken.errno !== "EAGAIN") return taken;
8274
- await changed(this.header, SAB_I_ASYNC, seen, this.waitAsync);
8289
+ if (signal?.aborted) {
8290
+ await this.raw({ op: "async-cancel", id });
8291
+ throw signal.reason;
8292
+ }
8293
+ await untilAborted(changed(this.header, SAB_I_ASYNC, seen, this.waitAsync), signal);
8275
8294
  }
8276
8295
  }
8277
8296
  deliver() {
@@ -8344,6 +8363,125 @@ var init_js_kernel = __esm({
8344
8363
  }
8345
8364
  });
8346
8365
 
8366
+ // src/process/js/js-children.ts
8367
+ function exitedOf(status2) {
8368
+ const signal = status2 & 127;
8369
+ return signal ? { status: 128 + signal, signal } : { status: status2 >> 8 & 255 };
8370
+ }
8371
+ function readable(io, fd) {
8372
+ const cancelled = new AbortController();
8373
+ return new ReadableStream(
8374
+ {
8375
+ async pull(controller) {
8376
+ const chunk = await io.read(fd, void 0, cancelled.signal).catch((err) => {
8377
+ if (cancelled.signal.aborted) return void 0;
8378
+ throw err;
8379
+ });
8380
+ if (chunk === void 0) return;
8381
+ if (chunk.length > 0) {
8382
+ controller.enqueue(chunk);
8383
+ return;
8384
+ }
8385
+ controller.close();
8386
+ await io.close(fd);
8387
+ },
8388
+ cancel: () => {
8389
+ cancelled.abort();
8390
+ return io.close(fd);
8391
+ }
8392
+ },
8393
+ { highWaterMark: 0 }
8394
+ );
8395
+ }
8396
+ function writable(io, fd) {
8397
+ return new WritableStream({
8398
+ write: (chunk, controller) => io.send(fd, chunk, controller.signal),
8399
+ close: () => io.close(fd),
8400
+ abort: () => io.close(fd)
8401
+ });
8402
+ }
8403
+ function childOps(kernel, io, defaults) {
8404
+ const wait = async (pid) => {
8405
+ const r = await kernel.blocking({ op: "proc-wait", pid, nohang: false });
8406
+ const [, status2] = r.ok && r.kind === "json" ? r.json : [0, 0];
8407
+ return exitedOf(status2);
8408
+ };
8409
+ const kill = async (pid, signal = SIGTERM) => {
8410
+ await kernel.call({ op: "proc-kill", pid, sig: signal === 0 ? 0 : defaults.signal(signal) });
8411
+ };
8412
+ const childOf = (pid, mine) => {
8413
+ const [stdin, stdout, stderr] = mine;
8414
+ return {
8415
+ pid,
8416
+ ...stdin !== void 0 ? { stdin: writable(io, stdin) } : {},
8417
+ ...stdout !== void 0 ? { stdout: readable(io, stdout) } : {},
8418
+ ...stderr !== void 0 ? { stderr: readable(io, stderr) } : {},
8419
+ wait: () => wait(pid),
8420
+ kill: (signal) => kill(pid, signal)
8421
+ };
8422
+ };
8423
+ const spawn = async (o) => {
8424
+ const [file] = o.argv;
8425
+ if (file === void 0) throw new JsCallError("EINVAL", "spawn");
8426
+ const mine = [];
8427
+ const theirs = [];
8428
+ try {
8429
+ const stdio = await slots(kernel, o, mine, theirs);
8430
+ const pid = await kernel.json({
8431
+ op: "proc-spawn",
8432
+ file,
8433
+ argv: [...o.argv],
8434
+ env: { ...o.env ?? defaults.env },
8435
+ cwd: o.cwd ?? defaults.cwd,
8436
+ stdio
8437
+ });
8438
+ return childOf(pid, mine);
8439
+ } catch (err) {
8440
+ await closeAll(io, mine);
8441
+ throw err;
8442
+ } finally {
8443
+ await closeAll(io, theirs);
8444
+ }
8445
+ };
8446
+ return { spawn, wait, kill };
8447
+ }
8448
+ async function closeAll(io, fds) {
8449
+ for (const fd of fds) if (fd !== void 0) await io.close(fd).catch(() => void 0);
8450
+ }
8451
+ async function preflight(kernel, hows) {
8452
+ for (const [n, how] of hows.entries()) {
8453
+ if (how === "pipe" || how === "null") continue;
8454
+ if (how !== "inherit" && typeof how !== "number") throw new JsCallError("EINVAL", "spawn");
8455
+ await kernel.json({ op: "fd-info", fd: how === "inherit" ? n : how });
8456
+ }
8457
+ }
8458
+ async function slots(kernel, o, mine, theirs) {
8459
+ const hows = STDIO2.map((name) => o[name] ?? "inherit");
8460
+ await preflight(kernel, hows);
8461
+ const stdio = [];
8462
+ for (const [n, how] of hows.entries()) {
8463
+ if (how === "inherit") stdio.push({ fd: n });
8464
+ else if (how === "null") stdio.push({ none: true });
8465
+ else if (typeof how === "number") stdio.push({ fd: how });
8466
+ else {
8467
+ const [read, write] = await kernel.json({ op: "fd-pipe" });
8468
+ mine[n] = n === 0 ? write : read;
8469
+ theirs.push(n === 0 ? read : write);
8470
+ stdio.push({ fd: n === 0 ? read : write });
8471
+ }
8472
+ }
8473
+ return stdio;
8474
+ }
8475
+ var STDIO2, SIGTERM;
8476
+ var init_js_children = __esm({
8477
+ "src/process/js/js-children.ts"() {
8478
+ "use strict";
8479
+ init_js_kernel();
8480
+ STDIO2 = ["stdin", "stdout", "stderr"];
8481
+ SIGTERM = 15;
8482
+ }
8483
+ });
8484
+
8347
8485
  // src/process/js/js-io.ts
8348
8486
  function typeOf(info) {
8349
8487
  if (info.meta && "dir" in info.meta) return "directory";
@@ -8708,22 +8846,20 @@ function createContext(o) {
8708
8846
  infos.set(fd, got);
8709
8847
  return got;
8710
8848
  };
8711
- const read = async (fd, max = CHUNK) => {
8849
+ const read = async (fd, max = CHUNK, signal) => {
8712
8850
  index(max, "read");
8713
8851
  const emulated = readDevice(await info(fd), max, random);
8714
8852
  if (emulated) return emulated;
8715
- const r = await kernel.blocking({ op: "fd-read", fd, max: Math.min(max, MAX_IO) });
8716
- return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
8853
+ return readPipe(kernel, fd, Math.min(max, MAX_IO), signal);
8717
8854
  };
8718
- const writeAll = async (fd, data) => {
8855
+ const writeAll = async (fd, data, signal) => {
8719
8856
  const i = await info(fd);
8720
8857
  if (writeDevice(i)) return;
8721
8858
  let at = 0;
8722
8859
  while (at < data.length) {
8723
8860
  const body = data.subarray(at, at + MAX_IO);
8724
8861
  try {
8725
- const r = await kernel.blocking({ op: "fd-write", fd, body });
8726
- at += written(r, body.length);
8862
+ at += signal ? await sendSome(kernel, fd, body, signal) : written(await kernel.blocking({ op: "fd-write", fd, body }), body.length);
8727
8863
  } catch (err) {
8728
8864
  if (brokenPipe(err, i)) await kernel.call({ op: "proc-kill", pid: o.pid, sig: SIG.PIPE });
8729
8865
  throw err;
@@ -8744,7 +8880,7 @@ function createContext(o) {
8744
8880
  }
8745
8881
  })();
8746
8882
  };
8747
- const writable = (fd) => new WritableStream({ write: (chunk) => write(fd, chunk) });
8883
+ const writable2 = (fd) => new WritableStream({ write: (chunk) => write(fd, chunk) });
8748
8884
  const statOf = async (op, path) => {
8749
8885
  const abs = resolve(path);
8750
8886
  await kernel.call({ op: "fd-path-flush", path: abs });
@@ -8779,6 +8915,11 @@ function createContext(o) {
8779
8915
  infos,
8780
8916
  handles
8781
8917
  });
8918
+ const children = childOps(
8919
+ kernel,
8920
+ { read, send: writeAll, close: (fd) => ctx.close(fd) },
8921
+ { env: o.env, cwd: o.cwd, signal: signalNumber }
8922
+ );
8782
8923
  const ctx = {
8783
8924
  argv: o.argv,
8784
8925
  env: o.env,
@@ -8797,8 +8938,8 @@ function createContext(o) {
8797
8938
  },
8798
8939
  { highWaterMark: 0 }
8799
8940
  ),
8800
- stdout: writable(1),
8801
- stderr: writable(2),
8941
+ stdout: writable2(1),
8942
+ stderr: writable2(2),
8802
8943
  read,
8803
8944
  write,
8804
8945
  async close(fd) {
@@ -8821,6 +8962,7 @@ function createContext(o) {
8821
8962
  reset: async (signal) => kernel.setHandler(signalNumber(signal), "default")
8822
8963
  },
8823
8964
  sync,
8965
+ ...children,
8824
8966
  exit
8825
8967
  };
8826
8968
  const drain2 = async () => {
@@ -8897,6 +9039,29 @@ function fileHandle(kernel, fd, path, append, forget) {
8897
9039
  }
8898
9040
  };
8899
9041
  }
9042
+ async function readPipe(kernel, fd, max, signal) {
9043
+ if (signal) return receiveSome(kernel, fd, max, signal);
9044
+ const r = await kernel.blocking({ op: "fd-read", fd, max });
9045
+ return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
9046
+ }
9047
+ async function receiveSome(kernel, fd, max, signal) {
9048
+ for (; ; ) {
9049
+ signal.throwIfAborted();
9050
+ const r = await kernel.raw({ op: "fd-read", fd, max, nonblock: true });
9051
+ if (r.ok) return r.kind === "bytes" ? r.bytes : new Uint8Array(0);
9052
+ if (r.errno !== "EAGAIN") throw new JsCallError(r.errno, "fd-read");
9053
+ await kernel.blocking({ op: "fd-select", read: [fd], write: [], timeoutMs: -1 }, signal);
9054
+ }
9055
+ }
9056
+ async function sendSome(kernel, fd, body, signal) {
9057
+ for (; ; ) {
9058
+ signal.throwIfAborted();
9059
+ const r = await kernel.raw({ op: "fd-write", fd, body, nonblock: true });
9060
+ if (r.ok) return written(r, body.length);
9061
+ if (r.errno !== "EAGAIN") throw new JsCallError(r.errno, "fd-write");
9062
+ await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
9063
+ }
9064
+ }
8900
9065
  function pathOps(kernel, resolve, statOf, open) {
8901
9066
  return {
8902
9067
  stat: (path) => statOf("stat", path),
@@ -8930,6 +9095,7 @@ var init_js_context = __esm({
8930
9095
  "use strict";
8931
9096
  init_signals();
8932
9097
  init_sync_fs_wire();
9098
+ init_js_children();
8933
9099
  init_js_io();
8934
9100
  init_js_kernel();
8935
9101
  init_js_sync();