@ai-ecoverse/slicc-kernel 1.95.3 → 1.97.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.
@@ -4703,7 +4703,7 @@ var KERNEL_VERSION, OS_RELEASE;
4703
4703
  var init_version = __esm({
4704
4704
  "src/version.ts"() {
4705
4705
  "use strict";
4706
- KERNEL_VERSION = true ? "1.95.3" : "0.0.0-dev";
4706
+ KERNEL_VERSION = true ? "1.97.0" : "0.0.0-dev";
4707
4707
  OS_RELEASE = "6.0.0-slicc";
4708
4708
  }
4709
4709
  });
@@ -6473,6 +6473,7 @@ function entryOf(info) {
6473
6473
  return {
6474
6474
  type: "kernel",
6475
6475
  kind: info.kind,
6476
+ dgram: info.dgram === true,
6476
6477
  nonblock: ((info.flags ?? 0) & O_NONBLOCK2) !== 0,
6477
6478
  append: ((info.flags ?? 0) & O_APPEND2) !== 0
6478
6479
  };
@@ -6687,8 +6688,8 @@ var init_wasi_fds = __esm({
6687
6688
  sockets() {
6688
6689
  return [...this.table].filter(([, e]) => e.type === "kernel" && e.kind === "socket").map(([fd]) => fd).sort((a, b) => a - b);
6689
6690
  }
6690
- adopt(fd, kind, nonblock) {
6691
- this.table.set(fd, { type: "kernel", kind, nonblock, append: false });
6691
+ adopt(fd, kind, nonblock, dgram = false) {
6692
+ this.table.set(fd, { type: "kernel", kind, dgram, nonblock, append: false });
6692
6693
  if (this.shared && nonblock) this.publishFlags(fd, { nonblock, append: false });
6693
6694
  this.bump();
6694
6695
  }
@@ -6910,9 +6911,17 @@ var init_wasi_fds = __esm({
6910
6911
  if (!e.kind) {
6911
6912
  const info = this.kernel.call({ op: "fd-info", fd });
6912
6913
  e.kind = info.kind ?? (info.tty ? "tty" : "stream");
6914
+ e.dgram = info.dgram === true;
6913
6915
  }
6914
6916
  return e.kind;
6915
6917
  }
6918
+ datagram(fd, e) {
6919
+ if (this.kind(fd, e) !== "socket") return false;
6920
+ if (e.dgram === void 0) {
6921
+ e.dgram = this.kernel.call({ op: "fd-info", fd }).dgram === true;
6922
+ }
6923
+ return e.dgram;
6924
+ }
6916
6925
  flushAll() {
6917
6926
  for (const buffer of this.buffers.values()) {
6918
6927
  try {
@@ -7464,169 +7473,526 @@ var init_wasi_termios = __esm({
7464
7473
  }
7465
7474
  });
7466
7475
 
7467
- // src/process/wasi/wasi-host.ts
7468
- function idOf3(value2) {
7469
- return value2 >>> 0 === 4294967295 ? void 0 : value2 >>> 0;
7476
+ // src/kernel/net/datagram-wire.ts
7477
+ function decodeReceived(raw) {
7478
+ const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
7479
+ const length = view.getUint8(3);
7480
+ return {
7481
+ truncated: (view.getUint8(0) & 1) !== 0,
7482
+ port: view.getUint16(1),
7483
+ host: new TextDecoder().decode(raw.subarray(4, 4 + length)),
7484
+ bytes: raw.subarray(4 + length)
7485
+ };
7470
7486
  }
7471
- function linkedOf(st) {
7472
- return (st.nlink ?? 1) > 1 ? st : void 0;
7487
+ var init_datagram_wire = __esm({
7488
+ "src/kernel/net/datagram-wire.ts"() {
7489
+ "use strict";
7490
+ }
7491
+ });
7492
+
7493
+ // src/kernel/net/routes.ts
7494
+ function ipv4Bytes(text) {
7495
+ const parts = text.split(".");
7496
+ if (parts.length !== 4 || !parts.every((p) => /^\d{1,3}$/.test(p))) return void 0;
7497
+ const bytes = parts.map(Number);
7498
+ return bytes.every((b) => b <= 255) ? bytes : void 0;
7473
7499
  }
7474
- function linkedElsewhere(fs, path) {
7500
+ function ipv6Groups(text) {
7501
+ if (!text.includes(":")) return void 0;
7502
+ let canonical;
7475
7503
  try {
7476
- return linkedOf(fs.lstat(path));
7504
+ canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
7477
7505
  } catch {
7478
7506
  return void 0;
7479
7507
  }
7508
+ const [head, tail] = canonical.split("::");
7509
+ const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
7510
+ const front = part(head);
7511
+ const back = part(tail);
7512
+ return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
7480
7513
  }
7481
- function filetypeOf(s) {
7482
- if (!s) return FILETYPE.UNKNOWN;
7483
- if (s.isSymbolicLink) return FILETYPE.SYMBOLIC_LINK;
7484
- if (s.isDirectory) return FILETYPE.DIRECTORY;
7485
- return s.isFile ? FILETYPE.REGULAR_FILE : FILETYPE.UNKNOWN;
7514
+ function toBits(values, width) {
7515
+ return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
7486
7516
  }
7487
- function filestatOf(path, s) {
7488
- return {
7489
- filetype: filetypeOf(s),
7490
- size: BigInt(s.size),
7491
- ino: s.ino !== void 0 ? BigInt(s.ino) : pathInode(path),
7492
- ...s.nlink !== void 0 ? { nlink: BigInt(s.nlink) } : {},
7493
- mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) * NS_PER_MS
7494
- };
7517
+ function addressBits(host) {
7518
+ const v4 = ipv4Bytes(host);
7519
+ if (v4) return { v6: false, bits: toBits(v4, 8) };
7520
+ const v6 = ipv6Groups(host);
7521
+ return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
7495
7522
  }
7496
- function kernelFiletype(kind) {
7497
- switch (kind) {
7498
- case "tty":
7499
- case "sealed":
7500
- case "clipboard":
7501
- return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
7502
- case "device":
7503
- return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
7504
- case "socket":
7505
- return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
7506
- case "file":
7507
- return { filetype: FILETYPE.REGULAR_FILE, seeks: true };
7508
- default:
7509
- return { filetype: FILETYPE.UNKNOWN, seeks: false };
7523
+ function parsePrefix(text) {
7524
+ const parts = text.trim().split("/");
7525
+ if (parts.length > 2) return void 0;
7526
+ const [address = "", size] = parts;
7527
+ const parsed = addressBits(address);
7528
+ if (!parsed) return void 0;
7529
+ const max = parsed.v6 ? 128 : 32;
7530
+ const length = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
7531
+ if (length < 0 || length > max) return void 0;
7532
+ return { ...parsed, length };
7533
+ }
7534
+ var HOST_ADDRESS, RESERVED;
7535
+ var init_routes = __esm({
7536
+ "src/kernel/net/routes.ts"() {
7537
+ "use strict";
7538
+ init_loopback_names();
7539
+ HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
7540
+ RESERVED = [
7541
+ "0.0.0.0/8",
7542
+ "127.0.0.0/8",
7543
+ "169.254.0.0/16",
7544
+ "224.0.0.0/4",
7545
+ "240.0.0.0/4",
7546
+ "::/96",
7547
+ "::ffff:0:0/96",
7548
+ "fe80::/10",
7549
+ "ff00::/8"
7550
+ ].map((p) => parsePrefix(p));
7551
+ }
7552
+ });
7553
+
7554
+ // src/process/wasi/wasix-sockets.ts
7555
+ function readAddr(view, ptr) {
7556
+ const tag = view.getUint8(ptr);
7557
+ if (tag === UNIX) {
7558
+ let end = ptr + 2;
7559
+ while (end < ptr + 110 && view.getUint8(end) !== 0) end++;
7560
+ const path = new TextDecoder().decode(
7561
+ new Uint8Array(view.buffer, ptr + 2, end - ptr - 2).slice()
7562
+ );
7563
+ return { family: "unix", path };
7564
+ }
7565
+ const port2 = view.getUint16(ptr + 2, true);
7566
+ if (tag === INET4) {
7567
+ const host = [0, 1, 2, 3].map((i) => view.getUint8(ptr + 4 + i)).join(".");
7568
+ return { family: "inet", host, port: port2 };
7569
+ }
7570
+ if (tag === INET6) {
7571
+ return { family: "inet", host: ipv6Host(new Uint8Array(view.buffer, ptr + 4, 16)), port: port2 };
7510
7572
  }
7573
+ throw new WasiError("EAFNOSUPPORT");
7511
7574
  }
7512
- function direntRecord(next2, ino, name2, filetype) {
7513
- const nameBytes = new TextEncoder().encode(name2);
7514
- const record = new Uint8Array(SIZE.DIRENT + nameBytes.length);
7515
- const v = new DataView(record.buffer);
7516
- v.setBigUint64(0, BigInt(next2), true);
7517
- v.setBigUint64(8, ino, true);
7518
- v.setUint32(16, nameBytes.length, true);
7519
- v.setUint8(20, filetype);
7520
- record.set(nameBytes, SIZE.DIRENT);
7521
- return record;
7575
+ function ipv6Host(bytes) {
7576
+ const zeros = (n) => bytes.subarray(0, n).every((b) => b === 0);
7577
+ if (zeros(16)) return "0.0.0.0";
7578
+ if (zeros(15) && bytes[15] === 1) return LOOPBACK;
7579
+ if (zeros(10) && bytes[10] === 255 && bytes[11] === 255) return bytes.subarray(12).join(".");
7580
+ const groups = [0, 2, 4, 6, 8, 10, 12, 14].map(
7581
+ (i) => (bytes[i] << 8 | bytes[i + 1]).toString(16)
7582
+ );
7583
+ return new URL(`http://[${groups.join(":")}]/`).hostname.slice(1, -1);
7522
7584
  }
7523
- function wrap(table) {
7524
- const out = {};
7525
- for (const [name2, fn] of Object.entries(table)) {
7526
- out[name2] = (...args) => {
7527
- try {
7528
- return fn(...args) ?? E.SUCCESS;
7529
- } catch (e) {
7530
- if (e instanceof WasiExit) throw e;
7531
- if (e instanceof WasiError) return wasiErrnoOf(e.code);
7532
- const code2 = e?.code;
7533
- if (typeof code2 === "string") return wasiErrnoOf(code2);
7534
- if (e instanceof RangeError) return E.FAULT;
7535
- throw e;
7536
- }
7537
- };
7585
+ function writeAddr(view, ptr, addr) {
7586
+ new Uint8Array(view.buffer, ptr, 110).fill(0);
7587
+ if (!addr) return;
7588
+ if (addr.family === "unix") {
7589
+ view.setUint8(ptr, UNIX);
7590
+ new Uint8Array(view.buffer, ptr + 2, 107).set(
7591
+ new TextEncoder().encode(addr.path).subarray(0, 107)
7592
+ );
7593
+ return;
7538
7594
  }
7539
- return out;
7595
+ view.setUint16(ptr + 2, addr.port, true);
7596
+ const groups = ipv4(addr.host) ? void 0 : ipv6Groups(addr.host);
7597
+ if (groups) {
7598
+ view.setUint8(ptr, INET6);
7599
+ groups.forEach((g, i) => void view.setUint16(ptr + 4 + i * 2, g));
7600
+ return;
7601
+ }
7602
+ view.setUint8(ptr, INET4);
7603
+ const octets = ipv4(addr.host) ?? [127, 0, 0, 1];
7604
+ octets.forEach((b, i) => void view.setUint8(ptr + 4 + i, b));
7540
7605
  }
7541
- var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, AT_EACCESS2, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, SIG_IGN, SEALED_MODE, WasiHost;
7542
- var init_wasi_host = __esm({
7543
- "src/process/wasi/wasi-host.ts"() {
7544
- "use strict";
7545
- init_dev_removal();
7546
- init_physical_path();
7547
- init_cpu_clock();
7548
- init_cred();
7549
- init_wasi_abi();
7550
- init_wasi_fds();
7551
- init_wasi_files();
7552
- init_wasi_memory();
7553
- init_wasi_poll();
7554
- init_wasi_termios();
7555
- WasiExit = class extends Error {
7556
- code;
7557
- constructor(code2) {
7558
- super(`exit ${code2}`);
7559
- this.code = code2;
7560
- }
7561
- };
7562
- IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
7563
- NS_PER_MS = 1000000n;
7564
- AT_SYMLINK_NOFOLLOW2 = 1;
7565
- AT_EACCESS2 = 2;
7566
- ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
7567
- GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
7568
- S_IFIFO = 4096;
7569
- DEFAULT_UMASK = 18;
7570
- MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
7571
- MAX_READ = 1024 * 1024;
7572
- SIGPIPE_EXIT = 141;
7573
- SIG_IGN = 1;
7574
- SEALED_MODE = 8630;
7575
- WasiHost = class {
7576
- mem = new WasiMemory();
7577
- fds;
7578
- started = performance.now();
7579
- cache;
7580
- startCwd;
7581
- interruptWakes = false;
7582
- entered = false;
7583
- onRaise;
7584
- muted;
7585
- signals;
7586
- sigmask;
7587
- linkedTls;
7588
- linkedModules;
7589
- interrupted;
7590
- quietly = (fn) => fn();
7591
- listening;
7592
- o;
7593
- constructor(o) {
7594
- const { kernel } = o;
7595
- const call2 = (req) => {
7596
- if (req.op !== "fd-promote") this.fds.flushEarly();
7597
- return kernel.call(req);
7598
- };
7599
- const sys = new Proxy(kernel.sys, {
7600
- get: (target, name2) => {
7601
- const member = Reflect.get(target, name2);
7602
- if (typeof member !== "function") return member;
7603
- return (...args) => {
7604
- this.fds.flushEarly();
7605
- return member.apply(target, args);
7606
- };
7607
- }
7608
- });
7609
- this.o = { ...o, kernel: { sys, call: call2 } };
7610
- this.startCwd = o.cwd;
7611
- this.fds = new WasiFds(this.o.kernel, o.fs);
7612
- if (o.shared) this.fds.share(o.shared, true);
7613
- else if (o.forked) this.fds.restore(o.forked.fds, o.forked.cloexec);
7614
- else this.fds.setup(o.cwd, o.inherited ?? [], o.preopenRoot === true);
7615
- this.listening = o.shared ? [] : this.fds.sockets();
7616
- }
7617
- get cwd() {
7618
- return this.fds.cwd() ?? this.startCwd;
7619
- }
7620
- created(path, mode) {
7621
- const umask = this.o.kernel.call({ op: "proc-umask" });
7622
- if (umask !== DEFAULT_UMASK) this.o.fs.chmod(path, mode & ~umask);
7623
- }
7624
- sliccTtyImports() {
7625
- return wrap(sliccTty(this.mem, this.fds, this.o.kernel, () => this.interrupted?.()));
7626
- }
7627
- sliccFsImports() {
7628
- const { mem, fds } = this;
7629
- const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
7606
+ function ipBytes(host) {
7607
+ const groups = ipv4(host) ? void 0 : ipv6Groups(host);
7608
+ return groups ? groups.flatMap((g) => [g >> 8, g & 255]) : ipv4(host);
7609
+ }
7610
+ function ipv4(host) {
7611
+ const parts = host.split(".");
7612
+ if (parts.length !== 4) return void 0;
7613
+ const bytes = parts.map((p) => /^\d{1,3}$/.test(p) ? Number(p) : Number.NaN);
7614
+ return bytes.every((b) => b >= 0 && b <= 255) ? bytes : void 0;
7615
+ }
7616
+ function openRequest(af, type) {
7617
+ if (af !== INET4 && af !== INET6 && af !== UNIX) throw new WasiError("EAFNOSUPPORT");
7618
+ if (type !== STREAM && (type !== DGRAM || af === UNIX)) throw new WasiError("EPROTONOSUPPORT");
7619
+ const domain = af === UNIX ? "unix" : "inet";
7620
+ return {
7621
+ op: "sock-open",
7622
+ domain,
7623
+ ...type === DGRAM ? { type: "dgram" } : {}
7624
+ };
7625
+ }
7626
+ function optionalAddr(view, ptr) {
7627
+ if (ptr === 0 || view.getUint8(ptr) === 0) return void 0;
7628
+ return readAddr(view, ptr);
7629
+ }
7630
+ function datagramCalls(host) {
7631
+ const { mem, o } = host;
7632
+ const call2 = (req) => o.kernel.call(req);
7633
+ return {
7634
+ recvFrom(fd, nonblock, iovs, n, riflags, outLen, outFlags, outAddr) {
7635
+ const max = Math.min(mem.capacity(iovs, n), MAX_DATAGRAM);
7636
+ const peek = (riflags & RIFLAG_PEEK) !== 0;
7637
+ const raw = call2({ op: "sock-recvfrom", fd, max, peek, nonblock });
7638
+ const got = decodeReceived(raw);
7639
+ const view = mem.view();
7640
+ view.setUint32(outLen, mem.scatter(iovs, n, got.bytes), true);
7641
+ view.setUint16(outFlags, got.truncated ? RECV_DATA_TRUNCATED : 0, true);
7642
+ if (outAddr)
7643
+ writeAddr(mem.view(), outAddr, { family: "inet", host: got.host, port: got.port });
7644
+ return E.SUCCESS;
7645
+ },
7646
+ sendTo(fd, nonblock, iovs, n, addr, out) {
7647
+ const to = optionalAddr(mem.view(), addr);
7648
+ const body = mem.gather(iovs, n);
7649
+ const sent = call2({ op: "sock-sendto", fd, body, ...to ? { addr: to } : {}, nonblock });
7650
+ mem.view().setUint32(out, sent, true);
7651
+ return E.SUCCESS;
7652
+ }
7653
+ };
7654
+ }
7655
+ function wasixSocketImports(host, preview1) {
7656
+ const { mem, fds, o } = host;
7657
+ const call2 = (req) => o.kernel.call(req);
7658
+ const socket = (fd) => {
7659
+ const e = fds.get(fd);
7660
+ if (e.type !== "kernel" || fds.kind(fd, e) !== "socket") throw new WasiError("ENOTSOCK");
7661
+ return e;
7662
+ };
7663
+ const option = (opt) => OPTIONS[opt];
7664
+ const datagrams = (fd) => {
7665
+ try {
7666
+ const e = fds.get(fd);
7667
+ return e.type === "kernel" && fds.datagram(fd, e);
7668
+ } catch {
7669
+ return false;
7670
+ }
7671
+ };
7672
+ const dgram = datagramCalls(host);
7673
+ return {
7674
+ sock_open: (af, type, _proto, out) => {
7675
+ const req = openRequest(af, type);
7676
+ const fd = call2(req);
7677
+ fds.adopt(fd, "socket", false, "type" in req);
7678
+ mem.view().setUint32(out, fd, true);
7679
+ },
7680
+ sock_pair: (af, type, _proto, out1, out2) => {
7681
+ if (af !== UNIX)
7682
+ throw new WasiError(af === INET4 || af === INET6 ? "EOPNOTSUPP" : "EAFNOSUPPORT");
7683
+ if (type !== STREAM) throw new WasiError("EPROTONOSUPPORT");
7684
+ mem.view().setUint32(out1, 0, true);
7685
+ mem.view().setUint32(out2, 0, true);
7686
+ const [a, b] = call2({ op: "sock-pair", domain: "unix" });
7687
+ fds.adopt(a, "socket", false);
7688
+ fds.adopt(b, "socket", false);
7689
+ mem.view().setUint32(out1, a, true);
7690
+ mem.view().setUint32(out2, b, true);
7691
+ },
7692
+ sock_bind: (fd, addr) => {
7693
+ socket(fd);
7694
+ call2({ op: "sock-bind", fd, addr: readAddr(mem.view(), addr) });
7695
+ },
7696
+ sock_listen: (fd, backlog) => {
7697
+ socket(fd);
7698
+ call2({ op: "sock-listen", fd, backlog });
7699
+ },
7700
+ sock_connect: (fd, addr) => {
7701
+ const e = socket(fd);
7702
+ call2({ op: "sock-connect", fd, addr: readAddr(mem.view(), addr), nonblock: e.nonblock });
7703
+ },
7704
+ sock_accept_v2: (fd, flags, outFd, outAddr) => {
7705
+ const e = socket(fd);
7706
+ const r = call2({ op: "sock-accept", fd, nonblock: e.nonblock });
7707
+ fds.adopt(r.fd, "socket", (flags & FDFLAGS.NONBLOCK) !== 0);
7708
+ mem.view().setUint32(outFd, r.fd, true);
7709
+ writeAddr(mem.view(), outAddr, r.peer);
7710
+ },
7711
+ sock_addr_local: (fd, out) => {
7712
+ socket(fd);
7713
+ writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: false }));
7714
+ },
7715
+ sock_addr_peer: (fd, out) => {
7716
+ socket(fd);
7717
+ writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: true }));
7718
+ },
7719
+ sock_recv_from: (fd, iovs, n, riflags, outLen, outFlags, outAddr) => {
7720
+ if (datagrams(fd)) {
7721
+ const e = socket(fd);
7722
+ return dgram.recvFrom(fd, e.nonblock, iovs, n, riflags, outLen, outFlags, outAddr);
7723
+ }
7724
+ const r = preview1.sock_recv(
7725
+ fd,
7726
+ iovs,
7727
+ n,
7728
+ riflags,
7729
+ outLen,
7730
+ outFlags
7731
+ );
7732
+ if (r !== E.SUCCESS) return r;
7733
+ writeAddr(mem.view(), outAddr, call2({ op: "sock-name", fd, peer: true }));
7734
+ return E.SUCCESS;
7735
+ },
7736
+ sock_send_to: (fd, iovs, n, flags, addr, out) => {
7737
+ if (datagrams(fd)) return dgram.sendTo(fd, socket(fd).nonblock, iovs, n, addr, out);
7738
+ return preview1.sock_send(
7739
+ fd,
7740
+ iovs,
7741
+ n,
7742
+ flags,
7743
+ out
7744
+ );
7745
+ },
7746
+ sock_status: (fd, out) => {
7747
+ socket(fd);
7748
+ mem.view().setUint8(out, 1);
7749
+ },
7750
+ sock_get_opt_flag: (fd, opt, out) => {
7751
+ socket(fd);
7752
+ const pair = option(opt);
7753
+ const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
7754
+ mem.view().setUint8(out, v ? 1 : 0);
7755
+ },
7756
+ sock_set_opt_flag: (fd, opt, flag) => {
7757
+ socket(fd);
7758
+ const pair = option(opt);
7759
+ if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: flag ? 1 : 0 });
7760
+ },
7761
+ sock_get_opt_size: (fd, opt, out) => {
7762
+ socket(fd);
7763
+ const pair = option(opt);
7764
+ const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
7765
+ mem.view().setBigUint64(out, BigInt(v), true);
7766
+ },
7767
+ sock_set_opt_size: (fd, opt, size) => {
7768
+ socket(fd);
7769
+ const pair = option(opt);
7770
+ if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: Number(size) });
7771
+ },
7772
+ sock_get_opt_time: (fd, _opt, out) => {
7773
+ socket(fd);
7774
+ new Uint8Array(mem.view().buffer, out, 16).fill(0);
7775
+ },
7776
+ sock_set_opt_time: (fd) => void socket(fd),
7777
+ sock_send_file: () => E.NOSYS,
7778
+ resolve: (name2, len, _port, addrs, naddrs, out) => {
7779
+ const found = call2({ op: "sock-resolve", name: mem.string(name2, len), family: 0 });
7780
+ const ips = found.map(ipBytes).filter((ip) => ip !== void 0);
7781
+ if (ips.length === 0) throw new WasiError("ENOENT");
7782
+ if (naddrs < 1) throw new WasiError("EINVAL");
7783
+ const view = mem.view();
7784
+ const count = Math.min(ips.length, naddrs);
7785
+ new Uint8Array(view.buffer, addrs, ADDR_IP_SIZE * count).fill(0);
7786
+ for (let i = 0; i < count; i++) {
7787
+ const at = addrs + i * ADDR_IP_SIZE;
7788
+ view.setUint8(at, ips[i].length === 4 ? INET4 : INET6);
7789
+ new Uint8Array(view.buffer, at + 2, ips[i].length).set(ips[i]);
7790
+ }
7791
+ view.setUint32(out, count, true);
7792
+ }
7793
+ };
7794
+ }
7795
+ var INET4, INET6, UNIX, STREAM, DGRAM, RECV_DATA_TRUNCATED, RIFLAG_PEEK, MAX_DATAGRAM, ADDR_IP_SIZE, LOOPBACK, OPTIONS;
7796
+ var init_wasix_sockets = __esm({
7797
+ "src/process/wasi/wasix-sockets.ts"() {
7798
+ "use strict";
7799
+ init_datagram_wire();
7800
+ init_routes();
7801
+ init_wasi_abi();
7802
+ init_wasi_files();
7803
+ INET4 = 1;
7804
+ INET6 = 2;
7805
+ UNIX = 3;
7806
+ STREAM = 1;
7807
+ DGRAM = 2;
7808
+ RECV_DATA_TRUNCATED = 1;
7809
+ RIFLAG_PEEK = 1;
7810
+ MAX_DATAGRAM = 65536;
7811
+ ADDR_IP_SIZE = 18;
7812
+ LOOPBACK = "127.0.0.1";
7813
+ OPTIONS = {
7814
+ 1: [1, 15],
7815
+ 2: [1, 2],
7816
+ 3: [6, 1],
7817
+ 4: [1, 5],
7818
+ 6: [1, 6],
7819
+ 10: [1, 30],
7820
+ 11: [1, 4],
7821
+ 12: [1, 9],
7822
+ 14: [1, 10],
7823
+ 15: [1, 8],
7824
+ 16: [1, 7],
7825
+ 25: [1, 3]
7826
+ };
7827
+ }
7828
+ });
7829
+
7830
+ // src/process/wasi/wasi-host.ts
7831
+ function idOf3(value2) {
7832
+ return value2 >>> 0 === 4294967295 ? void 0 : value2 >>> 0;
7833
+ }
7834
+ function linkedOf(st) {
7835
+ return (st.nlink ?? 1) > 1 ? st : void 0;
7836
+ }
7837
+ function linkedElsewhere(fs, path) {
7838
+ try {
7839
+ return linkedOf(fs.lstat(path));
7840
+ } catch {
7841
+ return void 0;
7842
+ }
7843
+ }
7844
+ function filetypeOf(s) {
7845
+ if (!s) return FILETYPE.UNKNOWN;
7846
+ if (s.isSymbolicLink) return FILETYPE.SYMBOLIC_LINK;
7847
+ if (s.isDirectory) return FILETYPE.DIRECTORY;
7848
+ return s.isFile ? FILETYPE.REGULAR_FILE : FILETYPE.UNKNOWN;
7849
+ }
7850
+ function filestatOf(path, s) {
7851
+ return {
7852
+ filetype: filetypeOf(s),
7853
+ size: BigInt(s.size),
7854
+ ino: s.ino !== void 0 ? BigInt(s.ino) : pathInode(path),
7855
+ ...s.nlink !== void 0 ? { nlink: BigInt(s.nlink) } : {},
7856
+ mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) * NS_PER_MS
7857
+ };
7858
+ }
7859
+ function kernelFiletype(kind) {
7860
+ switch (kind) {
7861
+ case "tty":
7862
+ case "sealed":
7863
+ case "clipboard":
7864
+ return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
7865
+ case "device":
7866
+ return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
7867
+ case "socket":
7868
+ return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
7869
+ case "dgram":
7870
+ return { filetype: FILETYPE.SOCKET_DGRAM, seeks: false };
7871
+ case "file":
7872
+ return { filetype: FILETYPE.REGULAR_FILE, seeks: true };
7873
+ default:
7874
+ return { filetype: FILETYPE.UNKNOWN, seeks: false };
7875
+ }
7876
+ }
7877
+ function direntRecord(next2, ino, name2, filetype) {
7878
+ const nameBytes = new TextEncoder().encode(name2);
7879
+ const record = new Uint8Array(SIZE.DIRENT + nameBytes.length);
7880
+ const v = new DataView(record.buffer);
7881
+ v.setBigUint64(0, BigInt(next2), true);
7882
+ v.setBigUint64(8, ino, true);
7883
+ v.setUint32(16, nameBytes.length, true);
7884
+ v.setUint8(20, filetype);
7885
+ record.set(nameBytes, SIZE.DIRENT);
7886
+ return record;
7887
+ }
7888
+ function wrap(table) {
7889
+ const out = {};
7890
+ for (const [name2, fn] of Object.entries(table)) {
7891
+ out[name2] = (...args) => {
7892
+ try {
7893
+ return fn(...args) ?? E.SUCCESS;
7894
+ } catch (e) {
7895
+ if (e instanceof WasiExit) throw e;
7896
+ if (e instanceof WasiError) return wasiErrnoOf(e.code);
7897
+ const code2 = e?.code;
7898
+ if (typeof code2 === "string") return wasiErrnoOf(code2);
7899
+ if (e instanceof RangeError) return E.FAULT;
7900
+ throw e;
7901
+ }
7902
+ };
7903
+ }
7904
+ return out;
7905
+ }
7906
+ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, AT_EACCESS2, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, SIG_IGN, SEALED_MODE, WasiHost;
7907
+ var init_wasi_host = __esm({
7908
+ "src/process/wasi/wasi-host.ts"() {
7909
+ "use strict";
7910
+ init_dev_removal();
7911
+ init_physical_path();
7912
+ init_cpu_clock();
7913
+ init_cred();
7914
+ init_wasi_abi();
7915
+ init_wasi_fds();
7916
+ init_wasi_files();
7917
+ init_wasi_memory();
7918
+ init_wasi_poll();
7919
+ init_wasi_termios();
7920
+ init_wasix_sockets();
7921
+ WasiExit = class extends Error {
7922
+ code;
7923
+ constructor(code2) {
7924
+ super(`exit ${code2}`);
7925
+ this.code = code2;
7926
+ }
7927
+ };
7928
+ IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
7929
+ NS_PER_MS = 1000000n;
7930
+ AT_SYMLINK_NOFOLLOW2 = 1;
7931
+ AT_EACCESS2 = 2;
7932
+ ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
7933
+ GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
7934
+ S_IFIFO = 4096;
7935
+ DEFAULT_UMASK = 18;
7936
+ MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
7937
+ MAX_READ = 1024 * 1024;
7938
+ SIGPIPE_EXIT = 141;
7939
+ SIG_IGN = 1;
7940
+ SEALED_MODE = 8630;
7941
+ WasiHost = class {
7942
+ mem = new WasiMemory();
7943
+ fds;
7944
+ started = performance.now();
7945
+ cache;
7946
+ startCwd;
7947
+ interruptWakes = false;
7948
+ entered = false;
7949
+ onRaise;
7950
+ muted;
7951
+ signals;
7952
+ sigmask;
7953
+ linkedTls;
7954
+ linkedModules;
7955
+ interrupted;
7956
+ quietly = (fn) => fn();
7957
+ listening;
7958
+ o;
7959
+ constructor(o) {
7960
+ const { kernel } = o;
7961
+ const call2 = (req) => {
7962
+ if (req.op !== "fd-promote") this.fds.flushEarly();
7963
+ return kernel.call(req);
7964
+ };
7965
+ const sys = new Proxy(kernel.sys, {
7966
+ get: (target, name2) => {
7967
+ const member = Reflect.get(target, name2);
7968
+ if (typeof member !== "function") return member;
7969
+ return (...args) => {
7970
+ this.fds.flushEarly();
7971
+ return member.apply(target, args);
7972
+ };
7973
+ }
7974
+ });
7975
+ this.o = { ...o, kernel: { sys, call: call2 } };
7976
+ this.startCwd = o.cwd;
7977
+ this.fds = new WasiFds(this.o.kernel, o.fs);
7978
+ if (o.shared) this.fds.share(o.shared, true);
7979
+ else if (o.forked) this.fds.restore(o.forked.fds, o.forked.cloexec);
7980
+ else this.fds.setup(o.cwd, o.inherited ?? [], o.preopenRoot === true);
7981
+ this.listening = o.shared ? [] : this.fds.sockets();
7982
+ }
7983
+ get cwd() {
7984
+ return this.fds.cwd() ?? this.startCwd;
7985
+ }
7986
+ created(path, mode) {
7987
+ const umask = this.o.kernel.call({ op: "proc-umask" });
7988
+ if (umask !== DEFAULT_UMASK) this.o.fs.chmod(path, mode & ~umask);
7989
+ }
7990
+ sliccTtyImports() {
7991
+ return wrap(sliccTty(this.mem, this.fds, this.o.kernel, () => this.interrupted?.()));
7992
+ }
7993
+ sliccFsImports() {
7994
+ const { mem, fds } = this;
7995
+ const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
7630
7996
  const pathOf = (fd) => {
7631
7997
  const e = fds.get(fd);
7632
7998
  if (e.type === "dir") return e.path;
@@ -8055,6 +8421,18 @@ var init_wasi_host = __esm({
8055
8421
  },
8056
8422
  sock_recv: (fd, iovs, n, riflags, outLen, outFlags) => {
8057
8423
  const e = this.socket(fd);
8424
+ if (this.fds.datagram(fd, e)) {
8425
+ return datagramCalls(this).recvFrom(
8426
+ fd,
8427
+ e.nonblock,
8428
+ iovs,
8429
+ n,
8430
+ riflags,
8431
+ outLen,
8432
+ outFlags,
8433
+ 0
8434
+ );
8435
+ }
8058
8436
  const peek = (riflags & RIFLAGS.PEEK) !== 0;
8059
8437
  const want = mem.capacity(iovs, n);
8060
8438
  const data = (riflags & RIFLAGS.WAITALL) !== 0 && !peek ? this.recvAll(fd, want, e.nonblock) : o.kernel.sys.read(fd, Math.min(want, MAX_READ), { nonblock: e.nonblock, peek });
@@ -8221,7 +8599,7 @@ var init_wasi_host = __esm({
8221
8599
  if (e.type === "kernel") {
8222
8600
  const kind = this.fds.kind(fd, e);
8223
8601
  if (kind === "device") this.interrupted?.();
8224
- ({ filetype, seeks } = kernelFiletype(kind));
8602
+ ({ filetype, seeks } = kernelFiletype(this.fds.datagram(fd, e) ? "dgram" : kind));
8225
8603
  if (e.nonblock) flags |= FDFLAGS.NONBLOCK;
8226
8604
  if (e.append) flags |= FDFLAGS.APPEND;
8227
8605
  } else if (e.type === "file") {
@@ -8849,7 +9227,7 @@ function importsContext({
8849
9227
  }
8850
9228
  function loopbackHost(host) {
8851
9229
  if (host === "localhost") return "127.0.0.1";
8852
- if (typeof host === "string" && LOOPBACK.test(host)) return host;
9230
+ if (typeof host === "string" && LOOPBACK2.test(host)) return host;
8853
9231
  throw new WasiError("EINVAL");
8854
9232
  }
8855
9233
  function network(raw, call2) {
@@ -8928,7 +9306,7 @@ function processes(host, call2, inThread) {
8928
9306
  }
8929
9307
  };
8930
9308
  }
8931
- var UID2, LOOPBACK, SOL_SOCKET, SO_ERROR, STDIO;
9309
+ var UID2, LOOPBACK2, SOL_SOCKET, SO_ERROR, STDIO;
8932
9310
  var init_wasi_imports = __esm({
8933
9311
  "src/process/wasi/wasi-imports.ts"() {
8934
9312
  "use strict";
@@ -8937,7 +9315,7 @@ var init_wasi_imports = __esm({
8937
9315
  init_wasi_threads();
8938
9316
  init_wasix_process();
8939
9317
  UID2 = 1e3;
8940
- LOOPBACK = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
9318
+ LOOPBACK2 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
8941
9319
  SOL_SOCKET = 1;
8942
9320
  SO_ERROR = 4;
8943
9321
  STDIO = ["stdin", "stdout", "stderr"];
@@ -10434,524 +10812,252 @@ var init_wasix_linker = __esm({
10434
10812
  memory: this.memory,
10435
10813
  table: this.table,
10436
10814
  stackPointer: this.stackPointer,
10437
- backing: record.backing,
10438
- userData: record.userData
10439
- });
10440
- this.table.set(record.index, fn);
10441
- this.types.set(fn, sig);
10442
- }
10443
- reserveLoad(size) {
10444
- return this.indices?.load(this.table.length, size) ?? {
10445
- base: this.table.length,
10446
- handle: this.nextHandle++
10447
- };
10448
- }
10449
- reserve(size) {
10450
- return this.indices?.reserve(this.table.length, size) ?? this.table.length;
10451
- }
10452
- tlsBases() {
10453
- const bases = [];
10454
- for (const [handle, linked] of this.modules) {
10455
- const base = linked.instance.exports.__tls_base;
10456
- if (base instanceof WebAssembly.Global) bases.push([handle, base.value]);
10457
- }
10458
- return bases;
10459
- }
10460
- carryTls(linked) {
10461
- const base = this.forkedTls?.get(linked.handle);
10462
- const global = linked.instance.exports.__tls_base;
10463
- if (base === void 0 || !(global instanceof WebAssembly.Global)) return false;
10464
- global.value = base;
10465
- return true;
10466
- }
10467
- replay(record) {
10468
- if (record.kind === "closure") {
10469
- growTable(this.table, record.index + 1);
10470
- this.live.add(record.index);
10471
- return;
10472
- }
10473
- if (record.kind === "closure-free") {
10474
- this.live.delete(record.index);
10475
- if (record.index < this.table.length) this.table.set(record.index, null);
10476
- return;
10477
- }
10478
- if (record.kind === "closure-prepare") {
10479
- this.install(record);
10480
- return;
10481
- }
10482
- if (record.kind === "load") {
10483
- if (this.modules.has(record.handle)) return;
10484
- const linked = this.instantiate(record.path, this.moduleAt(record.path), record, false);
10485
- linked.needed.push(...record.needed ?? []);
10486
- this.nextHandle = Math.max(this.nextHandle, record.handle + 1);
10487
- return;
10488
- }
10489
- const value2 = record.handle === 0 ? this.main?.exports[record.name] : this.module(record.handle).instance.exports[record.name];
10490
- if (typeof value2 !== "function") throw new DlError(`${record.name}: not a function`);
10491
- growTable(this.table, record.index + 1);
10492
- this.table.set(record.index, value2);
10493
- this.slots.set(value2, record.index);
10494
- }
10495
- moduleAt(path) {
10496
- const cached = this.cache?.[path];
10497
- if (cached) return cached;
10498
- const bytes = this.host.read(path);
10499
- if (!bytes) throw new DlError(`${path}: gone`);
10500
- return new WebAssembly.Module(bytes);
10501
- }
10502
- module(handle) {
10503
- const m = this.modules.get(handle);
10504
- if (!m) throw new DlError(`invalid handle ${handle}`);
10505
- return m;
10506
- }
10507
- locate(name2, cwd, ldPath) {
10508
- if (name2.includes("/"))
10509
- return name2.startsWith("/") ? normalize(name2) : normalize(`${cwd}/${name2}`);
10510
- for (const dir of [...ldPath.filter(Boolean), ...LIBRARY_DIRS]) {
10511
- const path = normalize(`${dir.startsWith("/") ? "" : `${cwd}/`}${dir}/${name2}`);
10512
- if (this.byPath.has(path) || this.host.read(path)) return path;
10513
- }
10514
- throw new DlError(`${name2}: not found`);
10515
- }
10516
- load(path, cwd, ldPath) {
10517
- const loaded = this.byPath.get(path);
10518
- if (loaded) return loaded;
10519
- const bytes = this.host.read(path);
10520
- if (!bytes) throw new DlError(`${path}: no such file`);
10521
- let module;
10522
- try {
10523
- module = new WebAssembly.Module(bytes);
10524
- } catch (e) {
10525
- throw new DlError(`${path}: not a wasm module (${e.message})`);
10526
- }
10527
- const info = dylinkInfo(module);
10528
- if (!info) throw new DlError(`${path}: not a side module (no dylink.0)`);
10529
- const dir = path.slice(0, path.lastIndexOf("/")) || "/";
10530
- const search = [dir, ...ldPath, ...info.runtimePath.map((p) => expandOrigin(p, dir))];
10531
- const needed = info.needed.map(
10532
- (n) => this.load(this.locate(n, cwd, search), cwd, ldPath).handle
10533
- );
10534
- const memoryBase = this.allocate(info.memorySize, 2 ** info.memoryAlign);
10535
- const { base: tableBase, handle } = this.reserveLoad(info.tableSize);
10536
- const record = {
10537
- kind: "load",
10538
- handle,
10539
- path,
10540
- memoryBase,
10541
- tableBase,
10542
- ...needed.length > 0 ? { needed } : {}
10543
- };
10544
- const linked = this.instantiate(path, module, record, true);
10545
- linked.needed.push(...needed);
10546
- this.publisher?.(record);
10547
- return linked;
10548
- }
10549
- instantiate(path, module, at, init) {
10550
- const info = dylinkInfo(module);
10551
- growTable(this.table, at.tableBase + info.tableSize);
10552
- const pending = [];
10553
- const env = {
10554
- memory: this.memory,
10555
- __indirect_function_table: this.table,
10556
- __stack_pointer: this.stackPointer,
10557
- __memory_base: new WebAssembly.Global({ value: "i32", mutable: false }, at.memoryBase),
10558
- __table_base: new WebAssembly.Global({ value: "i32", mutable: false }, at.tableBase),
10559
- __c_longjmp: this.cLongjmp,
10560
- __cpp_exception: this.cppException
10561
- };
10562
- const gotMem = {};
10563
- const gotFunc = {};
10564
- const linked = {
10565
- handle: at.handle,
10566
- path,
10567
- module,
10568
- info,
10569
- instance: void 0,
10570
- memoryBase: at.memoryBase,
10571
- tableBase: at.tableBase,
10572
- needed: []
10573
- };
10574
- for (const imp of WebAssembly.Module.imports(module)) {
10575
- if (imp.module === "env" && imp.kind === "function" && !(imp.name in env)) {
10576
- env[imp.name] = this.functionImport(imp.name);
10577
- } else if (imp.module === "GOT.mem") {
10578
- const g = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
10579
- gotMem[imp.name] = g;
10580
- pending.push(() => {
10581
- g.value = this.addressOrNull(imp.name);
10582
- });
10583
- } else if (imp.module === "GOT.func") {
10584
- const g = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
10585
- gotFunc[imp.name] = g;
10586
- pending.push(() => {
10587
- g.value = this.slotOrNull(imp.name);
10588
- });
10589
- }
10590
- }
10591
- const imports = {
10592
- ...this.host.hostImports(module),
10593
- env,
10594
- "GOT.mem": gotMem,
10595
- "GOT.func": gotFunc
10596
- };
10597
- linked.instance = new WebAssembly.Instance(module, imports);
10598
- this.types.register(() => this.host.read(path), linked.instance, this.table, at.tableBase);
10599
- this.modules.set(at.handle, linked);
10600
- const first = this.byPath.get(path);
10601
- if (!first || at.handle < first.handle) this.byPath.set(path, linked);
10602
- for (const resolve of pending) resolve();
10603
- if (init) {
10604
- call(linked.instance, "__wasm_apply_data_relocs");
10605
- call(linked.instance, "__wasm_call_ctors");
10606
- } else if (!this.carryTls(linked)) {
10607
- call(linked.instance, "__wasix_init_tls");
10608
- }
10609
- return linked;
10610
- }
10611
- functionImport(name2) {
10612
- const now = this.find(name2);
10613
- if (now && typeof now[1] === "function") return now[1];
10614
- let resolved2;
10615
- return (...args) => {
10616
- if (!resolved2) {
10617
- const later = this.find(name2);
10618
- if (!later || typeof later[1] !== "function")
10619
- throw new WebAssembly.RuntimeError(`unresolved symbol ${name2}`);
10620
- resolved2 = later[1];
10621
- }
10622
- return resolved2(...args);
10623
- };
10624
- }
10625
- addressOrNull(name2) {
10626
- const found = this.find(name2);
10627
- if (!found || !(found[1] instanceof WebAssembly.Global)) return 0;
10628
- return this.baseOf(found[0]) + found[1].value;
10629
- }
10630
- slotOrNull(name2) {
10631
- const found = this.find(name2);
10632
- if (!found || typeof found[1] !== "function") return 0;
10633
- return this.slot(found[1], found[0], name2);
10634
- }
10635
- find(name2) {
10636
- const inMain = this.main?.exports[name2];
10637
- if (inMain !== void 0) return [0, inMain];
10638
- for (const m of this.modules.values()) {
10639
- const v = m.instance?.exports[name2];
10640
- if (v !== void 0) return [m.handle, v];
10641
- }
10642
- return void 0;
10643
- }
10644
- findIn(m, name2, seen) {
10645
- if (seen.has(m.handle)) return void 0;
10646
- seen.add(m.handle);
10647
- const v = m.instance.exports[name2];
10648
- if (v !== void 0) return [m.handle, v];
10649
- for (const h of m.needed) {
10650
- const found = this.findIn(this.module(h), name2, seen);
10651
- if (found) return found;
10652
- }
10653
- return void 0;
10654
- }
10655
- baseOf(handle) {
10656
- return handle === 0 ? this.memoryBase : this.module(handle).memoryBase;
10657
- }
10658
- indexed = 0;
10659
- indexTable() {
10660
- for (let i = this.indexed; i < this.table.length; i++) {
10661
- const fn = this.table.get(i);
10662
- if (fn && !this.slots.has(fn)) this.slots.set(fn, i);
10663
- }
10664
- this.indexed = this.table.length;
10665
- }
10666
- slot(fn, handle, name2) {
10667
- this.indexTable();
10668
- const known = this.slots.get(fn);
10669
- if (known !== void 0) return known;
10670
- const index3 = this.reserve(1);
10671
- growTable(this.table, index3 + 1);
10672
- this.table.set(index3, fn);
10673
- this.slots.set(fn, index3);
10674
- this.publisher?.({ kind: "slot", index: index3, handle, name: name2 });
10675
- return index3;
10815
+ backing: record.backing,
10816
+ userData: record.userData
10817
+ });
10818
+ this.table.set(record.index, fn);
10819
+ this.types.set(fn, sig);
10676
10820
  }
10677
- allocate(size, alignment) {
10678
- if (size === 0) return 0;
10679
- const to = Math.max(alignment, 16);
10680
- const pages2 = Math.ceil((size + (to > PAGE2 ? to : 0)) / PAGE2);
10681
- return align(this.memory.grow(pages2) * PAGE2, to);
10821
+ reserveLoad(size) {
10822
+ return this.indices?.load(this.table.length, size) ?? {
10823
+ base: this.table.length,
10824
+ handle: this.nextHandle++
10825
+ };
10682
10826
  }
10683
- };
10684
- }
10685
- });
10686
-
10687
- // src/kernel/net/routes.ts
10688
- function ipv4Bytes(text) {
10689
- const parts = text.split(".");
10690
- if (parts.length !== 4 || !parts.every((p) => /^\d{1,3}$/.test(p))) return void 0;
10691
- const bytes = parts.map(Number);
10692
- return bytes.every((b) => b <= 255) ? bytes : void 0;
10693
- }
10694
- function ipv6Groups(text) {
10695
- if (!text.includes(":")) return void 0;
10696
- let canonical;
10697
- try {
10698
- canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
10699
- } catch {
10700
- return void 0;
10701
- }
10702
- const [head, tail] = canonical.split("::");
10703
- const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
10704
- const front = part(head);
10705
- const back = part(tail);
10706
- return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
10707
- }
10708
- function toBits(values, width) {
10709
- return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
10710
- }
10711
- function addressBits(host) {
10712
- const v4 = ipv4Bytes(host);
10713
- if (v4) return { v6: false, bits: toBits(v4, 8) };
10714
- const v6 = ipv6Groups(host);
10715
- return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
10716
- }
10717
- function parsePrefix(text) {
10718
- const parts = text.trim().split("/");
10719
- if (parts.length > 2) return void 0;
10720
- const [address = "", size] = parts;
10721
- const parsed = addressBits(address);
10722
- if (!parsed) return void 0;
10723
- const max = parsed.v6 ? 128 : 32;
10724
- const length = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
10725
- if (length < 0 || length > max) return void 0;
10726
- return { ...parsed, length };
10727
- }
10728
- var HOST_ADDRESS, RESERVED;
10729
- var init_routes = __esm({
10730
- "src/kernel/net/routes.ts"() {
10731
- "use strict";
10732
- init_loopback_names();
10733
- HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
10734
- RESERVED = [
10735
- "0.0.0.0/8",
10736
- "127.0.0.0/8",
10737
- "169.254.0.0/16",
10738
- "224.0.0.0/4",
10739
- "240.0.0.0/4",
10740
- "::/96",
10741
- "::ffff:0:0/96",
10742
- "fe80::/10",
10743
- "ff00::/8"
10744
- ].map((p) => parsePrefix(p));
10745
- }
10746
- });
10747
-
10748
- // src/process/wasi/wasix-sockets.ts
10749
- function readAddr(view, ptr) {
10750
- const tag = view.getUint8(ptr);
10751
- if (tag === UNIX) {
10752
- let end = ptr + 2;
10753
- while (end < ptr + 110 && view.getUint8(end) !== 0) end++;
10754
- const path = new TextDecoder().decode(
10755
- new Uint8Array(view.buffer, ptr + 2, end - ptr - 2).slice()
10756
- );
10757
- return { family: "unix", path };
10758
- }
10759
- const port2 = view.getUint16(ptr + 2, true);
10760
- if (tag === INET4) {
10761
- const host = [0, 1, 2, 3].map((i) => view.getUint8(ptr + 4 + i)).join(".");
10762
- return { family: "inet", host, port: port2 };
10763
- }
10764
- if (tag === INET6) {
10765
- return { family: "inet", host: ipv6Host(new Uint8Array(view.buffer, ptr + 4, 16)), port: port2 };
10766
- }
10767
- throw new WasiError("EAFNOSUPPORT");
10768
- }
10769
- function ipv6Host(bytes) {
10770
- const zeros = (n) => bytes.subarray(0, n).every((b) => b === 0);
10771
- if (zeros(16)) return "0.0.0.0";
10772
- if (zeros(15) && bytes[15] === 1) return LOOPBACK2;
10773
- if (zeros(10) && bytes[10] === 255 && bytes[11] === 255) return bytes.subarray(12).join(".");
10774
- const groups = [0, 2, 4, 6, 8, 10, 12, 14].map(
10775
- (i) => (bytes[i] << 8 | bytes[i + 1]).toString(16)
10776
- );
10777
- return new URL(`http://[${groups.join(":")}]/`).hostname.slice(1, -1);
10778
- }
10779
- function writeAddr(view, ptr, addr) {
10780
- new Uint8Array(view.buffer, ptr, 110).fill(0);
10781
- if (!addr) return;
10782
- if (addr.family === "unix") {
10783
- view.setUint8(ptr, UNIX);
10784
- new Uint8Array(view.buffer, ptr + 2, 107).set(
10785
- new TextEncoder().encode(addr.path).subarray(0, 107)
10786
- );
10787
- return;
10788
- }
10789
- view.setUint16(ptr + 2, addr.port, true);
10790
- const groups = ipv4(addr.host) ? void 0 : ipv6Groups(addr.host);
10791
- if (groups) {
10792
- view.setUint8(ptr, INET6);
10793
- groups.forEach((g, i) => void view.setUint16(ptr + 4 + i * 2, g));
10794
- return;
10795
- }
10796
- view.setUint8(ptr, INET4);
10797
- const octets = ipv4(addr.host) ?? [127, 0, 0, 1];
10798
- octets.forEach((b, i) => void view.setUint8(ptr + 4 + i, b));
10799
- }
10800
- function ipBytes(host) {
10801
- const groups = ipv4(host) ? void 0 : ipv6Groups(host);
10802
- return groups ? groups.flatMap((g) => [g >> 8, g & 255]) : ipv4(host);
10803
- }
10804
- function ipv4(host) {
10805
- const parts = host.split(".");
10806
- if (parts.length !== 4) return void 0;
10807
- const bytes = parts.map((p) => /^\d{1,3}$/.test(p) ? Number(p) : Number.NaN);
10808
- return bytes.every((b) => b >= 0 && b <= 255) ? bytes : void 0;
10809
- }
10810
- function wasixSocketImports(host, preview1) {
10811
- const { mem, fds, o } = host;
10812
- const call2 = (req) => o.kernel.call(req);
10813
- const socket = (fd) => {
10814
- const e = fds.get(fd);
10815
- if (e.type !== "kernel" || fds.kind(fd, e) !== "socket") throw new WasiError("ENOTSOCK");
10816
- return e;
10817
- };
10818
- const option = (opt) => OPTIONS[opt];
10819
- return {
10820
- sock_open: (af, type, _proto, out) => {
10821
- if (af !== INET4 && af !== INET6 && af !== UNIX) throw new WasiError("EAFNOSUPPORT");
10822
- if (type !== STREAM) throw new WasiError("EPROTONOSUPPORT");
10823
- const fd = call2({ op: "sock-open", domain: af === UNIX ? "unix" : "inet" });
10824
- fds.adopt(fd, "socket", false);
10825
- mem.view().setUint32(out, fd, true);
10826
- },
10827
- sock_pair: (af, type, _proto, out1, out2) => {
10828
- if (af !== UNIX)
10829
- throw new WasiError(af === INET4 || af === INET6 ? "EOPNOTSUPP" : "EAFNOSUPPORT");
10830
- if (type !== STREAM) throw new WasiError("EPROTONOSUPPORT");
10831
- mem.view().setUint32(out1, 0, true);
10832
- mem.view().setUint32(out2, 0, true);
10833
- const [a, b] = call2({ op: "sock-pair", domain: "unix" });
10834
- fds.adopt(a, "socket", false);
10835
- fds.adopt(b, "socket", false);
10836
- mem.view().setUint32(out1, a, true);
10837
- mem.view().setUint32(out2, b, true);
10838
- },
10839
- sock_bind: (fd, addr) => {
10840
- socket(fd);
10841
- call2({ op: "sock-bind", fd, addr: readAddr(mem.view(), addr) });
10842
- },
10843
- sock_listen: (fd, backlog) => {
10844
- socket(fd);
10845
- call2({ op: "sock-listen", fd, backlog });
10846
- },
10847
- sock_connect: (fd, addr) => {
10848
- const e = socket(fd);
10849
- call2({ op: "sock-connect", fd, addr: readAddr(mem.view(), addr), nonblock: e.nonblock });
10850
- },
10851
- sock_accept_v2: (fd, flags, outFd, outAddr) => {
10852
- const e = socket(fd);
10853
- const r = call2({ op: "sock-accept", fd, nonblock: e.nonblock });
10854
- fds.adopt(r.fd, "socket", (flags & FDFLAGS.NONBLOCK) !== 0);
10855
- mem.view().setUint32(outFd, r.fd, true);
10856
- writeAddr(mem.view(), outAddr, r.peer);
10857
- },
10858
- sock_addr_local: (fd, out) => {
10859
- socket(fd);
10860
- writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: false }));
10861
- },
10862
- sock_addr_peer: (fd, out) => {
10863
- socket(fd);
10864
- writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: true }));
10865
- },
10866
- sock_recv_from: (fd, iovs, n, riflags, outLen, outFlags, outAddr) => {
10867
- const r = preview1.sock_recv(
10868
- fd,
10869
- iovs,
10870
- n,
10871
- riflags,
10872
- outLen,
10873
- outFlags
10874
- );
10875
- if (r !== E.SUCCESS) return r;
10876
- writeAddr(mem.view(), outAddr, call2({ op: "sock-name", fd, peer: true }));
10877
- return E.SUCCESS;
10878
- },
10879
- sock_send_to: (fd, iovs, n, flags, _addr, out) => preview1.sock_send(fd, iovs, n, flags, out),
10880
- sock_status: (fd, out) => {
10881
- socket(fd);
10882
- mem.view().setUint8(out, 1);
10883
- },
10884
- sock_get_opt_flag: (fd, opt, out) => {
10885
- socket(fd);
10886
- const pair = option(opt);
10887
- const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
10888
- mem.view().setUint8(out, v ? 1 : 0);
10889
- },
10890
- sock_set_opt_flag: (fd, opt, flag) => {
10891
- socket(fd);
10892
- const pair = option(opt);
10893
- if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: flag ? 1 : 0 });
10894
- },
10895
- sock_get_opt_size: (fd, opt, out) => {
10896
- socket(fd);
10897
- const pair = option(opt);
10898
- const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
10899
- mem.view().setBigUint64(out, BigInt(v), true);
10900
- },
10901
- sock_set_opt_size: (fd, opt, size) => {
10902
- socket(fd);
10903
- const pair = option(opt);
10904
- if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: Number(size) });
10905
- },
10906
- sock_get_opt_time: (fd, _opt, out) => {
10907
- socket(fd);
10908
- new Uint8Array(mem.view().buffer, out, 16).fill(0);
10909
- },
10910
- sock_set_opt_time: (fd) => void socket(fd),
10911
- sock_send_file: () => E.NOSYS,
10912
- resolve: (name2, len, _port, addrs, naddrs, out) => {
10913
- const found = call2({ op: "sock-resolve", name: mem.string(name2, len), family: 0 });
10914
- const ips = found.map(ipBytes).filter((ip) => ip !== void 0);
10915
- if (ips.length === 0) throw new WasiError("ENOENT");
10916
- if (naddrs < 1) throw new WasiError("EINVAL");
10917
- const view = mem.view();
10918
- const count = Math.min(ips.length, naddrs);
10919
- new Uint8Array(view.buffer, addrs, ADDR_IP_SIZE * count).fill(0);
10920
- for (let i = 0; i < count; i++) {
10921
- const at = addrs + i * ADDR_IP_SIZE;
10922
- view.setUint8(at, ips[i].length === 4 ? INET4 : INET6);
10923
- new Uint8Array(view.buffer, at + 2, ips[i].length).set(ips[i]);
10827
+ reserve(size) {
10828
+ return this.indices?.reserve(this.table.length, size) ?? this.table.length;
10829
+ }
10830
+ tlsBases() {
10831
+ const bases = [];
10832
+ for (const [handle, linked] of this.modules) {
10833
+ const base = linked.instance.exports.__tls_base;
10834
+ if (base instanceof WebAssembly.Global) bases.push([handle, base.value]);
10835
+ }
10836
+ return bases;
10837
+ }
10838
+ carryTls(linked) {
10839
+ const base = this.forkedTls?.get(linked.handle);
10840
+ const global = linked.instance.exports.__tls_base;
10841
+ if (base === void 0 || !(global instanceof WebAssembly.Global)) return false;
10842
+ global.value = base;
10843
+ return true;
10844
+ }
10845
+ replay(record) {
10846
+ if (record.kind === "closure") {
10847
+ growTable(this.table, record.index + 1);
10848
+ this.live.add(record.index);
10849
+ return;
10850
+ }
10851
+ if (record.kind === "closure-free") {
10852
+ this.live.delete(record.index);
10853
+ if (record.index < this.table.length) this.table.set(record.index, null);
10854
+ return;
10855
+ }
10856
+ if (record.kind === "closure-prepare") {
10857
+ this.install(record);
10858
+ return;
10859
+ }
10860
+ if (record.kind === "load") {
10861
+ if (this.modules.has(record.handle)) return;
10862
+ const linked = this.instantiate(record.path, this.moduleAt(record.path), record, false);
10863
+ linked.needed.push(...record.needed ?? []);
10864
+ this.nextHandle = Math.max(this.nextHandle, record.handle + 1);
10865
+ return;
10866
+ }
10867
+ const value2 = record.handle === 0 ? this.main?.exports[record.name] : this.module(record.handle).instance.exports[record.name];
10868
+ if (typeof value2 !== "function") throw new DlError(`${record.name}: not a function`);
10869
+ growTable(this.table, record.index + 1);
10870
+ this.table.set(record.index, value2);
10871
+ this.slots.set(value2, record.index);
10872
+ }
10873
+ moduleAt(path) {
10874
+ const cached = this.cache?.[path];
10875
+ if (cached) return cached;
10876
+ const bytes = this.host.read(path);
10877
+ if (!bytes) throw new DlError(`${path}: gone`);
10878
+ return new WebAssembly.Module(bytes);
10879
+ }
10880
+ module(handle) {
10881
+ const m = this.modules.get(handle);
10882
+ if (!m) throw new DlError(`invalid handle ${handle}`);
10883
+ return m;
10884
+ }
10885
+ locate(name2, cwd, ldPath) {
10886
+ if (name2.includes("/"))
10887
+ return name2.startsWith("/") ? normalize(name2) : normalize(`${cwd}/${name2}`);
10888
+ for (const dir of [...ldPath.filter(Boolean), ...LIBRARY_DIRS]) {
10889
+ const path = normalize(`${dir.startsWith("/") ? "" : `${cwd}/`}${dir}/${name2}`);
10890
+ if (this.byPath.has(path) || this.host.read(path)) return path;
10891
+ }
10892
+ throw new DlError(`${name2}: not found`);
10893
+ }
10894
+ load(path, cwd, ldPath) {
10895
+ const loaded = this.byPath.get(path);
10896
+ if (loaded) return loaded;
10897
+ const bytes = this.host.read(path);
10898
+ if (!bytes) throw new DlError(`${path}: no such file`);
10899
+ let module;
10900
+ try {
10901
+ module = new WebAssembly.Module(bytes);
10902
+ } catch (e) {
10903
+ throw new DlError(`${path}: not a wasm module (${e.message})`);
10904
+ }
10905
+ const info = dylinkInfo(module);
10906
+ if (!info) throw new DlError(`${path}: not a side module (no dylink.0)`);
10907
+ const dir = path.slice(0, path.lastIndexOf("/")) || "/";
10908
+ const search = [dir, ...ldPath, ...info.runtimePath.map((p) => expandOrigin(p, dir))];
10909
+ const needed = info.needed.map(
10910
+ (n) => this.load(this.locate(n, cwd, search), cwd, ldPath).handle
10911
+ );
10912
+ const memoryBase = this.allocate(info.memorySize, 2 ** info.memoryAlign);
10913
+ const { base: tableBase, handle } = this.reserveLoad(info.tableSize);
10914
+ const record = {
10915
+ kind: "load",
10916
+ handle,
10917
+ path,
10918
+ memoryBase,
10919
+ tableBase,
10920
+ ...needed.length > 0 ? { needed } : {}
10921
+ };
10922
+ const linked = this.instantiate(path, module, record, true);
10923
+ linked.needed.push(...needed);
10924
+ this.publisher?.(record);
10925
+ return linked;
10926
+ }
10927
+ instantiate(path, module, at, init) {
10928
+ const info = dylinkInfo(module);
10929
+ growTable(this.table, at.tableBase + info.tableSize);
10930
+ const pending = [];
10931
+ const env = {
10932
+ memory: this.memory,
10933
+ __indirect_function_table: this.table,
10934
+ __stack_pointer: this.stackPointer,
10935
+ __memory_base: new WebAssembly.Global({ value: "i32", mutable: false }, at.memoryBase),
10936
+ __table_base: new WebAssembly.Global({ value: "i32", mutable: false }, at.tableBase),
10937
+ __c_longjmp: this.cLongjmp,
10938
+ __cpp_exception: this.cppException
10939
+ };
10940
+ const gotMem = {};
10941
+ const gotFunc = {};
10942
+ const linked = {
10943
+ handle: at.handle,
10944
+ path,
10945
+ module,
10946
+ info,
10947
+ instance: void 0,
10948
+ memoryBase: at.memoryBase,
10949
+ tableBase: at.tableBase,
10950
+ needed: []
10951
+ };
10952
+ for (const imp of WebAssembly.Module.imports(module)) {
10953
+ if (imp.module === "env" && imp.kind === "function" && !(imp.name in env)) {
10954
+ env[imp.name] = this.functionImport(imp.name);
10955
+ } else if (imp.module === "GOT.mem") {
10956
+ const g = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
10957
+ gotMem[imp.name] = g;
10958
+ pending.push(() => {
10959
+ g.value = this.addressOrNull(imp.name);
10960
+ });
10961
+ } else if (imp.module === "GOT.func") {
10962
+ const g = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
10963
+ gotFunc[imp.name] = g;
10964
+ pending.push(() => {
10965
+ g.value = this.slotOrNull(imp.name);
10966
+ });
10967
+ }
10968
+ }
10969
+ const imports = {
10970
+ ...this.host.hostImports(module),
10971
+ env,
10972
+ "GOT.mem": gotMem,
10973
+ "GOT.func": gotFunc
10974
+ };
10975
+ linked.instance = new WebAssembly.Instance(module, imports);
10976
+ this.types.register(() => this.host.read(path), linked.instance, this.table, at.tableBase);
10977
+ this.modules.set(at.handle, linked);
10978
+ const first = this.byPath.get(path);
10979
+ if (!first || at.handle < first.handle) this.byPath.set(path, linked);
10980
+ for (const resolve of pending) resolve();
10981
+ if (init) {
10982
+ call(linked.instance, "__wasm_apply_data_relocs");
10983
+ call(linked.instance, "__wasm_call_ctors");
10984
+ } else if (!this.carryTls(linked)) {
10985
+ call(linked.instance, "__wasix_init_tls");
10986
+ }
10987
+ return linked;
10988
+ }
10989
+ functionImport(name2) {
10990
+ const now = this.find(name2);
10991
+ if (now && typeof now[1] === "function") return now[1];
10992
+ let resolved2;
10993
+ return (...args) => {
10994
+ if (!resolved2) {
10995
+ const later = this.find(name2);
10996
+ if (!later || typeof later[1] !== "function")
10997
+ throw new WebAssembly.RuntimeError(`unresolved symbol ${name2}`);
10998
+ resolved2 = later[1];
10999
+ }
11000
+ return resolved2(...args);
11001
+ };
11002
+ }
11003
+ addressOrNull(name2) {
11004
+ const found = this.find(name2);
11005
+ if (!found || !(found[1] instanceof WebAssembly.Global)) return 0;
11006
+ return this.baseOf(found[0]) + found[1].value;
11007
+ }
11008
+ slotOrNull(name2) {
11009
+ const found = this.find(name2);
11010
+ if (!found || typeof found[1] !== "function") return 0;
11011
+ return this.slot(found[1], found[0], name2);
11012
+ }
11013
+ find(name2) {
11014
+ const inMain = this.main?.exports[name2];
11015
+ if (inMain !== void 0) return [0, inMain];
11016
+ for (const m of this.modules.values()) {
11017
+ const v = m.instance?.exports[name2];
11018
+ if (v !== void 0) return [m.handle, v];
11019
+ }
11020
+ return void 0;
11021
+ }
11022
+ findIn(m, name2, seen) {
11023
+ if (seen.has(m.handle)) return void 0;
11024
+ seen.add(m.handle);
11025
+ const v = m.instance.exports[name2];
11026
+ if (v !== void 0) return [m.handle, v];
11027
+ for (const h of m.needed) {
11028
+ const found = this.findIn(this.module(h), name2, seen);
11029
+ if (found) return found;
11030
+ }
11031
+ return void 0;
11032
+ }
11033
+ baseOf(handle) {
11034
+ return handle === 0 ? this.memoryBase : this.module(handle).memoryBase;
11035
+ }
11036
+ indexed = 0;
11037
+ indexTable() {
11038
+ for (let i = this.indexed; i < this.table.length; i++) {
11039
+ const fn = this.table.get(i);
11040
+ if (fn && !this.slots.has(fn)) this.slots.set(fn, i);
11041
+ }
11042
+ this.indexed = this.table.length;
11043
+ }
11044
+ slot(fn, handle, name2) {
11045
+ this.indexTable();
11046
+ const known = this.slots.get(fn);
11047
+ if (known !== void 0) return known;
11048
+ const index3 = this.reserve(1);
11049
+ growTable(this.table, index3 + 1);
11050
+ this.table.set(index3, fn);
11051
+ this.slots.set(fn, index3);
11052
+ this.publisher?.({ kind: "slot", index: index3, handle, name: name2 });
11053
+ return index3;
11054
+ }
11055
+ allocate(size, alignment) {
11056
+ if (size === 0) return 0;
11057
+ const to = Math.max(alignment, 16);
11058
+ const pages2 = Math.ceil((size + (to > PAGE2 ? to : 0)) / PAGE2);
11059
+ return align(this.memory.grow(pages2) * PAGE2, to);
10924
11060
  }
10925
- view.setUint32(out, count, true);
10926
- }
10927
- };
10928
- }
10929
- var INET4, INET6, UNIX, STREAM, ADDR_IP_SIZE, LOOPBACK2, OPTIONS;
10930
- var init_wasix_sockets = __esm({
10931
- "src/process/wasi/wasix-sockets.ts"() {
10932
- "use strict";
10933
- init_routes();
10934
- init_wasi_abi();
10935
- init_wasi_files();
10936
- INET4 = 1;
10937
- INET6 = 2;
10938
- UNIX = 3;
10939
- STREAM = 1;
10940
- ADDR_IP_SIZE = 18;
10941
- LOOPBACK2 = "127.0.0.1";
10942
- OPTIONS = {
10943
- 1: [1, 15],
10944
- 2: [1, 2],
10945
- 3: [6, 1],
10946
- 4: [1, 5],
10947
- 6: [1, 6],
10948
- 10: [1, 30],
10949
- 11: [1, 4],
10950
- 12: [1, 9],
10951
- 14: [1, 10],
10952
- 15: [1, 8],
10953
- 16: [1, 7],
10954
- 25: [1, 3]
10955
11061
  };
10956
11062
  }
10957
11063
  });
@@ -11630,7 +11736,7 @@ function kernelOf(init, port2, hooks = { masks: () => null, raise: () => {
11630
11736
  const call2 = (req) => {
11631
11737
  const r = transport.call(req, Number.POSITIVE_INFINITY, req.op);
11632
11738
  if (!r.ok) throw new SyscallError(r.errno);
11633
- return r.kind === "json" ? r.json : void 0;
11739
+ return r.kind === "json" ? r.json : r.kind === "bytes" ? r.bytes : void 0;
11634
11740
  };
11635
11741
  const say = (text) => sys.write(2, new TextEncoder().encode(`${init.argv0}: ${text}
11636
11742
  `));
@@ -12675,7 +12781,7 @@ function flagsOf(o) {
12675
12781
  const access = write2 ? o.read ? O_RDWR6 : O_WRONLY6 : 0;
12676
12782
  return access | (o.append ? O_APPEND4 : 0);
12677
12783
  }
12678
- function openRequest(abs, o) {
12784
+ function openRequest2(abs, o) {
12679
12785
  return {
12680
12786
  op: "fd-open-vfs",
12681
12787
  path: abs,
@@ -12855,7 +12961,7 @@ function* aliasOf(fd, abs, o) {
12855
12961
  if (file) {
12856
12962
  const at = yield { op: "fd-vfs-stat", fd };
12857
12963
  if (!at.orphan)
12858
- return { fd: yield openRequest(at.path, { ...o, create: false }), file };
12964
+ return { fd: yield openRequest2(at.path, { ...o, create: false }), file };
12859
12965
  const wantWrite = o.write === true || o.append === true || o.truncate === true;
12860
12966
  if (wantWrite && info.access === "read") throw new JsCallError("EBADF", abs);
12861
12967
  if (!wantWrite && info.access === "write") throw new JsCallError("EBADF", abs);
@@ -12880,7 +12986,7 @@ function* opened(abs, o) {
12880
12986
  if (isExclusive(o)) throw new JsCallError("EEXIST", abs);
12881
12987
  switch (node.kind) {
12882
12988
  case "device":
12883
- return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
12989
+ return { fd: yield openRequest2(abs, { ...o, create: false }), file: false };
12884
12990
  case "tty":
12885
12991
  return { fd: yield { op: "fd-open-tty" }, file: false };
12886
12992
  case "clipboard":
@@ -14059,7 +14165,7 @@ function syncOps(kernel, shared) {
14059
14165
  existing = absent(err);
14060
14166
  }
14061
14167
  checkOpen(abs, options, existing);
14062
- const fd = kernel.json(openRequest(abs, options));
14168
+ const fd = kernel.json(openRequest2(abs, options));
14063
14169
  try {
14064
14170
  kernel.call({ op: "fd-vfs-stat", fd });
14065
14171
  } catch (err) {
@@ -14669,7 +14775,7 @@ async function vfsStat(kernel, abs, op, tryDev) {
14669
14775
  async function vfsOpen(kernel, abs, options, statOf, infos, handles) {
14670
14776
  const existing = await statOf(isExclusive(options) ? "lstat" : "stat", abs).catch(absent);
14671
14777
  checkOpen(abs, options, existing);
14672
- const fd = await kernel.json(openRequest(abs, options));
14778
+ const fd = await kernel.json(openRequest2(abs, options));
14673
14779
  try {
14674
14780
  await kernel.call({ op: "fd-vfs-stat", fd });
14675
14781
  } catch (err) {