@ai-ecoverse/slicc-kernel 1.48.0 → 1.48.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.
@@ -1673,7 +1673,7 @@ function ptyStat(path) {
1673
1673
  function nonblocking(stream) {
1674
1674
  return (stream.flags & O_NONBLOCK) !== 0 ? { nonblock: true } : void 0;
1675
1675
  }
1676
- var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
1676
+ var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
1677
1677
  var init_kernel_streams = __esm({
1678
1678
  "src/process/kernel-streams.ts"() {
1679
1679
  "use strict";
@@ -1684,6 +1684,7 @@ var init_kernel_streams = __esm({
1684
1684
  POLLHUP = 16;
1685
1685
  POLLRDNORM = 64;
1686
1686
  POLLWRNORM = 256;
1687
+ TCSETSF = 21508;
1687
1688
  O_NONBLOCK = 2048;
1688
1689
  SOCKET_MODE = 49663;
1689
1690
  PTY_PATH = /^\/dev\/(?:ptmx|pts\/(\d+))$/;
@@ -1802,8 +1803,8 @@ var init_kernel_streams = __esm({
1802
1803
  return {
1803
1804
  ops: {
1804
1805
  ioctl_tcgets: () => this.call(() => this.sys.tcgets?.(kfd)),
1805
- ioctl_tcsets: (_tty, _op, termios) => this.call(() => {
1806
- this.sys.tcsets?.(kfd, termios);
1806
+ ioctl_tcsets: (_tty, op, termios) => this.call(() => {
1807
+ this.sys.tcsets?.(kfd, termios, op === TCSETSF);
1807
1808
  return 0;
1808
1809
  }),
1809
1810
  ioctl_tiocgwinsz: () => this.call(() => this.sys.winsize?.(kfd) ?? [24, 80]),
@@ -3926,8 +3927,8 @@ function kernelSys(transport) {
3926
3927
  tcgets(fd) {
3927
3928
  return json(call2({ op: "tty-get", fd }, `tty-get ${fd}`));
3928
3929
  },
3929
- tcsets(fd, termios) {
3930
- call2({ op: "tty-set", fd, termios }, `tty-set ${fd}`);
3930
+ tcsets(fd, termios, flush) {
3931
+ call2({ op: "tty-set", fd, termios, ...flush ? { flush } : {} }, `tty-set ${fd}`);
3931
3932
  },
3932
3933
  winsize(fd) {
3933
3934
  return json(call2({ op: "tty-winsz", fd }, `tty-winsz ${fd}`));
@@ -5499,7 +5500,7 @@ function sliccTty(mem, fds, kernel) {
5499
5500
  if (actions < 0 || actions > TCSAFLUSH) throw new WasiError("EINVAL");
5500
5501
  const at = terminal(fd);
5501
5502
  needs(sys.tcsets);
5502
- sys.tcsets?.(at, readTermios(mem, ptr));
5503
+ sys.tcsets?.(at, readTermios(mem, ptr), actions === TCSAFLUSH);
5503
5504
  };
5504
5505
  const size = (fd, ptr) => {
5505
5506
  const [rows, cols] = needs(sys.winsize?.(terminal(fd)));
@@ -5778,8 +5779,8 @@ var init_wasi_host = __esm({
5778
5779
  return BigInt(Math.round((performance.now() - this.started) * 1e6)) + 1n;
5779
5780
  }
5780
5781
  environ() {
5781
- const listen = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
5782
- const env = { PWD: this.cwd, ...this.o.env, ...listen };
5782
+ const listen2 = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
5783
+ const env = { PWD: this.cwd, ...this.o.env, ...listen2 };
5783
5784
  return Object.entries(env).map(([k, v]) => `${k}=${v}`);
5784
5785
  }
5785
5786
  processImports() {
@@ -6315,7 +6316,7 @@ function restarted2(issue) {
6315
6316
  function resolveFrom(cwd, path) {
6316
6317
  return normalize(path.startsWith("/") ? path : `${cwd}/${path}`);
6317
6318
  }
6318
- var O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUNC, WasixProcess;
6319
+ var O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUNC, JOIN_NON_BLOCKING, JOIN_WAKE_STOPPED, JOIN_STOPPED, WasixProcess;
6319
6320
  var init_wasix_process = __esm({
6320
6321
  "src/process/wasi/wasix-process.ts"() {
6321
6322
  "use strict";
@@ -6327,6 +6328,9 @@ var init_wasix_process = __esm({
6327
6328
  O_APPEND2 = 1024;
6328
6329
  OFLAG_CREAT = 1;
6329
6330
  OFLAG_TRUNC = 8;
6331
+ JOIN_NON_BLOCKING = 1;
6332
+ JOIN_WAKE_STOPPED = 2;
6333
+ JOIN_STOPPED = 3;
6330
6334
  WasixProcess = class {
6331
6335
  host;
6332
6336
  driver;
@@ -6456,13 +6460,21 @@ var init_wasix_process = __esm({
6456
6460
  const v = this.host.mem.view();
6457
6461
  const pid = v.getUint8(pidPtr) === 1 ? v.getUint32(pidPtr + 4, true) : -1;
6458
6462
  this.host.mem.bytes(statusPtr, 6).fill(0);
6459
- const [child, status2] = this.call({ op: "proc-wait", pid, nohang: (flags & 1) !== 0 });
6463
+ const [child, status2] = this.call({
6464
+ op: "proc-wait",
6465
+ pid,
6466
+ nohang: (flags & JOIN_NON_BLOCKING) !== 0,
6467
+ ...flags & JOIN_WAKE_STOPPED ? { untraced: true } : {}
6468
+ });
6460
6469
  if (child === 0) return;
6461
6470
  this.host.o.fs.invalidate?.();
6462
6471
  v.setUint8(pidPtr, 1);
6463
6472
  v.setUint32(pidPtr + 4, child, true);
6464
6473
  const sig = status2 & 127;
6465
- if (sig) {
6474
+ if (sig === 127) {
6475
+ v.setUint8(statusPtr, JOIN_STOPPED);
6476
+ v.setUint8(statusPtr + 2, status2 >> 8 & 255);
6477
+ } else if (sig) {
6466
6478
  v.setUint8(statusPtr, 2);
6467
6479
  v.setUint8(statusPtr + 4, sig);
6468
6480
  } else {
@@ -8989,6 +9001,56 @@ function latin1(bytes) {
8989
9001
  }
8990
9002
  return text;
8991
9003
  }
9004
+ function quoted(input, from) {
9005
+ let value2 = "";
9006
+ let at = from + 1;
9007
+ while (at < input.length) {
9008
+ const char = input[at++];
9009
+ if (char === '"') break;
9010
+ if (char !== "\\") value2 += char;
9011
+ else if (at < input.length) value2 += input[at++];
9012
+ else value2 += char;
9013
+ }
9014
+ return [value2, at];
9015
+ }
9016
+ function parameter(text, from, params) {
9017
+ let at = from + 1;
9018
+ while (SPACE.test(text[at] ?? "")) at++;
9019
+ let end = at;
9020
+ while (end < text.length && text[end] !== ";" && text[end] !== "=") end++;
9021
+ const name = text.slice(at, end).toLowerCase();
9022
+ if (text[end] !== "=") return end;
9023
+ const start2 = end + 1;
9024
+ let value2;
9025
+ if (text[start2] === '"') {
9026
+ [value2, at] = quoted(text, start2);
9027
+ end = text.indexOf(";", at);
9028
+ } else {
9029
+ end = text.indexOf(";", start2);
9030
+ value2 = text.slice(start2, end < 0 ? void 0 : end).replace(/[\t\n\r ]+$/, "");
9031
+ if (!value2) return end < 0 ? text.length : end;
9032
+ }
9033
+ if (end < 0) end = text.length;
9034
+ if (TOKEN.test(name) && QUOTABLE.test(value2) && !params.has(name)) {
9035
+ params.set(name, value2);
9036
+ }
9037
+ return end;
9038
+ }
9039
+ function mimeType(input) {
9040
+ const text = input.replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
9041
+ const slash = text.indexOf("/");
9042
+ const semi = text.indexOf(";", slash);
9043
+ const type = text.slice(0, slash);
9044
+ const subtype = text.slice(slash + 1, semi < 0 ? void 0 : semi).replace(/[\t\n\r ]+$/, "");
9045
+ if (slash < 0 || !TOKEN.test(type) || !TOKEN.test(subtype)) return void 0;
9046
+ const params = /* @__PURE__ */ new Map();
9047
+ for (let at = semi < 0 ? text.length : semi; at < text.length; ) at = parameter(text, at, params);
9048
+ let out = `${type}/${subtype}`.toLowerCase();
9049
+ for (const [name, value2] of params) {
9050
+ out += `;${name}=${TOKEN.test(value2) ? value2 : `"${value2.replace(/["\\]/g, "\\$&")}"`}`;
9051
+ }
9052
+ return out;
9053
+ }
8992
9054
  function dataResponse(request) {
8993
9055
  const url = withoutFragment(new URL(request.url));
8994
9056
  const rest2 = url.slice("data:".length);
@@ -8998,7 +9060,7 @@ function dataResponse(request) {
8998
9060
  let body = percentDecode(rest2.slice(comma + 1));
8999
9061
  const base642 = BASE64.exec(type);
9000
9062
  if (base642) {
9001
- type = type.slice(0, base642.index).replace(/[\t\n\f\r ]+$/, "");
9063
+ type = type.slice(0, base642.index);
9002
9064
  let binary;
9003
9065
  try {
9004
9066
  binary = atob(latin1(body));
@@ -9008,11 +9070,10 @@ function dataResponse(request) {
9008
9070
  body = Uint8Array.from(binary, (c) => c.charCodeAt(0));
9009
9071
  }
9010
9072
  if (type.startsWith(";")) type = `text/plain${type}`;
9011
- if (!MIME.test(type)) type = "text/plain;charset=US-ASCII";
9012
- const response = new Response(body, {
9013
- status: 200,
9014
- headers: { "content-type": type }
9015
- });
9073
+ const response = new Response(
9074
+ request.method === "HEAD" ? null : body,
9075
+ { status: 200, headers: { "content-type": mimeType(type) ?? "text/plain;charset=US-ASCII" } }
9076
+ );
9016
9077
  return withMeta(response, url, false);
9017
9078
  }
9018
9079
  function withMeta(response, url, redirected) {
@@ -9200,7 +9261,7 @@ function fetchOp(kernel) {
9200
9261
  }
9201
9262
  };
9202
9263
  }
9203
- var CHUNK, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, MIME, BASE64, SLICE;
9264
+ var CHUNK, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, TOKEN, QUOTABLE, SPACE, BASE64, SLICE;
9204
9265
  var init_js_fetch = __esm({
9205
9266
  "src/process/js/js-fetch.ts"() {
9206
9267
  "use strict";
@@ -9219,7 +9280,9 @@ var init_js_fetch = __esm({
9219
9280
  DECODED = /* @__PURE__ */ new Set(["gzip", "x-gzip", "deflate"]);
9220
9281
  CREDENTIALS = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2"]);
9221
9282
  OVER = /* @__PURE__ */ Symbol("over");
9222
- MIME = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+(?:[\t ]*;.*)?$/s;
9283
+ TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
9284
+ QUOTABLE = /^[\t\x20-\x7e\x80-\xff]*$/;
9285
+ SPACE = /[\t\n\r ]/;
9223
9286
  BASE64 = /; *base64$/i;
9224
9287
  SLICE = 32768;
9225
9288
  }
@@ -9696,6 +9759,7 @@ function rawOf(termios) {
9696
9759
  }
9697
9760
  function ttyOps(kernel) {
9698
9761
  const saved = /* @__PURE__ */ new Map();
9762
+ const terminalOf = async (fd) => (await kernel.json({ op: "fd-info", fd })).terminal ?? `fd ${fd}`;
9699
9763
  const getAttr = async (fd) => await kernel.json({ op: "tty-get", fd });
9700
9764
  const setAttr = async (fd, termios) => {
9701
9765
  await kernel.call({ op: "tty-set", fd, termios: copy(termios) });
@@ -9704,14 +9768,15 @@ function ttyOps(kernel) {
9704
9768
  getAttr,
9705
9769
  setAttr,
9706
9770
  async setRaw(fd, raw) {
9771
+ const terminal = await terminalOf(fd);
9707
9772
  if (!raw) {
9708
- const original = saved.get(fd);
9709
- saved.delete(fd);
9710
- if (original) await setAttr(fd, original);
9773
+ const original = saved.get(terminal);
9774
+ saved.delete(terminal);
9775
+ if (original) await setAttr(fd, original.termios);
9711
9776
  return;
9712
9777
  }
9713
9778
  const current = await getAttr(fd);
9714
- if (!saved.has(fd)) saved.set(fd, current);
9779
+ if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current });
9715
9780
  await setAttr(fd, rawOf(current));
9716
9781
  },
9717
9782
  async size(fd) {
@@ -9724,9 +9789,9 @@ function ttyOps(kernel) {
9724
9789
  }
9725
9790
  };
9726
9791
  const restore = async () => {
9727
- for (const [fd, original] of [...saved].reverse()) {
9728
- saved.delete(fd);
9729
- await setAttr(fd, original).catch(() => void 0);
9792
+ for (const [terminal, { fd, termios }] of [...saved].reverse()) {
9793
+ saved.delete(terminal);
9794
+ await setAttr(fd, termios).catch(() => void 0);
9730
9795
  }
9731
9796
  };
9732
9797
  return { tty, restore };
@@ -9905,6 +9970,11 @@ var init_js_websocket = __esm({
9905
9970
  });
9906
9971
 
9907
9972
  // src/process/js/js-context.ts
9973
+ function listen(listeners, listener) {
9974
+ const own = (error, promise) => listener(error, promise);
9975
+ listeners.add(own);
9976
+ return () => void listeners.delete(own);
9977
+ }
9908
9978
  function identityOf(answer2, fallback) {
9909
9979
  const id = answer2;
9910
9980
  return {
@@ -10026,6 +10096,7 @@ function createContext(o) {
10026
10096
  const terminal = ttyOps(kernel);
10027
10097
  const io = { read, send: writeAll, close: (fd) => ctx.close(fd) };
10028
10098
  const children = childOps(kernel, io, { env: o.env, cwd: o.cwd, signal: signalNumber });
10099
+ const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
10029
10100
  const ctx = {
10030
10101
  argv: o.argv,
10031
10102
  env: o.env,
@@ -10073,7 +10144,9 @@ function createContext(o) {
10073
10144
  net: netOps(kernel, io),
10074
10145
  websocket: websocketOp(kernel),
10075
10146
  tty: terminal.tty,
10076
- exit
10147
+ exit,
10148
+ onUncaught: (listener) => listen(strays.exception, listener),
10149
+ onUnhandledRejection: (listener) => listen(strays.rejection, listener)
10077
10150
  };
10078
10151
  const drain2 = async () => {
10079
10152
  for (; ; ) {
@@ -10292,19 +10365,19 @@ __export(js_runtime_exports, {
10292
10365
  runJsProcess: () => runJsProcess,
10293
10366
  trapStrays: () => trapStrays
10294
10367
  });
10295
- function trapStrays(scope2, fail) {
10368
+ function trapStrays(scope2, stray) {
10296
10369
  if (typeof scope2.process?.on === "function") {
10297
- scope2.process.on("unhandledRejection", fail);
10298
- scope2.process.on("uncaughtException", fail);
10370
+ scope2.process.on("unhandledRejection", (err, promise) => stray("rejection", err, promise));
10371
+ scope2.process.on("uncaughtException", (err) => stray("exception", err));
10299
10372
  return;
10300
10373
  }
10301
10374
  scope2.addEventListener?.("unhandledrejection", (event) => {
10302
10375
  event.preventDefault();
10303
- fail(event.reason);
10376
+ stray("rejection", event.reason, event.promise);
10304
10377
  });
10305
10378
  scope2.addEventListener?.("error", (event) => {
10306
10379
  event.preventDefault();
10307
- fail(event.error);
10380
+ stray("exception", event.error);
10308
10381
  });
10309
10382
  }
10310
10383
  async function settledStrays() {
@@ -10341,6 +10414,7 @@ async function runJsProcess(init, port2, deps = {}) {
10341
10414
  waitAsync: deps.waitAsync
10342
10415
  });
10343
10416
  void kernel.watchStops();
10417
+ const strays = { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
10344
10418
  const id = identityOf(await kernel.json({ op: "proc-identity" }), init);
10345
10419
  kernel.pid = id.pid;
10346
10420
  const { ctx, drain: drain2 } = createContext({
@@ -10351,12 +10425,23 @@ async function runJsProcess(init, port2, deps = {}) {
10351
10425
  ppid: id.ppid,
10352
10426
  cwd: init.cwd,
10353
10427
  exit: (status3) => exited(statusOf(status3)),
10354
- lane: laneOf(init.lane)
10428
+ lane: laneOf(init.lane),
10429
+ strays
10355
10430
  });
10356
10431
  const say = (text) => ctx.write(2, `${init.argv0}: ${text}
10357
10432
  `).catch(() => void 0);
10358
10433
  let main;
10359
- trapStrays(deps.scope ?? globalThis, fail);
10434
+ trapStrays(deps.scope ?? globalThis, (kind, err, promise) => {
10435
+ const listeners = [...strays[kind]];
10436
+ if (listeners.length === 0) return fail(err);
10437
+ for (const listener of listeners) {
10438
+ try {
10439
+ listener(err, promise);
10440
+ } catch (thrown) {
10441
+ fail(thrown);
10442
+ }
10443
+ }
10444
+ });
10360
10445
  try {
10361
10446
  (deps.lockdown ?? lockdown)();
10362
10447
  main = mainOf(await (deps.load ?? importSource)(init.program.glue));