@ai-ecoverse/slicc-kernel 1.48.1 → 1.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1991,12 +1991,12 @@ var init_kernel_streams = __esm({
1991
1991
  usePipes(pipefs) {
1992
1992
  const createPipe = pipefs.createPipe.bind(pipefs);
1993
1993
  pipefs.createPipe = () => {
1994
- const [read, write] = this.call(() => this.sys.pipe());
1994
+ const [read2, write2] = this.call(() => this.sys.pipe());
1995
1995
  let fds;
1996
1996
  try {
1997
1997
  fds = createPipe();
1998
1998
  } catch (e) {
1999
- for (const kfd of [read, write]) {
1999
+ for (const kfd of [read2, write2]) {
2000
2000
  try {
2001
2001
  this.sys.close(kfd);
2002
2002
  } catch {
@@ -2004,8 +2004,8 @@ var init_kernel_streams = __esm({
2004
2004
  }
2005
2005
  throw e;
2006
2006
  }
2007
- this.attach(this.Fs.getStream(fds.readable_fd), read, false);
2008
- this.attach(this.Fs.getStream(fds.writable_fd), write, false);
2007
+ this.attach(this.Fs.getStream(fds.readable_fd), read2, false);
2008
+ this.attach(this.Fs.getStream(fds.writable_fd), write2, false);
2009
2009
  return fds;
2010
2010
  };
2011
2011
  }
@@ -2394,12 +2394,12 @@ function readInto(sys, kfd, target, at) {
2394
2394
  }
2395
2395
  return done;
2396
2396
  }
2397
- function positioned(original, write, deps) {
2397
+ function positioned(original, write2, deps) {
2398
2398
  return (fd, iov, iovcnt, ...rest2) => {
2399
2399
  const stream = deps.fs()?.getStream(Number(fd));
2400
2400
  const memory = deps.memory();
2401
2401
  const kfd = stream?.sliccKernelFile ? stream.sliccKernelFd : void 0;
2402
- if (kfd === void 0 || !memory || !(write ? deps.sys.pwrite : deps.sys.pread)) {
2402
+ if (kfd === void 0 || !memory || !(write2 ? deps.sys.pwrite : deps.sys.pread)) {
2403
2403
  return original(fd, iov, iovcnt, ...rest2);
2404
2404
  }
2405
2405
  const at = offsetOf(rest2);
@@ -2411,7 +2411,7 @@ function positioned(original, write, deps) {
2411
2411
  const ptr = view.getUint32(Number(iov) + i * 8, true);
2412
2412
  const len = view.getUint32(Number(iov) + i * 8 + 4, true);
2413
2413
  const part = new Uint8Array(memory.buffer, ptr, len);
2414
- const moved = write ? deps.sys.pwrite?.(kfd, part.slice(), at + done) ?? 0 : readInto(deps.sys, kfd, part, at + done);
2414
+ const moved = write2 ? deps.sys.pwrite?.(kfd, part.slice(), at + done) ?? 0 : readInto(deps.sys, kfd, part, at + done);
2415
2415
  done += moved;
2416
2416
  if (moved < len) break;
2417
2417
  }
@@ -2424,13 +2424,13 @@ function positioned(original, write, deps) {
2424
2424
  }
2425
2425
  function positionalIo(imports, deps) {
2426
2426
  for (const namespace of namespaces(imports)) {
2427
- for (const [name, write] of [
2427
+ for (const [name, write2] of [
2428
2428
  ["fd_pread", false],
2429
2429
  ["fd_pwrite", true]
2430
2430
  ]) {
2431
2431
  const key = keyOf(namespace, name, deps.glue);
2432
2432
  if (key !== void 0) {
2433
- namespace[key] = positioned(namespace[key], write, deps);
2433
+ namespace[key] = positioned(namespace[key], write2, deps);
2434
2434
  }
2435
2435
  }
2436
2436
  }
@@ -2558,10 +2558,10 @@ function useZeroDevices(Fs) {
2558
2558
  }
2559
2559
  ]
2560
2560
  ];
2561
- for (const [path, minor, write] of devices) {
2561
+ for (const [path, minor, write2] of devices) {
2562
2562
  if (analyzePath.call(Fs, path).exists) continue;
2563
2563
  const dev = makedev.call(Fs, 1, minor);
2564
- registerDevice.call(Fs, dev, { read: zeros, write, llseek: () => 0 });
2564
+ registerDevice.call(Fs, dev, { read: zeros, write: write2, llseek: () => 0 });
2565
2565
  mkdev.call(Fs, path, CHAR_DEVICE, dev);
2566
2566
  }
2567
2567
  }
@@ -2957,38 +2957,38 @@ function drain(Fs, stream) {
2957
2957
  }
2958
2958
  return out;
2959
2959
  }
2960
- function kernelSelect(Fs, transport, read, write, timeoutMs) {
2960
+ function kernelSelect(Fs, transport, read2, write2, timeoutMs) {
2961
2961
  const kernel = (fd) => Fs.getStream(fd)?.sliccKernelFd;
2962
- const kr = read.map(kernel);
2963
- const kw = write.map(kernel);
2962
+ const kr = read2.map(kernel);
2963
+ const kw = write2.map(kernel);
2964
2964
  const r = transport.call({ op: "fd-select", read: kr, write: kw, timeoutMs }, Infinity, "select");
2965
2965
  if (!r.ok) return -wasiErrno(r.errno);
2966
2966
  const got = r.kind === "json" ? r.json : { read: [], write: [] };
2967
2967
  return {
2968
- read: read.filter((_, i) => got.read.includes(kr[i])),
2969
- write: write.filter((_, i) => got.write.includes(kw[i]))
2968
+ read: read2.filter((_, i) => got.read.includes(kr[i])),
2969
+ write: write2.filter((_, i) => got.write.includes(kw[i]))
2970
2970
  };
2971
2971
  }
2972
- function ownReady(Fs, read, write) {
2972
+ function ownReady(Fs, read2, write2) {
2973
2973
  const flags = (fd) => {
2974
2974
  const stream = Fs.getStream(fd);
2975
2975
  if (!stream) return POLLNVAL;
2976
2976
  return stream.stream_ops.poll ? stream.stream_ops.poll(stream) : POLLIN2 | POLLOUT2;
2977
2977
  };
2978
2978
  return {
2979
- read: read.filter((fd) => flags(fd) & (POLLIN2 | POLLHUP2 | POLLERR2 | POLLNVAL)),
2980
- write: write.filter((fd) => flags(fd) & (POLLOUT2 | POLLERR2 | POLLNVAL))
2979
+ read: read2.filter((fd) => flags(fd) & (POLLIN2 | POLLHUP2 | POLLERR2 | POLLNVAL)),
2980
+ write: write2.filter((fd) => flags(fd) & (POLLOUT2 | POLLERR2 | POLLNVAL))
2981
2981
  };
2982
2982
  }
2983
- function anySelect(Fs, transport, read, write, timeoutMs) {
2983
+ function anySelect(Fs, transport, read2, write2, timeoutMs) {
2984
2984
  const kernel = (fd) => Fs.getStream(fd)?.sliccKernelFd;
2985
2985
  const own = (fd) => kernel(fd) === void 0;
2986
- if (![...read, ...write].some(own)) return kernelSelect(Fs, transport, read, write, timeoutMs);
2986
+ if (![...read2, ...write2].some(own)) return kernelSelect(Fs, transport, read2, write2, timeoutMs);
2987
2987
  const deadline = timeoutMs < 0 ? Number.POSITIVE_INFINITY : Date.now() + timeoutMs;
2988
- const kernelRead = read.filter((fd) => !own(fd));
2989
- const kernelWrite = write.filter((fd) => !own(fd));
2988
+ const kernelRead = read2.filter((fd) => !own(fd));
2989
+ const kernelWrite = write2.filter((fd) => !own(fd));
2990
2990
  for (; ; ) {
2991
- const local = ownReady(Fs, read.filter(own), write.filter(own));
2991
+ const local = ownReady(Fs, read2.filter(own), write2.filter(own));
2992
2992
  const pending = local.read.length > 0 || local.write.length > 0;
2993
2993
  const slice = pending ? 0 : Math.min(SELECT_SLICE_MS, Math.max(0, deadline - Date.now()));
2994
2994
  const got = kernelSelect(Fs, transport, kernelRead, kernelWrite, slice);
@@ -3095,7 +3095,7 @@ function createProcessKernel(deps) {
3095
3095
  if (!r.ok) return -wasiErrno(r.errno);
3096
3096
  return r.kind === "json" ? r.json : -wasiErrno("EIO");
3097
3097
  },
3098
- select: (read, write, timeoutMs) => anySelect(Fs, transport, read, write, timeoutMs),
3098
+ select: (read2, write2, timeoutMs) => anySelect(Fs, transport, read2, write2, timeoutMs),
3099
3099
  execWait,
3100
3100
  execve(file, argv, env, cwd) {
3101
3101
  const pid = spawnChild(file, argv, env, cwd, [0, 1, 2], void 0, true);
@@ -5393,17 +5393,17 @@ function writeEvents(mem, ptr, events) {
5393
5393
  }
5394
5394
  function classify(fds, subs) {
5395
5395
  const events = [];
5396
- const read = [];
5397
- const write = [];
5396
+ const read2 = [];
5397
+ const write2 = [];
5398
5398
  for (const s of subs) {
5399
5399
  if (s.type === EVENTTYPE.CLOCK) continue;
5400
5400
  const e = fds.find(s.fd);
5401
5401
  if (!e) events.push({ userdata: s.userdata, error: E.BADF, type: s.type });
5402
5402
  else if (e.type !== "kernel")
5403
5403
  events.push({ userdata: s.userdata, error: E.SUCCESS, type: s.type });
5404
- else (s.type === EVENTTYPE.FD_READ ? read : write).push(s.fd);
5404
+ else (s.type === EVENTTYPE.FD_READ ? read2 : write2).push(s.fd);
5405
5405
  }
5406
- return { events, read, write };
5406
+ return { events, read: read2, write: write2 };
5407
5407
  }
5408
5408
  function readyEvents(subs, ready) {
5409
5409
  return subs.filter(
@@ -5419,11 +5419,11 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
5419
5419
  if (nsubs === 0) return E.INVAL;
5420
5420
  const { mem, kernel } = deps;
5421
5421
  const subs = readSubscriptions(mem, inPtr, nsubs, deps.now);
5422
- const { events, read, write } = classify(deps.fds, subs);
5422
+ const { events, read: read2, write: write2 } = classify(deps.fds, subs);
5423
5423
  let interrupted = false;
5424
5424
  const earliest = subs.reduce((min, s) => Math.min(min, s.deadline), Infinity);
5425
5425
  const expired = () => performance.now() + CLOCK_SLACK_MS >= earliest;
5426
- if (read.length > 0 || write.length > 0 || events.length === 0) {
5426
+ if (read2.length > 0 || write2.length > 0 || events.length === 0) {
5427
5427
  do {
5428
5428
  let timeoutMs = -1;
5429
5429
  if (events.length > 0) timeoutMs = 0;
@@ -5431,7 +5431,7 @@ function pollOneoff(deps, inPtr, outPtr, nsubs, neventsPtr) {
5431
5431
  timeoutMs = Math.max(0, Math.ceil(earliest - performance.now()));
5432
5432
  let ready;
5433
5433
  try {
5434
- ready = kernel.call({ op: "fd-select", read, write, timeoutMs });
5434
+ ready = kernel.call({ op: "fd-select", read: read2, write: write2, timeoutMs });
5435
5435
  } catch (e) {
5436
5436
  if (!deps.interruptWakes || e.code !== "EINTR") throw e;
5437
5437
  interrupted = true;
@@ -5552,7 +5552,6 @@ function kernelFiletype(kind) {
5552
5552
  case "device":
5553
5553
  return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
5554
5554
  case "socket":
5555
- case "stream":
5556
5555
  return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
5557
5556
  case "file":
5558
5557
  return { filetype: FILETYPE.REGULAR_FILE, seeks: true };
@@ -5589,7 +5588,7 @@ function wrap(table) {
5589
5588
  }
5590
5589
  return out;
5591
5590
  }
5592
- var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
5591
+ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
5593
5592
  var init_wasi_host = __esm({
5594
5593
  "src/process/wasi/wasi-host.ts"() {
5595
5594
  "use strict";
@@ -5610,6 +5609,7 @@ var init_wasi_host = __esm({
5610
5609
  IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
5611
5610
  NS_PER_MS = 1000000n;
5612
5611
  AT_SYMLINK_NOFOLLOW2 = 1;
5612
+ S_IFIFO = 4096;
5613
5613
  DEFAULT_UMASK = 18;
5614
5614
  MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
5615
5615
  MAX_READ = 1024 * 1024;
@@ -5686,7 +5686,12 @@ var init_wasi_host = __esm({
5686
5686
  const old = this.o.kernel.call({ op: "proc-umask", mask });
5687
5687
  mem.view().setUint32(out, old, true);
5688
5688
  },
5689
- fd_mode: (fd, out) => void mem.view().setUint32(out, modeOf(this.o.fs.stat(pathOf(fd))), true),
5689
+ fd_mode: (fd, out) => {
5690
+ const e = fds.get(fd);
5691
+ const pipe = e.type === "kernel" && fds.kind(fd, e) === "stream";
5692
+ const mode = pipe ? S_IFIFO | 384 : modeOf(this.o.fs.stat(pathOf(fd)));
5693
+ mem.view().setUint32(out, mode, true);
5694
+ },
5690
5695
  path_mode: (dirfd, p, l, flags, out) => {
5691
5696
  const path = at(dirfd, p, l);
5692
5697
  const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
@@ -5779,8 +5784,8 @@ var init_wasi_host = __esm({
5779
5784
  return BigInt(Math.round((performance.now() - this.started) * 1e6)) + 1n;
5780
5785
  }
5781
5786
  environ() {
5782
- const listen = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
5783
- const env = { PWD: this.cwd, ...this.o.env, ...listen };
5787
+ const listen2 = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
5788
+ const env = { PWD: this.cwd, ...this.o.env, ...listen2 };
5784
5789
  return Object.entries(env).map(([k, v]) => `${k}=${v}`);
5785
5790
  }
5786
5791
  processImports() {
@@ -6664,10 +6669,10 @@ function processes(host, call2, inThread) {
6664
6669
  const slot = (n, how, mine, theirs) => {
6665
6670
  if (how === "inherit") return { fd: n };
6666
6671
  if (how === "null") return { none: true };
6667
- const [read, write] = call2({ op: "fd-pipe" });
6668
- mine[n] = n === 0 ? write : read;
6669
- theirs.push(n === 0 ? read : write);
6670
- return { fd: n === 0 ? read : write };
6672
+ const [read2, write2] = call2({ op: "fd-pipe" });
6673
+ mine[n] = n === 0 ? write2 : read2;
6674
+ theirs.push(n === 0 ? read2 : write2);
6675
+ return { fd: n === 0 ? read2 : write2 };
6671
6676
  };
6672
6677
  return {
6673
6678
  spawn(o) {
@@ -7051,6 +7056,289 @@ var init_wasix_fork = __esm({
7051
7056
  }
7052
7057
  });
7053
7058
 
7059
+ // src/process/wasi/wasix-ffi.ts
7060
+ function read(view, at, type) {
7061
+ if (type === "i32") return view.getInt32(at, true);
7062
+ if (type === "i64") return view.getBigInt64(at, true);
7063
+ if (type === "f32") return view.getFloat32(at, true);
7064
+ return view.getFloat64(at, true);
7065
+ }
7066
+ function write(view, at, type, value2) {
7067
+ if (type === "i32") view.setInt32(at, Number(value2), true);
7068
+ else if (type === "i64") view.setBigInt64(at, BigInt(value2), true);
7069
+ else if (type === "f32") view.setFloat32(at, Number(value2), true);
7070
+ else view.setFloat64(at, Number(value2), true);
7071
+ }
7072
+ function scalars(types) {
7073
+ if (types.includes("other")) throw new WasiError("EINVAL");
7074
+ return types;
7075
+ }
7076
+ function callDynamic(ctx, id, values, valuesLen, results, resultsLen, strict) {
7077
+ const table = ctx.table();
7078
+ if (!table) throw new WasiError("ENOTSUP");
7079
+ const fn = id < table.length ? table.get(id) : null;
7080
+ const sig = fn ? ctx.types.of(fn) : void 0;
7081
+ if (!fn || !sig) throw new WasiError("EINVAL");
7082
+ const params = scalars(sig.params);
7083
+ const outs = scalars(sig.results);
7084
+ const view = ctx.mem.view();
7085
+ const end = values + valuesLen;
7086
+ let at = values;
7087
+ const args = params.map((type) => {
7088
+ if (at + SIZE2[type] > end) {
7089
+ if (strict) throw new WasiError("EINVAL");
7090
+ return type === "i64" ? 0n : 0;
7091
+ }
7092
+ const v = read(view, at, type);
7093
+ at += SIZE2[type];
7094
+ return v;
7095
+ });
7096
+ if (strict && at !== end) throw new WasiError("EINVAL");
7097
+ const returned = fn(...args);
7098
+ const got = outs.length === 1 ? [returned] : returned ?? [];
7099
+ const after = ctx.mem.view();
7100
+ const stop = results + resultsLen;
7101
+ let out = results;
7102
+ outs.forEach((type, i) => {
7103
+ if (out + SIZE2[type] > stop) {
7104
+ if (strict) throw new WasiError("EINVAL");
7105
+ return;
7106
+ }
7107
+ write(after, out, type, got[i]);
7108
+ out += SIZE2[type];
7109
+ });
7110
+ if (strict && out !== stop) throw new WasiError("EINVAL");
7111
+ }
7112
+ var SIZE2;
7113
+ var init_wasix_ffi = __esm({
7114
+ "src/process/wasi/wasix-ffi.ts"() {
7115
+ "use strict";
7116
+ init_wasi_files();
7117
+ SIZE2 = { i32: 4, i64: 8, f32: 4, f64: 8 };
7118
+ }
7119
+ });
7120
+
7121
+ // src/process/wasi/wasm-functypes.ts
7122
+ function readTypes(r, s) {
7123
+ for (let i = r.u32(); i > 0; i--) {
7124
+ r.byte();
7125
+ const params = [];
7126
+ for (let n = r.u32(); n > 0; n--) params.push(r.valtype());
7127
+ const results = [];
7128
+ for (let n = r.u32(); n > 0; n--) results.push(r.valtype());
7129
+ s.info.sigs.push({ params, results });
7130
+ }
7131
+ }
7132
+ function readImports(r, s) {
7133
+ for (let i = r.u32(); i > 0; i--) {
7134
+ r.name();
7135
+ const field2 = r.name();
7136
+ const kind = r.byte();
7137
+ if (kind === 0) s.info.funcs.push(r.u32());
7138
+ else if (kind === 1) {
7139
+ r.valtype();
7140
+ r.limits();
7141
+ } else if (kind === 2) r.limits();
7142
+ else if (kind === 3) {
7143
+ r.valtype();
7144
+ r.byte();
7145
+ s.globals.push(field2);
7146
+ } else {
7147
+ r.byte();
7148
+ r.u32();
7149
+ }
7150
+ }
7151
+ }
7152
+ function readFunctions(r, s) {
7153
+ for (let i = r.u32(); i > 0; i--) s.info.funcs.push(r.u32());
7154
+ }
7155
+ function constExpr(r, s) {
7156
+ let value2 = 0;
7157
+ let tableBase = false;
7158
+ let known = true;
7159
+ for (; ; ) {
7160
+ const op = r.byte();
7161
+ if (op === 11) return known ? { value: value2, tableBase } : void 0;
7162
+ if (op === 65) value2 += r.s32();
7163
+ else if (op === 35) {
7164
+ const g = s.globals[r.u32()];
7165
+ if (g === TABLE_BASE) tableBase = true;
7166
+ else if (typeof g === "number") value2 += g;
7167
+ else known = false;
7168
+ } else if (op === 210) {
7169
+ value2 = r.u32();
7170
+ } else if (op in SKIP) {
7171
+ SKIP[op]?.(r);
7172
+ known = false;
7173
+ } else if (op !== 106) {
7174
+ r.at = r.bytes.length;
7175
+ return void 0;
7176
+ }
7177
+ }
7178
+ }
7179
+ function readGlobals(r, s) {
7180
+ for (let i = r.u32(); i > 0; i--) {
7181
+ r.valtype();
7182
+ r.byte();
7183
+ const init = constExpr(r, s);
7184
+ s.globals.push(init && !init.tableBase ? init.value : void 0);
7185
+ }
7186
+ }
7187
+ function readExports(r, s) {
7188
+ for (let i = r.u32(); i > 0; i--) {
7189
+ const name = r.name();
7190
+ const kind = r.byte();
7191
+ const index2 = r.u32();
7192
+ if (kind === 0) s.info.exports[name] = index2;
7193
+ }
7194
+ }
7195
+ function readElems(r, s) {
7196
+ for (let i = r.u32(); i > 0; i--) {
7197
+ const flags = r.u32();
7198
+ const active = (flags & 1) === 0;
7199
+ const table = flags & 2 ? active ? r.u32() : 0 : 0;
7200
+ const offset = active ? constExpr(r, s) : void 0;
7201
+ if (flags & 3) r.valtype();
7202
+ const funcs = [];
7203
+ for (let n = r.u32(); n > 0; n--) {
7204
+ if (flags & 4) {
7205
+ const ref = constExpr(r, s);
7206
+ funcs.push(ref ? ref.value : -1);
7207
+ } else funcs.push(r.u32());
7208
+ }
7209
+ if (offset && table === 0) {
7210
+ s.info.elems.push({ offset: offset.value, tableBase: offset.tableBase, funcs });
7211
+ }
7212
+ }
7213
+ }
7214
+ function funcTypeInfo(bytes) {
7215
+ const r = new Reader(bytes);
7216
+ const s = { info: { sigs: [], funcs: [], exports: {}, elems: [] }, globals: [] };
7217
+ while (r.at < bytes.length) {
7218
+ const id = r.byte();
7219
+ const end = r.u32() + r.at;
7220
+ SECTIONS[id]?.(r, s);
7221
+ r.at = end;
7222
+ }
7223
+ return s.info;
7224
+ }
7225
+ var VALTYPES, TABLE_BASE, Reader, SKIP, SECTIONS, FuncTypes;
7226
+ var init_wasm_functypes = __esm({
7227
+ "src/process/wasi/wasm-functypes.ts"() {
7228
+ "use strict";
7229
+ VALTYPES = {
7230
+ 127: "i32",
7231
+ 126: "i64",
7232
+ 125: "f32",
7233
+ 124: "f64"
7234
+ };
7235
+ TABLE_BASE = "__table_base";
7236
+ Reader = class {
7237
+ at = 8;
7238
+ bytes;
7239
+ constructor(bytes) {
7240
+ this.bytes = bytes;
7241
+ }
7242
+ byte() {
7243
+ return this.bytes[this.at++] ?? 0;
7244
+ }
7245
+ u32() {
7246
+ let result = 0;
7247
+ let shift = 0;
7248
+ for (; ; ) {
7249
+ const b = this.byte();
7250
+ result |= (b & 127) << shift;
7251
+ if (!(b & 128)) return result >>> 0;
7252
+ shift += 7;
7253
+ }
7254
+ }
7255
+ s32() {
7256
+ let result = 0;
7257
+ let shift = 0;
7258
+ let b;
7259
+ do {
7260
+ b = this.byte();
7261
+ result |= (b & 127) << shift;
7262
+ shift += 7;
7263
+ } while (b & 128);
7264
+ return shift < 32 && b & 64 ? result | -1 << shift : result;
7265
+ }
7266
+ name() {
7267
+ const len = this.u32();
7268
+ const s = new TextDecoder().decode(this.bytes.subarray(this.at, this.at + len));
7269
+ this.at += len;
7270
+ return s;
7271
+ }
7272
+ valtype() {
7273
+ const code2 = this.byte();
7274
+ if (code2 === 99 || code2 === 100) this.s32();
7275
+ return VALTYPES[code2] ?? "other";
7276
+ }
7277
+ limits() {
7278
+ const flags = this.byte();
7279
+ this.u32();
7280
+ if (flags & 1) this.u32();
7281
+ }
7282
+ };
7283
+ SKIP = {
7284
+ 66: (r) => r.s32(),
7285
+ 67: (r) => {
7286
+ r.at += 4;
7287
+ },
7288
+ 68: (r) => {
7289
+ r.at += 8;
7290
+ },
7291
+ 208: (r) => r.valtype()
7292
+ };
7293
+ SECTIONS = {
7294
+ 1: readTypes,
7295
+ 2: readImports,
7296
+ 3: readFunctions,
7297
+ 6: readGlobals,
7298
+ 7: readExports,
7299
+ 9: readElems
7300
+ };
7301
+ FuncTypes = class {
7302
+ known = /* @__PURE__ */ new WeakMap();
7303
+ pending = [];
7304
+ register(read2, instance, table, tableBase) {
7305
+ this.pending.push(() => {
7306
+ const bytes = read2();
7307
+ if (bytes) this.add(funcTypeInfo(bytes), instance, table, tableBase);
7308
+ });
7309
+ }
7310
+ add(info, instance, table, tableBase) {
7311
+ 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];
7314
+ const type = sig(func);
7315
+ if (typeof fn === "function" && type) this.known.set(fn, type);
7316
+ }
7317
+ if (!table) return;
7318
+ for (const seg of info.elems) {
7319
+ const start2 = seg.offset + (seg.tableBase ? tableBase : 0);
7320
+ seg.funcs.forEach((func, i) => {
7321
+ const type = sig(func);
7322
+ const fn = start2 + i < table.length ? table.get(start2 + i) : null;
7323
+ if (fn && type) this.known.set(fn, type);
7324
+ });
7325
+ }
7326
+ }
7327
+ set(fn, sig) {
7328
+ this.known.set(fn, sig);
7329
+ }
7330
+ of(fn) {
7331
+ const known = this.known.get(fn);
7332
+ if (known || this.pending.length === 0) return known;
7333
+ const pending = this.pending;
7334
+ this.pending = [];
7335
+ for (const run of pending) run();
7336
+ return this.known.get(fn);
7337
+ }
7338
+ };
7339
+ }
7340
+ });
7341
+
7054
7342
  // src/process/wasi/wasix-linker.ts
7055
7343
  function expandOrigin(entry, dir) {
7056
7344
  return entry.replace(/\$(?:ORIGIN\b|\{ORIGIN\})/g, dir);
@@ -7069,13 +7357,14 @@ function call(instance, name) {
7069
7357
  const fn = instance.exports[name];
7070
7358
  if (typeof fn === "function") fn();
7071
7359
  }
7072
- var TABLE_BASE, PAGE2, STACK_SIZE, LIBRARY_DIRS, DlError, WasixLinker;
7360
+ var TABLE_BASE2, PAGE2, STACK_SIZE, LIBRARY_DIRS, DlError, WasixLinker;
7073
7361
  var init_wasix_linker = __esm({
7074
7362
  "src/process/wasi/wasix-linker.ts"() {
7075
7363
  "use strict";
7076
7364
  init_dylink();
7077
7365
  init_wasi_files();
7078
- TABLE_BASE = 1;
7366
+ init_wasm_functypes();
7367
+ TABLE_BASE2 = 1;
7079
7368
  PAGE2 = 65536;
7080
7369
  STACK_SIZE = 8 * 1024 * 1024;
7081
7370
  LIBRARY_DIRS = ["/lib", "/usr/lib", "/usr/local/lib"];
@@ -7096,6 +7385,8 @@ var init_wasix_linker = __esm({
7096
7385
  slots = /* @__PURE__ */ new Map();
7097
7386
  nextHandle = 1;
7098
7387
  publisher;
7388
+ closures;
7389
+ types = new FuncTypes();
7099
7390
  memory;
7100
7391
  host;
7101
7392
  constructor(memory, mainInfo, host, thread = false) {
@@ -7107,7 +7398,7 @@ var init_wasix_linker = __esm({
7107
7398
  if (!thread) growTo(memory, this.stackHigh);
7108
7399
  this.table = new WebAssembly.Table({
7109
7400
  element: "anyfunc",
7110
- initial: TABLE_BASE + mainInfo.tableSize
7401
+ initial: TABLE_BASE2 + mainInfo.tableSize
7111
7402
  });
7112
7403
  this.stackPointer = new WebAssembly.Global(
7113
7404
  { value: "i32", mutable: true },
@@ -7127,7 +7418,7 @@ var init_wasix_linker = __esm({
7127
7418
  __indirect_function_table: this.table,
7128
7419
  __stack_pointer: this.stackPointer,
7129
7420
  __memory_base: i32(this.memoryBase),
7130
- __table_base: i32(TABLE_BASE),
7421
+ __table_base: i32(TABLE_BASE2),
7131
7422
  __c_longjmp: this.cLongjmp,
7132
7423
  __cpp_exception: this.cppException
7133
7424
  };
@@ -7179,7 +7470,22 @@ var init_wasix_linker = __esm({
7179
7470
  for (const [path, linked] of this.byPath) out[path] = linked.module;
7180
7471
  return out;
7181
7472
  }
7473
+ allocateClosure() {
7474
+ const index2 = this.closures.allocate(
7475
+ this.table.length
7476
+ );
7477
+ growTable(this.table, index2 + 1);
7478
+ return index2;
7479
+ }
7480
+ freeClosure(index2) {
7481
+ this.closures?.free(index2);
7482
+ this.table.set(index2, null);
7483
+ }
7182
7484
  replay(record) {
7485
+ if (record.kind === "closure") {
7486
+ growTable(this.table, record.index + 1);
7487
+ return;
7488
+ }
7183
7489
  if (record.kind === "load") {
7184
7490
  if (this.modules.has(record.handle)) return;
7185
7491
  this.instantiate(record.path, this.moduleAt(record.path), record, false);
@@ -7294,6 +7600,7 @@ var init_wasix_linker = __esm({
7294
7600
  "GOT.func": gotFunc
7295
7601
  };
7296
7602
  linked.instance = new WebAssembly.Instance(module, imports);
7603
+ this.types.register(() => this.host.read(path), linked.instance, this.table, at.tableBase);
7297
7604
  this.modules.set(at.handle, linked);
7298
7605
  this.byPath.set(path, linked);
7299
7606
  for (const resolve of pending) resolve();
@@ -7671,9 +7978,11 @@ var init_wasix_host = __esm({
7671
7978
  init_wasi_files();
7672
7979
  init_wasi_host();
7673
7980
  init_wasi_threads();
7981
+ init_wasix_ffi();
7674
7982
  init_wasix_linker();
7675
7983
  init_wasix_process();
7676
7984
  init_wasix_sockets();
7985
+ init_wasm_functypes();
7677
7986
  FDFLAGSEXT_CLOEXEC = 1;
7678
7987
  SPAWN_OP_SIZE = 56;
7679
7988
  SPAWN_OPS = ["close", "dup2", "open", "chdir", "fchdir"];
@@ -7685,6 +7994,8 @@ var init_wasix_host = __esm({
7685
7994
  process;
7686
7995
  threads;
7687
7996
  linker;
7997
+ types = new FuncTypes();
7998
+ table;
7688
7999
  signals;
7689
8000
  host;
7690
8001
  driver;
@@ -7766,6 +8077,18 @@ var init_wasix_host = __esm({
7766
8077
  ...this.processImports(),
7767
8078
  ...this.threadImports(),
7768
8079
  ...this.dlImports(),
8080
+ closure_allocate: (out) => {
8081
+ if (!this.linker) throw new WasiError("ENOTSUP");
8082
+ this.mem.view().setUint32(out, this.linker.allocateClosure(), true);
8083
+ },
8084
+ closure_free: (index2) => {
8085
+ if (!this.linker) throw new WasiError("ENOTSUP");
8086
+ this.linker.freeClosure(index2);
8087
+ },
8088
+ call_dynamic: (...a) => void callDynamic(
8089
+ { mem: this.mem, table: () => this.table, types: this.types },
8090
+ ...a
8091
+ ),
7769
8092
  ...wasixSocketImports(this.host, this.host.imports())
7770
8093
  });
7771
8094
  }
@@ -8087,12 +8410,12 @@ function nameFrame(line, module, name) {
8087
8410
  const found = name(Number(m[4]));
8088
8411
  return found === void 0 ? line : `${m[1]}${found} (${m[2]})`;
8089
8412
  }
8090
- function sidecarNames(read, path) {
8413
+ function sidecarNames(read2, path) {
8091
8414
  let names;
8092
8415
  return (index2) => {
8093
8416
  if (!names) {
8094
8417
  try {
8095
- names = parseFunctionNames(read(path));
8418
+ names = parseFunctionNames(read2(path));
8096
8419
  } catch {
8097
8420
  names = /* @__PURE__ */ new Map();
8098
8421
  }
@@ -8262,7 +8585,8 @@ async function instantiate(host, module, memory, threads, {
8262
8585
  stats,
8263
8586
  signals,
8264
8587
  program,
8265
- foreign
8588
+ foreign,
8589
+ path
8266
8590
  } = {}) {
8267
8591
  const driver = new AsyncifyDriver(host.mem);
8268
8592
  const wasixHost = WebAssembly.Module.imports(module).some((i) => i.module === WASIX) ? new WasixHost(host, driver, module) : void 0;
@@ -8288,7 +8612,10 @@ async function instantiate(host, module, memory, threads, {
8288
8612
  ) : void 0;
8289
8613
  if (sync) {
8290
8614
  ({ preview1, wasix } = sync.guard(preview1, wasix));
8291
- if (wasixHost) wasixHost.linker = sync.linker;
8615
+ if (wasixHost) {
8616
+ wasixHost.linker = sync.linker;
8617
+ wasixHost.types = sync.linker.types;
8618
+ }
8292
8619
  if (threads) {
8293
8620
  sync.linker.cache = threads.received;
8294
8621
  threads.modules = () => sync.linker.compiled();
@@ -8319,6 +8646,14 @@ async function instantiate(host, module, memory, threads, {
8319
8646
  stats?.phase("instantiate");
8320
8647
  const exports = instance.exports;
8321
8648
  host.mem.bind(memory ?? exports.memory);
8649
+ if (wasixHost) {
8650
+ const table = sync?.linker.table ?? exportedTable(instance);
8651
+ wasixHost.table = table;
8652
+ if (path !== void 0) {
8653
+ const read2 = linkerHost(host, () => ({})).read;
8654
+ wasixHost.types.register(() => read2(path), instance, table, sync ? TABLE_BASE2 : 0);
8655
+ }
8656
+ }
8322
8657
  if (sync) {
8323
8658
  sync.linker.bindMain(instance, !thread);
8324
8659
  if (thread) sync.catchUp();
@@ -8326,6 +8661,10 @@ async function instantiate(host, module, memory, threads, {
8326
8661
  }
8327
8662
  return { instance, driver };
8328
8663
  }
8664
+ function exportedTable(instance) {
8665
+ const table = instance.exports.__indirect_function_table;
8666
+ return table instanceof WebAssembly.Table ? table : void 0;
8667
+ }
8329
8668
  function linkerHost(host, imports) {
8330
8669
  return {
8331
8670
  read: (path) => {
@@ -8405,6 +8744,7 @@ async function runWasiProcess(init, port2) {
8405
8744
  stats,
8406
8745
  signals,
8407
8746
  foreign: init.program.foreign,
8747
+ path: init.program.path,
8408
8748
  ...program ? { program } : {}
8409
8749
  });
8410
8750
  restoreExportedMemory(instance, memory, init);
@@ -8489,6 +8829,7 @@ async function runWasiThread(init, port2) {
8489
8829
  const { instance } = await instantiate(host, init.program.module, thread.memory, threads, {
8490
8830
  thread: true,
8491
8831
  foreign: init.program.foreign,
8832
+ path: init.program.path,
8492
8833
  ...program ? { program } : {}
8493
8834
  });
8494
8835
  signals.bind(instance.exports);
@@ -8568,6 +8909,14 @@ var init_wasi_runtime = __esm({
8568
8909
  this.call = call2;
8569
8910
  this.ids = ids;
8570
8911
  linker.publisher = (record) => this.publish(record);
8912
+ linker.closures = {
8913
+ allocate: (floor) => {
8914
+ const index2 = this.call({ op: "dl-closure", floor });
8915
+ this.catchUp();
8916
+ return index2;
8917
+ },
8918
+ free: (index2) => void this.call({ op: "dl-closure-free", index: index2 })
8919
+ };
8571
8920
  }
8572
8921
  publish(record) {
8573
8922
  const since = this.call({ op: "dl-log", append: record, from: this.count });
@@ -8926,10 +9275,10 @@ async function slots(kernel, o, mine, theirs) {
8926
9275
  else if (how === "null") stdio.push({ none: true });
8927
9276
  else if (typeof how === "number") stdio.push({ fd: how });
8928
9277
  else {
8929
- const [read, write] = await kernel.json({ op: "fd-pipe" });
8930
- mine[n] = n === 0 ? write : read;
8931
- theirs.push(n === 0 ? read : write);
8932
- stdio.push({ fd: n === 0 ? read : write });
9278
+ const [read2, write2] = await kernel.json({ op: "fd-pipe" });
9279
+ mine[n] = n === 0 ? write2 : read2;
9280
+ theirs.push(n === 0 ? read2 : write2);
9281
+ stdio.push({ fd: n === 0 ? read2 : write2 });
8933
9282
  }
8934
9283
  }
8935
9284
  return stdio;
@@ -9349,8 +9698,8 @@ function checkOpen(abs, o, existing) {
9349
9698
  if (existing?.isDirectory) throw new JsCallError("EISDIR", abs);
9350
9699
  }
9351
9700
  function flagsOf(o) {
9352
- const write = o.write || o.append || o.truncate;
9353
- const access = write ? o.read ? O_RDWR6 : O_WRONLY6 : 0;
9701
+ const write2 = o.write || o.append || o.truncate;
9702
+ const access = write2 ? o.read ? O_RDWR6 : O_WRONLY6 : 0;
9354
9703
  return access | (o.append ? O_APPEND3 : 0);
9355
9704
  }
9356
9705
  function openRequest(abs, o) {
@@ -9535,14 +9884,14 @@ function syncOps(kernel, shared) {
9535
9884
  infos.set(fd, got);
9536
9885
  return got;
9537
9886
  };
9538
- const read = (fd, max = CHUNK2) => {
9887
+ const read2 = (fd, max = CHUNK2) => {
9539
9888
  index(max, "read");
9540
9889
  const emulated = readDevice(info(fd), max, shared.random);
9541
9890
  if (emulated) return emulated;
9542
9891
  const r = kernel.blocking({ op: "fd-read", fd, max: Math.min(max, MAX_IO) });
9543
9892
  return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
9544
9893
  };
9545
- const write = (fd, data) => {
9894
+ const write2 = (fd, data) => {
9546
9895
  const bytes = typeof data === "string" ? encoder2.encode(data) : data;
9547
9896
  const i = info(fd);
9548
9897
  if (writeDevice(i)) return;
@@ -9589,8 +9938,8 @@ function syncOps(kernel, shared) {
9589
9938
  return handle.file;
9590
9939
  };
9591
9940
  return {
9592
- read,
9593
- write,
9941
+ read: read2,
9942
+ write: write2,
9594
9943
  close(fd) {
9595
9944
  handles.get(fd)?.();
9596
9945
  handles.delete(fd);
@@ -9970,6 +10319,11 @@ var init_js_websocket = __esm({
9970
10319
  });
9971
10320
 
9972
10321
  // src/process/js/js-context.ts
10322
+ function listen(listeners, listener) {
10323
+ const own = (error, promise) => listener(error, promise);
10324
+ listeners.add(own);
10325
+ return () => void listeners.delete(own);
10326
+ }
9973
10327
  function identityOf(answer2, fallback) {
9974
10328
  const id = answer2;
9975
10329
  return {
@@ -10019,7 +10373,7 @@ function createContext(o) {
10019
10373
  infos.set(fd, got);
10020
10374
  return got;
10021
10375
  };
10022
- const read = async (fd, max = CHUNK2, signal) => {
10376
+ const read2 = async (fd, max = CHUNK2, signal) => {
10023
10377
  index(max, "read");
10024
10378
  const emulated = readDevice(await info(fd), max, random);
10025
10379
  if (emulated) return emulated;
@@ -10039,7 +10393,7 @@ function createContext(o) {
10039
10393
  }
10040
10394
  }
10041
10395
  };
10042
- const write = (fd, data) => {
10396
+ const write2 = (fd, data) => {
10043
10397
  const bytes = typeof data === "string" ? encoder3.encode(data) : data;
10044
10398
  let settle;
10045
10399
  const settled = new Promise((resolve2) => settle = resolve2);
@@ -10053,7 +10407,7 @@ function createContext(o) {
10053
10407
  }
10054
10408
  })();
10055
10409
  };
10056
- const writable2 = (fd) => new WritableStream({ write: (chunk) => write(fd, chunk) });
10410
+ const writable2 = (fd) => new WritableStream({ write: (chunk) => write2(fd, chunk) });
10057
10411
  const statOf = async (op, path) => {
10058
10412
  const abs = resolve(path);
10059
10413
  await kernel.call({ op: "fd-path-flush", path: abs });
@@ -10089,8 +10443,9 @@ function createContext(o) {
10089
10443
  handles
10090
10444
  });
10091
10445
  const terminal = ttyOps(kernel);
10092
- const io = { read, send: writeAll, close: (fd) => ctx.close(fd) };
10446
+ const io = { read: read2, send: writeAll, close: (fd) => ctx.close(fd) };
10093
10447
  const children = childOps(kernel, io, { env: o.env, cwd: o.cwd, signal: signalNumber });
10448
+ const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
10094
10449
  const ctx = {
10095
10450
  argv: o.argv,
10096
10451
  env: o.env,
@@ -10102,7 +10457,7 @@ function createContext(o) {
10102
10457
  stdin: new ReadableStream(
10103
10458
  {
10104
10459
  async pull(controller) {
10105
- const chunk = await read(0);
10460
+ const chunk = await read2(0);
10106
10461
  if (chunk.length === 0) controller.close();
10107
10462
  else controller.enqueue(chunk);
10108
10463
  }
@@ -10111,8 +10466,8 @@ function createContext(o) {
10111
10466
  ),
10112
10467
  stdout: writable2(1),
10113
10468
  stderr: writable2(2),
10114
- read,
10115
- write,
10469
+ read: read2,
10470
+ write: write2,
10116
10471
  async close(fd) {
10117
10472
  handles.get(fd)?.();
10118
10473
  handles.delete(fd);
@@ -10138,7 +10493,9 @@ function createContext(o) {
10138
10493
  net: netOps(kernel, io),
10139
10494
  websocket: websocketOp(kernel),
10140
10495
  tty: terminal.tty,
10141
- exit
10496
+ exit,
10497
+ onUncaught: (listener) => listen(strays.exception, listener),
10498
+ onUnhandledRejection: (listener) => listen(strays.rejection, listener)
10142
10499
  };
10143
10500
  const drain2 = async () => {
10144
10501
  for (; ; ) {
@@ -10357,19 +10714,19 @@ __export(js_runtime_exports, {
10357
10714
  runJsProcess: () => runJsProcess,
10358
10715
  trapStrays: () => trapStrays
10359
10716
  });
10360
- function trapStrays(scope2, fail) {
10717
+ function trapStrays(scope2, stray) {
10361
10718
  if (typeof scope2.process?.on === "function") {
10362
- scope2.process.on("unhandledRejection", fail);
10363
- scope2.process.on("uncaughtException", fail);
10719
+ scope2.process.on("unhandledRejection", (err, promise) => stray("rejection", err, promise));
10720
+ scope2.process.on("uncaughtException", (err) => stray("exception", err));
10364
10721
  return;
10365
10722
  }
10366
10723
  scope2.addEventListener?.("unhandledrejection", (event) => {
10367
10724
  event.preventDefault();
10368
- fail(event.reason);
10725
+ stray("rejection", event.reason, event.promise);
10369
10726
  });
10370
10727
  scope2.addEventListener?.("error", (event) => {
10371
10728
  event.preventDefault();
10372
- fail(event.error);
10729
+ stray("exception", event.error);
10373
10730
  });
10374
10731
  }
10375
10732
  async function settledStrays() {
@@ -10406,6 +10763,7 @@ async function runJsProcess(init, port2, deps = {}) {
10406
10763
  waitAsync: deps.waitAsync
10407
10764
  });
10408
10765
  void kernel.watchStops();
10766
+ const strays = { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
10409
10767
  const id = identityOf(await kernel.json({ op: "proc-identity" }), init);
10410
10768
  kernel.pid = id.pid;
10411
10769
  const { ctx, drain: drain2 } = createContext({
@@ -10416,12 +10774,23 @@ async function runJsProcess(init, port2, deps = {}) {
10416
10774
  ppid: id.ppid,
10417
10775
  cwd: init.cwd,
10418
10776
  exit: (status3) => exited(statusOf(status3)),
10419
- lane: laneOf(init.lane)
10777
+ lane: laneOf(init.lane),
10778
+ strays
10420
10779
  });
10421
10780
  const say = (text) => ctx.write(2, `${init.argv0}: ${text}
10422
10781
  `).catch(() => void 0);
10423
10782
  let main;
10424
- trapStrays(deps.scope ?? globalThis, fail);
10783
+ trapStrays(deps.scope ?? globalThis, (kind, err, promise) => {
10784
+ const listeners = [...strays[kind]];
10785
+ if (listeners.length === 0) return fail(err);
10786
+ for (const listener of listeners) {
10787
+ try {
10788
+ listener(err, promise);
10789
+ } catch (thrown) {
10790
+ fail(thrown);
10791
+ }
10792
+ }
10793
+ });
10425
10794
  try {
10426
10795
  (deps.lockdown ?? lockdown)();
10427
10796
  main = mainOf(await (deps.load ?? importSource)(init.program.glue));