@ai-ecoverse/slicc-kernel 1.48.1 → 1.49.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.
package/dist/node.js CHANGED
@@ -9165,6 +9165,8 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
9165
9165
  "proc-cred",
9166
9166
  "proc-setcred",
9167
9167
  "dl-log",
9168
+ "dl-closure",
9169
+ "dl-closure-free",
9168
9170
  "fd-renumber",
9169
9171
  "fd-promote",
9170
9172
  "fd-open-tty",
@@ -9203,6 +9205,7 @@ function isWasmSyscall(req) {
9203
9205
  return typeof op === "string" && SYSCALL_OPS.has(op);
9204
9206
  }
9205
9207
  var MAX_READ = 1024 * 1024;
9208
+ var KEYBOARD = /* @__PURE__ */ new Set([SIG.INT, SIG.QUIT, SIG.TSTP]);
9206
9209
  var DEFAULT_UMASK = 18;
9207
9210
  var DYING = { ok: false, errno: "EINTR", message: "the process is being killed" };
9208
9211
  var HOSTS_ONLY = new Resolver({ routes: new Routes() });
@@ -9221,6 +9224,8 @@ var WasmProcess = class {
9221
9224
  execTermsig;
9222
9225
  stopped = 0;
9223
9226
  stops = 0;
9227
+ owed = false;
9228
+ waits = 0;
9224
9229
  resumed = Promise.resolve();
9225
9230
  wake;
9226
9231
  stateListeners = [];
@@ -9276,6 +9281,7 @@ var WasmProcess = class {
9276
9281
  return "terminate";
9277
9282
  }
9278
9283
  this.options.onPending?.(sig);
9284
+ if (this.options.jobs?.keyboard && KEYBOARD.has(sig)) this.owed = true;
9279
9285
  const blocked = this.interrupt;
9280
9286
  this.interrupt = new AbortController();
9281
9287
  blocked.abort();
@@ -9320,8 +9326,10 @@ var WasmProcess = class {
9320
9326
  await this.resumed;
9321
9327
  if (this.dying) return DYING;
9322
9328
  const stops = this.stops;
9329
+ const waits = this.waits;
9323
9330
  const result = await this.dispatch(req, cancelled);
9324
9331
  if (this.dying) return DYING;
9332
+ if (!result.ok && result.errno === "EINTR" && this.waits !== waits) this.owed = false;
9325
9333
  const restart = !result.ok && result.errno === "EINTR" && this.stops !== stops;
9326
9334
  if (restart && !this.options.hasPending?.()) continue;
9327
9335
  await this.resumed;
@@ -9374,8 +9382,11 @@ var WasmProcess = class {
9374
9382
  refuseIfPending(restart) {
9375
9383
  if (restart && this.options.hasPending?.()) throw new KernelError("EINTR");
9376
9384
  }
9377
- blockingSignal(cancelled) {
9378
- if (this.options.hasPending?.() || cancelled?.aborted) throw new KernelError("EINTR");
9385
+ blockingSignal(cancelled, owing = true) {
9386
+ if (owing) this.waits++;
9387
+ if (this.options.hasPending?.() || cancelled?.aborted || owing && this.owed) {
9388
+ throw new KernelError("EINTR");
9389
+ }
9379
9390
  return cancelled ? AbortSignal.any([this.interrupt.signal, cancelled]) : this.interrupt.signal;
9380
9391
  }
9381
9392
  async read(req, cancelled) {
@@ -9521,7 +9532,7 @@ var WasmProcess = class {
9521
9532
  return { ok: true, kind: "json", json: this.options.jobs?.terminalNames() ?? [] };
9522
9533
  case "fd-select": {
9523
9534
  const { read, write, timeoutMs } = req;
9524
- const signal = this.blockingSignal(cancelled);
9535
+ const signal = this.blockingSignal(cancelled, timeoutMs !== 0);
9525
9536
  const selected = await selectFds(this.fds, read, write, timeoutMs, signal);
9526
9537
  return { ok: true, kind: "json", json: selected };
9527
9538
  }
@@ -9772,6 +9783,11 @@ var WasmProcess = class {
9772
9783
  case "dl-log":
9773
9784
  if (req.append) this.dlLog.push(req.append);
9774
9785
  return { ok: true, kind: "json", json: this.dlLog.slice(req.from) };
9786
+ case "dl-closure":
9787
+ return { ok: true, kind: "json", json: this.allocateClosure(req.floor) };
9788
+ case "dl-closure-free":
9789
+ this.freeClosure(req.index);
9790
+ return { ok: true, kind: "void" };
9775
9791
  case "sig-mask":
9776
9792
  this.caught = req.caught;
9777
9793
  this.ignored = req.ignored;
@@ -9808,6 +9824,18 @@ var WasmProcess = class {
9808
9824
  }
9809
9825
  alarm;
9810
9826
  dlLog = [];
9827
+ closures = { next: 0, free: [], live: /* @__PURE__ */ new Set() };
9828
+ allocateClosure(floor) {
9829
+ const index = this.closures.free.pop() ?? Math.max(floor, this.closures.next);
9830
+ this.closures.next = Math.max(this.closures.next, index + 1);
9831
+ this.closures.live.add(index);
9832
+ this.dlLog.push({ kind: "closure", index });
9833
+ return index;
9834
+ }
9835
+ freeClosure(index) {
9836
+ if (!this.closures.live.delete(index)) throw new KernelError("EINVAL");
9837
+ this.closures.free.push(index);
9838
+ }
9811
9839
  asyncOps = new AsyncOps(
9812
9840
  (req, cancelled) => this.syscall(req, cancelled),
9813
9841
  () => this.options.onAsync?.()
@@ -10197,6 +10225,7 @@ var JobTable = class {
10197
10225
  handoffs = /* @__PURE__ */ new Map();
10198
10226
  foreground = /* @__PURE__ */ new Map();
10199
10227
  terminals = /* @__PURE__ */ new Map();
10228
+ keyboard = false;
10200
10229
  add(pid, parentPid, signal, terminal) {
10201
10230
  const parent = parentPid === void 0 ? void 0 : this.members.get(parentPid);
10202
10231
  if (!parent && terminal) this.terminals.set(pid, terminal);
@@ -10366,6 +10395,14 @@ var JobTable = class {
10366
10395
  signalForeground(tty, fallback, sig) {
10367
10396
  this.killGroup(this.tcgetpgrp(tty, fallback), sig);
10368
10397
  }
10398
+ fromKeyboard(send) {
10399
+ this.keyboard = true;
10400
+ try {
10401
+ send();
10402
+ } finally {
10403
+ this.keyboard = false;
10404
+ }
10405
+ }
10369
10406
  };
10370
10407
 
10371
10408
  // src/kernel/settling.ts
@@ -11974,6 +12011,7 @@ var Launcher = class {
11974
12011
  module,
11975
12012
  ...memory ? { memory } : {},
11976
12013
  foreign,
12014
+ path: target.wasm,
11977
12015
  ...names ? { names } : {},
11978
12016
  ...imports !== void 0 ? { imports } : {},
11979
12017
  ...target.preopenRoot ? { preopenRoot: true } : {}
@@ -12201,7 +12239,8 @@ var Launcher = class {
12201
12239
  keySignal(tty, fallback, sig, send) {
12202
12240
  const pgid = this.jobs.tcgetpgrp(tty, fallback);
12203
12241
  const foreground = () => this.jobs.tcgetpgrp(tty, fallback);
12204
- this.settling.deliver(sig, pgid, send, tty.reading ? void 0 : foreground);
12242
+ const keyed = () => this.jobs.fromKeyboard(send);
12243
+ this.settling.deliver(sig, pgid, keyed, tty.reading ? void 0 : foreground);
12205
12244
  }
12206
12245
  umaskOf(pid) {
12207
12246
  return this.processes.get(pid)?.umask?.() ?? DEFAULT_UMASK;
@@ -13533,13 +13572,18 @@ function nodeWorker(file, live, closed) {
13533
13572
  }
13534
13573
  };
13535
13574
  const worker = closed ? void 0 : new Worker(file);
13575
+ let ending = false;
13536
13576
  if (worker) {
13537
13577
  const kill = () => {
13578
+ ending = true;
13538
13579
  void worker.terminate();
13539
13580
  fail3(TERMINATED);
13540
13581
  };
13541
13582
  live.add(kill);
13542
- worker.once("exit", () => live.delete(kill));
13583
+ worker.once("exit", (code) => {
13584
+ live.delete(kill);
13585
+ if (!ending) fail3(`the process worker exited with ${code}`);
13586
+ });
13543
13587
  worker.on("error", (err) => fail3(String(err)));
13544
13588
  } else {
13545
13589
  setTimeout(() => fail3(TERMINATED), 0);
@@ -13560,7 +13604,10 @@ function nodeWorker(file, live, closed) {
13560
13604
  const listener = messages.get(handler);
13561
13605
  if (listener) worker?.off("message", listener);
13562
13606
  },
13563
- terminate: () => void worker?.terminate()
13607
+ terminate: () => {
13608
+ ending = true;
13609
+ void worker?.terminate();
13610
+ }
13564
13611
  };
13565
13612
  }
13566
13613
  function textOf(on) {