@ai-ecoverse/slicc-kernel 1.32.3 → 1.33.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
@@ -3064,7 +3064,7 @@ function argsOf(pkg, raw) {
3064
3064
  }
3065
3065
  function abiOf(raw, fallback) {
3066
3066
  const abi = raw ?? fallback;
3067
- return abi === "emscripten" || abi === "wasi" ? abi : void 0;
3067
+ return abi === "emscripten" || abi === "wasi" || abi === "js" ? abi : void 0;
3068
3068
  }
3069
3069
  function commandOf(pkg, name2, raw, packageAbi, shared) {
3070
3070
  const withEnv = envFields({ ...shared, ...envOf(pkg, raw.env) });
@@ -3073,11 +3073,25 @@ function commandOf(pkg, name2, raw, packageAbi, shared) {
3073
3073
  return { name: name2, abi: packageAbi, glue: script, wasm: script, argv0: name2, script, ...withEnv };
3074
3074
  }
3075
3075
  const abi = abiOf(raw.abi, packageAbi);
3076
+ const argv0 = typeof raw.argv0 === "string" && raw.argv0 ? raw.argv0 : name2;
3077
+ const args = argsOf(pkg, raw.args);
3078
+ if (abi === "js") {
3079
+ const module = inside(pkg, raw.module);
3080
+ if (!module) return void 0;
3081
+ return {
3082
+ name: name2,
3083
+ abi,
3084
+ glue: module,
3085
+ wasm: module,
3086
+ argv0,
3087
+ ...raw.argv0Path === true ? { argv0Path: true } : {},
3088
+ ...args ? { args } : {},
3089
+ ...withEnv
3090
+ };
3091
+ }
3076
3092
  const wasm = inside(pkg, raw.wasm);
3077
3093
  const glue = abi === "wasi" ? wasm : inside(pkg, raw.glue);
3078
3094
  if (!abi || !glue || !wasm) return void 0;
3079
- const argv0 = typeof raw.argv0 === "string" && raw.argv0 ? raw.argv0 : name2;
3080
- const args = argsOf(pkg, raw.args);
3081
3095
  const imports = abi === "wasi" ? inside(pkg, raw.imports) : void 0;
3082
3096
  return {
3083
3097
  name: name2,
@@ -3784,12 +3798,12 @@ var MountTable = class {
3784
3798
  }
3785
3799
  list() {
3786
3800
  const mounted = [...this.mounts.values()].map(
3787
- ({ type, source, target, options, state, error, present }) => ({
3801
+ ({ type, source, target, options, state, error, present: present2 }) => ({
3788
3802
  type,
3789
3803
  source,
3790
3804
  target,
3791
3805
  options: { ...options },
3792
- state: state === "ok" && present?.() === false ? "nomedium" : state,
3806
+ state: state === "ok" && present2?.() === false ? "nomedium" : state,
3793
3807
  ...error ? { error } : {}
3794
3808
  })
3795
3809
  );
@@ -4498,6 +4512,8 @@ var SAB_I_MEMORY = 10;
4498
4512
  var SAB_I_TOTAL_HI = 11;
4499
4513
  var SAB_I_OFFSET_HI = 12;
4500
4514
  var SAB_I_KILLED = 13;
4515
+ var SAB_I_ASYNC = 14;
4516
+ var SAB_I_STOP = 15;
4501
4517
  var U32 = 2 ** 32;
4502
4518
  function storeU53(header3, lo, hi, value) {
4503
4519
  Atomics.store(header3, hi, Math.floor(value / U32));
@@ -4679,8 +4695,10 @@ var AsyncOps = class {
4679
4695
  waiters = /* @__PURE__ */ new Set();
4680
4696
  closed = false;
4681
4697
  run;
4682
- constructor(run2) {
4698
+ onReady;
4699
+ constructor(run2, onReady) {
4683
4700
  this.run = run2;
4701
+ this.onReady = onReady;
4684
4702
  }
4685
4703
  submit(req) {
4686
4704
  const id = this.hold();
@@ -4757,6 +4775,7 @@ var AsyncOps = class {
4757
4775
  this.results.set(id, result);
4758
4776
  this.ready.push(id);
4759
4777
  this.wake();
4778
+ this.onReady?.();
4760
4779
  }
4761
4780
  wake() {
4762
4781
  for (const wake of [...this.waiters]) wake();
@@ -7117,6 +7136,9 @@ var VfsNode = class {
7117
7136
  }
7118
7137
  return this.data;
7119
7138
  }
7139
+ holds() {
7140
+ return this.dirty;
7141
+ }
7120
7142
  replace(contents2) {
7121
7143
  this.ranged = void 0;
7122
7144
  this.data = new Uint8Array(contents2);
@@ -7227,9 +7249,34 @@ var VfsNode = class {
7227
7249
  var VfsNodes = class {
7228
7250
  byPath = /* @__PURE__ */ new Map();
7229
7251
  fs;
7252
+ entries = /* @__PURE__ */ new Map();
7230
7253
  constructor(fs) {
7231
7254
  this.fs = fs;
7232
7255
  }
7256
+ async onEntry(path, op) {
7257
+ const key = await this.entryKey(path);
7258
+ const run2 = (this.entries.get(key) ?? Promise.resolve()).then(op);
7259
+ const tail = run2.catch(() => void 0);
7260
+ this.entries.set(key, tail);
7261
+ void tail.then(() => {
7262
+ if (this.entries.get(key) === tail) this.entries.delete(key);
7263
+ });
7264
+ return run2;
7265
+ }
7266
+ async entryKey(path) {
7267
+ const parent = parentOf5(path);
7268
+ const dir = await realDir(this.fs, parent).catch(() => parent);
7269
+ const name2 = path.slice(path.lastIndexOf("/") + 1);
7270
+ return dir === "/" ? `/${name2}` : `${dir}/${name2}`;
7271
+ }
7272
+ createExclusive(path) {
7273
+ return this.onEntry(path, async () => {
7274
+ const node = this.byPath.get(path);
7275
+ const held = node ? await node.serial(async () => node.holds()) : false;
7276
+ if (held || await present(this.fs, path)) throw fsError("EEXIST", path);
7277
+ await this.fs.writeFile(path, new Uint8Array(0));
7278
+ });
7279
+ }
7233
7280
  open(path, pin) {
7234
7281
  let node = this.byPath.get(path);
7235
7282
  if (!node) {
@@ -7298,6 +7345,16 @@ var VfsNodes = class {
7298
7345
  }
7299
7346
  }
7300
7347
  };
7348
+ async function present(fs, path, follow = false) {
7349
+ const look = (follow ? void 0 : fs.lstat) ?? fs.stat;
7350
+ try {
7351
+ await (look ? look.call(fs, path) : fs.readFileBuffer(path));
7352
+ return true;
7353
+ } catch (err) {
7354
+ if (err?.code === "ENOENT") return false;
7355
+ throw err;
7356
+ }
7357
+ }
7301
7358
  var MAX_LINKS5 = 40;
7302
7359
  function parentOf5(path) {
7303
7360
  return path.slice(0, path.lastIndexOf("/")) || "/";
@@ -7362,12 +7419,17 @@ function keepingOpen(fs, nodes) {
7362
7419
  await fs.rm(path, options);
7363
7420
  nodes.unlinked(at);
7364
7421
  },
7365
- async rename(from, to) {
7422
+ rename(from, to) {
7366
7423
  const [a, b] = [fs.resolvePath("/", from), fs.resolvePath("/", to)];
7367
- await nodes.unlinking(b);
7368
- await fs.rename(from, to);
7369
- nodes.renamed(a, b);
7370
- }
7424
+ return nodes.onEntry(b, async () => {
7425
+ await nodes.unlinking(b);
7426
+ await fs.rename(from, to);
7427
+ nodes.renamed(a, b);
7428
+ });
7429
+ },
7430
+ writeFile: (path, content) => nodes.onEntry(fs.resolvePath("/", path), () => fs.writeFile(path, content)),
7431
+ symlink: (target, path) => nodes.onEntry(fs.resolvePath("/", path), () => fs.symlink(target, path)),
7432
+ mkdir: (path, options) => nodes.onEntry(fs.resolvePath("/", path), () => fs.mkdir(path, options))
7371
7433
  };
7372
7434
  }
7373
7435
  function vfsFile(fs, opts, nodes) {
@@ -7706,6 +7768,21 @@ var WasmProcess = class {
7706
7768
  this.options.hasPending?.() ? AbortSignal.abort() : this.interrupt.signal
7707
7769
  );
7708
7770
  }
7771
+ async openVfs(req) {
7772
+ await refuseReadonly(this.options.fs, req.path, req.flags, req);
7773
+ const fd = this.fds.install(heldFile(), 3);
7774
+ try {
7775
+ if (req.exclusive) await this.nodes.createExclusive(req.path);
7776
+ this.fds.installAt(fd, this.openVfsFile(req));
7777
+ if (req.existing && !await present(this.options.fs, req.path, true)) {
7778
+ throw new KernelError("ENOENT");
7779
+ }
7780
+ } catch (err) {
7781
+ await Promise.resolve(this.fds.close(fd));
7782
+ throw err;
7783
+ }
7784
+ return fd;
7785
+ }
7709
7786
  openVfsFile(req) {
7710
7787
  return vfsFile(
7711
7788
  this.options.fs,
@@ -7748,8 +7825,7 @@ var WasmProcess = class {
7748
7825
  case "fd-poll":
7749
7826
  return { ok: true, kind: "json", json: pollFile(this.fds.get(req.fd).file) };
7750
7827
  case "fd-open-vfs":
7751
- await refuseReadonly(this.options.fs, req.path, req.flags, req);
7752
- return { ok: true, kind: "json", json: this.fds.install(this.openVfsFile(req), 3) };
7828
+ return { ok: true, kind: "json", json: await this.openVfs(req) };
7753
7829
  case "fd-info":
7754
7830
  return { ok: true, kind: "json", json: this.fdInfo(req.fd) };
7755
7831
  case "fd-list":
@@ -8027,6 +8103,7 @@ var WasmProcess = class {
8027
8103
  case "sig-mask":
8028
8104
  this.caught = req.caught;
8029
8105
  this.ignored = req.ignored;
8106
+ this.inherited &= ~(req.defaults ?? 0);
8030
8107
  return { ok: true, kind: "void" };
8031
8108
  case "sig-pause":
8032
8109
  return this.pause();
@@ -8056,7 +8133,10 @@ var WasmProcess = class {
8056
8133
  }
8057
8134
  alarm;
8058
8135
  dlLog = [];
8059
- asyncOps = new AsyncOps((req) => this.syscall(req));
8136
+ asyncOps = new AsyncOps(
8137
+ (req) => this.syscall(req),
8138
+ () => this.options.onAsync?.()
8139
+ );
8060
8140
  alarmEvery;
8061
8141
  setAlarm(sig, first, every, timer) {
8062
8142
  if (!isSignal(sig)) throw new KernelError("EINVAL");
@@ -8165,6 +8245,26 @@ var Dying = class {
8165
8245
  return [typeof reported === "number" ? reported : CRASHED, void 0];
8166
8246
  }
8167
8247
  };
8248
+ function processInit(opts, sab) {
8249
+ const base = {
8250
+ type: WASM_PROCESS_INIT,
8251
+ pid: opts.shownPid ?? opts.pid,
8252
+ argv0: opts.argv0,
8253
+ args: opts.args,
8254
+ env: opts.env,
8255
+ cwd: opts.cwd,
8256
+ sab,
8257
+ ...opts.ppid !== void 0 ? { ppid: opts.ppid } : {}
8258
+ };
8259
+ if (opts.program.abi === "js") {
8260
+ return { ...base, program: opts.program, fds: inheritedFds(opts.fds) };
8261
+ }
8262
+ return {
8263
+ ...base,
8264
+ program: opts.program,
8265
+ ...opts.fork ? { fork: opts.fork } : { fds: inheritedFds(opts.fds) }
8266
+ };
8267
+ }
8168
8268
  function spawnWasmProcess(opts) {
8169
8269
  const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
8170
8270
  const header3 = new Int32Array(sab, 0, SAB_HEADER_I32);
@@ -8190,11 +8290,22 @@ function spawnWasmProcess(opts) {
8190
8290
  locks: opts.locks,
8191
8291
  onReap: opts.onReap,
8192
8292
  resolver: opts.resolver,
8193
- onPending: (sig) => void Atomics.or(header3, SAB_I_SIGNALS, sigbit(sig)),
8293
+ onPending: (sig) => {
8294
+ Atomics.or(header3, SAB_I_SIGNALS, sigbit(sig));
8295
+ Atomics.notify(header3, SAB_I_SIGNALS);
8296
+ },
8297
+ onAsync: () => {
8298
+ Atomics.add(header3, SAB_I_ASYNC, 1);
8299
+ Atomics.notify(header3, SAB_I_ASYNC);
8300
+ },
8194
8301
  onTimer: (which) => void Atomics.or(header3, SAB_I_TIMERS, 1 << which),
8195
8302
  hasPending: () => Atomics.load(header3, SAB_I_SIGNALS) !== 0 || Atomics.load(header3, SAB_I_TIMERS) !== 0,
8196
8303
  raise: (sig) => signal(sig),
8197
- ...opts.program.abi === "wasi" ? { pendingBits: () => Atomics.load(header3, SAB_I_SIGNALS) } : {}
8304
+ ...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header3, SAB_I_SIGNALS) } : {}
8305
+ });
8306
+ process.onState((state) => {
8307
+ Atomics.store(header3, SAB_I_STOP, state === "stopped" ? 1 : 0);
8308
+ Atomics.notify(header3, SAB_I_STOP);
8198
8309
  });
8199
8310
  const holds = new HeldPaths();
8200
8311
  opts.held?.add(holds);
@@ -8255,7 +8366,8 @@ function spawnWasmProcess(opts) {
8255
8366
  end?.();
8256
8367
  };
8257
8368
  const spawnThread = (thread) => {
8258
- if (done4) return;
8369
+ const { program } = opts;
8370
+ if (done4 || program.abi === "js") return;
8259
8371
  if (threads.size >= WASM_MAX_THREADS - 1) {
8260
8372
  opts.onError?.(`more than ${WASM_MAX_THREADS} threads`);
8261
8373
  finish(CRASHED);
@@ -8280,7 +8392,7 @@ function spawnWasmProcess(opts) {
8280
8392
  const tinit = {
8281
8393
  type: WASM_THREAD_INIT,
8282
8394
  pid: opts.shownPid ?? opts.pid,
8283
- program: opts.program,
8395
+ program,
8284
8396
  argv0: opts.argv0,
8285
8397
  args: opts.args,
8286
8398
  env: opts.env,
@@ -8291,18 +8403,7 @@ function spawnWasmProcess(opts) {
8291
8403
  };
8292
8404
  tw.postMessage(tinit);
8293
8405
  };
8294
- const init = {
8295
- type: WASM_PROCESS_INIT,
8296
- pid: opts.shownPid ?? opts.pid,
8297
- program: opts.program,
8298
- argv0: opts.argv0,
8299
- args: opts.args,
8300
- env: opts.env,
8301
- cwd: opts.cwd,
8302
- sab,
8303
- ...opts.ppid !== void 0 ? { ppid: opts.ppid } : {},
8304
- ...opts.fork ? { fork: opts.fork } : { fds: inheritedFds(opts.fds) }
8305
- };
8406
+ const init = processInit(opts, sab);
8306
8407
  worker.postMessage(init, opts.fork ? [opts.fork.memory.buffer] : []);
8307
8408
  const signal = (sig) => {
8308
8409
  if (process.signal(sig) !== "terminate") return;
@@ -9984,6 +10085,9 @@ var Launcher = class {
9984
10085
  return await this.base.exists(optional) ? optional : void 0;
9985
10086
  }
9986
10087
  async program(target, env) {
10088
+ if (target.abi === "js") {
10089
+ return { abi: "js", glue: await this.base.readFile(target.wasm), path: target.wasm };
10090
+ }
9987
10091
  if (target.abi !== "wasi") {
9988
10092
  const [glue, { module: module2 }] = await Promise.all([
9989
10093
  this.base.readFile(target.glue),