@ai-ecoverse/slicc-kernel 1.50.0 → 1.52.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.
@@ -9,8 +9,8 @@ var __esm = (fn, res, err) => function __init() {
9
9
  }
10
10
  };
11
11
  var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
12
+ for (var name2 in all)
13
+ __defProp(target, name2, { get: all[name2], enumerable: true });
14
14
  };
15
15
 
16
16
  // src/kernel/protocol.ts
@@ -30,13 +30,13 @@ var init_protocol = __esm({
30
30
  });
31
31
 
32
32
  // src/kernel/net/loopback-names.ts
33
- function reserved(name) {
34
- const lower = name.toLowerCase();
33
+ function reserved(name2) {
34
+ const lower = name2.toLowerCase();
35
35
  return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
36
36
  }
37
- function isHostname(name) {
38
- if (typeof name !== "string" || name.length > 253 || reserved(name)) return false;
39
- return name.split(".").every((l) => LABEL.test(l));
37
+ function isHostname(name2) {
38
+ if (typeof name2 !== "string" || name2.length > 253 || reserved(name2)) return false;
39
+ return name2.split(".").every((l) => LABEL.test(l));
40
40
  }
41
41
  function hostnameOf(env) {
42
42
  return isHostname(env.HOSTNAME) ? env.HOSTNAME : DEFAULT_HOSTNAME;
@@ -416,11 +416,11 @@ var init_types = __esm({
416
416
  // src/process/wasi/wasi-abi.ts
417
417
  function wasiErrnoOf(code2) {
418
418
  if (!code2) return E.IO;
419
- const name = code2.startsWith("E") ? code2.slice(1) : code2;
420
- if (name === "OPNOTSUPP") return E.NOTSUP;
421
- if (name === "WOULDBLOCK") return E.AGAIN;
422
- if (name === "NOMEDIUM") return E.NODEV;
423
- return E[name] ?? E.IO;
419
+ const name2 = code2.startsWith("E") ? code2.slice(1) : code2;
420
+ if (name2 === "OPNOTSUPP") return E.NOTSUP;
421
+ if (name2 === "WOULDBLOCK") return E.AGAIN;
422
+ if (name2 === "NOMEDIUM") return E.NODEV;
423
+ return E[name2] ?? E.IO;
424
424
  }
425
425
  function wasixSignal(sig) {
426
426
  return Number.isInteger(sig) && sig >= 1 && sig <= 31 ? sig : void 0;
@@ -563,7 +563,7 @@ var init_wasi_errno = __esm({
563
563
  "use strict";
564
564
  init_wasi_abi();
565
565
  WASI_ERRNO = {
566
- ...Object.fromEntries(Object.entries(E).map(([name, errno2]) => [`E${name}`, errno2])),
566
+ ...Object.fromEntries(Object.entries(E).map(([name2, errno2]) => [`E${name2}`, errno2])),
567
567
  EWOULDBLOCK: E.AGAIN,
568
568
  ENOTSUP: 138,
569
569
  EOPNOTSUPP: 138,
@@ -641,8 +641,8 @@ function createHelpers(Fs, ops) {
641
641
  function freshState(stat) {
642
642
  return { ...stat ? { stat } : {}, len: 0, loaded: false, dirty: false, openCount: 0 };
643
643
  }
644
- function makeNode(parent, name, st) {
645
- const node = Fs.createNode(parent, name, modeFromStat(st), 0);
644
+ function makeNode(parent, name2, st) {
645
+ const node = Fs.createNode(parent, name2, modeFromStat(st), 0);
646
646
  node.node_ops = ops.node;
647
647
  node.stream_ops = ops.stream;
648
648
  node.live = freshState(st);
@@ -660,9 +660,9 @@ function createHelpers(Fs, ops) {
660
660
  }
661
661
  return node.live.stat;
662
662
  }
663
- function childPath(parent, name) {
663
+ function childPath(parent, name2) {
664
664
  const base = liveNodePath(parent);
665
- return base === "/" ? `/${name}` : `${base}/${name}`;
665
+ return base === "/" ? `/${name2}` : `${base}/${name2}`;
666
666
  }
667
667
  function ensureLoaded(node) {
668
668
  const s = node.live;
@@ -829,15 +829,15 @@ function createNodeOps(h) {
829
829
  if (times) setTimes(node, path, ...times);
830
830
  node.live.stat = void 0;
831
831
  },
832
- lookup(parent, name) {
833
- const listed = parent.live.listed?.get(name);
834
- parent.live.listed?.delete(name);
835
- const st = listed ?? call2(() => bridgeOf(parent).lstat(childPath(parent, name)));
836
- return makeNode(parent, name, st);
832
+ lookup(parent, name2) {
833
+ const listed = parent.live.listed?.get(name2);
834
+ parent.live.listed?.delete(name2);
835
+ const st = listed ?? call2(() => bridgeOf(parent).lstat(childPath(parent, name2)));
836
+ return makeNode(parent, name2, st);
837
837
  },
838
- mknod(parent, name, mode) {
838
+ mknod(parent, name2, mode) {
839
839
  parent.live.listed = void 0;
840
- const path = childPath(parent, name);
840
+ const path = childPath(parent, name2);
841
841
  if (Fs.isDir(mode)) {
842
842
  call2(() => bridgeOf(parent).mkdir(path));
843
843
  const perm = mode & PERM_MASK & ~UMASK;
@@ -850,7 +850,7 @@ function createNodeOps(h) {
850
850
  } else {
851
851
  throw new Fs.ErrnoError(wasiErrno("EPERM"));
852
852
  }
853
- const node = makeNode(parent, name, {
853
+ const node = makeNode(parent, name2, {
854
854
  isFile: Fs.isFile(mode),
855
855
  isDirectory: Fs.isDir(mode),
856
856
  isSymbolicLink: false,
@@ -877,11 +877,11 @@ function createNodeOps(h) {
877
877
  oldNode.parent = newDir;
878
878
  oldNode.live.stat = void 0;
879
879
  },
880
- unlink(parent, name) {
880
+ unlink(parent, name2) {
881
881
  parent.live.listed = void 0;
882
882
  let open;
883
883
  try {
884
- const node = Fs.lookupNode?.(parent, name);
884
+ const node = Fs.lookupNode?.(parent, name2);
885
885
  if (node && node.live?.openCount > 0 && Fs.isFile(node.mode)) open = node;
886
886
  } catch {
887
887
  }
@@ -891,18 +891,18 @@ function createNodeOps(h) {
891
891
  if (ranged) ranged.pin();
892
892
  else ensureLoaded(open);
893
893
  }
894
- call2(() => bridgeOf(parent).unlink(childPath(parent, name)));
894
+ call2(() => bridgeOf(parent).unlink(childPath(parent, name2)));
895
895
  if (open) open.live.orphan = true;
896
896
  },
897
- rmdir(parent, name) {
897
+ rmdir(parent, name2) {
898
898
  parent.live.listed = void 0;
899
- call2(() => bridgeOf(parent).rmdir(childPath(parent, name)));
899
+ call2(() => bridgeOf(parent).rmdir(childPath(parent, name2)));
900
900
  },
901
901
  readdir(node) {
902
902
  const listed = call2(() => bridgeOf(node).readdirStat(liveNodePath(node)));
903
903
  node.live.listed = /* @__PURE__ */ new Map();
904
- for (const [name, st] of listed) if (st) node.live.listed.set(name, st);
905
- return [".", "..", ...listed.map(([name]) => name)];
904
+ for (const [name2, st] of listed) if (st) node.live.listed.set(name2, st);
905
+ return [".", "..", ...listed.map(([name2]) => name2)];
906
906
  },
907
907
  symlink(parent, newName, target) {
908
908
  parent.live.listed = void 0;
@@ -1165,28 +1165,28 @@ function liveRoot(Fs, bridge) {
1165
1165
  const memfs = root.memfs ?? root.node_ops;
1166
1166
  const live = plugin.node_ops;
1167
1167
  root.memfs = memfs;
1168
- const own = (name) => Object.hasOwn(root.contents ?? {}, name);
1168
+ const own = (name2) => Object.hasOwn(root.contents ?? {}, name2);
1169
1169
  root.node_ops = {
1170
1170
  ...memfs,
1171
- lookup: (parent, name) => live.lookup(parent, name),
1172
- mknod: (parent, name, mode, dev) => live.mknod(parent, name, mode, dev),
1173
- unlink: (parent, name) => live.unlink(parent, name),
1174
- rmdir: (parent, name) => (own(name) ? memfs : live).rmdir(parent, name),
1175
- symlink: (parent, name, target) => live.symlink(parent, name, target),
1176
- rename: (node, dir, name) => (node.live ? live : memfs).rename(node, dir, name),
1171
+ lookup: (parent, name2) => live.lookup(parent, name2),
1172
+ mknod: (parent, name2, mode, dev) => live.mknod(parent, name2, mode, dev),
1173
+ unlink: (parent, name2) => live.unlink(parent, name2),
1174
+ rmdir: (parent, name2) => (own(name2) ? memfs : live).rmdir(parent, name2),
1175
+ symlink: (parent, name2, target) => live.symlink(parent, name2, target),
1176
+ rename: (node, dir, name2) => (node.live ? live : memfs).rename(node, dir, name2),
1177
1177
  readdir(node) {
1178
1178
  const names = new Set(memfs.readdir(node));
1179
- for (const name of live.readdir(node)) names.add(name);
1179
+ for (const name2 of live.readdir(node)) names.add(name2);
1180
1180
  return [...names];
1181
1181
  }
1182
1182
  };
1183
1183
  }
1184
1184
  function crosses(Fs, from, to) {
1185
1185
  const parentOf = (path) => Fs.lookupPath?.(path, { parent: true }).node;
1186
- const name = from.replace(/\/+$/, "").split("/").pop() ?? "";
1186
+ const name2 = from.replace(/\/+$/, "").split("/").pop() ?? "";
1187
1187
  try {
1188
1188
  const fromDir = parentOf(from);
1189
- const node = fromDir && Fs.lookupNode?.(fromDir, name);
1189
+ const node = fromDir && Fs.lookupNode?.(fromDir, name2);
1190
1190
  const dir = parentOf(to);
1191
1191
  return !!node && !!dir && !!node.live !== !!dir.live;
1192
1192
  } catch {
@@ -1227,8 +1227,8 @@ function guardKeptNodes(Fs, handled) {
1227
1227
  Fs.sliccKept = true;
1228
1228
  const lookupPath = Fs.lookupPath.bind(Fs);
1229
1229
  Fs.open = (path, flags, mode) => {
1230
- const name = path.slice(path.lastIndexOf("/") + 1);
1231
- if (![...handled].some((held) => held.name === name)) return open(path, flags, mode);
1230
+ const name2 = path.slice(path.lastIndexOf("/") + 1);
1231
+ if (![...handled].some((held) => held.name === name2)) return open(path, flags, mode);
1232
1232
  let node;
1233
1233
  try {
1234
1234
  node = lookupPath(path, { follow: true }).node;
@@ -1276,7 +1276,7 @@ function topLevelDirs(bridge, warn) {
1276
1276
  warn(`cannot list the VFS root, nothing mounted: ${String(err)}`);
1277
1277
  return void 0;
1278
1278
  }
1279
- const candidates = names.filter((name) => name && !name.includes("/") && !MODULE_OWNED_DIRS.has(name)).map((name) => `/${name}`);
1279
+ const candidates = names.filter((name2) => name2 && !name2.includes("/") && !MODULE_OWNED_DIRS.has(name2)).map((name2) => `/${name2}`);
1280
1280
  for (const dir of SYNTHETIC_DIRS) if (!candidates.includes(dir)) candidates.push(dir);
1281
1281
  const dirs = [];
1282
1282
  for (const dir of candidates) {
@@ -1754,14 +1754,14 @@ var init_kernel_streams = __esm({
1754
1754
  nameTerminal(stream) {
1755
1755
  const kfd = stream.sliccKernelFd;
1756
1756
  if (!stream.tty || kfd === void 0) return;
1757
- const name = this.sys.ttyName?.(kfd);
1758
- if (name) this.nameStream(stream, name);
1757
+ const name2 = this.sys.ttyName?.(kfd);
1758
+ if (name2) this.nameStream(stream, name2);
1759
1759
  }
1760
- nameStream(stream, name) {
1761
- stream.path = name;
1762
- this.ttyNode(name);
1760
+ nameStream(stream, name2) {
1761
+ stream.path = name2;
1762
+ this.ttyNode(name2);
1763
1763
  if (typeof this.Fs.stat !== "function") return;
1764
- stream.stream_ops = { ...stream.stream_ops, getattr: () => this.Fs.stat?.(name) ?? {} };
1764
+ stream.stream_ops = { ...stream.stream_ops, getattr: () => this.Fs.stat?.(name2) ?? {} };
1765
1765
  }
1766
1766
  creatingTerminal = false;
1767
1767
  useTerminalNodes() {
@@ -1769,12 +1769,12 @@ var init_kernel_streams = __esm({
1769
1769
  const { lookupNode, readdir, getPath, mkdev, makedev } = fs;
1770
1770
  const ttyNames = this.sys.ttyNames?.bind(this.sys);
1771
1771
  if (!lookupNode || !readdir || !getPath || !mkdev || !makedev || !ttyNames) return;
1772
- fs.lookupNode = (parent, name) => {
1772
+ fs.lookupNode = (parent, name2) => {
1773
1773
  try {
1774
- return lookupNode.call(fs, parent, name);
1774
+ return lookupNode.call(fs, parent, name2);
1775
1775
  } catch (e) {
1776
- const path = `/dev/${name}`;
1777
- if (this.creatingTerminal || !TTY_NAME.test(name) || getPath.call(fs, parent) !== "/dev")
1776
+ const path = `/dev/${name2}`;
1777
+ if (this.creatingTerminal || !TTY_NAME.test(name2) || getPath.call(fs, parent) !== "/dev")
1778
1778
  throw e;
1779
1779
  if (!ttyNames().includes(path)) throw e;
1780
1780
  this.creatingTerminal = true;
@@ -1783,21 +1783,21 @@ var init_kernel_streams = __esm({
1783
1783
  } finally {
1784
1784
  this.creatingTerminal = false;
1785
1785
  }
1786
- return lookupNode.call(fs, parent, name);
1786
+ return lookupNode.call(fs, parent, name2);
1787
1787
  }
1788
1788
  };
1789
1789
  fs.readdir = (path) => {
1790
1790
  const names = readdir.call(fs, path);
1791
1791
  if (path.replace(/\/+$/, "") !== "/dev") return names;
1792
- const missing = ttyNames().map((tty) => tty.slice("/dev/".length)).filter((name) => TTY_NAME.test(name) && !names.includes(name));
1792
+ const missing = ttyNames().map((tty) => tty.slice("/dev/".length)).filter((name2) => TTY_NAME.test(name2) && !names.includes(name2));
1793
1793
  return [...names, ...missing];
1794
1794
  };
1795
1795
  }
1796
- ttyNode(name) {
1796
+ ttyNode(name2) {
1797
1797
  const { analyzePath, mkdev, makedev } = this.Fs;
1798
- if (!TTY_PATH.test(name) || !analyzePath || !mkdev || !makedev) return;
1799
- if (!analyzePath.call(this.Fs, name).exists)
1800
- mkdev.call(this.Fs, name, makedev.call(this.Fs, 6, 0));
1798
+ if (!TTY_PATH.test(name2) || !analyzePath || !mkdev || !makedev) return;
1799
+ if (!analyzePath.call(this.Fs, name2).exists)
1800
+ mkdev.call(this.Fs, name2, makedev.call(this.Fs, 6, 0));
1801
1801
  }
1802
1802
  ttyOps(kfd) {
1803
1803
  return {
@@ -1834,18 +1834,18 @@ var init_kernel_streams = __esm({
1834
1834
  size: this.call(() => size.call(this.sys, kfd))
1835
1835
  }));
1836
1836
  }
1837
- describe(stream, name, getattr) {
1837
+ describe(stream, name2, getattr) {
1838
1838
  if (this.descriptions.size === 0) this.useDescriptions();
1839
- this.descriptions.set(name, getattr);
1840
- stream.path = name;
1839
+ this.descriptions.set(name2, getattr);
1840
+ stream.path = name2;
1841
1841
  stream.stream_ops = { ...stream.stream_ops, getattr };
1842
1842
  }
1843
1843
  useDescriptions() {
1844
1844
  const fs = this.Fs;
1845
- for (const name of ["stat", "lstat"]) {
1846
- const original = fs[name];
1845
+ for (const name2 of ["stat", "lstat"]) {
1846
+ const original = fs[name2];
1847
1847
  if (typeof original !== "function") continue;
1848
- fs[name] = (path, ...rest2) => {
1848
+ fs[name2] = (path, ...rest2) => {
1849
1849
  const getattr = this.descriptions.get(path);
1850
1850
  return getattr ? getattr() : original.call(fs, path, ...rest2);
1851
1851
  };
@@ -1932,15 +1932,15 @@ var init_kernel_streams = __esm({
1932
1932
  }
1933
1933
  usePtyPaths() {
1934
1934
  const fs = this.Fs;
1935
- for (const name of ["chown", "lchown", "chmod", "lchmod"]) {
1936
- const original = fs[name];
1935
+ for (const name2 of ["chown", "lchown", "chmod", "lchmod"]) {
1936
+ const original = fs[name2];
1937
1937
  if (typeof original !== "function") continue;
1938
- fs[name] = (path, ...rest2) => isPtyPath(path) ? this.existingPty(path) : original.call(fs, path, ...rest2);
1938
+ fs[name2] = (path, ...rest2) => isPtyPath(path) ? this.existingPty(path) : original.call(fs, path, ...rest2);
1939
1939
  }
1940
- for (const name of ["stat", "lstat"]) {
1941
- const original = fs[name];
1940
+ for (const name2 of ["stat", "lstat"]) {
1941
+ const original = fs[name2];
1942
1942
  if (typeof original !== "function") continue;
1943
- fs[name] = (path, ...rest2) => {
1943
+ fs[name2] = (path, ...rest2) => {
1944
1944
  if (!isPtyPath(path)) return original.call(fs, path, ...rest2);
1945
1945
  this.existingPty(path);
1946
1946
  return ptyStat(path);
@@ -1953,14 +1953,14 @@ var init_kernel_streams = __esm({
1953
1953
  if (!exists) throw new this.Fs.ErrnoError(wasiErrno("ENOENT"));
1954
1954
  }
1955
1955
  devicePath(path) {
1956
- const name = path.slice(path.lastIndexOf("/") + 1);
1957
- if (!TTY_NAME.test(name)) return void 0;
1956
+ const name2 = path.slice(path.lastIndexOf("/") + 1);
1957
+ if (!TTY_NAME.test(name2)) return void 0;
1958
1958
  const { lookupPath, cwd } = this.Fs;
1959
1959
  const absolute = path.startsWith("/") ? path : `${cwd?.call(this.Fs) ?? "/"}/${path}`;
1960
1960
  const dir = absolute.slice(0, absolute.lastIndexOf("/")) || "/";
1961
1961
  try {
1962
1962
  const real = lookupPath?.call(this.Fs, dir, { follow: true }).path ?? dir;
1963
- return `${real === "/" ? "" : real}/${name}`;
1963
+ return `${real === "/" ? "" : real}/${name2}`;
1964
1964
  } catch {
1965
1965
  return absolute;
1966
1966
  }
@@ -2257,11 +2257,11 @@ function kernelTimer(setitimer, timer) {
2257
2257
  return 0;
2258
2258
  };
2259
2259
  }
2260
- function syscallOf(glue, name, value2) {
2260
+ function syscallOf(glue, name2, value2) {
2261
2261
  const names = Object.keys(IMPORT_NAMES);
2262
2262
  const own = names.find((key) => glue[key] !== void 0 && glue[key] === value2);
2263
2263
  if (own) return own;
2264
- return typeof value2 === "function" ? names.find((key) => glue[key] !== void 0 && IMPORT_NAMES[key] === name) : void 0;
2264
+ return typeof value2 === "function" ? names.find((key) => glue[key] !== void 0 && IMPORT_NAMES[key] === name2) : void 0;
2265
2265
  }
2266
2266
  function wrapCloexecSyscalls(imports, glue, deps) {
2267
2267
  if (!glue) return;
@@ -2270,10 +2270,10 @@ function wrapCloexecSyscalls(imports, glue, deps) {
2270
2270
  for (const namespace of Object.values(imports)) {
2271
2271
  if (!namespace || typeof namespace !== "object" || seen.has(namespace)) continue;
2272
2272
  seen.add(namespace);
2273
- for (const [name, value2] of Object.entries(namespace)) {
2274
- const key = syscallOf(glue, name, value2);
2273
+ for (const [name2, value2] of Object.entries(namespace)) {
2274
+ const key = syscallOf(glue, name2, value2);
2275
2275
  const wrap2 = key && factories[key];
2276
- if (wrap2) namespace[name] = wrap2(value2);
2276
+ if (wrap2) namespace[name2] = wrap2(value2);
2277
2277
  }
2278
2278
  }
2279
2279
  }
@@ -2317,7 +2317,7 @@ function kernelUmask(imports, deps) {
2317
2317
  function noFollowUtimes(imports, fs, glue) {
2318
2318
  for (const namespace of namespaces(imports)) {
2319
2319
  const key = Object.keys(namespace).find(
2320
- (name) => glue !== void 0 && namespace[name] === glue || name === "__syscall_utimensat"
2320
+ (name2) => glue !== void 0 && namespace[name2] === glue || name2 === "__syscall_utimensat"
2321
2321
  );
2322
2322
  const utimensat = key === void 0 ? void 0 : namespace[key];
2323
2323
  if (key === void 0 || typeof utimensat !== "function") continue;
@@ -2357,10 +2357,10 @@ function namespaces(imports) {
2357
2357
  }
2358
2358
  return [...seen];
2359
2359
  }
2360
- function keyOf(namespace, name, glue) {
2361
- const own = glue?.[name];
2360
+ function keyOf(namespace, name2, glue) {
2361
+ const own = glue?.[name2];
2362
2362
  const found = typeof own === "function" ? Object.keys(namespace).find((k) => namespace[k] === own) : void 0;
2363
- return found ?? (typeof namespace[name] === "function" ? name : void 0);
2363
+ return found ?? (typeof namespace[name2] === "function" ? name2 : void 0);
2364
2364
  }
2365
2365
  function syncFsync(imports, fs, glue) {
2366
2366
  for (const namespace of namespaces(imports)) {
@@ -2424,11 +2424,11 @@ function positioned(original, write2, deps) {
2424
2424
  }
2425
2425
  function positionalIo(imports, deps) {
2426
2426
  for (const namespace of namespaces(imports)) {
2427
- for (const [name, write2] of [
2427
+ for (const [name2, write2] of [
2428
2428
  ["fd_pread", false],
2429
2429
  ["fd_pwrite", true]
2430
2430
  ]) {
2431
- const key = keyOf(namespace, name, deps.glue);
2431
+ const key = keyOf(namespace, name2, deps.glue);
2432
2432
  if (key !== void 0) {
2433
2433
  namespace[key] = positioned(namespace[key], write2, deps);
2434
2434
  }
@@ -2530,8 +2530,8 @@ function describeFdDir(Fs) {
2530
2530
  dir.node_ops = {
2531
2531
  ...ops,
2532
2532
  getattr: () => syntheticAttr(DIR_MODE, 1),
2533
- lookup: (parent, name) => {
2534
- const entry = lookup(parent, name);
2533
+ lookup: (parent, name2) => {
2534
+ const entry = lookup(parent, name2);
2535
2535
  entry.node_ops = {
2536
2536
  ...entry.node_ops,
2537
2537
  getattr: () => syntheticAttr(LINK_MODE, entry.id ?? 0)
@@ -2568,13 +2568,13 @@ function useZeroDevices(Fs) {
2568
2568
  function linkStdio(Fs) {
2569
2569
  const { unlink, symlink } = Fs;
2570
2570
  if (!unlink || !symlink) return;
2571
- for (const [fd, name] of ["stdin", "stdout", "stderr"].entries()) {
2571
+ for (const [fd, name2] of ["stdin", "stdout", "stderr"].entries()) {
2572
2572
  try {
2573
- unlink.call(Fs, `/dev/${name}`);
2573
+ unlink.call(Fs, `/dev/${name2}`);
2574
2574
  } catch {
2575
2575
  }
2576
2576
  try {
2577
- symlink.call(Fs, `/proc/self/fd/${fd}`, `/dev/${name}`);
2577
+ symlink.call(Fs, `/proc/self/fd/${fd}`, `/dev/${name2}`);
2578
2578
  } catch {
2579
2579
  }
2580
2580
  }
@@ -2626,14 +2626,14 @@ function mountTable(mounts = []) {
2626
2626
  }
2627
2627
  function accounts(env = {}) {
2628
2628
  const user = env.USER ?? "web_user";
2629
- const name = NAME.test(user) && user !== "root" ? user : "user";
2629
+ const name2 = NAME.test(user) && user !== "root" ? user : "user";
2630
2630
  const home = env.HOME || "/home";
2631
2631
  return {
2632
2632
  passwd: `root:x:0:0:root:/root:/bin/sh
2633
- ${name}:x:1000:1000:${name}:${home}:/bin/bash
2633
+ ${name2}:x:1000:1000:${name2}:${home}:/bin/bash
2634
2634
  `,
2635
2635
  group: `root:x:0:
2636
- ${name}:x:1000:
2636
+ ${name2}:x:1000:
2637
2637
  `
2638
2638
  };
2639
2639
  }
@@ -3442,9 +3442,9 @@ function createSocketKernel(deps) {
3442
3442
  }),
3443
3443
  shutdown: (fd, how) => guard(() => done({ op: "sock-shutdown", fd: kfd(fd), how })),
3444
3444
  name: (fd, peer) => guard(() => json({ op: "sock-name", fd: kfd(fd), peer })),
3445
- getopt: (fd, level, name) => guard(() => ({ value: json({ op: "sock-getopt", fd: kfd(fd), level, name }) })),
3446
- setopt: (fd, level, name, value2) => guard(() => done({ op: "sock-setopt", fd: kfd(fd), level, name, value: value2 })),
3447
- resolve: (name, family = 4) => guard(() => json({ op: "sock-resolve", name, family })),
3445
+ getopt: (fd, level, name2) => guard(() => ({ value: json({ op: "sock-getopt", fd: kfd(fd), level, name: name2 }) })),
3446
+ setopt: (fd, level, name2, value2) => guard(() => done({ op: "sock-setopt", fd: kfd(fd), level, name: name2, value: value2 })),
3447
+ resolve: (name2, family = 4) => guard(() => json({ op: "sock-resolve", name: name2, family })),
3448
3448
  send: (fd, bytes, flags) => guard(() => {
3449
3449
  const stream = socketAt(fd);
3450
3450
  const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
@@ -3501,8 +3501,8 @@ var init_cred = __esm({
3501
3501
 
3502
3502
  // src/process/procfs.ts
3503
3503
  function commOf(info) {
3504
- const name = info.argv[0] ?? "";
3505
- return name.slice(name.lastIndexOf("/") + 1).slice(0, 15);
3504
+ const name2 = info.argv[0] ?? "";
3505
+ return name2.slice(name2.lastIndexOf("/") + 1).slice(0, 15);
3506
3506
  }
3507
3507
  function ttyNumber(tty) {
3508
3508
  const pts = tty && /^\/dev\/pts\/(\d+)$/.exec(tty);
@@ -3589,12 +3589,12 @@ function pidStatus(info) {
3589
3589
  ""
3590
3590
  ].join("\n");
3591
3591
  }
3592
- function pidFile(name, info, boot) {
3593
- if (name === "cmdline") return info.state === "Z" ? "" : `${info.argv.join("\0")}\0`;
3594
- if (name === "comm") return `${commOf(info)}
3592
+ function pidFile(name2, info, boot) {
3593
+ if (name2 === "cmdline") return info.state === "Z" ? "" : `${info.argv.join("\0")}\0`;
3594
+ if (name2 === "comm") return `${commOf(info)}
3595
3595
  `;
3596
- if (name === "stat") return pidStat(info, boot);
3597
- if (name === "statm") {
3596
+ if (name2 === "stat") return pidStat(info, boot);
3597
+ if (name2 === "statm") {
3598
3598
  const p = pages(info.memory);
3599
3599
  return `${p} ${p} 0 0 0 ${p} 0
3600
3600
  `;
@@ -3618,18 +3618,18 @@ function memoryInfo(source, used = 0) {
3618
3618
  ["SwapFree", kb(0)]
3619
3619
  ].map(([key, value2]) => `${`${key}:`.padEnd(16)}${value2.padStart(12)}`).concat("").join("\n");
3620
3620
  }
3621
- function systemFile(name, listing, now, memory) {
3621
+ function systemFile(name2, listing, now, memory) {
3622
3622
  const up = Math.max(0, now - listing.boot) / 1e3;
3623
- if (name === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
3623
+ if (name2 === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
3624
3624
  `;
3625
- if (name === "meminfo") {
3625
+ if (name2 === "meminfo") {
3626
3626
  return memoryInfo(
3627
3627
  memory,
3628
3628
  listing.processes.reduce((sum, p) => sum + p.memory, 0)
3629
3629
  );
3630
3630
  }
3631
3631
  const live = listing.processes.filter((p) => p.state !== "Z");
3632
- if (name === "loadavg") {
3632
+ if (name2 === "loadavg") {
3633
3633
  const last = Math.max(0, ...listing.processes.map((p) => p.pid));
3634
3634
  return `0.00 0.00 0.00 1/${live.length} ${last}
3635
3635
  `;
@@ -3688,8 +3688,8 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3688
3688
  return;
3689
3689
  }
3690
3690
  const error = (errno2 = ENOENT) => new Fs.ErrnoError(errno2);
3691
- const fresh = (parent, name, mode) => {
3692
- const node = createNode.call(Fs, parent, name, mode, 0);
3691
+ const fresh = (parent, name2, mode) => {
3692
+ const node = createNode.call(Fs, parent, name2, mode, 0);
3693
3693
  hashRemoveNode.call(Fs, node);
3694
3694
  node.node_ops = { getattr: attr, setattr: () => {
3695
3695
  } };
@@ -3702,8 +3702,8 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3702
3702
  };
3703
3703
  return node;
3704
3704
  };
3705
- const file = (parent, name, content) => {
3706
- const node = fresh(parent, name, FILE_MODE);
3705
+ const file = (parent, name2, content) => {
3706
+ const node = fresh(parent, name2, FILE_MODE);
3707
3707
  node.stream_ops = {
3708
3708
  open: (stream) => {
3709
3709
  stream.sliccProc = new TextEncoder().encode(content());
@@ -3725,15 +3725,15 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3725
3725
  };
3726
3726
  const find = (processes2, target, own) => (own ? processes2.find((p) => p.tid === target) : void 0) ?? processes2.find((p) => p.pid === target || p.tid === target);
3727
3727
  const infoOf = (target) => find(procList().processes, target, false);
3728
- const pidContent = (target, name, own = false) => () => {
3728
+ const pidContent = (target, name2, own = false) => () => {
3729
3729
  const listing = procList();
3730
3730
  const info = find(listing.processes, target, own);
3731
3731
  if (!info) throw error(ESRCH);
3732
- return pidFile(name, info, listing.boot);
3732
+ return pidFile(name2, info, listing.boot);
3733
3733
  };
3734
3734
  const pidNames = (names) => [.../* @__PURE__ */ new Set([...names, ...PID_FILES])];
3735
- const pidDir = (name, target) => {
3736
- const dir = fresh(proc, name, DIR_MODE2);
3735
+ const pidDir = (name2, target) => {
3736
+ const dir = fresh(proc, name2, DIR_MODE2);
3737
3737
  dir.node_ops.lookup = (parent, child) => {
3738
3738
  if (!PID_FILES.includes(child)) throw error();
3739
3739
  return file(parent, child, pidContent(target, child));
@@ -3746,25 +3746,25 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3746
3746
  const readdir = procOps.readdir?.bind(procOps);
3747
3747
  proc.node_ops = {
3748
3748
  ...procOps,
3749
- lookup: (parent, name) => {
3750
- if (/^[1-9]\d*$/.test(name)) {
3751
- if (!infoOf(Number(name))) throw error();
3752
- return pidDir(name, Number(name));
3749
+ lookup: (parent, name2) => {
3750
+ if (/^[1-9]\d*$/.test(name2)) {
3751
+ if (!infoOf(Number(name2))) throw error();
3752
+ return pidDir(name2, Number(name2));
3753
3753
  }
3754
- if (name === "mounts") return file(parent, name, () => mountTable(sys.mountList?.() ?? []));
3755
- if (SYSTEM_FILES.includes(name)) {
3754
+ if (name2 === "mounts") return file(parent, name2, () => mountTable(sys.mountList?.() ?? []));
3755
+ if (SYSTEM_FILES.includes(name2)) {
3756
3756
  return file(
3757
3757
  parent,
3758
- name,
3759
- () => systemFile(name, procList(), Date.now(), memory)
3758
+ name2,
3759
+ () => systemFile(name2, procList(), Date.now(), memory)
3760
3760
  );
3761
3761
  }
3762
3762
  if (!lookup) throw error();
3763
- return lookup(parent, name);
3763
+ return lookup(parent, name2);
3764
3764
  },
3765
3765
  readdir: (node) => {
3766
3766
  const names = new Set(readdir ? readdir(node) : [".", ".."]);
3767
- for (const name of [...SYSTEM_FILES, "mounts"]) names.add(name);
3767
+ for (const name2 of [...SYSTEM_FILES, "mounts"]) names.add(name2);
3768
3768
  for (const p of procList().processes) names.add(String(p.pid));
3769
3769
  return [...names];
3770
3770
  }
@@ -3774,18 +3774,18 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3774
3774
  const shownPid = () => String(find(procList().processes, pid, true)?.pid ?? pid);
3775
3775
  link.node_ops.readlink = shownPid;
3776
3776
  const procLookup = proc.node_ops.lookup;
3777
- proc.node_ops.lookup = (parent, name) => name === "self" ? link : name === shownPid() ? self : procLookup(parent, name);
3777
+ proc.node_ops.lookup = (parent, name2) => name2 === "self" ? link : name2 === shownPid() ? self : procLookup(parent, name2);
3778
3778
  const selfOps = self.node_ops;
3779
3779
  const selfLookup = selfOps.lookup?.bind(selfOps);
3780
3780
  const selfReaddir = selfOps.readdir?.bind(selfOps);
3781
3781
  self.node_ops = {
3782
3782
  ...selfOps,
3783
- lookup: (parent, name) => {
3784
- if (PID_FILES.includes(name)) {
3785
- return file(parent, name, pidContent(pid, name, true));
3783
+ lookup: (parent, name2) => {
3784
+ if (PID_FILES.includes(name2)) {
3785
+ return file(parent, name2, pidContent(pid, name2, true));
3786
3786
  }
3787
3787
  if (!selfLookup) throw error();
3788
- return selfLookup(parent, name);
3788
+ return selfLookup(parent, name2);
3789
3789
  },
3790
3790
  readdir: (node) => pidNames(selfReaddir ? selfReaddir(node) : [".", ".."])
3791
3791
  };
@@ -3920,9 +3920,9 @@ function kernelSys(transport) {
3920
3920
  ttyNames() {
3921
3921
  return json(call2({ op: "fd-tty-names" }, "fd-tty-names"));
3922
3922
  },
3923
- openTty(name) {
3924
- const req = name === void 0 ? { op: "fd-open-tty" } : { op: "fd-open-tty", name };
3925
- return json(call2(req, `fd-open-tty ${name ?? ""}`));
3923
+ openTty(name2) {
3924
+ const req = name2 === void 0 ? { op: "fd-open-tty" } : { op: "fd-open-tty", name: name2 };
3925
+ return json(call2(req, `fd-open-tty ${name2 ?? ""}`));
3926
3926
  },
3927
3927
  tcgets(fd) {
3928
3928
  return json(call2({ op: "tty-get", fd }, `tty-get ${fd}`));
@@ -4013,8 +4013,8 @@ function wireKernelStdio(Fs, streams, sys) {
4013
4013
  function glueBody(glue) {
4014
4014
  return glue.startsWith("#!") ? glue.slice(glue.indexOf("\n") + 1) : glue;
4015
4015
  }
4016
- function ownValue(module, name) {
4017
- const own = Object.getOwnPropertyDescriptor(module, name);
4016
+ function ownValue(module, name2) {
4017
+ const own = Object.getOwnPropertyDescriptor(module, name2);
4018
4018
  return own && "value" in own ? own.value : void 0;
4019
4019
  }
4020
4020
  function identify(transport, init) {
@@ -4342,11 +4342,66 @@ var init_process_runtime = __esm({
4342
4342
  }
4343
4343
  });
4344
4344
 
4345
+ // src/fs/physical-path.ts
4346
+ function start(path) {
4347
+ return { done: [], todo: path.split("/").filter((p) => p !== ""), hops: 0 };
4348
+ }
4349
+ function next(walk) {
4350
+ while (walk.todo.length > 0) {
4351
+ const part = walk.todo.shift();
4352
+ if (part === ".") continue;
4353
+ if (part === "..") {
4354
+ walk.done.pop();
4355
+ continue;
4356
+ }
4357
+ return part;
4358
+ }
4359
+ return void 0;
4360
+ }
4361
+ function lexical(path) {
4362
+ const walk = start(path);
4363
+ for (let part = next(walk); part !== void 0; part = next(walk)) walk.done.push(part);
4364
+ return `/${walk.done.join("/")}`;
4365
+ }
4366
+ function rest(walk, part) {
4367
+ return lexical(`/${[...walk.done, part, ...walk.todo].join("/")}`);
4368
+ }
4369
+ function follow(walk, target) {
4370
+ if (++walk.hops > MAX_HOPS) return false;
4371
+ if (target.startsWith("/")) walk.done.length = 0;
4372
+ walk.todo = [...target.split("/").filter((p) => p !== ""), ...walk.todo];
4373
+ return true;
4374
+ }
4375
+ function physicalPath(fs, path) {
4376
+ const walk = start(path);
4377
+ for (let part = next(walk); part !== void 0; part = next(walk)) {
4378
+ const at = `/${[...walk.done, part].join("/")}`;
4379
+ let target;
4380
+ try {
4381
+ target = fs.lstat(at).isSymbolicLink ? fs.readlink(at) : void 0;
4382
+ } catch {
4383
+ return rest(walk, part);
4384
+ }
4385
+ if (target === void 0) walk.done.push(part);
4386
+ else if (!follow(walk, target)) {
4387
+ throw Object.assign(new Error("too many levels of symbolic links"), { code: "ELOOP" });
4388
+ }
4389
+ }
4390
+ return `/${walk.done.join("/")}`;
4391
+ }
4392
+ var MAX_HOPS;
4393
+ var init_physical_path = __esm({
4394
+ "src/fs/physical-path.ts"() {
4395
+ "use strict";
4396
+ MAX_HOPS = 40;
4397
+ }
4398
+ });
4399
+
4345
4400
  // src/process/wasi/dylink.ts
4346
4401
  function dylinkInfo(module) {
4347
- const [section] = WebAssembly.Module.customSections(module, "dylink.0");
4348
- if (!section) return void 0;
4349
- const bytes = new Uint8Array(section);
4402
+ const [section2] = WebAssembly.Module.customSections(module, "dylink.0");
4403
+ if (!section2) return void 0;
4404
+ const bytes = new Uint8Array(section2);
4350
4405
  let at = 0;
4351
4406
  const uleb = () => {
4352
4407
  let value2 = 0;
@@ -4454,10 +4509,10 @@ function cachingBridge(bridge, now = () => performance.now()) {
4454
4509
  readdirStat: (p) => {
4455
4510
  const list = bridge.readdirStat(p);
4456
4511
  const base = p === "/" ? "" : p;
4457
- for (const [name, st] of list) {
4512
+ for (const [name2, st] of list) {
4458
4513
  if (!st) continue;
4459
- lstats.set(`${base}/${name}`, st);
4460
- if (!st.isSymbolicLink) stats.set(`${base}/${name}`, st);
4514
+ lstats.set(`${base}/${name2}`, st);
4515
+ if (!st.isSymbolicLink) stats.set(`${base}/${name2}`, st);
4461
4516
  }
4462
4517
  return list;
4463
4518
  },
@@ -4715,6 +4770,10 @@ function kernelEntry2() {
4715
4770
  function deviceEntry(meta) {
4716
4771
  return { type: "device", device: meta.device, ...meta.access ? { access: meta.access } : {} };
4717
4772
  }
4773
+ function refuseWrite(s, oflags, rights) {
4774
+ const writes = (rights & RIGHTS.FD_WRITE) !== 0n || (oflags & OFLAGS.TRUNC) !== 0;
4775
+ if (s?.readonly && writes) throw new WasiError("EROFS");
4776
+ }
4718
4777
  function preopenOf(e) {
4719
4778
  return {
4720
4779
  ...e.preopen ? { preopen: e.preopen } : {},
@@ -4822,8 +4881,8 @@ var init_wasi_fds = __esm({
4822
4881
  } catch {
4823
4882
  return out;
4824
4883
  }
4825
- for (const name of [.../* @__PURE__ */ new Set([...names, "dev", ...SYNTHETIC_DIRS2])].sort()) {
4826
- const path = `/${name}`;
4884
+ for (const name2 of [.../* @__PURE__ */ new Set([...names, "dev", ...SYNTHETIC_DIRS2])].sort()) {
4885
+ const path = `/${name2}`;
4827
4886
  if (path === "/dev") {
4828
4887
  out.push({ type: "dir", path, preopen: path });
4829
4888
  continue;
@@ -5182,6 +5241,7 @@ var init_wasi_fds = __esm({
5182
5241
  return this.install({ type: "dir", path });
5183
5242
  }
5184
5243
  if (!s && !(oflags & OFLAGS.CREAT)) throw new WasiError("ENOENT");
5244
+ refuseWrite(s, oflags, rights);
5185
5245
  if (this.shared) return this.kernelFile(path, s, oflags, rights, fdflags);
5186
5246
  return this.install({ type: "file", file: this.file(path, s, oflags, rights, fdflags) });
5187
5247
  }
@@ -5559,8 +5619,8 @@ function kernelFiletype(kind) {
5559
5619
  return { filetype: FILETYPE.UNKNOWN, seeks: false };
5560
5620
  }
5561
5621
  }
5562
- function direntRecord(next2, ino, name, filetype) {
5563
- const nameBytes = new TextEncoder().encode(name);
5622
+ function direntRecord(next2, ino, name2, filetype) {
5623
+ const nameBytes = new TextEncoder().encode(name2);
5564
5624
  const record = new Uint8Array(SIZE.DIRENT + nameBytes.length);
5565
5625
  const v = new DataView(record.buffer);
5566
5626
  v.setBigUint64(0, BigInt(next2), true);
@@ -5572,8 +5632,8 @@ function direntRecord(next2, ino, name, filetype) {
5572
5632
  }
5573
5633
  function wrap(table) {
5574
5634
  const out = {};
5575
- for (const [name, fn] of Object.entries(table)) {
5576
- out[name] = (...args) => {
5635
+ for (const [name2, fn] of Object.entries(table)) {
5636
+ out[name2] = (...args) => {
5577
5637
  try {
5578
5638
  return fn(...args) ?? E.SUCCESS;
5579
5639
  } catch (e) {
@@ -5634,8 +5694,8 @@ var init_wasi_host = __esm({
5634
5694
  return kernel.call(req);
5635
5695
  };
5636
5696
  const sys = new Proxy(kernel.sys, {
5637
- get: (target, name) => {
5638
- const member = Reflect.get(target, name);
5697
+ get: (target, name2) => {
5698
+ const member = Reflect.get(target, name2);
5639
5699
  if (typeof member !== "function") return member;
5640
5700
  return (...args) => {
5641
5701
  this.fds.flushEarly();
@@ -5863,13 +5923,13 @@ var init_wasi_host = __esm({
5863
5923
  } else if (e.type === "dir") this.setTimes(e.path, atim, mtim, flags);
5864
5924
  },
5865
5925
  fd_prestat_get: (fd, out) => {
5866
- const name = new TextEncoder().encode(fds.preopen(fd).preopen);
5926
+ const name2 = new TextEncoder().encode(fds.preopen(fd).preopen);
5867
5927
  mem.view().setUint8(out, PREOPENTYPE_DIR);
5868
- mem.view().setUint32(out + 4, name.length, true);
5928
+ mem.view().setUint32(out + 4, name2.length, true);
5869
5929
  },
5870
5930
  fd_prestat_dir_name: (fd, buf, len) => {
5871
- const name = new TextEncoder().encode(fds.preopen(fd).preopen);
5872
- mem.bytes(buf, Math.min(len, name.length)).set(name.subarray(0, len));
5931
+ const name2 = new TextEncoder().encode(fds.preopen(fd).preopen);
5932
+ mem.bytes(buf, Math.min(len, name2.length)).set(name2.subarray(0, len));
5873
5933
  },
5874
5934
  fd_readdir: (fd, buf, len, cookie, used) => void this.readdir(fd, buf, len, Number(cookie), used)
5875
5935
  };
@@ -6148,14 +6208,14 @@ var init_wasi_host = __esm({
6148
6208
  const { names, stats } = dir.listing;
6149
6209
  let at = 0;
6150
6210
  for (let i = cookie; i < names.length && at < len; i++) {
6151
- const name = names[i];
6152
- const full = name === "." ? dir.path : name === ".." ? normalize(`${dir.path}/..`) : resolveUnder(dir.path, name);
6153
- if (!stats.has(name)) stats.set(name, this.lstatOrNull(full));
6154
- const st = stats.get(name) ?? null;
6211
+ const name2 = names[i];
6212
+ const full = name2 === "." ? dir.path : name2 === ".." ? normalize(`${dir.path}/..`) : resolveUnder(dir.path, name2);
6213
+ if (!stats.has(name2)) stats.set(name2, this.lstatOrNull(full));
6214
+ const st = stats.get(name2) ?? null;
6155
6215
  const record = direntRecord(
6156
6216
  i + 1,
6157
6217
  st?.ino !== void 0 ? BigInt(st.ino) : pathInode(full),
6158
- name,
6218
+ name2,
6159
6219
  filetypeOf(st)
6160
6220
  );
6161
6221
  const n = Math.min(record.length, len - at);
@@ -6167,7 +6227,7 @@ var init_wasi_host = __esm({
6167
6227
  list(path) {
6168
6228
  const { fs } = this.o;
6169
6229
  const listed = fs.readdirStat(path);
6170
- return { names: [".", "..", ...listed.map(([name]) => name)], stats: new Map(listed) };
6230
+ return { names: [".", "..", ...listed.map(([name2]) => name2)], stats: new Map(listed) };
6171
6231
  }
6172
6232
  lstatOrNull(path) {
6173
6233
  try {
@@ -6253,61 +6313,6 @@ var init_wasi_threads = __esm({
6253
6313
  }
6254
6314
  });
6255
6315
 
6256
- // src/fs/physical-path.ts
6257
- function start(path) {
6258
- return { done: [], todo: path.split("/").filter((p) => p !== ""), hops: 0 };
6259
- }
6260
- function next(walk) {
6261
- while (walk.todo.length > 0) {
6262
- const part = walk.todo.shift();
6263
- if (part === ".") continue;
6264
- if (part === "..") {
6265
- walk.done.pop();
6266
- continue;
6267
- }
6268
- return part;
6269
- }
6270
- return void 0;
6271
- }
6272
- function lexical(path) {
6273
- const walk = start(path);
6274
- for (let part = next(walk); part !== void 0; part = next(walk)) walk.done.push(part);
6275
- return `/${walk.done.join("/")}`;
6276
- }
6277
- function rest(walk, part) {
6278
- return lexical(`/${[...walk.done, part, ...walk.todo].join("/")}`);
6279
- }
6280
- function follow(walk, target) {
6281
- if (++walk.hops > MAX_HOPS) return false;
6282
- if (target.startsWith("/")) walk.done.length = 0;
6283
- walk.todo = [...target.split("/").filter((p) => p !== ""), ...walk.todo];
6284
- return true;
6285
- }
6286
- function physicalPath(fs, path) {
6287
- const walk = start(path);
6288
- for (let part = next(walk); part !== void 0; part = next(walk)) {
6289
- const at = `/${[...walk.done, part].join("/")}`;
6290
- let target;
6291
- try {
6292
- target = fs.lstat(at).isSymbolicLink ? fs.readlink(at) : void 0;
6293
- } catch {
6294
- return rest(walk, part);
6295
- }
6296
- if (target === void 0) walk.done.push(part);
6297
- else if (!follow(walk, target)) {
6298
- throw Object.assign(new Error("too many levels of symbolic links"), { code: "ELOOP" });
6299
- }
6300
- }
6301
- return `/${walk.done.join("/")}`;
6302
- }
6303
- var MAX_HOPS;
6304
- var init_physical_path = __esm({
6305
- "src/fs/physical-path.ts"() {
6306
- "use strict";
6307
- MAX_HOPS = 40;
6308
- }
6309
- });
6310
-
6311
6316
  // src/process/wasi/wasix-process.ts
6312
6317
  function restarted2(issue) {
6313
6318
  for (; ; ) {
@@ -6354,18 +6359,18 @@ var init_wasix_process = __esm({
6354
6359
  environment() {
6355
6360
  return { ...this.host.o.env, PWD: this.host.cwd };
6356
6361
  }
6357
- locate(name, search, path) {
6358
- if (name.includes("/"))
6359
- return name.startsWith("/") ? name : normalize(`${this.host.cwd}/${name}`);
6360
- if (!search) return name;
6362
+ locate(name2, search, path) {
6363
+ if (name2.includes("/"))
6364
+ return name2.startsWith("/") ? name2 : normalize(`${this.host.cwd}/${name2}`);
6365
+ if (!search) return name2;
6361
6366
  for (const dir of path.split(":")) {
6362
6367
  if (!dir) continue;
6363
6368
  const candidate = normalize(
6364
- `${dir.startsWith("/") ? "" : `${this.host.cwd}/`}${dir}/${name}`
6369
+ `${dir.startsWith("/") ? "" : `${this.host.cwd}/`}${dir}/${name2}`
6365
6370
  );
6366
6371
  if (this.host.o.fs.exists(candidate)) return candidate;
6367
6372
  }
6368
- return name;
6373
+ return name2;
6369
6374
  }
6370
6375
  childFds(ops) {
6371
6376
  const { fds } = this.host;
@@ -6680,7 +6685,7 @@ function processes(host, call2, inThread) {
6680
6685
  const theirs = [];
6681
6686
  host.fds.promoteFiles();
6682
6687
  try {
6683
- const stdio = STDIO.map((name, n) => slot(n, o[name] ?? "inherit", mine, theirs));
6688
+ const stdio = STDIO.map((name2, n) => slot(n, o[name2] ?? "inherit", mine, theirs));
6684
6689
  const req = {
6685
6690
  op: "proc-spawn",
6686
6691
  file: o.argv[0],
@@ -6692,8 +6697,8 @@ function processes(host, call2, inThread) {
6692
6697
  };
6693
6698
  const pid = restarted2(() => call2(req));
6694
6699
  const out = { pid };
6695
- STDIO.forEach((name, n) => {
6696
- if (mine[n] !== void 0) out[name] = mine[n];
6700
+ STDIO.forEach((name2, n) => {
6701
+ if (mine[n] !== void 0) out[name2] = mine[n];
6697
6702
  });
6698
6703
  return out;
6699
6704
  } catch (err) {
@@ -6748,6 +6753,191 @@ var init_wasi_module = __esm({
6748
6753
  }
6749
6754
  });
6750
6755
 
6756
+ // src/process/wasi/wasi-procfs.ts
6757
+ function inProc(path) {
6758
+ return path === "/proc" || path.startsWith("/proc/");
6759
+ }
6760
+ function procfsBridge(fs, tree) {
6761
+ const over = {
6762
+ readFile: (p) => inProc(p) ? tree.read(p) : fs.readFile(p),
6763
+ stat: (p) => inProc(p) ? tree.stat(p) : fs.stat(p),
6764
+ lstat: (p) => inProc(p) ? tree.stat(p, false) : fs.lstat(p),
6765
+ readdir: (p) => {
6766
+ if (inProc(p)) return tree.readdir(p);
6767
+ const names = fs.readdir(p);
6768
+ return p === "/" && !names.includes("proc") ? [...names, "proc"] : names;
6769
+ },
6770
+ exists: (p) => inProc(p) ? tree.exists(p) : fs.exists(p),
6771
+ readlink: (p) => inProc(p) ? tree.readlink(p) : fs.readlink(p),
6772
+ readdirStat: (p) => {
6773
+ if (!inProc(p)) {
6774
+ const listed = fs.readdirStat(p);
6775
+ if (p !== "/" || listed.some(([name2]) => name2 === "proc")) return listed;
6776
+ return [...listed, ["proc", tree.stat("/proc")]];
6777
+ }
6778
+ return tree.readdir(p).map((name2) => {
6779
+ try {
6780
+ return [name2, tree.stat(`${p}/${name2}`, false)];
6781
+ } catch {
6782
+ return [name2, null];
6783
+ }
6784
+ });
6785
+ },
6786
+ rename: (from, to) => {
6787
+ if (inProc(from) || inProc(to)) throw syncError("EROFS", from);
6788
+ fs.rename(from, to);
6789
+ },
6790
+ hold: (p, ...rest2) => inProc(p) ? void 0 : fs.hold?.(p, ...rest2),
6791
+ ...fs.pread ? {
6792
+ pread: (p, at, n, version) => inProc(p) ? tree.read(p).subarray(at, at + n) : fs.pread(p, at, n, version)
6793
+ } : {}
6794
+ };
6795
+ for (const name2 of READ_ONLY) {
6796
+ const fn = fs[name2];
6797
+ if (!fn) continue;
6798
+ over[name2] = (p, ...rest2) => {
6799
+ if (inProc(p)) throw syncError("EROFS", p);
6800
+ return fn.call(fs, p, ...rest2);
6801
+ };
6802
+ }
6803
+ return new Proxy(fs, {
6804
+ get: (target, key, receiver) => key in over ? over[key] : Reflect.get(target, key, receiver)
6805
+ });
6806
+ }
6807
+ var DIR_MODE3, FILE_MODE2, LINK_MODE3, PID_NAMES, SYSTEM_NAMES, ProcTree, READ_ONLY;
6808
+ var init_wasi_procfs = __esm({
6809
+ "src/process/wasi/wasi-procfs.ts"() {
6810
+ "use strict";
6811
+ init_sync_fs_wire();
6812
+ init_process_fds();
6813
+ init_procfs();
6814
+ DIR_MODE3 = 16749;
6815
+ FILE_MODE2 = 33060;
6816
+ LINK_MODE3 = 41471;
6817
+ PID_NAMES = PID_FILES;
6818
+ SYSTEM_NAMES = SYSTEM_FILES;
6819
+ ProcTree = class {
6820
+ source;
6821
+ pid;
6822
+ memory;
6823
+ constructor(source, pid, memory = memorySource()) {
6824
+ this.source = source;
6825
+ this.pid = pid;
6826
+ this.memory = memory;
6827
+ }
6828
+ listing() {
6829
+ return this.source.procList();
6830
+ }
6831
+ alive(pid) {
6832
+ return this.listing().processes.some((p) => p.pid === pid);
6833
+ }
6834
+ node(parts) {
6835
+ const [top, leaf, ...rest2] = parts;
6836
+ if (top === void 0) {
6837
+ return {
6838
+ kind: "dir",
6839
+ names: () => [
6840
+ ...SYSTEM_NAMES,
6841
+ "mounts",
6842
+ "self",
6843
+ ...this.listing().processes.map((p) => String(p.pid))
6844
+ ]
6845
+ };
6846
+ }
6847
+ if (top === "self") {
6848
+ return leaf === void 0 ? { kind: "link", target: String(this.pid) } : void 0;
6849
+ }
6850
+ if (leaf === void 0 && top === "mounts") {
6851
+ return { kind: "file", content: () => mountTable(this.source.mountList()) };
6852
+ }
6853
+ if (leaf === void 0 && SYSTEM_NAMES.includes(top)) {
6854
+ return {
6855
+ kind: "file",
6856
+ content: () => systemFile(top, this.listing(), Date.now(), this.memory)
6857
+ };
6858
+ }
6859
+ if (!/^[1-9]\d*$/.test(top) || rest2.length > 0 || !this.alive(Number(top))) return void 0;
6860
+ if (leaf === void 0) return { kind: "dir", names: () => [...PID_NAMES] };
6861
+ if (!PID_NAMES.includes(leaf)) return void 0;
6862
+ return {
6863
+ kind: "file",
6864
+ content: () => {
6865
+ const listing = this.listing();
6866
+ const info = listing.processes.find((p) => p.pid === Number(top));
6867
+ if (!info) throw syncError("ENOENT", `/proc/${top}/${leaf}`);
6868
+ return pidFile(leaf, info, listing.boot);
6869
+ }
6870
+ };
6871
+ }
6872
+ parts(path, follow2) {
6873
+ const parts = path.split("/").filter((p) => p !== "").slice(1);
6874
+ if (parts[0] === "self" && (follow2 || parts.length > 1)) parts[0] = String(this.pid);
6875
+ return parts;
6876
+ }
6877
+ find(path, follow2) {
6878
+ const node = this.node(this.parts(path, follow2));
6879
+ if (!node) throw syncError("ENOENT", path);
6880
+ return node;
6881
+ }
6882
+ stat(path, follow2 = true) {
6883
+ const node = this.find(path, follow2);
6884
+ const base = {
6885
+ isFile: false,
6886
+ isDirectory: false,
6887
+ size: 0,
6888
+ mtimeMs: Date.now(),
6889
+ readonly: true
6890
+ };
6891
+ if (node.kind === "dir") return { ...base, isDirectory: true, mode: DIR_MODE3 };
6892
+ if (node.kind === "link") {
6893
+ return { ...base, isSymbolicLink: true, mode: LINK_MODE3, size: node.target.length };
6894
+ }
6895
+ return { ...base, isFile: true, mode: FILE_MODE2, size: this.bytes(node).length };
6896
+ }
6897
+ bytes(node) {
6898
+ return new TextEncoder().encode(node.kind === "file" ? node.content() : "");
6899
+ }
6900
+ read(path) {
6901
+ const node = this.find(path, true);
6902
+ if (node.kind !== "file") throw syncError("EISDIR", path);
6903
+ return this.bytes(node);
6904
+ }
6905
+ readdir(path) {
6906
+ const node = this.find(path, true);
6907
+ if (node.kind !== "dir") throw syncError("ENOTDIR", path);
6908
+ return node.names();
6909
+ }
6910
+ readlink(path) {
6911
+ const node = this.find(path, false);
6912
+ if (node.kind !== "link") throw syncError("EINVAL", path);
6913
+ return node.target;
6914
+ }
6915
+ exists(path) {
6916
+ try {
6917
+ this.find(path, true);
6918
+ return true;
6919
+ } catch {
6920
+ return false;
6921
+ }
6922
+ }
6923
+ };
6924
+ READ_ONLY = [
6925
+ "writeFile",
6926
+ "mkdir",
6927
+ "rm",
6928
+ "unlink",
6929
+ "rmdir",
6930
+ "symlink",
6931
+ "chmod",
6932
+ "utimes",
6933
+ "lutimes",
6934
+ "create",
6935
+ "pwrite",
6936
+ "truncate"
6937
+ ];
6938
+ }
6939
+ });
6940
+
6751
6941
  // src/process/wasi/wasi-signals.ts
6752
6942
  var DELIVERED_MASK, KERNEL_DEFAULTS, LIBC_DEFAULT_EXIT, SA_RESTART, DISPOSITION_IGNORE, DISPOSITION_HANDLER, withBit, WASIX_LIBC_DEFAULT_LINE, WasiSignals;
6753
6943
  var init_wasi_signals = __esm({
@@ -6788,8 +6978,8 @@ var init_wasi_signals = __esm({
6788
6978
  bind(exports) {
6789
6979
  this.exports = exports;
6790
6980
  }
6791
- register(name) {
6792
- if (typeof this.exports?.[name] === "function") this.callback = name;
6981
+ register(name2) {
6982
+ if (typeof this.exports?.[name2] === "function") this.callback = name2;
6793
6983
  }
6794
6984
  useHook() {
6795
6985
  this.hooked = true;
@@ -6886,11 +7076,11 @@ var init_wasi_stats = __esm({
6886
7076
  mark = performance.now();
6887
7077
  wrap(tag, table) {
6888
7078
  return Object.fromEntries(
6889
- Object.entries(table).map(([name, value2]) => {
6890
- if (typeof value2 !== "function") return [name, value2];
7079
+ Object.entries(table).map(([name2, value2]) => {
7080
+ if (typeof value2 !== "function") return [name2, value2];
6891
7081
  const fn = value2;
6892
- const key = `${tag}.${name}`;
6893
- return [name, (...args) => this.time(key, () => fn.apply(table, args))];
7082
+ const key = `${tag}.${name2}`;
7083
+ return [name2, (...args) => this.time(key, () => fn.apply(table, args))];
6894
7084
  })
6895
7085
  );
6896
7086
  }
@@ -6902,9 +7092,9 @@ var init_wasi_stats = __esm({
6902
7092
  this.count(key, performance.now() - t);
6903
7093
  }
6904
7094
  }
6905
- phase(name) {
7095
+ phase(name2) {
6906
7096
  const now = performance.now();
6907
- this.phases.push([name, now - this.mark]);
7097
+ this.phases.push([name2, now - this.mark]);
6908
7098
  this.mark = now;
6909
7099
  }
6910
7100
  count(key, ms) {
@@ -6916,7 +7106,7 @@ var init_wasi_stats = __esm({
6916
7106
  }
6917
7107
  report() {
6918
7108
  const ms = (v) => v.toFixed(1).padStart(9);
6919
- const lines = this.phases.map(([name, t]) => `${ms(t)} ms ${name}`);
7109
+ const lines = this.phases.map(([name2, t]) => `${ms(t)} ms ${name2}`);
6920
7110
  lines.push(`${"total ms".padStart(12)} ${"calls".padStart(7)} ${"max ms".padStart(9)} call`);
6921
7111
  const sorted = [...this.rows].sort((a, b) => b[1].ms - a[1].ms);
6922
7112
  for (const [key, row] of sorted) {
@@ -6932,12 +7122,12 @@ var init_wasi_stats = __esm({
6932
7122
  // src/process/wasi/wasix-fork.ts
6933
7123
  function mutableGlobals(exports) {
6934
7124
  const out = [];
6935
- for (const [name, value2] of Object.entries(exports)) {
7125
+ for (const [name2, value2] of Object.entries(exports)) {
6936
7126
  if (!(value2 instanceof WebAssembly.Global) || typeof value2.value !== "number") continue;
6937
7127
  try {
6938
7128
  const v = value2.value;
6939
7129
  value2.value = v;
6940
- out.push([name, v]);
7130
+ out.push([name2, v]);
6941
7131
  } catch {
6942
7132
  }
6943
7133
  }
@@ -7047,8 +7237,8 @@ var init_wasix_fork = __esm({
7047
7237
  return E.SUCCESS;
7048
7238
  }
7049
7239
  restoreGlobals(globals) {
7050
- for (const [name, value2] of globals) {
7051
- const g = this.exports[name];
7240
+ for (const [name2, value2] of globals) {
7241
+ const g = this.exports[name2];
7052
7242
  if (g instanceof WebAssembly.Global) g.value = value2;
7053
7243
  }
7054
7244
  }
@@ -7118,6 +7308,173 @@ var init_wasix_ffi = __esm({
7118
7308
  }
7119
7309
  });
7120
7310
 
7311
+ // src/process/wasi/wasix-trampoline.ts
7312
+ function valueTypes(codes) {
7313
+ const out = [];
7314
+ for (const code2 of codes) {
7315
+ const type = CODES[code2];
7316
+ if (!type) return void 0;
7317
+ out.push(type);
7318
+ }
7319
+ return out;
7320
+ }
7321
+ function u32(n) {
7322
+ const out = [];
7323
+ let v = n >>> 0;
7324
+ do {
7325
+ let b = v & 127;
7326
+ v >>>= 7;
7327
+ if (v) b |= 128;
7328
+ out.push(b);
7329
+ } while (v);
7330
+ return out;
7331
+ }
7332
+ function s32(n) {
7333
+ const out = [];
7334
+ let v = n | 0;
7335
+ for (; ; ) {
7336
+ const b = v & 127;
7337
+ v >>= 7;
7338
+ if (v === 0 && !(b & 64) || v === -1 && b & 64) {
7339
+ out.push(b);
7340
+ return out;
7341
+ }
7342
+ out.push(b | 128);
7343
+ }
7344
+ }
7345
+ function name(s) {
7346
+ const bytes = [...new TextEncoder().encode(s)];
7347
+ return [...u32(bytes.length), ...bytes];
7348
+ }
7349
+ function section(id, body) {
7350
+ return [id, ...u32(body.length), ...body];
7351
+ }
7352
+ function vec(items) {
7353
+ return [...u32(items.length), ...items.flat()];
7354
+ }
7355
+ function align16(n) {
7356
+ return Math.ceil(n / 16) * 16;
7357
+ }
7358
+ function trampolineBytes(params, results, shared) {
7359
+ const sig = [
7360
+ 96,
7361
+ ...vec(params.map((t) => [VALTYPE[t]])),
7362
+ ...vec(results.map((t) => [VALTYPE[t]]))
7363
+ ];
7364
+ const backing = [96, ...vec([[127], [127], [127]]), ...vec([])];
7365
+ const memory = shared ? [3, 0, ...u32(65536)] : [0, 0];
7366
+ const imports = vec([
7367
+ [...name("env"), ...name("memory"), 2, ...memory],
7368
+ [...name("env"), ...name("__indirect_function_table"), 1, 112, 0, 0],
7369
+ [...name("env"), ...name("__stack_pointer"), 3, 127, 1],
7370
+ [...name("env"), ...name("backing"), 3, 127, 0],
7371
+ [...name("env"), ...name("user_data"), 3, 127, 0]
7372
+ ]);
7373
+ const n = params.length;
7374
+ const [orig, args, res] = [n, n + 1, n + 2];
7375
+ const valuesSize = align16(params.reduce((sum, t) => sum + SIZE3[t], 0));
7376
+ const resultsSize = align16(results.reduce((sum, t) => sum + SIZE3[t], 0));
7377
+ const body = [
7378
+ 35,
7379
+ 0,
7380
+ 34,
7381
+ ...u32(orig),
7382
+ 65,
7383
+ ...s32(resultsSize),
7384
+ 107,
7385
+ 34,
7386
+ ...u32(res)
7387
+ ];
7388
+ body.push(65, ...s32(valuesSize), 107, 34, ...u32(args), 36, 0);
7389
+ let at = 0;
7390
+ params.forEach((t, i) => {
7391
+ body.push(32, ...u32(args), 32, ...u32(i), ...STORE[t], 0, ...u32(at));
7392
+ at += SIZE3[t];
7393
+ });
7394
+ body.push(32, ...u32(args), 32, ...u32(res), 35, 2, 35, 1, 17, 1, 0);
7395
+ at = 0;
7396
+ for (const t of results) {
7397
+ body.push(32, ...u32(res), ...LOAD[t], 0, ...u32(at));
7398
+ at += SIZE3[t];
7399
+ }
7400
+ body.push(32, ...u32(orig), 36, 0, 11);
7401
+ const func = [...vec([[...u32(3), 127]]), ...body];
7402
+ return Uint8Array.from([
7403
+ 0,
7404
+ 97,
7405
+ 115,
7406
+ 109,
7407
+ 1,
7408
+ 0,
7409
+ 0,
7410
+ 0,
7411
+ ...section(1, vec([sig, backing])),
7412
+ ...section(2, imports),
7413
+ ...section(3, vec([[0]])),
7414
+ ...section(7, vec([[...name("t"), 0, 0]])),
7415
+ ...section(10, vec([[...u32(func.length), ...func]]))
7416
+ ]);
7417
+ }
7418
+ var CODES, VALTYPE, SIZE3, STORE, LOAD, Trampolines;
7419
+ var init_wasix_trampoline = __esm({
7420
+ "src/process/wasi/wasix-trampoline.ts"() {
7421
+ "use strict";
7422
+ CODES = ["i32", "i64", "f32", "f64", "v128"];
7423
+ VALTYPE = {
7424
+ i32: 127,
7425
+ i64: 126,
7426
+ f32: 125,
7427
+ f64: 124,
7428
+ v128: 123
7429
+ };
7430
+ SIZE3 = { i32: 4, i64: 8, f32: 4, f64: 8, v128: 16 };
7431
+ STORE = {
7432
+ i32: [54],
7433
+ i64: [55],
7434
+ f32: [56],
7435
+ f64: [57],
7436
+ v128: [253, 11]
7437
+ };
7438
+ LOAD = {
7439
+ i32: [40],
7440
+ i64: [41],
7441
+ f32: [42],
7442
+ f64: [43],
7443
+ v128: [253, 0]
7444
+ };
7445
+ Trampolines = class {
7446
+ modules = /* @__PURE__ */ new Map();
7447
+ get compiled() {
7448
+ return this.modules.size;
7449
+ }
7450
+ make(params, results, env) {
7451
+ const shared = env.memory.buffer instanceof SharedArrayBuffer;
7452
+ const key = `${params.join(",")}>${results.join(",")}${shared ? "s" : ""}`;
7453
+ let module = this.modules.get(key);
7454
+ if (!module) {
7455
+ module = new WebAssembly.Module(trampolineBytes(params, results, shared));
7456
+ this.modules.set(key, module);
7457
+ }
7458
+ const i32 = (v) => new WebAssembly.Global({ value: "i32", mutable: false }, v);
7459
+ const instance = new WebAssembly.Instance(module, {
7460
+ env: {
7461
+ memory: env.memory,
7462
+ __indirect_function_table: env.table,
7463
+ __stack_pointer: env.stackPointer,
7464
+ backing: i32(env.backing),
7465
+ user_data: i32(env.userData)
7466
+ }
7467
+ });
7468
+ const sig = {
7469
+ params: params.map((t) => t === "v128" ? "other" : t),
7470
+ results: results.map((t) => t === "v128" ? "other" : t)
7471
+ };
7472
+ return { fn: instance.exports.t, sig };
7473
+ }
7474
+ };
7475
+ }
7476
+ });
7477
+
7121
7478
  // src/process/wasi/wasm-functypes.ts
7122
7479
  function readTypes(r, s) {
7123
7480
  for (let i = r.u32(); i > 0; i--) {
@@ -7186,10 +7543,10 @@ function readGlobals(r, s) {
7186
7543
  }
7187
7544
  function readExports(r, s) {
7188
7545
  for (let i = r.u32(); i > 0; i--) {
7189
- const name = r.name();
7546
+ const name2 = r.name();
7190
7547
  const kind = r.byte();
7191
7548
  const index2 = r.u32();
7192
- if (kind === 0) s.info.exports[name] = index2;
7549
+ if (kind === 0) s.info.exports[name2] = index2;
7193
7550
  }
7194
7551
  }
7195
7552
  function readElems(r, s) {
@@ -7309,8 +7666,8 @@ var init_wasm_functypes = __esm({
7309
7666
  }
7310
7667
  add(info, instance, table, tableBase) {
7311
7668
  const sig = (func) => info.sigs[info.funcs[func] ?? -1];
7312
- for (const [name, func] of Object.entries(info.exports)) {
7313
- const fn = instance.exports[name];
7669
+ for (const [name2, func] of Object.entries(info.exports)) {
7670
+ const fn = instance.exports[name2];
7314
7671
  const type = sig(func);
7315
7672
  if (typeof fn === "function" && type) this.known.set(fn, type);
7316
7673
  }
@@ -7353,8 +7710,8 @@ function growTo(memory, bytes) {
7353
7710
  function growTable(table, length) {
7354
7711
  if (table.length < length) table.grow(length - table.length);
7355
7712
  }
7356
- function call(instance, name) {
7357
- const fn = instance.exports[name];
7713
+ function call(instance, name2) {
7714
+ const fn = instance.exports[name2];
7358
7715
  if (typeof fn === "function") fn();
7359
7716
  }
7360
7717
  var TABLE_BASE2, PAGE2, STACK_SIZE, LIBRARY_DIRS, DlError, WasixLinker;
@@ -7363,6 +7720,7 @@ var init_wasix_linker = __esm({
7363
7720
  "use strict";
7364
7721
  init_dylink();
7365
7722
  init_wasi_files();
7723
+ init_wasix_trampoline();
7366
7724
  init_wasm_functypes();
7367
7725
  TABLE_BASE2 = 1;
7368
7726
  PAGE2 = 65536;
@@ -7387,6 +7745,7 @@ var init_wasix_linker = __esm({
7387
7745
  publisher;
7388
7746
  indices;
7389
7747
  types = new FuncTypes();
7748
+ trampolines = new Trampolines();
7390
7749
  memory;
7391
7750
  host;
7392
7751
  constructor(memory, mainInfo, host, thread = false) {
@@ -7450,16 +7809,25 @@ var init_wasix_linker = __esm({
7450
7809
  this.main = instance;
7451
7810
  if (relocate) call(instance, "__wasm_apply_data_relocs");
7452
7811
  }
7453
- open(name, cwd, ldPath) {
7454
- return this.load(this.locate(name, cwd, ldPath), cwd, ldPath).handle;
7455
- }
7456
- symbol(handle, name) {
7457
- const found = handle === 0 ? this.find(name) : this.findIn(this.module(handle), name, /* @__PURE__ */ new Set());
7458
- if (!found) throw new DlError(`undefined symbol: ${name}`);
7812
+ mainPath;
7813
+ isMain(path) {
7814
+ if (this.mainPath === void 0) return false;
7815
+ if (path === this.mainPath) return true;
7816
+ const real = this.host.real;
7817
+ return real !== void 0 && real(path) === real(this.mainPath);
7818
+ }
7819
+ open(name2, cwd, ldPath) {
7820
+ const path = this.locate(name2, cwd, ldPath);
7821
+ if (this.isMain(path)) return 0;
7822
+ return this.load(path, cwd, ldPath).handle;
7823
+ }
7824
+ symbol(handle, name2) {
7825
+ const found = handle === 0 ? this.find(name2) : this.findIn(this.module(handle), name2, /* @__PURE__ */ new Set());
7826
+ if (!found) throw new DlError(`undefined symbol: ${name2}`);
7459
7827
  const [owner, value2] = found;
7460
- if (typeof value2 === "function") return this.slot(value2, owner, name);
7828
+ if (typeof value2 === "function") return this.slot(value2, owner, name2);
7461
7829
  if (value2 instanceof WebAssembly.Global) return this.baseOf(owner) + value2.value;
7462
- throw new DlError(`${name} is neither a function nor data`);
7830
+ throw new DlError(`${name2} is neither a function nor data`);
7463
7831
  }
7464
7832
  invalid(handle) {
7465
7833
  return !this.modules.has(handle);
@@ -7479,6 +7847,25 @@ var init_wasix_linker = __esm({
7479
7847
  this.indices?.free(index2);
7480
7848
  this.table.set(index2, null);
7481
7849
  }
7850
+ prepareClosure(record) {
7851
+ if (record.index >= this.table.length)
7852
+ throw new DlError(`closure ${record.index}: no such slot`);
7853
+ const full = { kind: "closure-prepare", ...record };
7854
+ this.install(full);
7855
+ this.publisher?.(full);
7856
+ }
7857
+ install(record) {
7858
+ growTable(this.table, record.index + 1);
7859
+ const { fn, sig } = this.trampolines.make(record.params, record.results, {
7860
+ memory: this.memory,
7861
+ table: this.table,
7862
+ stackPointer: this.stackPointer,
7863
+ backing: record.backing,
7864
+ userData: record.userData
7865
+ });
7866
+ this.table.set(record.index, fn);
7867
+ this.types.set(fn, sig);
7868
+ }
7482
7869
  reserve(size) {
7483
7870
  return this.indices?.reserve(this.table.length, size) ?? this.table.length;
7484
7871
  }
@@ -7491,6 +7878,10 @@ var init_wasix_linker = __esm({
7491
7878
  if (record.index < this.table.length) this.table.set(record.index, null);
7492
7879
  return;
7493
7880
  }
7881
+ if (record.kind === "closure-prepare") {
7882
+ this.install(record);
7883
+ return;
7884
+ }
7494
7885
  if (record.kind === "load") {
7495
7886
  if (this.modules.has(record.handle)) return;
7496
7887
  this.instantiate(record.path, this.moduleAt(record.path), record, false);
@@ -7515,14 +7906,14 @@ var init_wasix_linker = __esm({
7515
7906
  if (!m) throw new DlError(`invalid handle ${handle}`);
7516
7907
  return m;
7517
7908
  }
7518
- locate(name, cwd, ldPath) {
7519
- if (name.includes("/"))
7520
- return name.startsWith("/") ? normalize(name) : normalize(`${cwd}/${name}`);
7909
+ locate(name2, cwd, ldPath) {
7910
+ if (name2.includes("/"))
7911
+ return name2.startsWith("/") ? normalize(name2) : normalize(`${cwd}/${name2}`);
7521
7912
  for (const dir of [...ldPath.filter(Boolean), ...LIBRARY_DIRS]) {
7522
- const path = normalize(`${dir.startsWith("/") ? "" : `${cwd}/`}${dir}/${name}`);
7913
+ const path = normalize(`${dir.startsWith("/") ? "" : `${cwd}/`}${dir}/${name2}`);
7523
7914
  if (this.byPath.has(path) || this.host.read(path)) return path;
7524
7915
  }
7525
- throw new DlError(`${name}: not found`);
7916
+ throw new DlError(`${name2}: not found`);
7526
7917
  }
7527
7918
  load(path, cwd, ldPath) {
7528
7919
  const loaded = this.byPath.get(path);
@@ -7617,46 +8008,46 @@ var init_wasix_linker = __esm({
7617
8008
  }
7618
8009
  return linked;
7619
8010
  }
7620
- functionImport(name) {
7621
- const now = this.find(name);
8011
+ functionImport(name2) {
8012
+ const now = this.find(name2);
7622
8013
  if (now && typeof now[1] === "function") return now[1];
7623
8014
  let resolved2;
7624
8015
  return (...args) => {
7625
8016
  if (!resolved2) {
7626
- const later = this.find(name);
8017
+ const later = this.find(name2);
7627
8018
  if (!later || typeof later[1] !== "function")
7628
- throw new WebAssembly.RuntimeError(`unresolved symbol ${name}`);
8019
+ throw new WebAssembly.RuntimeError(`unresolved symbol ${name2}`);
7629
8020
  resolved2 = later[1];
7630
8021
  }
7631
8022
  return resolved2(...args);
7632
8023
  };
7633
8024
  }
7634
- addressOrNull(name) {
7635
- const found = this.find(name);
8025
+ addressOrNull(name2) {
8026
+ const found = this.find(name2);
7636
8027
  if (!found || !(found[1] instanceof WebAssembly.Global)) return 0;
7637
8028
  return this.baseOf(found[0]) + found[1].value;
7638
8029
  }
7639
- slotOrNull(name) {
7640
- const found = this.find(name);
8030
+ slotOrNull(name2) {
8031
+ const found = this.find(name2);
7641
8032
  if (!found || typeof found[1] !== "function") return 0;
7642
- return this.slot(found[1], found[0], name);
8033
+ return this.slot(found[1], found[0], name2);
7643
8034
  }
7644
- find(name) {
7645
- const inMain = this.main?.exports[name];
8035
+ find(name2) {
8036
+ const inMain = this.main?.exports[name2];
7646
8037
  if (inMain !== void 0) return [0, inMain];
7647
8038
  for (const m of this.modules.values()) {
7648
- const v = m.instance?.exports[name];
8039
+ const v = m.instance?.exports[name2];
7649
8040
  if (v !== void 0) return [m.handle, v];
7650
8041
  }
7651
8042
  return void 0;
7652
8043
  }
7653
- findIn(m, name, seen) {
8044
+ findIn(m, name2, seen) {
7654
8045
  if (seen.has(m.handle)) return void 0;
7655
8046
  seen.add(m.handle);
7656
- const v = m.instance.exports[name];
8047
+ const v = m.instance.exports[name2];
7657
8048
  if (v !== void 0) return [m.handle, v];
7658
8049
  for (const h of m.needed) {
7659
- const found = this.findIn(this.module(h), name, seen);
8050
+ const found = this.findIn(this.module(h), name2, seen);
7660
8051
  if (found) return found;
7661
8052
  }
7662
8053
  return void 0;
@@ -7664,14 +8055,23 @@ var init_wasix_linker = __esm({
7664
8055
  baseOf(handle) {
7665
8056
  return handle === 0 ? this.memoryBase : this.module(handle).memoryBase;
7666
8057
  }
7667
- slot(fn, handle, name) {
8058
+ indexed = 0;
8059
+ indexTable() {
8060
+ for (let i = this.indexed; i < this.table.length; i++) {
8061
+ const fn = this.table.get(i);
8062
+ if (fn && !this.slots.has(fn)) this.slots.set(fn, i);
8063
+ }
8064
+ this.indexed = this.table.length;
8065
+ }
8066
+ slot(fn, handle, name2) {
8067
+ this.indexTable();
7668
8068
  const known = this.slots.get(fn);
7669
8069
  if (known !== void 0) return known;
7670
8070
  const index2 = this.reserve(1);
7671
8071
  growTable(this.table, index2 + 1);
7672
8072
  this.table.set(index2, fn);
7673
8073
  this.slots.set(fn, index2);
7674
- this.publisher?.({ kind: "slot", index: index2, handle, name });
8074
+ this.publisher?.({ kind: "slot", index: index2, handle, name: name2 });
7675
8075
  return index2;
7676
8076
  }
7677
8077
  allocate(size, alignment) {
@@ -7909,8 +8309,8 @@ function wasixSocketImports(host, preview1) {
7909
8309
  },
7910
8310
  sock_set_opt_time: (fd) => void socket(fd),
7911
8311
  sock_send_file: () => E.NOSYS,
7912
- resolve: (name, len, _port, addrs, naddrs, out) => {
7913
- const found = call2({ op: "sock-resolve", name: mem.string(name, len), family: 0 });
8312
+ resolve: (name2, len, _port, addrs, naddrs, out) => {
8313
+ const found = call2({ op: "sock-resolve", name: mem.string(name2, len), family: 0 });
7914
8314
  const ips = found.map(ipBytes).filter((ip) => ip !== void 0);
7915
8315
  if (ips.length === 0) throw new WasiError("ENOENT");
7916
8316
  if (naddrs < 1) throw new WasiError("EINVAL");
@@ -7975,7 +8375,7 @@ function posixSignal(sig) {
7975
8375
  function nsToMs(ns) {
7976
8376
  return Math.ceil(Number(ns) / 1e6);
7977
8377
  }
7978
- var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON, ECHO, FUTEX_SLICE_MS, WasixHost;
8378
+ var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON, ECHO, FUTEX_SLICE_MS, MAIN_HANDLE, WasixHost;
7979
8379
  var init_wasix_host = __esm({
7980
8380
  "src/process/wasi/wasix-host.ts"() {
7981
8381
  "use strict";
@@ -7987,6 +8387,7 @@ var init_wasix_host = __esm({
7987
8387
  init_wasix_linker();
7988
8388
  init_wasix_process();
7989
8389
  init_wasix_sockets();
8390
+ init_wasix_trampoline();
7990
8391
  init_wasm_functypes();
7991
8392
  FDFLAGSEXT_CLOEXEC = 1;
7992
8393
  SPAWN_OP_SIZE = 56;
@@ -7995,6 +8396,7 @@ var init_wasix_host = __esm({
7995
8396
  ICANON = 2;
7996
8397
  ECHO = 8;
7997
8398
  FUTEX_SLICE_MS = 50;
8399
+ MAIN_HANDLE = 2147483647;
7998
8400
  WasixHost = class _WasixHost {
7999
8401
  process;
8000
8402
  threads;
@@ -8086,6 +8488,18 @@ var init_wasix_host = __esm({
8086
8488
  if (!this.linker) throw new WasiError("ENOTSUP");
8087
8489
  this.mem.view().setUint32(out, this.linker.allocateClosure(), true);
8088
8490
  },
8491
+ closure_prepare: (backing, index2, argTypes, argCount, resultTypes, resultCount, userData) => {
8492
+ if (!this.linker) throw new WasiError("ENOTSUP");
8493
+ const params = valueTypes(this.mem.bytes(argTypes, argCount));
8494
+ const results = valueTypes(this.mem.bytes(resultTypes, resultCount));
8495
+ if (!params || !results) throw new WasiError("EINVAL");
8496
+ try {
8497
+ this.linker.prepareClosure({ index: index2, backing, userData, params, results });
8498
+ } catch (e) {
8499
+ if (e instanceof DlError) throw new WasiError("EINVAL");
8500
+ throw e;
8501
+ }
8502
+ },
8089
8503
  closure_free: (index2) => {
8090
8504
  if (!this.linker) throw new WasiError("ENOTSUP");
8091
8505
  this.linker.freeClosure(index2);
@@ -8115,7 +8529,7 @@ var init_wasix_host = __esm({
8115
8529
  },
8116
8530
  proc_signals_sizes_get: (out) => void mem.view().setUint32(out, 0, true),
8117
8531
  proc_signals_get: () => E.SUCCESS,
8118
- callback_signal: (name, len) => void this.signals?.register(this.str(name, len)),
8532
+ callback_signal: (name2, len) => void this.signals?.register(this.str(name2, len)),
8119
8533
  proc_raise_interval: (sig, interval, repeat) => void host.o.kernel.call({
8120
8534
  op: "proc-alarm",
8121
8535
  sig: posixSignal(sig),
@@ -8262,23 +8676,23 @@ var init_wasix_host = __esm({
8262
8676
  return {
8263
8677
  dlopen: (p, pl, _flags, buf, len, lp, ll, out) => {
8264
8678
  if (p === 0) {
8265
- mem.view().setUint32(out, 0, true);
8679
+ mem.view().setUint32(out, MAIN_HANDLE, true);
8266
8680
  return E.SUCCESS;
8267
8681
  }
8268
8682
  return linked(
8269
8683
  buf,
8270
8684
  len,
8271
8685
  (l) => l.open(this.str(p, pl), host.cwd, lp === 0 ? [] : this.str(lp, ll).split(":")),
8272
- (h) => void mem.view().setUint32(out, h, true)
8686
+ (h) => void mem.view().setUint32(out, h === 0 ? MAIN_HANDLE : h, true)
8273
8687
  );
8274
8688
  },
8275
8689
  dlsym: (handle, s, sl, buf, len, out) => linked(
8276
8690
  buf,
8277
8691
  len,
8278
- (l) => l.symbol(handle, this.str(s, sl)),
8692
+ (l) => l.symbol(handle === MAIN_HANDLE ? 0 : handle, this.str(s, sl)),
8279
8693
  (v) => void mem.view().setUint32(out, v, true)
8280
8694
  ),
8281
- dl_invalid_handle: (handle) => handle !== 0 && this.linker && !this.linker.invalid(handle) ? E.SUCCESS : E.NOEXEC
8695
+ dl_invalid_handle: (handle) => handle === MAIN_HANDLE || handle !== 0 && this.linker && !this.linker.invalid(handle) ? E.SUCCESS : E.NOEXEC
8282
8696
  };
8283
8697
  }
8284
8698
  threadImports() {
@@ -8409,10 +8823,10 @@ function mainModule(lines) {
8409
8823
  }
8410
8824
  return void 0;
8411
8825
  }
8412
- function nameFrame(line, module, name) {
8826
+ function nameFrame(line, module, name2) {
8413
8827
  const m = UNNAMED_FRAME.exec(line);
8414
8828
  if (!m || m[3] !== module) return line;
8415
- const found = name(Number(m[4]));
8829
+ const found = name2(Number(m[4]));
8416
8830
  return found === void 0 ? line : `${m[1]}${found} (${m[2]})`;
8417
8831
  }
8418
8832
  function sidecarNames(read2, path) {
@@ -8448,29 +8862,29 @@ __export(wasi_runtime_exports, {
8448
8862
  trapMessage: () => trapMessage,
8449
8863
  unsupportedImport: () => unsupportedImport
8450
8864
  });
8451
- function enosys(module, name, foreign) {
8452
- const type = foreign?.[module]?.[name];
8453
- if (type === "other") throw new Error(noErrno(`${module}.${name}`));
8865
+ function enosys(module, name2, foreign) {
8866
+ const type = foreign?.[module]?.[name2];
8867
+ if (type === "other") throw new Error(noErrno(`${module}.${name2}`));
8454
8868
  if (type === "none") return () => void 0;
8455
8869
  if (type === "i64") return () => 52n;
8456
8870
  return () => 52;
8457
8871
  }
8458
8872
  function firstOther(foreign) {
8459
8873
  for (const [module, fields] of Object.entries(foreign)) {
8460
- const name = Object.keys(fields).find((field2) => fields[field2] === "other");
8461
- if (name !== void 0) return `${module}.${name}`;
8874
+ const name2 = Object.keys(fields).find((field2) => fields[field2] === "other");
8875
+ if (name2 !== void 0) return `${module}.${name2}`;
8462
8876
  }
8463
8877
  return void 0;
8464
8878
  }
8465
8879
  function accepted(imp, scope2) {
8466
- const { module, name, kind } = imp;
8880
+ const { module, name: name2, kind } = imp;
8467
8881
  if (module === PREVIEW1 || module === WASIX) return true;
8468
8882
  if (!RESERVED2.has(module) && (scope2.extended || scope2.wasi && kind === "function")) return true;
8469
8883
  if (scope2.pie && (module === "GOT.mem" || module === "GOT.func")) return true;
8470
8884
  if (scope2.pie && module === "env" && kind !== "memory") return true;
8471
- if (kind === "memory" && scope2.memory?.module === module && scope2.memory.name === name)
8885
+ if (kind === "memory" && scope2.memory?.module === module && scope2.memory.name === name2)
8472
8886
  return true;
8473
- return module === "wasi" && name === "thread-spawn" && (scope2.wasix || !!scope2.memory?.shared);
8887
+ return module === "wasi" && name2 === "thread-spawn" && (scope2.wasix || !!scope2.memory?.shared);
8474
8888
  }
8475
8889
  function unsupportedImport(module, memory, extended = false, foreign = {}) {
8476
8890
  const imports = WebAssembly.Module.imports(module);
@@ -8661,11 +9075,21 @@ async function instantiate(host, module, memory, threads, {
8661
9075
  }
8662
9076
  if (sync) {
8663
9077
  sync.linker.bindMain(instance, !thread);
9078
+ if (path !== void 0) sync.linker.mainPath = path;
8664
9079
  if (thread) sync.catchUp();
8665
9080
  sync.linker.bindMainGot();
8666
9081
  }
8667
9082
  return { instance, driver };
8668
9083
  }
9084
+ function procTree(call2, pid) {
9085
+ return new ProcTree(
9086
+ {
9087
+ procList: () => call2({ op: "proc-list" }),
9088
+ mountList: () => call2({ op: "mount-list" })
9089
+ },
9090
+ pid
9091
+ );
9092
+ }
8669
9093
  function exportedTable(instance) {
8670
9094
  const table = instance.exports.__indirect_function_table;
8671
9095
  return table instanceof WebAssembly.Table ? table : void 0;
@@ -8682,7 +9106,8 @@ function linkerHost(host, imports) {
8682
9106
  hostImports: () => {
8683
9107
  const { env: _env, "GOT.mem": _mem, "GOT.func": _func, ...rest2 } = imports();
8684
9108
  return rest2;
8685
- }
9109
+ },
9110
+ real: (path) => physicalPath(host.o.fs, path)
8686
9111
  };
8687
9112
  }
8688
9113
  function merge(base, extra) {
@@ -8736,7 +9161,10 @@ async function runWasiProcess(init, port2) {
8736
9161
  ppid: id.ppid,
8737
9162
  parent: () => identify(transport, init).ppid,
8738
9163
  kernel: { sys: traced(stats, "kernel", sys), call: call2 },
8739
- fs: cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport))),
9164
+ fs: procfsBridge(
9165
+ cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport))),
9166
+ procTree(call2, id.pid)
9167
+ ),
8740
9168
  ...descriptors(init, fork, threads)
8741
9169
  });
8742
9170
  if (threads) {
@@ -8784,12 +9212,12 @@ async function runWasiProcess(init, port2) {
8784
9212
  if (stats) report(stats, sys);
8785
9213
  }
8786
9214
  }
8787
- function trapMessage(e, env, where = "", name) {
9215
+ function trapMessage(e, env, where = "", name2) {
8788
9216
  const head = `wasm trap${where}: ${e.message}`;
8789
9217
  if (env.SLICC_WASM_BACKTRACE !== "1") return head;
8790
9218
  const lines = (e.stack ?? "").split("\n");
8791
- const main = name && mainModule(lines);
8792
- const frames = lines.filter((line) => /^\s+at .*wasm:\/\/wasm\//.test(line)).slice(0, BACKTRACE_FRAMES).map((line) => name && main ? nameFrame(line, main, name) : line);
9219
+ const main = name2 && mainModule(lines);
9220
+ const frames = lines.filter((line) => /^\s+at .*wasm:\/\/wasm\//.test(line)).slice(0, BACKTRACE_FRAMES).map((line) => name2 && main ? nameFrame(line, main, name2) : line);
8793
9221
  return frames.length ? `${head}
8794
9222
  ${frames.join("\n")}` : head;
8795
9223
  }
@@ -8827,7 +9255,7 @@ async function runWasiThread(init, port2) {
8827
9255
  ppid: id.ppid,
8828
9256
  parent: () => identify(transport, init).ppid,
8829
9257
  kernel: { sys, call: call2 },
8830
- fs: cachingBridge(createSyncFsSabBridge(transport)),
9258
+ fs: procfsBridge(cachingBridge(createSyncFsSabBridge(transport)), procTree(call2, id.pid)),
8831
9259
  shared: threads.ids
8832
9260
  });
8833
9261
  const program = await programImports(init.program, host, transport, thread.tid);
@@ -8869,6 +9297,7 @@ var TRAPPED, PREVIEW1, WASIX, SLICC, SIGNAL_CALLBACK, takeDefault, SLICC_FS, SLI
8869
9297
  var init_wasi_runtime = __esm({
8870
9298
  "src/process/wasi/wasi-runtime.ts"() {
8871
9299
  "use strict";
9300
+ init_physical_path();
8872
9301
  init_protocol();
8873
9302
  init_signals();
8874
9303
  init_sync_sab_bridge();
@@ -8881,6 +9310,7 @@ var init_wasi_runtime = __esm({
8881
9310
  init_wasi_host();
8882
9311
  init_wasi_imports();
8883
9312
  init_wasi_module();
9313
+ init_wasi_procfs();
8884
9314
  init_wasi_signals();
8885
9315
  init_wasi_stats();
8886
9316
  init_wasi_threads();
@@ -8940,8 +9370,8 @@ var init_wasi_runtime = __esm({
8940
9370
  const ids = this.ids;
8941
9371
  if (!ids) return { preview1, wasix };
8942
9372
  const wrap2 = (table) => Object.fromEntries(
8943
- Object.entries(table).map(([name, fn]) => [
8944
- name,
9373
+ Object.entries(table).map(([name2, fn]) => [
9374
+ name2,
8945
9375
  ((...args) => {
8946
9376
  if (Atomics.load(ids, DL_GEN) !== this.gen) this.catchUp();
8947
9377
  const result = fn(...args);
@@ -9273,7 +9703,7 @@ async function preflight(kernel, hows) {
9273
9703
  }
9274
9704
  }
9275
9705
  async function slots(kernel, o, mine, theirs) {
9276
- const hows = STDIO2.map((name) => o[name] ?? "inherit");
9706
+ const hows = STDIO2.map((name2) => o[name2] ?? "inherit");
9277
9707
  await preflight(kernel, hows);
9278
9708
  const stdio = [];
9279
9709
  for (const [n, how] of hows.entries()) {
@@ -9321,7 +9751,7 @@ function rewrite(hop, status2, location) {
9321
9751
  const toGet = (status2 === 301 || status2 === 302) && hop.method === "POST" || status2 === 303 && hop.method !== "GET" && hop.method !== "HEAD";
9322
9752
  const crossOrigin = next2.origin !== new URL(hop.url).origin;
9323
9753
  const headers = hop.headers.filter(
9324
- ([name]) => !(toGet && BODY_HEADERS.has(name.toLowerCase())) && !(crossOrigin && CREDENTIALS.has(name.toLowerCase()))
9754
+ ([name2]) => !(toGet && BODY_HEADERS.has(name2.toLowerCase())) && !(crossOrigin && CREDENTIALS.has(name2.toLowerCase()))
9325
9755
  );
9326
9756
  return {
9327
9757
  url: withoutFragment(next2),
@@ -9373,7 +9803,7 @@ function parameter(text, from, params) {
9373
9803
  while (SPACE.test(text[at] ?? "")) at++;
9374
9804
  let end = at;
9375
9805
  while (end < text.length && text[end] !== ";" && text[end] !== "=") end++;
9376
- const name = text.slice(at, end).toLowerCase();
9806
+ const name2 = text.slice(at, end).toLowerCase();
9377
9807
  if (text[end] !== "=") return end;
9378
9808
  const start2 = end + 1;
9379
9809
  let value2;
@@ -9386,8 +9816,8 @@ function parameter(text, from, params) {
9386
9816
  if (!value2) return end < 0 ? text.length : end;
9387
9817
  }
9388
9818
  if (end < 0) end = text.length;
9389
- if (TOKEN.test(name) && QUOTABLE.test(value2) && !params.has(name)) {
9390
- params.set(name, value2);
9819
+ if (TOKEN.test(name2) && QUOTABLE.test(value2) && !params.has(name2)) {
9820
+ params.set(name2, value2);
9391
9821
  }
9392
9822
  return end;
9393
9823
  }
@@ -9401,8 +9831,8 @@ function mimeType(input) {
9401
9831
  const params = /* @__PURE__ */ new Map();
9402
9832
  for (let at = semi < 0 ? text.length : semi; at < text.length; ) at = parameter(text, at, params);
9403
9833
  let out = `${type}/${subtype}`.toLowerCase();
9404
- for (const [name, value2] of params) {
9405
- out += `;${name}=${TOKEN.test(value2) ? value2 : `"${value2.replace(/["\\]/g, "\\$&")}"`}`;
9834
+ for (const [name2, value2] of params) {
9835
+ out += `;${name2}=${TOKEN.test(value2) ? value2 : `"${value2.replace(/["\\]/g, "\\$&")}"`}`;
9406
9836
  }
9407
9837
  return out;
9408
9838
  }
@@ -9603,7 +10033,7 @@ function fetchOp(kernel) {
9603
10033
  };
9604
10034
  for (let hops = 0; ; hops++) {
9605
10035
  const head = await send(hop, signal);
9606
- const location = head.headers.find(([name]) => name.toLowerCase() === "location")?.[1];
10036
+ const location = head.headers.find(([name2]) => name2.toLowerCase() === "location")?.[1];
9607
10037
  const follow2 = known.manualRedirects && REDIRECTS.has(head.status) && location !== void 0 && request.redirect !== "manual";
9608
10038
  if (!follow2) {
9609
10039
  const redirected = hops > 0 || head.redirected === true;
@@ -9748,9 +10178,9 @@ function port(n) {
9748
10178
  return n;
9749
10179
  }
9750
10180
  function netOps(kernel, io) {
9751
- const name = async (fd, peer) => addressOf(await kernel.json({ op: "sock-name", fd, peer }));
10181
+ const name2 = async (fd, peer) => addressOf(await kernel.json({ op: "sock-name", fd, peer }));
9752
10182
  const connection = async (fd) => {
9753
- const [local, remote] = [await name(fd, false), await name(fd, true)];
10183
+ const [local, remote] = [await name2(fd, false), await name2(fd, true)];
9754
10184
  const stop = new AbortController();
9755
10185
  let closed;
9756
10186
  const close = () => {
@@ -9832,7 +10262,7 @@ function netOps(kernel, io) {
9832
10262
  };
9833
10263
  await kernel.call({ op: "sock-bind", fd, addr });
9834
10264
  await kernel.call({ op: "sock-listen", fd, backlog: options.backlog ?? 128 });
9835
- return listener(fd, await name(fd, false));
10265
+ return listener(fd, await name2(fd, false));
9836
10266
  }),
9837
10267
  connect: async (options) => {
9838
10268
  const signal = options.signal ?? NEVER;
@@ -10143,10 +10573,25 @@ function ttyOps(kernel) {
10143
10573
  await kernel.call({ op: "tty-pgrp-set", fd, pgrp });
10144
10574
  }
10145
10575
  };
10576
+ const openOn = async (terminal, fd) => {
10577
+ const open = await kernel.json({ op: "fd-list" });
10578
+ const on = open.filter((entry) => entry.terminal === terminal);
10579
+ return (on.find((entry) => entry.fd === fd) ?? on[0])?.fd;
10580
+ };
10581
+ const reopened = async (terminal, termios) => {
10582
+ const fd = await kernel.json({ op: "fd-open-tty", name: terminal });
10583
+ try {
10584
+ await setAttr(fd, termios);
10585
+ } finally {
10586
+ await kernel.call({ op: "fd-close", fd });
10587
+ }
10588
+ };
10146
10589
  const restore = async () => {
10147
10590
  for (const [terminal, { fd, termios }] of [...saved].reverse()) {
10148
10591
  saved.delete(terminal);
10149
- await setAttr(fd, termios).catch(() => void 0);
10592
+ const at = await openOn(terminal, fd).catch(() => void 0);
10593
+ const back = at === void 0 ? reopened(terminal, termios) : setAttr(at, termios);
10594
+ await back.catch(() => void 0);
10150
10595
  }
10151
10596
  };
10152
10597
  return { tty, restore };
@@ -10664,22 +11109,22 @@ function chain(target) {
10664
11109
  return out;
10665
11110
  }
10666
11111
  function hide(target, names) {
10667
- for (const name of names) {
11112
+ for (const name2 of names) {
10668
11113
  const holders = chain(target);
10669
11114
  for (const holder of holders) {
10670
- if (Object.getOwnPropertyDescriptor(holder, name)?.configurable) {
10671
- Reflect.deleteProperty(holder, name);
11115
+ if (Object.getOwnPropertyDescriptor(holder, name2)?.configurable) {
11116
+ Reflect.deleteProperty(holder, name2);
10672
11117
  }
10673
11118
  }
10674
- const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name));
10675
- const defined = Reflect.defineProperty(target, name, {
11119
+ const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name2));
11120
+ const defined = Reflect.defineProperty(target, name2, {
10676
11121
  value: void 0,
10677
11122
  writable: false,
10678
11123
  enumerable: false,
10679
11124
  configurable: false
10680
11125
  });
10681
- if (kept || !defined && Reflect.get(target, name) !== void 0) {
10682
- throw new Error(`slicc-kernel: cannot withhold ${name} from a JS program`);
11126
+ if (kept || !defined && Reflect.get(target, name2) !== void 0) {
11127
+ throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
10683
11128
  }
10684
11129
  }
10685
11130
  }