@ai-ecoverse/slicc-kernel 1.68.0 → 1.69.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.
@@ -1310,7 +1310,7 @@ function createStreamOps(h) {
1310
1310
  }
1311
1311
  }
1312
1312
  };
1313
- const opened = (node, on, want = 0) => {
1313
+ const opened2 = (node, on, want = 0) => {
1314
1314
  const s = node.live;
1315
1315
  try {
1316
1316
  const handle = bridgeOf(node).hold?.(liveNodePath(node), on, true, s.handle, want);
@@ -1361,7 +1361,7 @@ function createStreamOps(h) {
1361
1361
  const want = permitted(stream, created);
1362
1362
  live.openCount++;
1363
1363
  counted = true;
1364
- if (live.openCount === 1) opened(stream.node, true, want);
1364
+ if (live.openCount === 1) opened2(stream.node, true, want);
1365
1365
  } catch (err) {
1366
1366
  if (counted) live.openCount--;
1367
1367
  if (stream.fd !== void 0) Fs.closeStream?.(stream.fd);
@@ -1392,7 +1392,7 @@ function createStreamOps(h) {
1392
1392
  s.len = 0;
1393
1393
  s.loaded = false;
1394
1394
  held(stream, -1);
1395
- opened(node, false);
1395
+ opened2(node, false);
1396
1396
  }
1397
1397
  },
1398
1398
  read(stream, buffer, offset, length, position) {
@@ -2130,8 +2130,8 @@ var init_kernel_streams = __esm({
2130
2130
  fs.readdir = (path) => {
2131
2131
  const names = readdir.call(fs, path);
2132
2132
  if (path.replace(/\/+$/, "") !== "/dev") return names;
2133
- const missing = ttyNames().map((tty) => tty.slice("/dev/".length)).filter((name2) => TTY_NAME.test(name2) && !names.includes(name2));
2134
- return [...names, ...missing];
2133
+ const missing2 = ttyNames().map((tty) => tty.slice("/dev/".length)).filter((name2) => TTY_NAME.test(name2) && !names.includes(name2));
2134
+ return [...names, ...missing2];
2135
2135
  };
2136
2136
  }
2137
2137
  ttyNode(name2) {
@@ -2909,13 +2909,13 @@ function describeFdDir(Fs) {
2909
2909
  return;
2910
2910
  }
2911
2911
  const ops = dir?.node_ops;
2912
- const lookup = ops?.lookup;
2913
- if (!dir || !lookup || ops.getattr) return;
2912
+ const lookup2 = ops?.lookup;
2913
+ if (!dir || !lookup2 || ops.getattr) return;
2914
2914
  dir.node_ops = {
2915
2915
  ...ops,
2916
2916
  getattr: () => syntheticAttr(DIR_MODE, 1),
2917
2917
  lookup: (parent, name2) => {
2918
- const entry = lookup(parent, name2);
2918
+ const entry = lookup2(parent, name2);
2919
2919
  entry.node_ops = {
2920
2920
  ...entry.node_ops,
2921
2921
  getattr: () => syntheticAttr(LINK_MODE, entry.id ?? 0)
@@ -4205,7 +4205,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
4205
4205
  return found;
4206
4206
  };
4207
4207
  const procOps = proc.node_ops;
4208
- const lookup = procOps.lookup?.bind(procOps);
4208
+ const lookup2 = procOps.lookup?.bind(procOps);
4209
4209
  const readdir = procOps.readdir?.bind(procOps);
4210
4210
  const listAll = (node) => {
4211
4211
  const names = new Set(readdir ? readdir(node) : [".", ".."]);
@@ -4228,8 +4228,8 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
4228
4228
  () => systemFile(name2, procList(), Date.now(), memory)
4229
4229
  );
4230
4230
  }
4231
- if (!lookup) throw error();
4232
- return lookup(parent, name2);
4231
+ if (!lookup2) throw error();
4232
+ return lookup2(parent, name2);
4233
4233
  },
4234
4234
  readdir: (node) => listAll(node)
4235
4235
  };
@@ -5447,6 +5447,34 @@ var init_wasi_files = __esm({
5447
5447
  }
5448
5448
  });
5449
5449
 
5450
+ // src/kernel/pipe.ts
5451
+ var PIPE_CAPACITY;
5452
+ var init_pipe = __esm({
5453
+ "src/kernel/pipe.ts"() {
5454
+ "use strict";
5455
+ PIPE_CAPACITY = 64 * 1024;
5456
+ }
5457
+ });
5458
+
5459
+ // src/kernel/fd-table.ts
5460
+ function deviceAt(path) {
5461
+ return DEVICE_PATHS.get(path);
5462
+ }
5463
+ var DEVICE_PATHS;
5464
+ var init_fd_table = __esm({
5465
+ "src/kernel/fd-table.ts"() {
5466
+ "use strict";
5467
+ init_pipe();
5468
+ DEVICE_PATHS = /* @__PURE__ */ new Map([
5469
+ ["/dev/null", "null"],
5470
+ ["/dev/zero", "zero"],
5471
+ ["/dev/full", "full"],
5472
+ ["/dev/urandom", "urandom"],
5473
+ ["/dev/random", "urandom"]
5474
+ ]);
5475
+ }
5476
+ });
5477
+
5450
5478
  // src/process/wasi/wasi-fds.ts
5451
5479
  function stdioAlias(path) {
5452
5480
  const m = /^\/dev\/(?:(stdin)|(stdout)|(stderr)|fd\/(\d+))$/.exec(path);
@@ -5454,7 +5482,7 @@ function stdioAlias(path) {
5454
5482
  return m[1] ? 0 : m[2] ? 1 : m[3] ? 2 : Number(m[4]);
5455
5483
  }
5456
5484
  function deviceOf(path) {
5457
- return DEVICES2[path];
5485
+ return deviceAt(path);
5458
5486
  }
5459
5487
  function within(path, root) {
5460
5488
  return path === root || path.startsWith(root === "/" ? "/" : `${root}/`);
@@ -5522,10 +5550,11 @@ function promoteRequest(fd, f, handed) {
5522
5550
  ...f.buffer.handle !== void 0 ? { handle: f.buffer.handle } : {}
5523
5551
  };
5524
5552
  }
5525
- var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND, DEVICES2, SEALED_PATH2, WasiFds, GEN;
5553
+ var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND, SEALED_PATH2, WasiFds, GEN;
5526
5554
  var init_wasi_fds = __esm({
5527
5555
  "src/process/wasi/wasi-fds.ts"() {
5528
5556
  "use strict";
5557
+ init_fd_table();
5529
5558
  init_sync_fs_wire();
5530
5559
  init_wasi_abi();
5531
5560
  init_wasi_files();
@@ -5534,13 +5563,6 @@ var init_wasi_fds = __esm({
5534
5563
  O_WRONLY4 = 1;
5535
5564
  O_RDWR4 = 2;
5536
5565
  O_APPEND = 1024;
5537
- DEVICES2 = {
5538
- "/dev/null": "null",
5539
- "/dev/zero": "zero",
5540
- "/dev/full": "full",
5541
- "/dev/urandom": "urandom",
5542
- "/dev/random": "urandom"
5543
- };
5544
5566
  SEALED_PATH2 = "/dev/sealed";
5545
5567
  WasiFds = class {
5546
5568
  table = /* @__PURE__ */ new Map();
@@ -6653,11 +6675,11 @@ var init_wasi_host = __esm({
6653
6675
  this.writeFilestat(statOut, this.fdFilestat(fd));
6654
6676
  owner(fdOwned(fd), out);
6655
6677
  },
6656
- path_filestat_owner: (dirfd, lookup, p, l, statOut, out) => {
6678
+ path_filestat_owner: (dirfd, lookup2, p, l, statOut, out) => {
6657
6679
  if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
6658
6680
  const path = at(dirfd, p, l);
6659
- this.writeFilestat(statOut, this.pathFilestat(path, lookup));
6660
- owner(pathOwned(path, (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
6681
+ this.writeFilestat(statOut, this.pathFilestat(path, lookup2));
6682
+ owner(pathOwned(path, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
6661
6683
  },
6662
6684
  path_owner: (dirfd, p, l, flags, out) => {
6663
6685
  if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
@@ -6883,11 +6905,11 @@ var init_wasi_host = __esm({
6883
6905
  mem.view().setUint32(out, fds.open(path, oflags, rights, fdflags), true);
6884
6906
  if (fresh) this.created(path, 438);
6885
6907
  },
6886
- path_filestat_get: (dirfd, lookup, p, l, out) => void this.writeFilestat(out, this.pathFilestat(at(dirfd, p, l), lookup)),
6887
- path_filestat_set_times: (dirfd, lookup, p, l, atim, mtim, flags) => {
6908
+ path_filestat_get: (dirfd, lookup2, p, l, out) => void this.writeFilestat(out, this.pathFilestat(at(dirfd, p, l), lookup2)),
6909
+ path_filestat_set_times: (dirfd, lookup2, p, l, atim, mtim, flags) => {
6888
6910
  const path = at(dirfd, p, l);
6889
6911
  fds.flushPath(path);
6890
- this.setTimes(path, atim, mtim, flags, (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0);
6912
+ this.setTimes(path, atim, mtim, flags, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0);
6891
6913
  },
6892
6914
  path_create_directory: (dirfd, p, l) => {
6893
6915
  const path = at(dirfd, p, l);
@@ -6920,10 +6942,10 @@ var init_wasi_host = __esm({
6920
6942
  mem.bytes(buf, n).set(target.subarray(0, n));
6921
6943
  mem.view().setUint32(used, n, true);
6922
6944
  },
6923
- path_link: (fd, lookup, p, l, fd2, p2, l2) => {
6945
+ path_link: (fd, lookup2, p, l, fd2, p2, l2) => {
6924
6946
  const from = at(fd, p, l);
6925
6947
  const to = at(fd2, p2, l2);
6926
- const follow2 = (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0;
6948
+ const follow2 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
6927
6949
  const source = follow2 ? physicalPath(o.fs, from) : from;
6928
6950
  fds.flushPath(from);
6929
6951
  if (source !== from) fds.flushPath(source);
@@ -7191,7 +7213,7 @@ var init_wasi_host = __esm({
7191
7213
  synthetic(path) {
7192
7214
  return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed;
7193
7215
  }
7194
- pathFilestat(path, lookup) {
7216
+ pathFilestat(path, lookup2) {
7195
7217
  if (this.synthetic(path)) {
7196
7218
  return this.local({
7197
7219
  filetype: FILETYPE.CHARACTER_DEVICE,
@@ -7201,7 +7223,7 @@ var init_wasi_host = __esm({
7201
7223
  });
7202
7224
  }
7203
7225
  this.fds.flushPath(path);
7204
- const follow2 = (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0;
7226
+ const follow2 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
7205
7227
  return filestatOf(path, follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path));
7206
7228
  }
7207
7229
  setTimes(path, atim, mtim, flags, follow2 = true) {
@@ -7399,12 +7421,12 @@ var init_wasix_process = __esm({
7399
7421
  fds.promoteFiles();
7400
7422
  const map = fds.inheritable();
7401
7423
  const nulls = /* @__PURE__ */ new Set();
7402
- const opened = [];
7424
+ const opened2 = [];
7403
7425
  let cwd = this.host.cwd;
7404
7426
  try {
7405
- for (const op of ops) cwd = this.applyFdOp(op, { map, nulls, opened }, cwd);
7427
+ for (const op of ops) cwd = this.applyFdOp(op, { map, nulls, opened: opened2 }, cwd);
7406
7428
  } catch (e) {
7407
- for (const kfd of opened) this.host.o.kernel.sys.close(kfd);
7429
+ for (const kfd of opened2) this.host.o.kernel.sys.close(kfd);
7408
7430
  throw e;
7409
7431
  }
7410
7432
  const stdio = [0, 1, 2].map((fd) => {
@@ -7415,10 +7437,10 @@ var init_wasix_process = __esm({
7415
7437
  ...[...map].filter(([fd]) => fd > 2).map(([fd, kernel]) => ({ fd, kernel })),
7416
7438
  ...[...nulls].filter((fd) => fd > 2).map((fd) => ({ fd, device: "null" }))
7417
7439
  ];
7418
- return { stdio, inherit, cwd, opened };
7440
+ return { stdio, inherit, cwd, opened: opened2 };
7419
7441
  }
7420
7442
  applyFdOp(op, slots3, cwd) {
7421
- const { map, nulls, opened } = slots3;
7443
+ const { map, nulls, opened: opened2 } = slots3;
7422
7444
  const { fds } = this.host;
7423
7445
  const point = (fd, kfd) => {
7424
7446
  if (kfd === void 0) {
@@ -7441,7 +7463,7 @@ var init_wasix_process = __esm({
7441
7463
  point(op.fd, void 0);
7442
7464
  } else if (op.cmd === "open") {
7443
7465
  const kfd = this.openFor(op, cwd);
7444
- opened.push(kfd);
7466
+ opened2.push(kfd);
7445
7467
  point(op.fd, kfd);
7446
7468
  } else if (op.cmd === "chdir") return this.physicalFrom(cwd, op.path);
7447
7469
  else return physicalPath(this.host.o.fs, fds.dir(op.fd).path);
@@ -7463,7 +7485,7 @@ var init_wasix_process = __esm({
7463
7485
  });
7464
7486
  }
7465
7487
  spawn(req, exec = false) {
7466
- const { stdio, inherit, cwd, opened } = this.childFds(req.ops ?? []);
7488
+ const { stdio, inherit, cwd, opened: opened2 } = this.childFds(req.ops ?? []);
7467
7489
  try {
7468
7490
  const spawn = {
7469
7491
  op: "proc-spawn",
@@ -7478,7 +7500,7 @@ var init_wasix_process = __esm({
7478
7500
  };
7479
7501
  return restarted2(() => this.call(spawn));
7480
7502
  } finally {
7481
- for (const kfd of opened) this.host.o.kernel.sys.close(kfd);
7503
+ for (const kfd of opened2) this.host.o.kernel.sys.close(kfd);
7482
7504
  this.host.o.fs.invalidate?.();
7483
7505
  }
7484
7506
  }
@@ -9823,8 +9845,8 @@ var init_wasix_host = __esm({
9823
9845
  mem.view().setUint16(out, host.fds.cloexec.has(fd) ? FDFLAGSEXT_CLOEXEC : 0, true);
9824
9846
  },
9825
9847
  fd_fdflags_set: (fd, flags) => void host.fds.setCloexec(fd, (flags & FDFLAGSEXT_CLOEXEC) !== 0),
9826
- path_open2: (dirfd, lookup, p, l, oflags, rights, inheriting, fdflags, fdflagsext, out) => {
9827
- const r = preview1.path_open(dirfd, lookup, p, l, oflags, rights, inheriting, fdflags, out);
9848
+ path_open2: (dirfd, lookup2, p, l, oflags, rights, inheriting, fdflags, fdflagsext, out) => {
9849
+ const r = preview1.path_open(dirfd, lookup2, p, l, oflags, rights, inheriting, fdflags, out);
9828
9850
  if (r === E.SUCCESS && fdflagsext & FDFLAGSEXT_CLOEXEC)
9829
9851
  host.fds.setCloexec(mem.view().getUint32(out, true), true);
9830
9852
  return r;
@@ -10797,6 +10819,11 @@ function untilAborted(work, signal) {
10797
10819
  work.then(done, done);
10798
10820
  });
10799
10821
  }
10822
+ function caughtOf(handlers) {
10823
+ let caught = 0;
10824
+ for (const sig of handlers.keys()) caught |= sigbit(sig);
10825
+ return caught;
10826
+ }
10800
10827
  var JsCallError, JsKernel;
10801
10828
  var init_js_kernel = __esm({
10802
10829
  "src/process/js/js-kernel.ts"() {
@@ -10824,6 +10851,7 @@ var init_js_kernel = __esm({
10824
10851
  reported = { caught: 0, ignored: 0 };
10825
10852
  watching = false;
10826
10853
  faulted = false;
10854
+ syncLane;
10827
10855
  constructor(o) {
10828
10856
  this.header = new Int32Array(o.sab, 0, SAB_HEADER_I32);
10829
10857
  this.transport = o.transport;
@@ -10926,16 +10954,41 @@ var init_js_kernel = __esm({
10926
10954
  if (sig === SIG.KILL || sig === SIG.STOP) {
10927
10955
  return Promise.reject(new JsCallError("EINVAL", "signal"));
10928
10956
  }
10957
+ if (this.syncLane) {
10958
+ try {
10959
+ this.changeNow(this.syncLane, sig, handler);
10960
+ return Promise.resolve();
10961
+ } catch (err) {
10962
+ return Promise.reject(err);
10963
+ }
10964
+ }
10929
10965
  const run = this.changing.then(() => this.change(sig, handler));
10930
10966
  this.changing = run.catch(() => void 0);
10931
10967
  return run;
10932
10968
  }
10933
- async change(sig, handler) {
10969
+ changeNow(lane, sig, handler) {
10970
+ const { handlers, ignored } = this.disposed(sig, handler);
10971
+ const defaults = handler === "default" ? sigbit(sig) : 0;
10972
+ const caught = caughtOf(handlers);
10973
+ if (caught !== this.reported.caught || ignored !== this.reported.ignored || defaults !== 0) {
10974
+ const r = lane({ op: "sig-mask", caught, ignored, ...defaults ? { defaults } : {} });
10975
+ if (!r.ok) throw new JsCallError(r.errno, "sig-mask");
10976
+ this.reported = { caught, ignored };
10977
+ }
10978
+ this.handlers = handlers;
10979
+ this.ignored = ignored;
10980
+ if (handlers.size > 0) void this.watch();
10981
+ }
10982
+ disposed(sig, handler) {
10934
10983
  const handlers = new Map(this.handlers);
10935
10984
  handlers.delete(sig);
10936
10985
  let ignored = this.ignored & ~sigbit(sig);
10937
10986
  if (handler === "ignore") ignored |= sigbit(sig);
10938
10987
  else if (handler !== "default") handlers.set(sig, handler);
10988
+ return { handlers, ignored };
10989
+ }
10990
+ async change(sig, handler) {
10991
+ const { handlers, ignored } = this.disposed(sig, handler);
10939
10992
  await this.report(handlers, ignored, handler === "default" ? sigbit(sig) : 0);
10940
10993
  this.handlers = handlers;
10941
10994
  this.ignored = ignored;
@@ -10945,8 +10998,7 @@ var init_js_kernel = __esm({
10945
10998
  this.call({ op: "proc-kill", pid: this.pid, sig }).catch(this.onError);
10946
10999
  }
10947
11000
  async report(handlers, ignored, defaults) {
10948
- let caught = 0;
10949
- for (const sig of handlers.keys()) caught |= sigbit(sig);
11001
+ const caught = caughtOf(handlers);
10950
11002
  const same = caught === this.reported.caught && ignored === this.reported.ignored;
10951
11003
  if (same && defaults === 0) return;
10952
11004
  this.reported = { caught, ignored };
@@ -11166,6 +11218,344 @@ var init_js_io = __esm({
11166
11218
  }
11167
11219
  });
11168
11220
 
11221
+ // src/process/js/js-dev.ts
11222
+ function inDev(abs) {
11223
+ return abs.startsWith("/dev") && (abs.length === 4 || abs[4] === "/");
11224
+ }
11225
+ function missing(path) {
11226
+ throw new JsCallError("ENOENT", path);
11227
+ }
11228
+ function nodeStat(mode, size = 0, owner) {
11229
+ return {
11230
+ isFile: false,
11231
+ isDirectory: (mode & S_IFMT2) === DIR,
11232
+ isSymbolicLink: (mode & S_IFMT2) === LINK,
11233
+ size,
11234
+ mode,
11235
+ mtimeMs: BORN,
11236
+ atimeMs: BORN,
11237
+ ctimeMs: BORN,
11238
+ nlink: 1,
11239
+ uid: owner?.uid ?? 0,
11240
+ gid: owner?.gid ?? 0
11241
+ };
11242
+ }
11243
+ function* lookup(abs) {
11244
+ if (abs === "/dev") return { kind: "dir", mode: DIR | 493 };
11245
+ const name2 = abs.slice("/dev/".length);
11246
+ if (DEVICES2.includes(name2)) return { kind: "device" };
11247
+ if (name2 === "tty") return { kind: "tty" };
11248
+ const std = STDIO3.indexOf(name2);
11249
+ if (std >= 0) return { kind: "link", target: `${SELF_FD}/${std}`, fd: std };
11250
+ if (name2 === "fd") return { kind: "link", target: SELF_FD };
11251
+ const fd = /^fd\/(\d+)$/.exec(name2)?.[1];
11252
+ if (fd !== void 0) return { kind: "fd", fd: Number(fd) };
11253
+ if (/^tty\d+$/.test(name2)) {
11254
+ const names = yield { op: "fd-tty-names" };
11255
+ if (names.includes(abs)) return { kind: "terminal", name: abs };
11256
+ }
11257
+ const pts = /^pts\/(\d+)$/.exec(name2)?.[1];
11258
+ if (pts !== void 0) {
11259
+ const open = yield { op: "pty-list" };
11260
+ if (open.includes(Number(pts))) return { kind: "terminal", name: abs, pts: Number(pts) };
11261
+ }
11262
+ return missing(abs);
11263
+ }
11264
+ function* fdInfo(fd, path) {
11265
+ try {
11266
+ return yield { op: "fd-info", fd };
11267
+ } catch (err) {
11268
+ if (err instanceof JsCallError && err.code === "EBADF") return missing(path);
11269
+ throw err;
11270
+ }
11271
+ }
11272
+ function* pathStat(path) {
11273
+ const s = parseSyncFsStat(yield { op: "stat", path });
11274
+ if (!s) throw new JsCallError("EIO", "stat");
11275
+ return s;
11276
+ }
11277
+ function* terminalStat(name2) {
11278
+ const owner = yield { op: "fd-tty-owner", name: name2 };
11279
+ if (owner) return nodeStat(CHAR | (owner.mode ?? 400), 0, owner);
11280
+ return nodeStat(CHAR | (name2.startsWith("/dev/pts/") ? 400 : 438));
11281
+ }
11282
+ function* fdStat(fd, path) {
11283
+ const info = yield* fdInfo(fd, path);
11284
+ if (info.meta && "dir" in info.meta) return yield* pathStat(info.meta.dir);
11285
+ if (info.kind === "file") {
11286
+ const file = yield { op: "fd-vfs-stat", fd };
11287
+ if (file.orphan) return { ...nodeStat(33152, file.size), isFile: true };
11288
+ return yield* pathStat(file.path);
11289
+ }
11290
+ if (info.terminal) return yield* terminalStat(info.terminal);
11291
+ if (info.kind === "device" || info.kind === "tty") return nodeStat(CHAR | 438);
11292
+ if (info.kind === "socket") return nodeStat(49663);
11293
+ return nodeStat(4480);
11294
+ }
11295
+ function* fdTarget(fd, path) {
11296
+ const info = yield* fdInfo(fd, path);
11297
+ if (info.meta && "dir" in info.meta) return info.meta.dir;
11298
+ if (info.kind === "file") return (yield { op: "fd-vfs-stat", fd }).path;
11299
+ if (info.terminal) return info.terminal;
11300
+ if (info.meta && "device" in info.meta) return `/dev/${info.meta.device}`;
11301
+ return `${info.kind === "socket" ? "socket" : "pipe"}:[${fd}]`;
11302
+ }
11303
+ function linkStat(target) {
11304
+ return nodeStat(LINK | 511, target.length);
11305
+ }
11306
+ function* devStat(abs, follow2) {
11307
+ const node = yield* lookup(abs);
11308
+ switch (node.kind) {
11309
+ case "dir":
11310
+ return nodeStat(node.mode);
11311
+ case "device":
11312
+ case "tty":
11313
+ return nodeStat(CHAR | 438);
11314
+ case "terminal":
11315
+ return yield* terminalStat(node.name);
11316
+ case "link":
11317
+ if (!follow2) return linkStat(node.target);
11318
+ return node.fd === void 0 ? nodeStat(DIR | 365) : yield* fdStat(node.fd, abs);
11319
+ case "fd":
11320
+ return follow2 ? yield* fdStat(node.fd, abs) : linkStat(yield* fdTarget(node.fd, abs));
11321
+ }
11322
+ }
11323
+ function* devExists(abs) {
11324
+ try {
11325
+ yield* devStat(abs, true);
11326
+ return true;
11327
+ } catch (err) {
11328
+ if (err instanceof JsCallError) return false;
11329
+ throw err;
11330
+ }
11331
+ }
11332
+ function* devReadlink(abs) {
11333
+ const node = yield* lookup(abs);
11334
+ if (node.kind === "link") return node.target;
11335
+ if (node.kind === "fd") return yield* fdTarget(node.fd, abs);
11336
+ throw new JsCallError("EINVAL", abs);
11337
+ }
11338
+ function* devReaddir(abs) {
11339
+ if (abs === "/dev/fd") {
11340
+ const fds = yield { op: "fd-list" };
11341
+ return fds.map(({ fd }) => String(fd));
11342
+ }
11343
+ const node = yield* lookup(abs);
11344
+ if (node.kind !== "dir") throw new JsCallError("ENOTDIR", abs);
11345
+ const names = yield { op: "fd-tty-names" };
11346
+ const ttys = names.filter((n) => /^\/dev\/tty\d+$/.test(n)).map((n) => n.slice(5));
11347
+ return [...DEVICES2, "tty", "fd", ...STDIO3, ...ttys].sort();
11348
+ }
11349
+ function* aliasOf(fd, abs, o) {
11350
+ const info = yield* fdInfo(fd, abs);
11351
+ const file = info.kind === "file";
11352
+ if (file) {
11353
+ const at = yield { op: "fd-vfs-stat", fd };
11354
+ if (!at.orphan)
11355
+ return { fd: yield openRequest(at.path, { ...o, create: false }), file };
11356
+ }
11357
+ const copy2 = yield { op: "fd-dup", fd, min: 3 };
11358
+ if (file && o.truncate) {
11359
+ try {
11360
+ yield { op: "fd-resize", fd: copy2, size: 0 };
11361
+ } catch (err) {
11362
+ yield { op: "fd-close", fd: copy2 };
11363
+ throw err;
11364
+ }
11365
+ }
11366
+ return { fd: copy2, file };
11367
+ }
11368
+ function* opened(abs, o) {
11369
+ const node = yield* lookup(abs);
11370
+ if (isExclusive(o)) throw new JsCallError("EEXIST", abs);
11371
+ switch (node.kind) {
11372
+ case "device":
11373
+ return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
11374
+ case "tty":
11375
+ return { fd: yield { op: "fd-open-tty" }, file: false };
11376
+ case "terminal": {
11377
+ const req = node.pts === void 0 ? { op: "fd-open-tty", name: node.name } : { op: "pty-slave-open", n: node.pts, noctty: true };
11378
+ return { fd: yield req, file: false };
11379
+ }
11380
+ case "fd":
11381
+ return yield* aliasOf(node.fd, abs, o);
11382
+ case "link":
11383
+ if (node.fd !== void 0) return yield* aliasOf(node.fd, abs, o);
11384
+ throw new JsCallError("EISDIR", abs);
11385
+ case "dir":
11386
+ throw new JsCallError("EISDIR", abs);
11387
+ }
11388
+ }
11389
+ function* devOpen(abs, o) {
11390
+ const write2 = o.write === true || o.append === true || o.truncate === true;
11391
+ return { ...yield* opened(abs, o), read: o.read === true || !write2, write: write2 };
11392
+ }
11393
+ async function devAsync(kernel, step) {
11394
+ let next2 = step.next();
11395
+ while (!next2.done) {
11396
+ let answer2;
11397
+ try {
11398
+ answer2 = { value: await kernel.json(next2.value) };
11399
+ } catch (error) {
11400
+ answer2 = { error };
11401
+ }
11402
+ next2 = "value" in answer2 ? step.next(answer2.value) : step.throw(answer2.error);
11403
+ }
11404
+ return next2.value;
11405
+ }
11406
+ function devSync(kernel, step) {
11407
+ let next2 = step.next();
11408
+ while (!next2.done) {
11409
+ let answer2;
11410
+ try {
11411
+ answer2 = { value: kernel.json(next2.value) };
11412
+ } catch (error) {
11413
+ answer2 = { error };
11414
+ }
11415
+ next2 = "value" in answer2 ? step.next(answer2.value) : step.throw(answer2.error);
11416
+ }
11417
+ return next2.value;
11418
+ }
11419
+ function tooLarge(got) {
11420
+ if (got > DEV_READ_MAX) throw new JsCallError("EFBIG", "readFile");
11421
+ }
11422
+ function liveness(path) {
11423
+ let open = true;
11424
+ return {
11425
+ live: () => {
11426
+ if (!open) throw new JsCallError("EBADF", path);
11427
+ },
11428
+ end: () => {
11429
+ open = false;
11430
+ }
11431
+ };
11432
+ }
11433
+ function allowed(may, what) {
11434
+ if (!may) throw new JsCallError("EBADF", what);
11435
+ }
11436
+ function streamFile(fd, path, io, access) {
11437
+ const { live, end } = liveness(path);
11438
+ const file = {
11439
+ fd,
11440
+ path,
11441
+ async size() {
11442
+ live();
11443
+ return 0;
11444
+ },
11445
+ async read(position, length) {
11446
+ index2(position, "read");
11447
+ index2(length, "read");
11448
+ live();
11449
+ allowed(access.read, "read");
11450
+ return length === 0 ? new Uint8Array(0) : io.read(fd, Math.min(length, MAX_IO));
11451
+ },
11452
+ async write(position, data) {
11453
+ index2(position, "write");
11454
+ live();
11455
+ allowed(access.write, "write");
11456
+ await io.write(fd, data);
11457
+ return data.length;
11458
+ },
11459
+ async truncate(size) {
11460
+ live();
11461
+ index2(size, "truncate");
11462
+ throw new JsCallError("EINVAL", "truncate");
11463
+ },
11464
+ sync: async () => live(),
11465
+ async close() {
11466
+ live();
11467
+ end();
11468
+ await io.close(fd);
11469
+ }
11470
+ };
11471
+ return { file, invalidate: end };
11472
+ }
11473
+ function streamSyncFile(fd, path, io, access) {
11474
+ const { live, end } = liveness(path);
11475
+ const file = {
11476
+ fd,
11477
+ path,
11478
+ size() {
11479
+ live();
11480
+ return 0;
11481
+ },
11482
+ read(position, length) {
11483
+ index2(position, "read");
11484
+ index2(length, "read");
11485
+ live();
11486
+ allowed(access.read, "read");
11487
+ return length === 0 ? new Uint8Array(0) : io.read(fd, Math.min(length, MAX_IO));
11488
+ },
11489
+ write(position, data) {
11490
+ index2(position, "write");
11491
+ live();
11492
+ allowed(access.write, "write");
11493
+ io.write(fd, data);
11494
+ return data.length;
11495
+ },
11496
+ truncate(size) {
11497
+ live();
11498
+ index2(size, "truncate");
11499
+ throw new JsCallError("EINVAL", "truncate");
11500
+ },
11501
+ sync: () => live(),
11502
+ close() {
11503
+ live();
11504
+ end();
11505
+ io.close(fd);
11506
+ }
11507
+ };
11508
+ return { file, invalidate: end };
11509
+ }
11510
+ async function readWhole(file) {
11511
+ try {
11512
+ const parts = [];
11513
+ let got = 0;
11514
+ for (; ; ) {
11515
+ const chunk = await file.read(got, MAX_IO);
11516
+ if (chunk.length === 0) return joined(parts, got);
11517
+ got += chunk.length;
11518
+ tooLarge(got);
11519
+ parts.push(chunk);
11520
+ }
11521
+ } finally {
11522
+ await file.close();
11523
+ }
11524
+ }
11525
+ function readWholeSync(file) {
11526
+ try {
11527
+ const parts = [];
11528
+ let got = 0;
11529
+ for (; ; ) {
11530
+ const chunk = file.read(got, MAX_IO);
11531
+ if (chunk.length === 0) return joined(parts, got);
11532
+ got += chunk.length;
11533
+ tooLarge(got);
11534
+ parts.push(chunk);
11535
+ }
11536
+ } finally {
11537
+ file.close();
11538
+ }
11539
+ }
11540
+ var DEV_READ_MAX, DEVICES2, STDIO3, SELF_FD, S_IFMT2, DIR, LINK, CHAR, BORN;
11541
+ var init_js_dev = __esm({
11542
+ "src/process/js/js-dev.ts"() {
11543
+ "use strict";
11544
+ init_sync_fs_wire();
11545
+ init_js_io();
11546
+ init_js_kernel();
11547
+ DEV_READ_MAX = 64 * 1024 * 1024;
11548
+ DEVICES2 = ["null", "zero", "full", "random", "urandom"];
11549
+ STDIO3 = ["stdin", "stdout", "stderr"];
11550
+ SELF_FD = "/proc/self/fd";
11551
+ S_IFMT2 = 61440;
11552
+ DIR = 16384;
11553
+ LINK = 40960;
11554
+ CHAR = 8192;
11555
+ BORN = Date.now();
11556
+ }
11557
+ });
11558
+
11169
11559
  // src/process/js/js-exit.ts
11170
11560
  function json(r) {
11171
11561
  return r.ok && r.kind === "json" ? r.json : void 0;
@@ -11178,10 +11568,10 @@ function restoreMode(lane, { terminal, fd, termios }) {
11178
11568
  lane({ op: "tty-set", fd: at, termios });
11179
11569
  return;
11180
11570
  }
11181
- const opened = json(lane({ op: "fd-open-tty", name: terminal }));
11182
- if (typeof opened !== "number") return;
11183
- lane({ op: "tty-set", fd: opened, termios });
11184
- lane({ op: "fd-close", fd: opened });
11571
+ const opened2 = json(lane({ op: "fd-open-tty", name: terminal }));
11572
+ if (typeof opened2 !== "number") return;
11573
+ lane({ op: "tty-set", fd: opened2, termios });
11574
+ lane({ op: "fd-close", fd: opened2 });
11185
11575
  }
11186
11576
  function writeOut(lane, fd, data) {
11187
11577
  let at = 0;
@@ -11630,7 +12020,7 @@ function netOps(kernel, io) {
11630
12020
  const r = await kernel.blocking({ op: "sock-resolve", name: host, family: 4 }, signal);
11631
12021
  return (r.ok && r.kind === "json" ? r.json : [])[0];
11632
12022
  };
11633
- const opened = async (use) => {
12023
+ const opened2 = async (use) => {
11634
12024
  const fd = await kernel.json({ op: "sock-open", domain: "inet" });
11635
12025
  try {
11636
12026
  return await use(fd);
@@ -11672,7 +12062,7 @@ function netOps(kernel, io) {
11672
12062
  };
11673
12063
  };
11674
12064
  return {
11675
- listen: (options = {}) => opened(async (fd) => {
12065
+ listen: (options = {}) => opened2(async (fd) => {
11676
12066
  const addr = {
11677
12067
  family: "inet",
11678
12068
  host: options.host ?? "127.0.0.1",
@@ -11692,7 +12082,7 @@ function netOps(kernel, io) {
11692
12082
  host: await resolve(host, signal),
11693
12083
  port: port(options.port)
11694
12084
  };
11695
- return opened(async (fd) => {
12085
+ return opened2(async (fd) => {
11696
12086
  const r = await kernel.raw({ op: "sock-connect", fd, addr, nonblock: true });
11697
12087
  if (!r.ok && r.errno !== "EINPROGRESS") throw new JsCallError(r.errno, "connect");
11698
12088
  await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
@@ -11726,7 +12116,7 @@ var init_js_net = __esm({
11726
12116
  // src/process/js/js-run.ts
11727
12117
  function stdioOf(how) {
11728
12118
  if (how === void 0) return "pipe";
11729
- if (!STDIO3.has(how)) throw new JsCallError("EINVAL", "run");
12119
+ if (!STDIO4.has(how)) throw new JsCallError("EINVAL", "run");
11730
12120
  return how;
11731
12121
  }
11732
12122
  function limit(value2) {
@@ -11774,13 +12164,13 @@ function runSync(kernel, d, o) {
11774
12164
  });
11775
12165
  return decodeRun(bytes, stdout, stderr);
11776
12166
  }
11777
- var encoder2, STDIO3;
12167
+ var encoder2, STDIO4;
11778
12168
  var init_js_run = __esm({
11779
12169
  "src/process/js/js-run.ts"() {
11780
12170
  "use strict";
11781
12171
  init_js_kernel();
11782
12172
  encoder2 = new TextEncoder();
11783
- STDIO3 = /* @__PURE__ */ new Set(["pipe", "ignore", "inherit"]);
12173
+ STDIO4 = /* @__PURE__ */ new Set(["pipe", "ignore", "inherit"]);
11784
12174
  }
11785
12175
  });
11786
12176
 
@@ -11823,13 +12213,30 @@ function syncOps(kernel, shared) {
11823
12213
  };
11824
12214
  const statOf = (op, path) => {
11825
12215
  const abs = resolve(path);
12216
+ if (inDev(abs)) return devSync(kernel, devStat(abs, op === "stat"));
11826
12217
  kernel.call({ op: "fd-path-flush", path: abs });
11827
12218
  const s = parseSyncFsStat(kernel.json({ op, path: abs }));
11828
12219
  if (!s) throw new JsCallError("EIO", op);
11829
12220
  return s;
11830
12221
  };
12222
+ const openDev2 = (abs, options) => {
12223
+ const { fd, file, ...access } = devSync(kernel, devOpen(abs, options));
12224
+ const forget = () => {
12225
+ infos.delete(fd);
12226
+ handles.delete(fd);
12227
+ };
12228
+ if (file) infos.set(fd, { kind: "file" });
12229
+ const close = (n) => {
12230
+ forget();
12231
+ kernel.call({ op: "fd-close", fd: n });
12232
+ };
12233
+ const handle = file ? syncFile(kernel, fd, abs, options.append === true, forget) : streamSyncFile(fd, abs, { read: (n, max) => read2(n, max), write: write2, close }, access);
12234
+ handles.set(fd, handle.invalidate);
12235
+ return handle.file;
12236
+ };
11831
12237
  const open = (path, options = {}) => {
11832
12238
  const abs = resolve(path);
12239
+ if (inDev(abs)) return openDev2(abs, options);
11833
12240
  let existing;
11834
12241
  try {
11835
12242
  existing = statOf(isExclusive(options) ? "lstat" : "stat", abs);
@@ -11933,17 +12340,30 @@ function syncPathOps(kernel, resolve, statOf, open) {
11933
12340
  return {
11934
12341
  stat: (path) => statOf("stat", path),
11935
12342
  lstat: (path) => statOf("lstat", path),
11936
- exists: (path) => kernel.json({ op: "exists", path: resolve(path) }) === true,
11937
- readdir: (path) => kernel.json({ op: "readdir", path: resolve(path) }),
12343
+ exists(path) {
12344
+ const abs = resolve(path);
12345
+ if (inDev(abs)) return devSync(kernel, devExists(abs));
12346
+ return kernel.json({ op: "exists", path: abs }) === true;
12347
+ },
12348
+ readdir(path) {
12349
+ const abs = resolve(path);
12350
+ if (inDev(abs)) return devSync(kernel, devReaddir(abs));
12351
+ return kernel.json({ op: "readdir", path: abs });
12352
+ },
11938
12353
  mkdir: (path) => void kernel.call({ op: "mkdir", path: resolve(path) }),
11939
12354
  rm: (path) => void kernel.call({ op: "rm", path: resolve(path) }),
11940
12355
  unlink: (path) => void kernel.call({ op: "unlink", path: resolve(path) }),
11941
12356
  rename: (from, to) => void kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
11942
12357
  link: (from, to) => void kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
11943
12358
  symlink: (target, path) => void kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
11944
- readlink: (path) => String(kernel.json({ op: "readlink", path: resolve(path) })),
12359
+ readlink(path) {
12360
+ const abs = resolve(path);
12361
+ if (inDev(abs)) return devSync(kernel, devReadlink(abs));
12362
+ return String(kernel.json({ op: "readlink", path: abs }));
12363
+ },
11945
12364
  readFile(path) {
11946
12365
  const abs = resolve(path);
12366
+ if (inDev(abs)) return readWholeSync(open(abs));
11947
12367
  kernel.call({ op: "fd-path-flush", path: abs });
11948
12368
  return kernel.bytes({ op: "read", path: abs });
11949
12369
  },
@@ -11964,6 +12384,7 @@ var init_js_sync = __esm({
11964
12384
  init_signals();
11965
12385
  init_sync_fs_wire();
11966
12386
  init_sync_sab_bridge();
12387
+ init_js_dev();
11967
12388
  init_js_io();
11968
12389
  init_js_kernel();
11969
12390
  encoder3 = new TextEncoder();
@@ -12364,6 +12785,7 @@ function createContext(o) {
12364
12785
  const writable2 = (fd) => new WritableStream({ write: (chunk) => write2(fd, chunk) });
12365
12786
  const statOf = async (op, path) => {
12366
12787
  const abs = resolve(path);
12788
+ if (inDev(abs)) return devAsync(kernel, devStat(abs, op === "stat"));
12367
12789
  await kernel.call({ op: "fd-path-flush", path: abs });
12368
12790
  const s = parseSyncFsStat(await kernel.json({ op, path: abs }));
12369
12791
  if (!s) throw new JsCallError("EIO", op);
@@ -12371,6 +12793,7 @@ function createContext(o) {
12371
12793
  };
12372
12794
  const open = async (path, options = {}) => {
12373
12795
  const abs = resolve(path);
12796
+ if (inDev(abs)) return openDev(kernel, abs, options, { infos, handles, read: read2, write: writeAll });
12374
12797
  const existing = await statOf(isExclusive(options) ? "lstat" : "stat", abs).catch(absent);
12375
12798
  checkOpen(abs, options, existing);
12376
12799
  const fd = await kernel.json(openRequest(abs, options));
@@ -12390,6 +12813,7 @@ function createContext(o) {
12390
12813
  };
12391
12814
  const fs = pathOps(kernel, resolve, statOf, open);
12392
12815
  const lane = o.lane ?? laneOf(void 0);
12816
+ if (o.lane) kernel.syncLane = o.lane;
12393
12817
  const syncKernel = new JsSyncKernel(lane, kernel, unwind);
12394
12818
  const terminal = ttyOps(kernel);
12395
12819
  const sync = {
@@ -12470,6 +12894,26 @@ function createContext(o) {
12470
12894
  };
12471
12895
  return { ctx, drain: drain2 };
12472
12896
  }
12897
+ async function openDev(kernel, abs, options, state) {
12898
+ const { fd, file, ...access } = await devAsync(kernel, devOpen(abs, options));
12899
+ const forget = () => {
12900
+ state.infos.delete(fd);
12901
+ state.handles.delete(fd);
12902
+ };
12903
+ if (file) state.infos.set(fd, { kind: "file" });
12904
+ const close = async (n) => {
12905
+ forget();
12906
+ await kernel.call({ op: "fd-close", fd: n });
12907
+ };
12908
+ const handle = file ? fileHandle(kernel, fd, abs, options.append === true, forget) : streamFile(
12909
+ fd,
12910
+ abs,
12911
+ { read: (n, max) => state.read(n, max), write: state.write, close },
12912
+ access
12913
+ );
12914
+ state.handles.set(fd, handle.invalidate);
12915
+ return handle.file;
12916
+ }
12473
12917
  function fileHandle(kernel, fd, path, append, forget) {
12474
12918
  let open = true;
12475
12919
  const live = () => {
@@ -12562,17 +13006,30 @@ function pathOps(kernel, resolve, statOf, open) {
12562
13006
  return {
12563
13007
  stat: (path) => statOf("stat", path),
12564
13008
  lstat: (path) => statOf("lstat", path),
12565
- exists: async (path) => await kernel.json({ op: "exists", path: resolve(path) }) === true,
12566
- readdir: async (path) => await kernel.json({ op: "readdir", path: resolve(path) }),
13009
+ async exists(path) {
13010
+ const abs = resolve(path);
13011
+ if (inDev(abs)) return devAsync(kernel, devExists(abs));
13012
+ return await kernel.json({ op: "exists", path: abs }) === true;
13013
+ },
13014
+ async readdir(path) {
13015
+ const abs = resolve(path);
13016
+ if (inDev(abs)) return devAsync(kernel, devReaddir(abs));
13017
+ return await kernel.json({ op: "readdir", path: abs });
13018
+ },
12567
13019
  mkdir: async (path) => void await kernel.call({ op: "mkdir", path: resolve(path) }),
12568
13020
  rm: async (path) => void await kernel.call({ op: "rm", path: resolve(path) }),
12569
13021
  unlink: async (path) => void await kernel.call({ op: "unlink", path: resolve(path) }),
12570
13022
  rename: async (from, to) => void await kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
12571
13023
  link: async (from, to) => void await kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
12572
13024
  symlink: async (target, path) => void await kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
12573
- readlink: async (path) => String(await kernel.json({ op: "readlink", path: resolve(path) })),
13025
+ async readlink(path) {
13026
+ const abs = resolve(path);
13027
+ if (inDev(abs)) return devAsync(kernel, devReadlink(abs));
13028
+ return String(await kernel.json({ op: "readlink", path: abs }));
13029
+ },
12574
13030
  async readFile(path) {
12575
13031
  const abs = resolve(path);
13032
+ if (inDev(abs)) return readWhole(await open(abs));
12576
13033
  await kernel.call({ op: "fd-path-flush", path: abs });
12577
13034
  return kernel.bytes({ op: "read", path: abs });
12578
13035
  },
@@ -12593,6 +13050,7 @@ var init_js_context = __esm({
12593
13050
  init_signals();
12594
13051
  init_sync_fs_wire();
12595
13052
  init_js_children();
13053
+ init_js_dev();
12596
13054
  init_js_exit();
12597
13055
  init_js_fetch();
12598
13056
  init_js_io();