@ai-ecoverse/slicc-kernel 1.57.0 → 1.57.1

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.
@@ -533,10 +533,26 @@ function pathInode(path) {
533
533
  }
534
534
  return h;
535
535
  }
536
- function cachingBridge(bridge, now = () => performance.now()) {
537
- const stats = /* @__PURE__ */ new Map();
538
- const lstats = /* @__PURE__ */ new Map();
536
+ function inoKey(st) {
537
+ return "ino" in st && typeof st.ino === "number" ? st.ino % 4294967296 | 0 : 0;
538
+ }
539
+ function pathHash(path) {
540
+ let h = 2166136261;
541
+ for (let i = 0; i < path.length; i++) h = Math.imul(h ^ path.charCodeAt(i), 16777619);
542
+ return h === 0 ? 1 : h;
543
+ }
544
+ function index(map, key, path) {
545
+ const paths = map.get(key) ?? /* @__PURE__ */ new Set();
546
+ paths.add(path);
547
+ map.set(key, paths);
548
+ }
549
+ function cachingBridge(bridge, now = () => performance.now(), shared) {
550
+ const blind = shared !== void 0 && shared.length * 4 < SHARED_IDS_BYTES;
551
+ const cache = new StatCache(blind ? void 0 : shared);
552
+ const { stats, lstats } = cache;
539
553
  const cached = (map, path, get) => {
554
+ if (blind) return get();
555
+ cache.fresh();
540
556
  let hit = map.get(path);
541
557
  if (hit === void 0 || "until" in hit && hit.until <= now()) {
542
558
  try {
@@ -544,22 +560,29 @@ function cachingBridge(bridge, now = () => performance.now()) {
544
560
  } catch (e) {
545
561
  hit = { error: e, until: now() + MISS_TTL_MS };
546
562
  }
547
- map.set(path, hit);
563
+ cache.put(map, path, hit);
548
564
  }
549
565
  if ("until" in hit) throw hit.error;
550
566
  return hit;
551
567
  };
552
- const invalidate = () => {
553
- stats.clear();
554
- lstats.clear();
568
+ const invalidate = () => cache.mutated([]);
569
+ const touched = (path, ino) => cache.changed(path, ino);
570
+ const mutating = (op, ...paths) => {
571
+ try {
572
+ return op();
573
+ } finally {
574
+ cache.mutated(paths);
575
+ }
555
576
  };
556
- const mutating = (op) => {
577
+ const rewriting = (p, op, ...also) => {
578
+ const ino = cache.inoOf(p, () => bridge.stat(p));
557
579
  try {
558
580
  return op();
559
581
  } finally {
560
- invalidate();
582
+ cache.mutated([p, ...also], ino);
561
583
  }
562
584
  };
585
+ const entry = (p) => [p, p.slice(0, p.lastIndexOf("/")) || "/"];
563
586
  return {
564
587
  readFile: (p) => bridge.readFile(p),
565
588
  readdir: (p) => bridge.readdir(p),
@@ -567,9 +590,9 @@ function cachingBridge(bridge, now = () => performance.now()) {
567
590
  const list = bridge.readdirStat(p);
568
591
  const base = p === "/" ? "" : p;
569
592
  for (const [name2, st] of list) {
570
- if (!st) continue;
571
- lstats.set(`${base}/${name2}`, st);
572
- if (!st.isSymbolicLink) stats.set(`${base}/${name2}`, st);
593
+ if (!st || blind) continue;
594
+ cache.put(lstats, `${base}/${name2}`, st);
595
+ if (!st.isSymbolicLink) cache.put(stats, `${base}/${name2}`, st);
573
596
  }
574
597
  return list;
575
598
  },
@@ -584,40 +607,41 @@ function cachingBridge(bridge, now = () => performance.now()) {
584
607
  return false;
585
608
  }
586
609
  },
587
- writeFile: (p, bytes, open) => mutating(() => bridge.writeFile(p, bytes, open)),
588
- mkdir: (p) => mutating(() => bridge.mkdir(p)),
610
+ writeFile: (p, bytes, open) => rewriting(p, () => bridge.writeFile(p, bytes, open), ...entry(p).slice(1)),
611
+ mkdir: (p) => mutating(() => bridge.mkdir(p), ...entry(p)),
589
612
  rm: (p) => mutating(() => bridge.rm(p)),
590
613
  rename: (from, to) => mutating(() => bridge.rename(from, to)),
591
614
  unlink: (p) => mutating(() => bridge.unlink(p)),
592
615
  rmdir: (p) => mutating(() => bridge.rmdir(p)),
593
- symlink: (target, link) => mutating(() => bridge.symlink(target, link)),
594
- chmod: (p, mode) => mutating(() => bridge.chmod(p, mode)),
595
- utimes: (p, a, m) => mutating(() => bridge.utimes(p, a, m)),
596
- lutimes: (p, a, m) => mutating(() => bridge.lutimes(p, a, m)),
616
+ symlink: (target, link) => mutating(() => bridge.symlink(target, link), ...entry(link)),
617
+ chmod: (p, mode) => rewriting(p, () => bridge.chmod(p, mode)),
618
+ utimes: (p, a, m) => rewriting(p, () => bridge.utimes(p, a, m)),
619
+ lutimes: (p, a, m) => mutating(() => bridge.lutimes(p, a, m), p),
597
620
  ...bridge.hold ? { hold: bridge.hold.bind(bridge) } : {},
598
621
  ...bridge.kept ? { kept: bridge.kept.bind(bridge) } : {},
599
- ...bridge.pinned ? { pinned: (handle) => pinnedIo(bridge, handle, mutating) } : {},
600
- ...bridge.create ? { create: (p) => mutating(() => bridge.create?.(p)) } : {},
622
+ ...bridge.pinned ? { pinned: (handle) => pinnedIo(bridge, handle, rewriting) } : {},
623
+ ...bridge.create ? { create: (p) => mutating(() => bridge.create?.(p), ...entry(p)) } : {},
601
624
  ...bridge.pread && bridge.pwrite && bridge.truncate ? {
602
625
  pread: bridge.pread.bind(bridge),
603
- pwrite: (p, at, bytes, transfer) => mutating(() => bridge.pwrite?.(p, at, bytes, transfer)),
604
- truncate: (p, size) => mutating(() => bridge.truncate?.(p, size))
626
+ pwrite: (p, at, bytes, transfer) => rewriting(p, () => bridge.pwrite?.(p, at, bytes, transfer)),
627
+ truncate: (p, size) => rewriting(p, () => bridge.truncate?.(p, size))
605
628
  } : {},
606
- invalidate
629
+ invalidate,
630
+ touched
607
631
  };
608
632
  }
609
- function pinnedIo(bridge, handle, mutating) {
633
+ function pinnedIo(bridge, handle, rewriting) {
610
634
  const io = bridge.pinned(handle);
611
635
  const { pread, pwrite, truncate } = io;
612
636
  return {
613
637
  readFile: (p) => io.readFile(p),
614
- writeFile: (p, bytes, open) => mutating(() => io.writeFile(p, bytes, open)),
638
+ writeFile: (p, bytes, open) => rewriting(p, () => io.writeFile(p, bytes, open)),
615
639
  pread: (p, at, n, version) => pread(p, at, n, version),
616
- pwrite: (p, at, bytes, transfer) => mutating(() => pwrite(p, at, bytes, transfer)),
617
- truncate: (p, size) => mutating(() => truncate(p, size))
640
+ pwrite: (p, at, bytes, transfer) => rewriting(p, () => pwrite(p, at, bytes, transfer)),
641
+ truncate: (p, size) => rewriting(p, () => truncate(p, size))
618
642
  };
619
643
  }
620
- var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS;
644
+ var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, FS_GEN, RING, RING_SIZE, SLOT, SHARED_IDS_BYTES, StatCache;
621
645
  var init_wasi_files = __esm({
622
646
  "src/process/wasi/wasi-files.ts"() {
623
647
  "use strict";
@@ -807,6 +831,110 @@ var init_wasi_files = __esm({
807
831
  };
808
832
  MAX_LINKS = 40;
809
833
  MISS_TTL_MS = 20;
834
+ FS_GEN = 4;
835
+ RING = 8;
836
+ RING_SIZE = 64;
837
+ SLOT = 3;
838
+ SHARED_IDS_BYTES = (RING + RING_SIZE * SLOT) * 4;
839
+ StatCache = class {
840
+ stats = /* @__PURE__ */ new Map();
841
+ lstats = /* @__PURE__ */ new Map();
842
+ byHash = /* @__PURE__ */ new Map();
843
+ byIno = /* @__PURE__ */ new Map();
844
+ shared;
845
+ seen;
846
+ constructor(shared) {
847
+ this.shared = shared;
848
+ this.seen = shared ? Atomics.load(shared, FS_GEN) : 0;
849
+ }
850
+ put(map, path, entry) {
851
+ map.set(path, entry);
852
+ if (!this.shared) return;
853
+ index(this.byHash, pathHash(path), path);
854
+ const ino = inoKey(entry);
855
+ if (ino !== 0) index(this.byIno, ino, path);
856
+ }
857
+ fresh() {
858
+ if (!this.shared) return;
859
+ const now = Atomics.load(this.shared, FS_GEN);
860
+ if (now === this.seen) return;
861
+ this.replay(now);
862
+ this.seen = now;
863
+ }
864
+ changed(path, ino = 0) {
865
+ const key = ino % 4294967296 | 0;
866
+ if (this.shared) {
867
+ const g = this.publish(this.shared, path === void 0 ? 0 : pathHash(path), key);
868
+ this.replay(g - 1);
869
+ this.seen = g;
870
+ if (path === void 0) this.clear();
871
+ else this.drop(pathHash(path), key);
872
+ }
873
+ if (path === void 0) return;
874
+ this.stats.delete(path);
875
+ this.lstats.delete(path);
876
+ }
877
+ mutated(paths, ino = 0) {
878
+ this.clear();
879
+ if (!this.shared) return;
880
+ const key = ino % 4294967296 | 0;
881
+ for (const [i, hash] of (paths.length > 0 ? paths.map(pathHash) : [0]).entries()) {
882
+ this.seen = this.publish(this.shared, hash, i === 0 ? key : 0);
883
+ }
884
+ }
885
+ inoOf(path, look) {
886
+ if (!this.shared) return 0;
887
+ this.fresh();
888
+ const hit = this.stats.get(path);
889
+ if (hit && "ino" in hit && typeof hit.ino === "number") return hit.ino;
890
+ try {
891
+ return look().ino ?? 0;
892
+ } catch {
893
+ return 0;
894
+ }
895
+ }
896
+ publish(shared, hash, ino) {
897
+ const g = Atomics.add(shared, FS_GEN, 1) + 1;
898
+ const at = RING + g % RING_SIZE * SLOT;
899
+ Atomics.store(shared, at, 0);
900
+ Atomics.store(shared, at + 1, hash);
901
+ Atomics.store(shared, at + 2, ino);
902
+ Atomics.store(shared, at, g);
903
+ return g;
904
+ }
905
+ replay(upTo) {
906
+ const shared = this.shared;
907
+ const missed = [];
908
+ for (let g = this.seen + 1; g <= upTo && upTo - this.seen <= RING_SIZE; g++) {
909
+ const at = RING + g % RING_SIZE * SLOT;
910
+ const tag = Atomics.load(shared, at);
911
+ const hash = Atomics.load(shared, at + 1);
912
+ const ino = Atomics.load(shared, at + 2);
913
+ if (tag !== g || hash === 0 || Atomics.load(shared, at) !== g) break;
914
+ missed.push([hash, ino]);
915
+ }
916
+ if (missed.length < upTo - this.seen) this.clear();
917
+ else for (const [hash, ino] of missed) this.drop(hash, ino);
918
+ }
919
+ drop(hash, ino) {
920
+ const paths = [
921
+ ...this.byHash.get(hash) ?? [],
922
+ ...ino === 0 ? [] : this.byIno.get(ino) ?? []
923
+ ];
924
+ for (const path of paths) {
925
+ this.stats.delete(path);
926
+ this.lstats.delete(path);
927
+ }
928
+ this.byHash.delete(hash);
929
+ if (ino !== 0) this.byIno.delete(ino);
930
+ }
931
+ clear() {
932
+ this.stats.clear();
933
+ this.lstats.clear();
934
+ this.byHash.clear();
935
+ this.byIno.clear();
936
+ }
937
+ };
810
938
  }
811
939
  });
812
940
 
@@ -836,6 +964,7 @@ var init_wasi_threads = __esm({
836
964
  "src/process/wasi/wasi-threads.ts"() {
837
965
  "use strict";
838
966
  init_protocol();
967
+ init_wasi_files();
839
968
  LAST_TID = 0;
840
969
  RUNNING = 1;
841
970
  MAIN_TID = 1;
@@ -858,7 +987,7 @@ var init_wasi_threads = __esm({
858
987
  this.memory = memory;
859
988
  this.cap = cap;
860
989
  this.tid = tid;
861
- this.ids = new Int32Array(ids ?? new SharedArrayBuffer(16));
990
+ this.ids = new Int32Array(ids ?? new SharedArrayBuffer(SHARED_IDS_BYTES));
862
991
  if (!ids) Atomics.store(this.ids, LAST_TID, MAIN_TID);
863
992
  }
864
993
  spawn(arg) {
@@ -1327,7 +1456,14 @@ var init_wasi_fds = __esm({
1327
1456
  handed.add(e.file.buffer);
1328
1457
  promoted.set(e.file, fd);
1329
1458
  }
1330
- this.table.set(fd, { type: "kernel", kind: "file", nonblock: false, append: e.file.append });
1459
+ this.table.set(fd, {
1460
+ type: "kernel",
1461
+ kind: "file",
1462
+ nonblock: false,
1463
+ append: e.file.append,
1464
+ path: e.file.path,
1465
+ ino: this.inoOf(e.file.path)
1466
+ });
1331
1467
  }
1332
1468
  for (const file of promoted.keys()) {
1333
1469
  if (--file.buffer.opens <= 0) {
@@ -1441,9 +1577,21 @@ var init_wasi_fds = __esm({
1441
1577
  buffer.orphan();
1442
1578
  this.buffers.delete(path);
1443
1579
  }
1580
+ inoOf(path) {
1581
+ try {
1582
+ return this.fs.stat(path).ino;
1583
+ } catch {
1584
+ return void 0;
1585
+ }
1586
+ }
1444
1587
  renamed(from, to) {
1445
1588
  if (from === to) return;
1446
1589
  if (this.shared) this.kernel.call({ op: "fd-path-renamed", from, to });
1590
+ for (const e of this.table.values()) {
1591
+ if (e.type === "kernel" && e.path !== void 0 && within(e.path, from)) {
1592
+ e.path = to + e.path.slice(from.length);
1593
+ }
1594
+ }
1447
1595
  const moved = [];
1448
1596
  for (const [p, buffer] of this.buffers) {
1449
1597
  if (within(p, from)) moved.push([p, buffer]);
@@ -1522,7 +1670,10 @@ var init_wasi_fds = __esm({
1522
1670
  const made = !existing && this.createNew(path, oflags);
1523
1671
  const truncate = made || (oflags & OFLAGS.TRUNC) !== 0;
1524
1672
  const fd = this.kernel.sys.openVfs(path, flags, 0, truncate ? { truncate } : {});
1525
- this.table.set(fd, { type: "kernel", kind: "file", nonblock: false, append });
1673
+ const was = existing && this.inoOf(path);
1674
+ if (truncate) this.fs.touched?.(path, was);
1675
+ const ino = existing ? was : this.inoOf(path);
1676
+ this.table.set(fd, { type: "kernel", kind: "file", nonblock: false, append, path, ino });
1526
1677
  if (append) this.publishFlags(fd, { nonblock: false, append });
1527
1678
  this.bump();
1528
1679
  return fd;
@@ -2316,11 +2467,29 @@ var init_wasi_host = __esm({
2316
2467
  if (!kernel.sys.pread) throw new WasiError("ESPIPE");
2317
2468
  return kernel.sys.pread(fd, Math.min(max, MAX_READ), at);
2318
2469
  },
2319
- pwrite: (body, at) => kernel.call({ op: "fd-pwrite", fd, offset: at, body }),
2470
+ pwrite: (body, at) => this.changed(fd, e, kernel.call({ op: "fd-pwrite", fd, offset: at, body })),
2320
2471
  size: () => this.kernelStat(fd).size,
2321
- truncate: (size) => void kernel.call({ op: "fd-resize", fd, size })
2472
+ truncate: (size) => this.changed(fd, e, void kernel.call({ op: "fd-resize", fd, size }))
2322
2473
  };
2323
2474
  }
2475
+ unnamed = /* @__PURE__ */ new WeakSet();
2476
+ changed(fd, e, result) {
2477
+ if (e.path === void 0 && !this.unnamed.has(e)) this.learnPath(fd, e);
2478
+ this.o.fs.touched?.(e.path, e.ino);
2479
+ return result;
2480
+ }
2481
+ learnPath(fd, e) {
2482
+ this.unnamed.add(e);
2483
+ let path;
2484
+ try {
2485
+ const st = this.kernelStat(fd);
2486
+ path = st.orphan ? void 0 : st.path;
2487
+ if (path !== void 0) e.ino = this.o.fs.stat(path).ino;
2488
+ } catch {
2489
+ return;
2490
+ }
2491
+ e.path = path;
2492
+ }
2324
2493
  kernelStat(fd) {
2325
2494
  return this.o.kernel.call({ op: "fd-vfs-stat", fd });
2326
2495
  }
@@ -2329,7 +2498,8 @@ var init_wasi_host = __esm({
2329
2498
  const e = this.fds.get(fd);
2330
2499
  if (e.type === "kernel") {
2331
2500
  try {
2332
- return this.o.kernel.sys.write(fd, data, { nonblock: e.nonblock });
2501
+ const n = this.o.kernel.sys.write(fd, data, { nonblock: e.nonblock });
2502
+ return this.fds.kind(fd, e) === "file" ? this.changed(fd, e, n) : n;
2333
2503
  } catch (err) {
2334
2504
  const broken = err.code === "EPIPE";
2335
2505
  if (broken && this.fds.kind(fd, e) !== "socket") throw new WasiExit(SIGPIPE_EXIT);
@@ -3025,8 +3195,8 @@ var init_sync_sab_wire = __esm({
3025
3195
  });
3026
3196
 
3027
3197
  // src/process/js/async-sab.ts
3028
- async function changed(header, index2, seen, waitAsync = defaultWaitAsync) {
3029
- const waited = waitAsync(header, index2, seen);
3198
+ async function changed(header, index3, seen, waitAsync = defaultWaitAsync) {
3199
+ const waited = waitAsync(header, index3, seen);
3030
3200
  if (waited.async) await waited.value;
3031
3201
  }
3032
3202
  function createAsyncSabTransport(sab, port3, waitAsync = defaultWaitAsync) {
@@ -3920,7 +4090,7 @@ function openRequest(abs, o) {
3920
4090
  ...o.truncate ? { truncate: true } : {}
3921
4091
  };
3922
4092
  }
3923
- function index(n, what) {
4093
+ function index2(n, what) {
3924
4094
  if (!Number.isSafeInteger(n) || n < 0) throw new JsCallError("EINVAL", what);
3925
4095
  }
3926
4096
  var CHUNK2, MAX_IO, O_WRONLY3, O_RDWR3, O_APPEND3;
@@ -4284,7 +4454,7 @@ function syncOps(kernel, shared) {
4284
4454
  return got;
4285
4455
  };
4286
4456
  const read2 = (fd, max = CHUNK2) => {
4287
- index(max, "read");
4457
+ index2(max, "read");
4288
4458
  const emulated = readDevice(info(fd), max, shared.random);
4289
4459
  if (emulated) return emulated;
4290
4460
  const r = kernel.blocking({ op: "fd-read", fd, max: Math.min(max, MAX_IO) });
@@ -4362,8 +4532,8 @@ function syncFile(kernel, fd, path, append, forget) {
4362
4532
  return kernel.json({ op: "fd-vfs-stat", fd }).size;
4363
4533
  },
4364
4534
  read(position, length) {
4365
- index(position, "read");
4366
- index(length, "read");
4535
+ index2(position, "read");
4536
+ index2(length, "read");
4367
4537
  const parts = [];
4368
4538
  let got = 0;
4369
4539
  do {
@@ -4378,7 +4548,7 @@ function syncFile(kernel, fd, path, append, forget) {
4378
4548
  return joined(parts, got);
4379
4549
  },
4380
4550
  write(position, data) {
4381
- index(position, "write");
4551
+ index2(position, "write");
4382
4552
  let at = 0;
4383
4553
  do {
4384
4554
  live();
@@ -4392,7 +4562,7 @@ function syncFile(kernel, fd, path, append, forget) {
4392
4562
  },
4393
4563
  truncate(size) {
4394
4564
  live();
4395
- index(size, "truncate");
4565
+ index2(size, "truncate");
4396
4566
  kernel.call({ op: "fd-resize", fd, size });
4397
4567
  },
4398
4568
  sync() {
@@ -4788,7 +4958,7 @@ function createContext(o) {
4788
4958
  return got;
4789
4959
  };
4790
4960
  const read2 = async (fd, max = CHUNK2, signal) => {
4791
- index(max, "read");
4961
+ index2(max, "read");
4792
4962
  const emulated = readDevice(await info(fd), max, random);
4793
4963
  if (emulated) return emulated;
4794
4964
  return readPipe(kernel, fd, Math.min(max, MAX_IO), signal);
@@ -4935,8 +5105,8 @@ function fileHandle(kernel, fd, path, append, forget) {
4935
5105
  return s.size;
4936
5106
  },
4937
5107
  async read(position, length) {
4938
- index(position, "read");
4939
- index(length, "read");
5108
+ index2(position, "read");
5109
+ index2(length, "read");
4940
5110
  const parts = [];
4941
5111
  let got = 0;
4942
5112
  do {
@@ -4951,7 +5121,7 @@ function fileHandle(kernel, fd, path, append, forget) {
4951
5121
  return joined(parts, got);
4952
5122
  },
4953
5123
  async write(position, data) {
4954
- index(position, "write");
5124
+ index2(position, "write");
4955
5125
  let at = 0;
4956
5126
  do {
4957
5127
  live();
@@ -4965,7 +5135,7 @@ function fileHandle(kernel, fd, path, append, forget) {
4965
5135
  },
4966
5136
  async truncate(size) {
4967
5137
  live();
4968
- index(size, "truncate");
5138
+ index2(size, "truncate");
4969
5139
  await kernel.call({ op: "fd-resize", fd, size });
4970
5140
  },
4971
5141
  async sync() {
@@ -9737,8 +9907,8 @@ function readExports(r, s) {
9737
9907
  for (let i = r.u32(); i > 0; i--) {
9738
9908
  const name2 = r.name();
9739
9909
  const kind = r.byte();
9740
- const index2 = r.u32();
9741
- if (kind === 0) s.info.exports[name2] = index2;
9910
+ const index3 = r.u32();
9911
+ if (kind === 0) s.info.exports[name2] = index3;
9742
9912
  }
9743
9913
  }
9744
9914
  function readElems(r, s) {
@@ -10041,15 +10211,15 @@ var init_wasix_linker = __esm({
10041
10211
  return out;
10042
10212
  }
10043
10213
  allocateClosure() {
10044
- const index2 = this.indices.allocate(this.table.length);
10045
- growTable(this.table, index2 + 1);
10046
- this.live.add(index2);
10047
- return index2;
10214
+ const index3 = this.indices.allocate(this.table.length);
10215
+ growTable(this.table, index3 + 1);
10216
+ this.live.add(index3);
10217
+ return index3;
10048
10218
  }
10049
- freeClosure(index2) {
10050
- this.indices?.free(index2);
10051
- this.live.delete(index2);
10052
- this.table.set(index2, null);
10219
+ freeClosure(index3) {
10220
+ this.indices?.free(index3);
10221
+ this.live.delete(index3);
10222
+ this.table.set(index3, null);
10053
10223
  }
10054
10224
  live = /* @__PURE__ */ new Set();
10055
10225
  prepareClosure(record) {
@@ -10282,12 +10452,12 @@ var init_wasix_linker = __esm({
10282
10452
  this.indexTable();
10283
10453
  const known = this.slots.get(fn);
10284
10454
  if (known !== void 0) return known;
10285
- const index2 = this.reserve(1);
10286
- growTable(this.table, index2 + 1);
10287
- this.table.set(index2, fn);
10288
- this.slots.set(fn, index2);
10289
- this.publisher?.({ kind: "slot", index: index2, handle, name: name2 });
10290
- return index2;
10455
+ const index3 = this.reserve(1);
10456
+ growTable(this.table, index3 + 1);
10457
+ this.table.set(index3, fn);
10458
+ this.slots.set(fn, index3);
10459
+ this.publisher?.({ kind: "slot", index: index3, handle, name: name2 });
10460
+ return index3;
10291
10461
  }
10292
10462
  allocate(size, alignment) {
10293
10463
  if (size === 0) return 0;
@@ -10572,11 +10742,11 @@ var init_wasix_sockets = __esm({
10572
10742
  });
10573
10743
 
10574
10744
  // src/process/wasi/wasix-host.ts
10575
- function futexWait(view, index2, expected, ms, interrupted) {
10745
+ function futexWait(view, index3, expected, ms, interrupted) {
10576
10746
  const deadline = performance.now() + ms;
10577
10747
  for (; ; ) {
10578
10748
  const slice = interrupted ? Math.min(FUTEX_SLICE_MS, ms) : ms;
10579
- if (Atomics.wait(view, index2, expected, slice) !== "timed-out") return true;
10749
+ if (Atomics.wait(view, index3, expected, slice) !== "timed-out") return true;
10580
10750
  if (interrupted?.()) return true;
10581
10751
  ms = deadline - performance.now();
10582
10752
  if (ms <= 0) return false;
@@ -10705,21 +10875,21 @@ var init_wasix_host = __esm({
10705
10875
  if (!this.linker) throw new WasiError("ENOTSUP");
10706
10876
  this.mem.view().setUint32(out, this.linker.allocateClosure(), true);
10707
10877
  },
10708
- closure_prepare: (backing, index2, argTypes, argCount, resultTypes, resultCount, userData) => {
10878
+ closure_prepare: (backing, index3, argTypes, argCount, resultTypes, resultCount, userData) => {
10709
10879
  if (!this.linker) throw new WasiError("ENOTSUP");
10710
10880
  const params = valueTypes(this.mem.bytes(argTypes, argCount));
10711
10881
  const results = valueTypes(this.mem.bytes(resultTypes, resultCount));
10712
10882
  if (!params || !results) throw new WasiError("EINVAL");
10713
10883
  try {
10714
- this.linker.prepareClosure({ index: index2, backing, userData, params, results });
10884
+ this.linker.prepareClosure({ index: index3, backing, userData, params, results });
10715
10885
  } catch (e) {
10716
10886
  if (e instanceof DlError) throw new WasiError("EINVAL");
10717
10887
  throw e;
10718
10888
  }
10719
10889
  },
10720
- closure_free: (index2) => {
10890
+ closure_free: (index3) => {
10721
10891
  if (!this.linker) throw new WasiError("ENOTSUP");
10722
- this.linker.freeClosure(index2);
10892
+ this.linker.freeClosure(index3);
10723
10893
  },
10724
10894
  call_dynamic: (...a) => void callDynamic(
10725
10895
  { mem: this.mem, table: () => this.table, types: this.types },
@@ -11024,10 +11194,10 @@ function parseFunctionNames(payload) {
11024
11194
  if (end > payload.length) throw new RangeError("truncated name section");
11025
11195
  if (id === 1) {
11026
11196
  for (let count = leb(); count > 0; count--) {
11027
- const index2 = leb();
11197
+ const index3 = leb();
11028
11198
  const length = leb();
11029
11199
  if (at + length > end) throw new RangeError("truncated name section");
11030
- names.set(index2, decoder3.decode(payload.subarray(at, at + length)));
11200
+ names.set(index3, decoder3.decode(payload.subarray(at, at + length)));
11031
11201
  at += length;
11032
11202
  }
11033
11203
  }
@@ -11051,7 +11221,7 @@ function nameFrame(line, module, name2) {
11051
11221
  }
11052
11222
  function sidecarNames(read2, path) {
11053
11223
  let names;
11054
- return (index2) => {
11224
+ return (index3) => {
11055
11225
  if (!names) {
11056
11226
  try {
11057
11227
  names = parseFunctionNames(read2(path));
@@ -11059,7 +11229,7 @@ function sidecarNames(read2, path) {
11059
11229
  names = /* @__PURE__ */ new Map();
11060
11230
  }
11061
11231
  }
11062
- return names.get(index2);
11232
+ return names.get(index3);
11063
11233
  };
11064
11234
  }
11065
11235
  var UNNAMED_FRAME, WASM_MODULE;
@@ -11420,7 +11590,7 @@ async function runWasiProcess(init, port3) {
11420
11590
  parent: () => identify(transport, init).ppid,
11421
11591
  kernel: { sys: traced(stats, "kernel", sys), call: call2 },
11422
11592
  fs: procfsBridge(
11423
- cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport))),
11593
+ cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport)), void 0, threads?.ids),
11424
11594
  procTree(call2, id.pid)
11425
11595
  ),
11426
11596
  ...descriptors(init, fork, threads)
@@ -11513,7 +11683,10 @@ async function runWasiThread(init, port3) {
11513
11683
  ppid: id.ppid,
11514
11684
  parent: () => identify(transport, init).ppid,
11515
11685
  kernel: { sys, call: call2 },
11516
- fs: procfsBridge(cachingBridge(createSyncFsSabBridge(transport)), procTree(call2, id.pid)),
11686
+ fs: procfsBridge(
11687
+ cachingBridge(createSyncFsSabBridge(transport), void 0, threads.ids),
11688
+ procTree(call2, id.pid)
11689
+ ),
11517
11690
  shared: threads.ids
11518
11691
  });
11519
11692
  const program = await programImports(init.program, host, transport, thread.tid);
@@ -11625,13 +11798,13 @@ var init_wasi_runtime = __esm({
11625
11798
  },
11626
11799
  unlock: () => this.call({ op: "dl-unlock", owner: this.owner }),
11627
11800
  allocate: (floor) => {
11628
- const index2 = this.call({ op: "dl-closure", floor });
11801
+ const index3 = this.call({ op: "dl-closure", floor });
11629
11802
  this.catchUp();
11630
11803
  this.bump();
11631
- return index2;
11804
+ return index3;
11632
11805
  },
11633
- free: (index2) => {
11634
- this.call({ op: "dl-closure-free", index: index2 });
11806
+ free: (index3) => {
11807
+ this.call({ op: "dl-closure-free", index: index3 });
11635
11808
  this.bump();
11636
11809
  }
11637
11810
  };