@ai-ecoverse/slicc-kernel 1.46.1 → 1.47.0

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.
@@ -2159,9 +2159,9 @@ function trackCloseOnExec(Fs) {
2159
2159
  if (typeof Fs.dupStream === "function") {
2160
2160
  const dupStream = Fs.dupStream.bind(Fs);
2161
2161
  Fs.dupStream = (stream, fd) => {
2162
- const copy = dupStream(stream, fd);
2163
- setCloseOnExec(copy, false);
2164
- return copy;
2162
+ const copy2 = dupStream(stream, fd);
2163
+ setCloseOnExec(copy2, false);
2164
+ return copy2;
2165
2165
  };
2166
2166
  }
2167
2167
  if (typeof Fs.open === "function") {
@@ -2184,9 +2184,9 @@ function cloexecFcntl(fcntl, deps) {
2184
2184
  const mark = marker(deps);
2185
2185
  return (fd, cmd, varargs) => {
2186
2186
  if (cmd === F_DUPFD_CLOEXEC) {
2187
- const copy = fcntl(fd, F_DUPFD, varargs);
2188
- if (copy >= 0) mark(copy, true);
2189
- return copy;
2187
+ const copy2 = fcntl(fd, F_DUPFD, varargs);
2188
+ if (copy2 >= 0) mark(copy2, true);
2189
+ return copy2;
2190
2190
  }
2191
2191
  if (cmd === F_GETFL) {
2192
2192
  const flags = fcntl(fd, cmd, varargs);
@@ -2596,9 +2596,9 @@ function useDevFd(Fs) {
2596
2596
  Fs.open = (path, flags, mode) => {
2597
2597
  const fd = fdOf(path);
2598
2598
  if (fd === void 0) return open(path, flags, mode);
2599
- const copy = Fs.dupStream(target(fd), -1);
2600
- setCloseOnExec(copy, typeof flags === "number" && (flags & O_CLOEXEC) !== 0);
2601
- return copy;
2599
+ const copy2 = Fs.dupStream(target(fd), -1);
2600
+ setCloseOnExec(copy2, typeof flags === "number" && (flags & O_CLOEXEC) !== 0);
2601
+ return copy2;
2602
2602
  };
2603
2603
  const { stat, fstat } = Fs;
2604
2604
  if (typeof stat !== "function" || typeof fstat !== "function") return;
@@ -3280,6 +3280,13 @@ var init_process_signals = __esm({
3280
3280
  this.quieted--;
3281
3281
  }
3282
3282
  }
3283
+ interrupt() {
3284
+ const header = this.header;
3285
+ const pending = Atomics.load(header, SAB_I_SIGNALS) | Atomics.load(header, SAB_I_TIMERS) | Atomics.load(header, SAB_I_KILLED);
3286
+ if (pending === 0) return false;
3287
+ this.deliver();
3288
+ return true;
3289
+ }
3283
3290
  deliver() {
3284
3291
  if (this.quieted > 0) return;
3285
3292
  const killed = Atomics.load(this.header, SAB_I_KILLED);
@@ -5539,6 +5546,7 @@ var init_wasi_host = __esm({
5539
5546
  onRaise;
5540
5547
  muted;
5541
5548
  signals;
5549
+ interrupted;
5542
5550
  listening;
5543
5551
  o;
5544
5552
  constructor(o) {
@@ -6644,7 +6652,7 @@ var init_wasi_module = __esm({
6644
6652
  });
6645
6653
 
6646
6654
  // src/process/wasi/wasi-signals.ts
6647
- var DELIVERED_MASK, STOP_DEFAULTS, LIBC_DEFAULT_EXIT, SA_RESTART, DISPOSITION_IGNORE, DISPOSITION_HANDLER, withBit, WASIX_LIBC_DEFAULT_LINE, WasiSignals;
6655
+ var DELIVERED_MASK, KERNEL_DEFAULTS, LIBC_DEFAULT_EXIT, SA_RESTART, DISPOSITION_IGNORE, DISPOSITION_HANDLER, withBit, WASIX_LIBC_DEFAULT_LINE, WasiSignals;
6648
6656
  var init_wasi_signals = __esm({
6649
6657
  "src/process/wasi/wasi-signals.ts"() {
6650
6658
  "use strict";
@@ -6652,7 +6660,7 @@ var init_wasi_signals = __esm({
6652
6660
  init_wasi_abi();
6653
6661
  init_wasi_host();
6654
6662
  DELIVERED_MASK = Object.values(SIG).filter((sig) => sig !== SIG.KILL && sig !== SIG.STOP).reduce((m, sig) => m | sigbit(sig), 0);
6655
- STOP_DEFAULTS = sigbit(SIG.TSTP) | sigbit(SIG.TTIN) | sigbit(SIG.TTOU);
6663
+ KERNEL_DEFAULTS = [SIG.TSTP, SIG.TTIN, SIG.TTOU, SIG.CHLD, SIG.CONT, SIG.URG, SIG.WINCH].map(sigbit).reduce((m, bit) => m | bit, 0);
6656
6664
  LIBC_DEFAULT_EXIT = 127;
6657
6665
  SA_RESTART = 268435456;
6658
6666
  DISPOSITION_IGNORE = 1;
@@ -6724,7 +6732,7 @@ var init_wasi_signals = __esm({
6724
6732
  return { caught, ignored: this.ignoring, restart: this.restarting, defaults };
6725
6733
  }
6726
6734
  if (!this.handler()) return null;
6727
- return { caught: DELIVERED_MASK & ~this.uncaught & ~STOP_DEFAULTS, ignored: 0, restart: 0 };
6735
+ return { caught: DELIVERED_MASK & ~this.uncaught & ~KERNEL_DEFAULTS, ignored: 0, restart: 0 };
6728
6736
  }
6729
6737
  raise(sig) {
6730
6738
  const handler = this.handler();
@@ -7545,6 +7553,16 @@ var init_wasix_sockets = __esm({
7545
7553
  });
7546
7554
 
7547
7555
  // src/process/wasi/wasix-host.ts
7556
+ function futexWait(view, index2, expected, ms, interrupted) {
7557
+ const deadline = performance.now() + ms;
7558
+ for (; ; ) {
7559
+ const slice = interrupted ? Math.min(FUTEX_SLICE_MS, ms) : ms;
7560
+ if (Atomics.wait(view, index2, expected, slice) !== "timed-out") return true;
7561
+ if (interrupted?.()) return true;
7562
+ ms = deadline - performance.now();
7563
+ if (ms <= 0) return false;
7564
+ }
7565
+ }
7548
7566
  function posixSignal(sig) {
7549
7567
  const posix = wasixSignal(sig);
7550
7568
  if (posix === void 0) throw new WasiError("EINVAL");
@@ -7553,7 +7571,7 @@ function posixSignal(sig) {
7553
7571
  function nsToMs(ns) {
7554
7572
  return Math.ceil(Number(ns) / 1e6);
7555
7573
  }
7556
- var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON, ECHO, WasixHost;
7574
+ var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON, ECHO, FUTEX_SLICE_MS, WasixHost;
7557
7575
  var init_wasix_host = __esm({
7558
7576
  "src/process/wasi/wasix-host.ts"() {
7559
7577
  "use strict";
@@ -7570,6 +7588,7 @@ var init_wasix_host = __esm({
7570
7588
  RIGHTS_FD_WRITE = 1n << 6n;
7571
7589
  ICANON = 2;
7572
7590
  ECHO = 8;
7591
+ FUTEX_SLICE_MS = 50;
7573
7592
  WasixHost = class _WasixHost {
7574
7593
  process;
7575
7594
  threads;
@@ -7856,7 +7875,7 @@ var init_wasix_host = __esm({
7856
7875
  if (!(this.threads?.known(tid) ?? tid === MAIN_TID)) throw new WasiError("ESRCH");
7857
7876
  const posix = posixSignal(sig);
7858
7877
  if (host.onRaise?.(posix)) return;
7859
- host.o.kernel.call({ op: "proc-kill", pid: host.o.pid, sig: posix });
7878
+ host.o.kernel.call({ op: "thread-kill", tid, sig: posix });
7860
7879
  },
7861
7880
  thread_spawn_v2: (startPtr, tidPtr) => {
7862
7881
  if (!this.threads) return E.NOTSUP;
@@ -7871,7 +7890,7 @@ var init_wasix_host = __esm({
7871
7890
  const ms = timed ? Number(v.getBigUint64(timeoutPtr + 8, true)) / 1e6 : Number.POSITIVE_INFINITY;
7872
7891
  v.setUint8(
7873
7892
  wokenPtr,
7874
- Atomics.wait(i32(), ptr >> 2, expected | 0, ms) === "timed-out" ? 0 : 1
7893
+ futexWait(i32(), ptr >> 2, expected | 0, ms, host.interrupted) ? 1 : 0
7875
7894
  );
7876
7895
  },
7877
7896
  futex_wake: (ptr, wokenPtr) => {
@@ -8092,20 +8111,20 @@ function newImportedMemory(spec) {
8092
8111
  });
8093
8112
  }
8094
8113
  }
8095
- function createImportedMemory(spec, copy) {
8114
+ function createImportedMemory(spec, copy2) {
8096
8115
  if (!spec) return void 0;
8097
8116
  const memory = newImportedMemory(spec);
8098
- if (copy) fillMemory(memory, copy);
8117
+ if (copy2) fillMemory(memory, copy2);
8099
8118
  return memory;
8100
8119
  }
8101
8120
  function restoreExportedMemory(instance, imported, init) {
8102
8121
  if (imported || !init.fork?.wasi) return;
8103
8122
  fillMemory(instance.exports.memory, init.fork.memory);
8104
8123
  }
8105
- function fillMemory(memory, copy) {
8106
- const pages2 = copy.byteLength / 65536 - memory.buffer.byteLength / 65536;
8124
+ function fillMemory(memory, copy2) {
8125
+ const pages2 = copy2.byteLength / 65536 - memory.buffer.byteLength / 65536;
8107
8126
  if (pages2 > 0) memory.grow(pages2);
8108
- new Uint8Array(memory.buffer).set(copy);
8127
+ new Uint8Array(memory.buffer).set(copy2);
8109
8128
  }
8110
8129
  function sizeOf(main) {
8111
8130
  return () => main.memory?.buffer.byteLength ?? 0;
@@ -8115,11 +8134,12 @@ function memoryOf(instance, imported) {
8115
8134
  }
8116
8135
  function kernelOf(init, port3, hooks = { masks: () => null, raise: () => {
8117
8136
  } }, memory) {
8118
- const transport = new SignalGate(
8137
+ const gate = new SignalGate(
8119
8138
  createSyncSabTransport(init.sab, port3, memory ? { memory } : {}),
8120
8139
  new Int32Array(init.sab, 0, SAB_HEADER_I32),
8121
8140
  hooks
8122
- ).transport();
8141
+ );
8142
+ const transport = gate.transport();
8123
8143
  const sys = kernelSys(transport);
8124
8144
  const call2 = (req) => {
8125
8145
  const r = transport.call(req, Number.POSITIVE_INFINITY, req.op);
@@ -8128,7 +8148,7 @@ function kernelOf(init, port3, hooks = { masks: () => null, raise: () => {
8128
8148
  };
8129
8149
  const say = (text) => sys.write(2, new TextEncoder().encode(`${init.argv0}: ${text}
8130
8150
  `));
8131
- return { transport, sys, call: call2, say };
8151
+ return { transport, sys, call: call2, say, gate };
8132
8152
  }
8133
8153
  function traced(stats, tag, table) {
8134
8154
  return stats ? stats.wrap(tag, table) : table;
@@ -8243,16 +8263,19 @@ function descriptors(init, fork, threads) {
8243
8263
  async function runWasiProcess(init, port3) {
8244
8264
  captureBacktraces(init.env);
8245
8265
  const signals = new WasiSignals(
8246
- (sig) => {
8247
- call2({ op: "proc-kill", pid: init.pid, sig });
8248
- if (defaultAction(sig) === "terminate") throw new WasiExit(128 + sig);
8249
- },
8266
+ takeDefault((req) => call2(req), init.pid),
8250
8267
  (code2) => {
8251
8268
  throw new WasiExit(code2);
8252
8269
  }
8253
8270
  );
8254
8271
  const main = {};
8255
- const { transport, sys, call: kernelCall, say } = kernelOf(init, port3, signals, sizeOf(main));
8272
+ const {
8273
+ transport,
8274
+ sys,
8275
+ call: kernelCall,
8276
+ say,
8277
+ gate
8278
+ } = kernelOf(init, port3, signals, sizeOf(main));
8256
8279
  const id = identify(transport, init);
8257
8280
  const stats = init.env.SLICC_WASI_STATS === "1" ? new WasiStats() : void 0;
8258
8281
  const call2 = stats ? timedCalls(stats, kernelCall) : kernelCall;
@@ -8300,6 +8323,7 @@ async function runWasiProcess(init, port3) {
8300
8323
  if (importsSigactionHook(module)) signals.useHook();
8301
8324
  if (fork?.signals) signals.restore(fork.signals);
8302
8325
  host.signals = signals;
8326
+ host.interrupted = () => gate.interrupt();
8303
8327
  host.onRaise = (sig) => signals.raised(sig);
8304
8328
  host.muted = (fd, data) => signals.muted(fd, data);
8305
8329
  const exports = instance.exports;
@@ -8350,8 +8374,12 @@ function captureBacktraces(env) {
8350
8374
  }
8351
8375
  async function runWasiThread(init, port3) {
8352
8376
  captureBacktraces(init.env);
8353
- const { transport, sys, call: call2, say } = kernelOf(init, port3);
8354
8377
  const { thread } = init;
8378
+ const { transport, sys, call: call2, say, gate } = kernelOf(init, port3, {
8379
+ masks: () => null,
8380
+ raise: (sig) => signals.raise(sig)
8381
+ });
8382
+ const signals = new WasiSignals(takeDefault(call2, init.pid));
8355
8383
  const threads = new WasiThreads(port3, thread.memory, threadCap(init.env), thread.tid, thread.ids);
8356
8384
  threads.received = thread.modules;
8357
8385
  const id = identify(transport, init);
@@ -8372,6 +8400,10 @@ async function runWasiThread(init, port3) {
8372
8400
  foreign: init.program.foreign,
8373
8401
  ...program ? { program } : {}
8374
8402
  });
8403
+ signals.bind(instance.exports);
8404
+ signals.register(SIGNAL_CALLBACK);
8405
+ host.interrupted = () => gate.interrupt();
8406
+ host.onRaise = (sig) => signals.raised(sig);
8375
8407
  const start2 = instance.exports.wasi_thread_start;
8376
8408
  try {
8377
8409
  start2(thread.tid, thread.arg);
@@ -8396,7 +8428,7 @@ async function runWasiThread(init, port3) {
8396
8428
  throw e;
8397
8429
  }
8398
8430
  }
8399
- var TRAPPED, PREVIEW1, WASIX, SLICC, SLICC_FS, RESERVED2, importsSigactionHook, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
8431
+ var TRAPPED, PREVIEW1, WASIX, SLICC, SIGNAL_CALLBACK, takeDefault, SLICC_FS, RESERVED2, importsSigactionHook, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
8400
8432
  var init_wasi_runtime = __esm({
8401
8433
  "src/process/wasi/wasi-runtime.ts"() {
8402
8434
  "use strict";
@@ -8423,6 +8455,11 @@ var init_wasi_runtime = __esm({
8423
8455
  PREVIEW1 = "wasi_snapshot_preview1";
8424
8456
  WASIX = "wasix_32v1";
8425
8457
  SLICC = "slicc";
8458
+ SIGNAL_CALLBACK = "__wasm_signal";
8459
+ takeDefault = (call2, pid) => (sig) => {
8460
+ call2({ op: "proc-kill", pid, sig });
8461
+ if (defaultAction(sig) === "terminate") throw new WasiExit(128 + sig);
8462
+ };
8426
8463
  SLICC_FS = "slicc_fs";
8427
8464
  RESERVED2 = RESERVED_NAMESPACES;
8428
8465
  importsSigactionHook = (module) => WebAssembly.Module.imports(module).some((i) => i.module === SLICC && i.name === "sigaction_set");
@@ -9503,6 +9540,77 @@ var init_js_sync = __esm({
9503
9540
  }
9504
9541
  });
9505
9542
 
9543
+ // src/process/js/js-tty.ts
9544
+ function copy(termios) {
9545
+ return { ...termios, c_cc: [...termios.c_cc] };
9546
+ }
9547
+ function rawOf(termios) {
9548
+ const raw = copy(termios);
9549
+ raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
9550
+ raw.c_oflag |= ONLCR;
9551
+ raw.c_cflag |= CS8;
9552
+ raw.c_lflag &= ~(ECHO2 | ICANON2 | IEXTEN | ISIG);
9553
+ raw.c_cc[VMIN] = 1;
9554
+ raw.c_cc[VTIME] = 0;
9555
+ return raw;
9556
+ }
9557
+ function ttyOps(kernel) {
9558
+ const saved = /* @__PURE__ */ new Map();
9559
+ const getAttr = async (fd) => await kernel.json({ op: "tty-get", fd });
9560
+ const setAttr = async (fd, termios) => {
9561
+ await kernel.call({ op: "tty-set", fd, termios: copy(termios) });
9562
+ };
9563
+ const tty = {
9564
+ getAttr,
9565
+ setAttr,
9566
+ async setRaw(fd, raw) {
9567
+ if (!raw) {
9568
+ const original = saved.get(fd);
9569
+ saved.delete(fd);
9570
+ if (original) await setAttr(fd, original);
9571
+ return;
9572
+ }
9573
+ const current = await getAttr(fd);
9574
+ if (!saved.has(fd)) saved.set(fd, current);
9575
+ await setAttr(fd, rawOf(current));
9576
+ },
9577
+ async size(fd) {
9578
+ const [rows, columns] = await kernel.json({ op: "tty-winsz", fd });
9579
+ return { columns, rows };
9580
+ },
9581
+ foreground: async (fd) => await kernel.json({ op: "tty-pgrp-get", fd }),
9582
+ async setForeground(fd, pgrp) {
9583
+ await kernel.call({ op: "tty-pgrp-set", fd, pgrp });
9584
+ }
9585
+ };
9586
+ const restore = async () => {
9587
+ for (const [fd, original] of [...saved]) {
9588
+ saved.delete(fd);
9589
+ await setAttr(fd, original).catch(() => void 0);
9590
+ }
9591
+ };
9592
+ return { tty, restore };
9593
+ }
9594
+ var BRKINT, INPCK, ISTRIP, ICRNL, IXON, ONLCR, CS8, ISIG, ICANON2, ECHO2, IEXTEN, VTIME, VMIN;
9595
+ var init_js_tty = __esm({
9596
+ "src/process/js/js-tty.ts"() {
9597
+ "use strict";
9598
+ BRKINT = 2;
9599
+ INPCK = 16;
9600
+ ISTRIP = 32;
9601
+ ICRNL = 256;
9602
+ IXON = 1024;
9603
+ ONLCR = 4;
9604
+ CS8 = 48;
9605
+ ISIG = 1;
9606
+ ICANON2 = 2;
9607
+ ECHO2 = 8;
9608
+ IEXTEN = 32768;
9609
+ VTIME = 5;
9610
+ VMIN = 6;
9611
+ }
9612
+ });
9613
+
9506
9614
  // src/process/js/js-websocket.ts
9507
9615
  function failed3(err) {
9508
9616
  return new TypeError("websocket failed", { cause: err });
@@ -9775,6 +9883,7 @@ function createContext(o) {
9775
9883
  infos,
9776
9884
  handles
9777
9885
  });
9886
+ const terminal = ttyOps(kernel);
9778
9887
  const io = { read, send: writeAll, close: (fd) => ctx.close(fd) };
9779
9888
  const children = childOps(kernel, io, { env: o.env, cwd: o.cwd, signal: signalNumber });
9780
9889
  const ctx = {
@@ -9823,14 +9932,16 @@ function createContext(o) {
9823
9932
  ...children,
9824
9933
  net: netOps(kernel, io),
9825
9934
  websocket: websocketOp(kernel),
9935
+ tty: terminal.tty,
9826
9936
  exit
9827
9937
  };
9828
9938
  const drain2 = async () => {
9829
9939
  for (; ; ) {
9830
9940
  await Promise.all([...pending]);
9831
9941
  await new Promise((resolve2) => setTimeout(resolve2, 0));
9832
- if (pending.size === 0) return;
9942
+ if (pending.size === 0) break;
9833
9943
  }
9944
+ await terminal.restore();
9834
9945
  };
9835
9946
  return { ctx, drain: drain2 };
9836
9947
  }
@@ -9961,6 +10072,7 @@ var init_js_context = __esm({
9961
10072
  init_js_kernel();
9962
10073
  init_js_net();
9963
10074
  init_js_sync();
10075
+ init_js_tty();
9964
10076
  init_js_websocket();
9965
10077
  JsExit = class extends Error {
9966
10078
  status;