@ai-ecoverse/slicc-kernel 1.64.1 → 1.65.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.
@@ -13,6 +13,94 @@ var __export = (target, all) => {
13
13
  __defProp(target, name2, { get: all[name2], enumerable: true });
14
14
  };
15
15
 
16
+ // src/process/js/lockdown.ts
17
+ function chain(target) {
18
+ const out = [];
19
+ for (let at = target; at && at !== Object.prototype; ) {
20
+ out.push(at);
21
+ at = Object.getPrototypeOf(at);
22
+ }
23
+ return out;
24
+ }
25
+ function hide(target, names) {
26
+ for (const name2 of names) {
27
+ const holders = chain(target);
28
+ for (const holder of holders) {
29
+ if (Object.getOwnPropertyDescriptor(holder, name2)?.configurable) {
30
+ Reflect.deleteProperty(holder, name2);
31
+ }
32
+ }
33
+ const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name2));
34
+ const defined = Reflect.defineProperty(target, name2, {
35
+ value: void 0,
36
+ writable: false,
37
+ enumerable: false,
38
+ configurable: false
39
+ });
40
+ if (kept || !defined && Reflect.get(target, name2) !== void 0) {
41
+ throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
42
+ }
43
+ }
44
+ }
45
+ function vacate(target, names) {
46
+ for (const name2 of names) {
47
+ for (let at = target; at && at !== Object.prototype; ) {
48
+ if (Object.getOwnPropertyDescriptor(at, name2)?.configurable) Reflect.deleteProperty(at, name2);
49
+ at = Object.getPrototypeOf(at);
50
+ }
51
+ Reflect.defineProperty(target, name2, {
52
+ value: void 0,
53
+ writable: true,
54
+ enumerable: false,
55
+ configurable: true
56
+ });
57
+ if (Reflect.get(target, name2) !== void 0) {
58
+ throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
59
+ }
60
+ }
61
+ }
62
+ function lockdown(scope2 = globalThis) {
63
+ hide(scope2, BLOCKED_GLOBALS);
64
+ vacate(scope2, OPEN_SLOTS);
65
+ const navigator = scope2.navigator;
66
+ if (navigator && typeof navigator === "object") hide(navigator, BLOCKED_NAVIGATOR);
67
+ }
68
+ var BLOCKED_GLOBALS, BLOCKED_NAVIGATOR, OPEN_SLOTS;
69
+ var init_lockdown = __esm({
70
+ "src/process/js/lockdown.ts"() {
71
+ "use strict";
72
+ BLOCKED_GLOBALS = [
73
+ "XMLHttpRequest",
74
+ "WebSocketStream",
75
+ "WebTransport",
76
+ "EventSource",
77
+ "importScripts",
78
+ "indexedDB",
79
+ "caches",
80
+ "cookieStore",
81
+ "Worker",
82
+ "SharedWorker",
83
+ "BroadcastChannel",
84
+ "postMessage",
85
+ "close",
86
+ "webkitRequestFileSystem",
87
+ "webkitRequestFileSystemSync",
88
+ "webkitResolveLocalFileSystemURL",
89
+ "webkitResolveLocalFileSystemSyncURL"
90
+ ];
91
+ BLOCKED_NAVIGATOR = [
92
+ "storage",
93
+ "storageBuckets",
94
+ "locks",
95
+ "serviceWorker",
96
+ "usb",
97
+ "hid",
98
+ "serial"
99
+ ];
100
+ OPEN_SLOTS = ["fetch", "WebSocket"];
101
+ }
102
+ });
103
+
16
104
  // src/kernel/protocol.ts
17
105
  var WASM_PROCESS_INIT, WASM_PROCESS_EXIT, WASM_PROCESS_ERROR, WASM_THREAD_SPAWN, WASM_THREAD_INIT, WASM_THREAD_EXIT, WASM_MAX_THREADS, WASM_DEFAULT_THREADS;
18
106
  var init_protocol = __esm({
@@ -573,16 +661,16 @@ var init_wasi_errno = __esm({
573
661
  });
574
662
 
575
663
  // src/realm/sync-fs-wire.ts
576
- function parseSyncFsUsage(json) {
577
- const u = json;
664
+ function parseSyncFsUsage(json2) {
665
+ const u = json2;
578
666
  if (!u || typeof u.quota !== "number" || typeof u.usage !== "number") return null;
579
667
  return { quota: u.quota, usage: u.usage };
580
668
  }
581
669
  function syncError(code2, label) {
582
670
  return Object.assign(new Error(`${code2}: ${label}`), { code: code2 });
583
671
  }
584
- function parseSyncFsStat(json) {
585
- const s = json;
672
+ function parseSyncFsStat(json2) {
673
+ const s = json2;
586
674
  if (!s || typeof s.isFile !== "boolean" || typeof s.isDirectory !== "boolean" || typeof s.size !== "number") {
587
675
  return null;
588
676
  }
@@ -1698,7 +1786,7 @@ function createSyncFsSabBridge(transport, opts = {}) {
1698
1786
  if (r.ok && r.kind === "bytes") return r.bytes;
1699
1787
  throw errnoError("EIO", path);
1700
1788
  }
1701
- function json(req, path) {
1789
+ function json2(req, path) {
1702
1790
  const r = run(req, path);
1703
1791
  if (r.ok && r.kind === "json") return r.json;
1704
1792
  throw errnoError("EIO", path);
@@ -1726,31 +1814,31 @@ function createSyncFsSabBridge(transport, opts = {}) {
1726
1814
  return {
1727
1815
  ...io({}),
1728
1816
  pinned: (handle) => io({ handle }),
1729
- kept: (handle) => json({ op: "kept", path: "/", handle }, "/") === true,
1817
+ kept: (handle) => json2({ op: "kept", path: "/", handle }, "/") === true,
1730
1818
  keptStat: (handle) => {
1731
- const s = parseSyncFsStat(json({ op: "stat", path: "/", handle }, "/"));
1819
+ const s = parseSyncFsStat(json2({ op: "stat", path: "/", handle }, "/"));
1732
1820
  if (!s) throw errnoError("EIO", "/");
1733
1821
  return s;
1734
1822
  },
1735
1823
  stat: (path) => {
1736
- const s = parseSyncFsStat(json({ op: "stat", path }, path));
1824
+ const s = parseSyncFsStat(json2({ op: "stat", path }, path));
1737
1825
  if (!s) throw errnoError("EIO", path);
1738
1826
  return s;
1739
1827
  },
1740
1828
  lstat: (path) => {
1741
- const s = parseSyncFsStat(json({ op: "lstat", path }, path));
1829
+ const s = parseSyncFsStat(json2({ op: "lstat", path }, path));
1742
1830
  if (!s) throw errnoError("EIO", path);
1743
1831
  return s;
1744
1832
  },
1745
1833
  readdir: (path) => {
1746
- const list = json({ op: "readdir", path }, path);
1834
+ const list = json2({ op: "readdir", path }, path);
1747
1835
  if (!Array.isArray(list) || !list.every((s) => typeof s === "string")) {
1748
1836
  throw errnoError("EIO", path);
1749
1837
  }
1750
1838
  return list;
1751
1839
  },
1752
1840
  readdirStat: (path) => {
1753
- const list = json({ op: "readdir-stat", path }, path);
1841
+ const list = json2({ op: "readdir-stat", path }, path);
1754
1842
  if (!Array.isArray(list)) throw errnoError("EIO", path);
1755
1843
  return list.map((entry) => {
1756
1844
  if (!Array.isArray(entry) || typeof entry[0] !== "string") throw errnoError("EIO", path);
@@ -1761,7 +1849,7 @@ function createSyncFsSabBridge(transport, opts = {}) {
1761
1849
  });
1762
1850
  },
1763
1851
  exists: (path) => {
1764
- const v = json({ op: "exists", path }, path);
1852
+ const v = json2({ op: "exists", path }, path);
1765
1853
  if (typeof v !== "boolean") throw errnoError("EIO", path);
1766
1854
  return v;
1767
1855
  },
@@ -1787,7 +1875,7 @@ function createSyncFsSabBridge(transport, opts = {}) {
1787
1875
  run({ op: "symlink", path: linkPath, arg2: target }, linkPath);
1788
1876
  },
1789
1877
  readlink: (path) => {
1790
- const target = json({ op: "readlink", path }, path);
1878
+ const target = json2({ op: "readlink", path }, path);
1791
1879
  if (typeof target !== "string") throw errnoError("EIO", path);
1792
1880
  return target;
1793
1881
  },
@@ -1817,11 +1905,11 @@ function createSyncFsSabBridge(transport, opts = {}) {
1817
1905
  },
1818
1906
  hold: (path, held, open, handle, want = 0) => {
1819
1907
  const mode = (held ? 1 : 0) | (open ? 2 : 0);
1820
- if (mode === 3) return json({ op: "hold", path, mode: mode | want }, path);
1908
+ if (mode === 3) return json2({ op: "hold", path, mode: mode | want }, path);
1821
1909
  run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
1822
1910
  return void 0;
1823
1911
  },
1824
- statfs: (path = "/") => parseSyncFsUsage(json({ op: "statfs", path }, path))
1912
+ statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path))
1825
1913
  };
1826
1914
  }
1827
1915
  var init_sync_sab_bridge = __esm({
@@ -2827,8 +2915,11 @@ function useDevFd(Fs) {
2827
2915
  return fstat.call(Fs, fd);
2828
2916
  };
2829
2917
  }
2918
+ function pinRootKind() {
2919
+ pinnedRoot = rootKind();
2920
+ }
2830
2921
  function mountTable(mounts = []) {
2831
- const root = globalThis.navigator?.storage ? "opfs" : "memory";
2922
+ const root = pinnedRoot ?? rootKind();
2832
2923
  const lines = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
2833
2924
  for (const m of mounts) {
2834
2925
  const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
@@ -2934,7 +3025,7 @@ function linuxDevices(Fs) {
2934
3025
  }
2935
3026
  }
2936
3027
  }
2937
- var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, AT_SYMLINK_NOFOLLOW, EMSCRIPTEN_EPERM, O_PATH, UTIME_NOW, UTIME_OMIT, PROT_WRITE, MAP_PRIVATE, MAP_TYPE, O_WRONLY, MAP_ALIGN, DIR_MODE, LINK_MODE, CHAR_DEVICE, O_ACCMODE2, O_CREAT2, field, NAME, AT_FDCWD, AT_EACCESS, DEVICE_MODES;
3028
+ var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, AT_SYMLINK_NOFOLLOW, EMSCRIPTEN_EPERM, O_PATH, UTIME_NOW, UTIME_OMIT, PROT_WRITE, MAP_PRIVATE, MAP_TYPE, O_WRONLY, MAP_ALIGN, DIR_MODE, LINK_MODE, CHAR_DEVICE, O_ACCMODE2, O_CREAT2, field, pinnedRoot, rootKind, NAME, AT_FDCWD, AT_EACCESS, DEVICE_MODES;
2938
3029
  var init_process_fds = __esm({
2939
3030
  "src/process/process-fds.ts"() {
2940
3031
  "use strict";
@@ -2976,6 +3067,7 @@ var init_process_fds = __esm({
2976
3067
  O_ACCMODE2 = 3;
2977
3068
  O_CREAT2 = 64;
2978
3069
  field = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
3070
+ rootKind = () => globalThis.navigator?.storage ? "opfs" : "memory";
2979
3071
  NAME = /^[a-z_][a-z0-9_-]*$/i;
2980
3072
  AT_FDCWD = -100;
2981
3073
  AT_EACCESS = 512;
@@ -3629,7 +3721,7 @@ function createSocketKernel(deps) {
3629
3721
  if (!r.ok) throw new SyscallError(r.errno);
3630
3722
  return r;
3631
3723
  };
3632
- const json = (req) => {
3724
+ const json2 = (req) => {
3633
3725
  const r = call2(req);
3634
3726
  return r.ok && r.kind === "json" ? r.json : void 0;
3635
3727
  };
@@ -3669,9 +3761,9 @@ function createSocketKernel(deps) {
3669
3761
  return stream.fd;
3670
3762
  };
3671
3763
  return {
3672
- socket: (domain, nonblock, cloexec) => guard(() => install(json({ op: "sock-open", domain }), nonblock, cloexec)),
3764
+ socket: (domain, nonblock, cloexec) => guard(() => install(json2({ op: "sock-open", domain }), nonblock, cloexec)),
3673
3765
  socketpair: (domain, nonblock, cloexec) => guard(() => {
3674
- const [a, b] = json({ op: "sock-pair", domain });
3766
+ const [a, b] = json2({ op: "sock-pair", domain });
3675
3767
  let first;
3676
3768
  try {
3677
3769
  first = install(a, nonblock, cloexec);
@@ -3706,7 +3798,7 @@ function createSocketKernel(deps) {
3706
3798
  fd: listener.sliccKernelFd,
3707
3799
  nonblock: (listener.flags & O_NONBLOCK) !== 0
3708
3800
  };
3709
- const got = json(req);
3801
+ const got = json2(req);
3710
3802
  return { fd: install(got.fd, nonblock, cloexec), peer: got.peer };
3711
3803
  }),
3712
3804
  connect: (fd, addr) => guard(() => {
@@ -3720,10 +3812,10 @@ function createSocketKernel(deps) {
3720
3812
  });
3721
3813
  }),
3722
3814
  shutdown: (fd, how) => guard(() => done({ op: "sock-shutdown", fd: kfd(fd), how })),
3723
- name: (fd, peer) => guard(() => json({ op: "sock-name", fd: kfd(fd), peer })),
3724
- getopt: (fd, level, name2) => guard(() => ({ value: json({ op: "sock-getopt", fd: kfd(fd), level, name: name2 }) })),
3815
+ name: (fd, peer) => guard(() => json2({ op: "sock-name", fd: kfd(fd), peer })),
3816
+ getopt: (fd, level, name2) => guard(() => ({ value: json2({ op: "sock-getopt", fd: kfd(fd), level, name: name2 }) })),
3725
3817
  setopt: (fd, level, name2, value2) => guard(() => done({ op: "sock-setopt", fd: kfd(fd), level, name: name2, value: value2 })),
3726
- resolve: (name2, family = 4) => guard(() => json({ op: "sock-resolve", name: name2, family })),
3818
+ resolve: (name2, family = 4) => guard(() => json2({ op: "sock-resolve", name: name2, family })),
3727
3819
  send: (fd, bytes, flags) => guard(() => {
3728
3820
  const stream = socketAt(fd);
3729
3821
  const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
@@ -4160,7 +4252,7 @@ function kernelSys(transport) {
4160
4252
  if (!r.ok) throw new SyscallError(r.errno);
4161
4253
  return r;
4162
4254
  };
4163
- const json = (r) => r.ok && r.kind === "json" ? r.json : void 0;
4255
+ const json2 = (r) => r.ok && r.kind === "json" ? r.json : void 0;
4164
4256
  return {
4165
4257
  read(fd, max, opts) {
4166
4258
  const flags = {
@@ -4177,20 +4269,20 @@ function kernelSys(transport) {
4177
4269
  body: bytes,
4178
4270
  ...opts?.nonblock ? { nonblock: true } : {}
4179
4271
  };
4180
- const n = json(call2(req, `fd-write ${fd}`));
4272
+ const n = json2(call2(req, `fd-write ${fd}`));
4181
4273
  return typeof n === "number" ? n : bytes.length;
4182
4274
  },
4183
4275
  close(fd) {
4184
4276
  call2({ op: "fd-close", fd }, `fd-close ${fd}`);
4185
4277
  },
4186
4278
  pipe() {
4187
- return json(call2({ op: "fd-pipe" }, "fd-pipe"));
4279
+ return json2(call2({ op: "fd-pipe" }, "fd-pipe"));
4188
4280
  },
4189
4281
  poll(fd) {
4190
- return json(call2({ op: "fd-poll", fd }, `fd-poll ${fd}`));
4282
+ return json2(call2({ op: "fd-poll", fd }, `fd-poll ${fd}`));
4191
4283
  },
4192
4284
  openVfs(path, flags, position, opts) {
4193
- return json(
4285
+ return json2(
4194
4286
  call2(
4195
4287
  {
4196
4288
  op: "fd-open-vfs",
@@ -4210,7 +4302,7 @@ function kernelSys(transport) {
4210
4302
  );
4211
4303
  },
4212
4304
  seek(fd, offset, whence) {
4213
- return json(call2({ op: "fd-seek", fd, offset, whence }, `fd-seek ${fd}`));
4305
+ return json2(call2({ op: "fd-seek", fd, offset, whence }, `fd-seek ${fd}`));
4214
4306
  },
4215
4307
  flush(fd) {
4216
4308
  call2({ op: "fd-flush", fd }, `fd-flush ${fd}`);
@@ -4220,64 +4312,64 @@ function kernelSys(transport) {
4220
4312
  return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
4221
4313
  },
4222
4314
  pwrite(fd, bytes, at) {
4223
- return json(
4315
+ return json2(
4224
4316
  call2({ op: "fd-pwrite", fd, offset: at, body: bytes }, `fd-pwrite ${fd}`)
4225
4317
  );
4226
4318
  },
4227
4319
  isatty(fd) {
4228
- return json(call2({ op: "fd-info", fd }, `fd-info ${fd}`))?.tty === true;
4320
+ return json2(call2({ op: "fd-info", fd }, `fd-info ${fd}`))?.tty === true;
4229
4321
  },
4230
4322
  ttyName(fd) {
4231
- return json(call2({ op: "fd-info", fd }, `fd-info ${fd}`))?.name;
4323
+ return json2(call2({ op: "fd-info", fd }, `fd-info ${fd}`))?.name;
4232
4324
  },
4233
4325
  kind(fd) {
4234
- return json(call2({ op: "fd-info", fd }, `fd-info ${fd}`))?.kind;
4326
+ return json2(call2({ op: "fd-info", fd }, `fd-info ${fd}`))?.kind;
4235
4327
  },
4236
4328
  heldMeta(fd) {
4237
- return json(call2({ op: "fd-info", fd }, `fd-info ${fd}`)).meta;
4329
+ return json2(call2({ op: "fd-info", fd }, `fd-info ${fd}`)).meta;
4238
4330
  },
4239
4331
  access(fd) {
4240
- return json(call2({ op: "fd-info", fd }, `fd-info ${fd}`)).access;
4332
+ return json2(call2({ op: "fd-info", fd }, `fd-info ${fd}`)).access;
4241
4333
  },
4242
4334
  size(fd) {
4243
- return json(call2({ op: "fd-vfs-stat", fd }, `fd-vfs-stat ${fd}`)).size;
4335
+ return json2(call2({ op: "fd-vfs-stat", fd }, `fd-vfs-stat ${fd}`)).size;
4244
4336
  },
4245
4337
  ttyNames() {
4246
- return json(call2({ op: "fd-tty-names" }, "fd-tty-names"));
4338
+ return json2(call2({ op: "fd-tty-names" }, "fd-tty-names"));
4247
4339
  },
4248
4340
  ttyOwner(name2) {
4249
- return json(call2({ op: "fd-tty-owner", name: name2 }, `fd-tty-owner ${name2}`));
4341
+ return json2(call2({ op: "fd-tty-owner", name: name2 }, `fd-tty-owner ${name2}`));
4250
4342
  },
4251
4343
  openTty(name2) {
4252
4344
  const req = name2 === void 0 ? { op: "fd-open-tty" } : { op: "fd-open-tty", name: name2 };
4253
- return json(call2(req, `fd-open-tty ${name2 ?? ""}`));
4345
+ return json2(call2(req, `fd-open-tty ${name2 ?? ""}`));
4254
4346
  },
4255
4347
  tcgets(fd) {
4256
- return json(call2({ op: "tty-get", fd }, `tty-get ${fd}`));
4348
+ return json2(call2({ op: "tty-get", fd }, `tty-get ${fd}`));
4257
4349
  },
4258
4350
  tcsets(fd, termios, flush) {
4259
4351
  call2({ op: "tty-set", fd, termios, ...flush ? { flush } : {} }, `tty-set ${fd}`);
4260
4352
  },
4261
4353
  winsize(fd) {
4262
- return json(call2({ op: "tty-winsz", fd }, `tty-winsz ${fd}`));
4354
+ return json2(call2({ op: "tty-winsz", fd }, `tty-winsz ${fd}`));
4263
4355
  },
4264
4356
  openPty() {
4265
- return json(call2({ op: "pty-open" }, "pty-open"));
4357
+ return json2(call2({ op: "pty-open" }, "pty-open"));
4266
4358
  },
4267
4359
  openPts(n, noctty) {
4268
- return json(call2({ op: "pty-slave-open", n, noctty }, `pty-slave-open ${n}`));
4360
+ return json2(call2({ op: "pty-slave-open", n, noctty }, `pty-slave-open ${n}`));
4269
4361
  },
4270
4362
  ptyNumbers() {
4271
- return json(call2({ op: "pty-list" }, "pty-list"));
4363
+ return json2(call2({ op: "pty-list" }, "pty-list"));
4272
4364
  },
4273
4365
  procList() {
4274
- return json(call2({ op: "proc-list" }, "proc-list"));
4366
+ return json2(call2({ op: "proc-list" }, "proc-list"));
4275
4367
  },
4276
4368
  mountList() {
4277
- return json(call2({ op: "mount-list" }, "mount-list"));
4369
+ return json2(call2({ op: "mount-list" }, "mount-list"));
4278
4370
  },
4279
4371
  ptyNumber(fd) {
4280
- return json(call2({ op: "pty-number", fd }, `pty-number ${fd}`));
4372
+ return json2(call2({ op: "pty-number", fd }, `pty-number ${fd}`));
4281
4373
  },
4282
4374
  ptyLock(fd, lock) {
4283
4375
  call2({ op: "pty-lock", fd, lock }, `pty-lock ${fd}`);
@@ -4401,8 +4493,8 @@ async function runWasmProcess(init, port2, deps = {}) {
4401
4493
  }
4402
4494
  };
4403
4495
  const sys = kernelSys(transport);
4404
- const encoder4 = new TextEncoder();
4405
- const say = (fd) => (text) => sys.write(fd, encoder4.encode(`${text}
4496
+ const encoder5 = new TextEncoder();
4497
+ const say = (fd) => (text) => sys.write(fd, encoder5.encode(`${text}
4406
4498
  `));
4407
4499
  let ready;
4408
4500
  let failed5;
@@ -6042,11 +6134,11 @@ var init_wasi_memory = __esm({
6042
6134
  return at;
6043
6135
  }
6044
6136
  putStrings(list, ptrs, buf) {
6045
- const encoder4 = new TextEncoder();
6137
+ const encoder5 = new TextEncoder();
6046
6138
  const v = this.view();
6047
6139
  let at = buf;
6048
6140
  list.forEach((s, i) => {
6049
- const b = encoder4.encode(s);
6141
+ const b = encoder5.encode(s);
6050
6142
  v.setUint32(ptrs + i * 4, at, true);
6051
6143
  this.bytes(at, b.length).set(b);
6052
6144
  v.setUint8(at + b.length, 0);
@@ -6054,12 +6146,12 @@ var init_wasi_memory = __esm({
6054
6146
  });
6055
6147
  }
6056
6148
  putSizes(list, countPtr, sizePtr) {
6057
- const encoder4 = new TextEncoder();
6149
+ const encoder5 = new TextEncoder();
6058
6150
  const v = this.view();
6059
6151
  v.setUint32(countPtr, list.length, true);
6060
6152
  v.setUint32(
6061
6153
  sizePtr,
6062
- list.reduce((n, s) => n + encoder4.encode(s).length + 1, 0),
6154
+ list.reduce((n, s) => n + encoder5.encode(s).length + 1, 0),
6063
6155
  true
6064
6156
  );
6065
6157
  }
@@ -10646,14 +10738,32 @@ var init_js_kernel = __esm({
10646
10738
  const result = await this.call(req);
10647
10739
  return result.ok && result.kind === "bytes" ? result.bytes : new Uint8Array(0);
10648
10740
  }
10649
- async blocking(req, signal) {
10741
+ async blocking(req, signal, track) {
10650
10742
  for (; ; ) {
10651
- const id = await this.json({ op: "async-submit", req });
10743
+ const id = await this.submit(req, track);
10652
10744
  const result = await this.settled(id, signal);
10653
10745
  if (result.ok) return result;
10654
10746
  if (result.errno !== "EINTR") throw new JsCallError(result.errno, req.op);
10655
10747
  }
10656
10748
  }
10749
+ acks = [];
10750
+ ack(id) {
10751
+ this.acks.push(id);
10752
+ }
10753
+ async submit(req, track) {
10754
+ const ack = this.acks;
10755
+ this.acks = [];
10756
+ const r = await this.transport.call({
10757
+ op: "async-submit",
10758
+ req,
10759
+ ...ack.length > 0 ? { ack } : {}
10760
+ });
10761
+ const id = r.ok && r.kind === "json" ? r.json : void 0;
10762
+ if (id !== void 0) track?.(id);
10763
+ this.deliver();
10764
+ if (id === void 0) throw new JsCallError(r.ok ? "EIO" : r.errno, "async-submit");
10765
+ return id;
10766
+ }
10657
10767
  async settled(id, signal) {
10658
10768
  for (; ; ) {
10659
10769
  const seen = Atomics.load(this.header, SAB_I_ASYNC);
@@ -10855,6 +10965,165 @@ var init_js_children = __esm({
10855
10965
  }
10856
10966
  });
10857
10967
 
10968
+ // src/process/js/js-io.ts
10969
+ function typeOf(info) {
10970
+ if (info.meta && "dir" in info.meta) return "directory";
10971
+ if (info.meta && "device" in info.meta) return "device";
10972
+ if (info.tty || info.kind === "tty") return "tty";
10973
+ if (info.kind === "socket") return "socket";
10974
+ return info.kind === "file" ? "file" : "pipe";
10975
+ }
10976
+ function device(info) {
10977
+ return info.meta && "device" in info.meta ? info.meta : void 0;
10978
+ }
10979
+ function readDevice(info, max, random) {
10980
+ if (typeOf(info) === "directory") throw new JsCallError("EISDIR", "read");
10981
+ const dev = device(info);
10982
+ if (!dev) return void 0;
10983
+ if (dev.access === "write") throw new JsCallError("EBADF", "read");
10984
+ if (dev.device === "null") return new Uint8Array(0);
10985
+ const out = new Uint8Array(Math.min(max, CHUNK));
10986
+ if (dev.device === "urandom") random(out);
10987
+ return out;
10988
+ }
10989
+ function writeDevice(info) {
10990
+ if (typeOf(info) === "directory") throw new JsCallError("EISDIR", "write");
10991
+ const dev = device(info);
10992
+ if (!dev) return false;
10993
+ if (dev.access === "read") throw new JsCallError("EBADF", "write");
10994
+ if (dev.device === "full") throw new JsCallError("ENOSPC", "write");
10995
+ return true;
10996
+ }
10997
+ function brokenPipe(err, info) {
10998
+ return err instanceof JsCallError && err.code === "EPIPE" && typeOf(info) !== "socket";
10999
+ }
11000
+ function written(r, fallback) {
11001
+ return r.ok && r.kind === "json" && typeof r.json === "number" ? r.json : fallback;
11002
+ }
11003
+ function joined(parts, length) {
11004
+ if (parts.length === 1) return parts[0];
11005
+ const out = new Uint8Array(length);
11006
+ let at = 0;
11007
+ for (const part of parts) {
11008
+ out.set(part, at);
11009
+ at += part.length;
11010
+ }
11011
+ return out;
11012
+ }
11013
+ function fileWrite(fd, append, offset, body) {
11014
+ return append ? { op: "fd-write", fd, body } : { op: "fd-pwrite", fd, offset, body };
11015
+ }
11016
+ function isExclusive(o) {
11017
+ return o.create === true && o.exclusive === true;
11018
+ }
11019
+ function absent(err) {
11020
+ if (err instanceof JsCallError && err.code === "ENOENT") return void 0;
11021
+ throw err;
11022
+ }
11023
+ function checkOpen(abs, o, existing) {
11024
+ if (existing && isExclusive(o)) throw new JsCallError("EEXIST", abs);
11025
+ if (!existing && !o.create) throw new JsCallError("ENOENT", abs);
11026
+ if (existing?.isDirectory) throw new JsCallError("EISDIR", abs);
11027
+ }
11028
+ function flagsOf(o) {
11029
+ const write2 = o.write || o.append || o.truncate;
11030
+ const access = write2 ? o.read ? O_RDWR6 : O_WRONLY6 : 0;
11031
+ return access | (o.append ? O_APPEND3 : 0);
11032
+ }
11033
+ function openRequest(abs, o) {
11034
+ return {
11035
+ op: "fd-open-vfs",
11036
+ path: abs,
11037
+ flags: flagsOf(o),
11038
+ position: 0,
11039
+ ...isExclusive(o) ? { exclusive: true } : o.create ? { create: true } : { existing: true },
11040
+ ...o.truncate ? { truncate: true } : {}
11041
+ };
11042
+ }
11043
+ function index2(n, what) {
11044
+ if (!Number.isSafeInteger(n) || n < 0) throw new JsCallError("EINVAL", what);
11045
+ }
11046
+ var CHUNK, MAX_IO, O_WRONLY6, O_RDWR6, O_APPEND3;
11047
+ var init_js_io = __esm({
11048
+ "src/process/js/js-io.ts"() {
11049
+ "use strict";
11050
+ init_js_kernel();
11051
+ CHUNK = 64 * 1024;
11052
+ MAX_IO = 1024 * 1024;
11053
+ O_WRONLY6 = 1;
11054
+ O_RDWR6 = 2;
11055
+ O_APPEND3 = 1024;
11056
+ }
11057
+ });
11058
+
11059
+ // src/process/js/js-exit.ts
11060
+ function json(r) {
11061
+ return r.ok && r.kind === "json" ? r.json : void 0;
11062
+ }
11063
+ function restoreMode(lane, { terminal, fd, termios }) {
11064
+ const open = json(lane({ op: "fd-list" })) ?? [];
11065
+ const on = open.filter((entry) => entry.terminal === terminal);
11066
+ const at = (on.find((entry) => entry.fd === fd) ?? on[0])?.fd;
11067
+ if (at !== void 0) {
11068
+ lane({ op: "tty-set", fd: at, termios });
11069
+ return;
11070
+ }
11071
+ const opened = json(lane({ op: "fd-open-tty", name: terminal }));
11072
+ if (typeof opened !== "number") return;
11073
+ lane({ op: "tty-set", fd: opened, termios });
11074
+ lane({ op: "fd-close", fd: opened });
11075
+ }
11076
+ function writeOut(lane, fd, data) {
11077
+ let at = 0;
11078
+ while (at < data.length) {
11079
+ const body = data.subarray(at, at + MAX_IO);
11080
+ const r = lane({ op: "fd-write", fd, body });
11081
+ if (!r.ok && r.errno === "EINTR") continue;
11082
+ if (!r.ok) return false;
11083
+ const n = written(r, body.length);
11084
+ if (n <= 0) return false;
11085
+ at += n;
11086
+ }
11087
+ return true;
11088
+ }
11089
+ function progress(result, len) {
11090
+ if (!result) return len;
11091
+ if (result.ok) return written(result, len);
11092
+ return result.errno === "EINTR" ? 0 : -1;
11093
+ }
11094
+ function settled(lane, writes) {
11095
+ const inFlight = writes.filter((w) => w.op !== void 0);
11096
+ const out = /* @__PURE__ */ new Map();
11097
+ if (inFlight.length === 0) return out;
11098
+ const r = lane({ op: "async-settle", ids: inFlight.map((w) => w.op) });
11099
+ const results = r.ok && r.kind === "json" ? r.json : [];
11100
+ inFlight.forEach((w, i) => {
11101
+ const result = results[i];
11102
+ out.set(w, progress(result, w.len));
11103
+ });
11104
+ return out;
11105
+ }
11106
+ function exitAtOnce(lane, writes, modes, status2) {
11107
+ const done = settled(lane, writes);
11108
+ const broken = /* @__PURE__ */ new Set();
11109
+ for (const w of writes) {
11110
+ const sent = done.get(w);
11111
+ if (sent === -1) broken.add(w.fd);
11112
+ if (broken.has(w.fd)) continue;
11113
+ if (!writeOut(lane, w.fd, w.data.subarray(w.at + (sent ?? 0)))) broken.add(w.fd);
11114
+ }
11115
+ for (const mode of modes) restoreMode(lane, mode);
11116
+ lane({ op: "proc-exit", status: status2 & 255 });
11117
+ const parked = new Int32Array(new SharedArrayBuffer(4));
11118
+ for (; ; ) Atomics.wait(parked, 0, 0);
11119
+ }
11120
+ var init_js_exit = __esm({
11121
+ "src/process/js/js-exit.ts"() {
11122
+ "use strict";
11123
+ init_js_io();
11124
+ }
11125
+ });
11126
+
10858
11127
  // src/process/js/js-fetch.ts
10859
11128
  function withoutFragment(url) {
10860
11129
  url.hash = "";
@@ -11087,7 +11356,7 @@ function fetchOp(kernel) {
11087
11356
  let r;
11088
11357
  try {
11089
11358
  signal.throwIfAborted();
11090
- r = await kernel.blocking({ op: "net-read", handle, max: CHUNK }, signal);
11359
+ r = await kernel.blocking({ op: "net-read", handle, max: CHUNK2 }, signal);
11091
11360
  } catch (err) {
11092
11361
  settle();
11093
11362
  await close(handle);
@@ -11176,12 +11445,12 @@ function fetchOp(kernel) {
11176
11445
  }
11177
11446
  };
11178
11447
  }
11179
- var CHUNK, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, TOKEN, QUOTABLE, SPACE, BASE64, SLICE;
11448
+ var CHUNK2, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, TOKEN, QUOTABLE, SPACE, BASE64, SLICE;
11180
11449
  var init_js_fetch = __esm({
11181
11450
  "src/process/js/js-fetch.ts"() {
11182
11451
  "use strict";
11183
11452
  init_js_kernel();
11184
- CHUNK = 64 * 1024;
11453
+ CHUNK2 = 64 * 1024;
11185
11454
  MAX_REDIRECTS = 20;
11186
11455
  NULL_BODY = /* @__PURE__ */ new Set([101, 103, 204, 205, 304]);
11187
11456
  REDIRECTS = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
@@ -11203,97 +11472,6 @@ var init_js_fetch = __esm({
11203
11472
  }
11204
11473
  });
11205
11474
 
11206
- // src/process/js/js-io.ts
11207
- function typeOf(info) {
11208
- if (info.meta && "dir" in info.meta) return "directory";
11209
- if (info.meta && "device" in info.meta) return "device";
11210
- if (info.tty || info.kind === "tty") return "tty";
11211
- if (info.kind === "socket") return "socket";
11212
- return info.kind === "file" ? "file" : "pipe";
11213
- }
11214
- function device(info) {
11215
- return info.meta && "device" in info.meta ? info.meta : void 0;
11216
- }
11217
- function readDevice(info, max, random) {
11218
- if (typeOf(info) === "directory") throw new JsCallError("EISDIR", "read");
11219
- const dev = device(info);
11220
- if (!dev) return void 0;
11221
- if (dev.access === "write") throw new JsCallError("EBADF", "read");
11222
- if (dev.device === "null") return new Uint8Array(0);
11223
- const out = new Uint8Array(Math.min(max, CHUNK2));
11224
- if (dev.device === "urandom") random(out);
11225
- return out;
11226
- }
11227
- function writeDevice(info) {
11228
- if (typeOf(info) === "directory") throw new JsCallError("EISDIR", "write");
11229
- const dev = device(info);
11230
- if (!dev) return false;
11231
- if (dev.access === "read") throw new JsCallError("EBADF", "write");
11232
- if (dev.device === "full") throw new JsCallError("ENOSPC", "write");
11233
- return true;
11234
- }
11235
- function brokenPipe(err, info) {
11236
- return err instanceof JsCallError && err.code === "EPIPE" && typeOf(info) !== "socket";
11237
- }
11238
- function written(r, fallback) {
11239
- return r.ok && r.kind === "json" && typeof r.json === "number" ? r.json : fallback;
11240
- }
11241
- function joined(parts, length) {
11242
- if (parts.length === 1) return parts[0];
11243
- const out = new Uint8Array(length);
11244
- let at = 0;
11245
- for (const part of parts) {
11246
- out.set(part, at);
11247
- at += part.length;
11248
- }
11249
- return out;
11250
- }
11251
- function fileWrite(fd, append, offset, body) {
11252
- return append ? { op: "fd-write", fd, body } : { op: "fd-pwrite", fd, offset, body };
11253
- }
11254
- function isExclusive(o) {
11255
- return o.create === true && o.exclusive === true;
11256
- }
11257
- function absent(err) {
11258
- if (err instanceof JsCallError && err.code === "ENOENT") return void 0;
11259
- throw err;
11260
- }
11261
- function checkOpen(abs, o, existing) {
11262
- if (existing && isExclusive(o)) throw new JsCallError("EEXIST", abs);
11263
- if (!existing && !o.create) throw new JsCallError("ENOENT", abs);
11264
- if (existing?.isDirectory) throw new JsCallError("EISDIR", abs);
11265
- }
11266
- function flagsOf(o) {
11267
- const write2 = o.write || o.append || o.truncate;
11268
- const access = write2 ? o.read ? O_RDWR6 : O_WRONLY6 : 0;
11269
- return access | (o.append ? O_APPEND3 : 0);
11270
- }
11271
- function openRequest(abs, o) {
11272
- return {
11273
- op: "fd-open-vfs",
11274
- path: abs,
11275
- flags: flagsOf(o),
11276
- position: 0,
11277
- ...isExclusive(o) ? { exclusive: true } : o.create ? { create: true } : { existing: true },
11278
- ...o.truncate ? { truncate: true } : {}
11279
- };
11280
- }
11281
- function index2(n, what) {
11282
- if (!Number.isSafeInteger(n) || n < 0) throw new JsCallError("EINVAL", what);
11283
- }
11284
- var CHUNK2, MAX_IO, O_WRONLY6, O_RDWR6, O_APPEND3;
11285
- var init_js_io = __esm({
11286
- "src/process/js/js-io.ts"() {
11287
- "use strict";
11288
- init_js_kernel();
11289
- CHUNK2 = 64 * 1024;
11290
- MAX_IO = 1024 * 1024;
11291
- O_WRONLY6 = 1;
11292
- O_RDWR6 = 2;
11293
- O_APPEND3 = 1024;
11294
- }
11295
- });
11296
-
11297
11475
  // src/process/js/js-net.ts
11298
11476
  function errnoName(errno2) {
11299
11477
  const found = Object.entries(E).find(([, n]) => n === errno2);
@@ -11435,6 +11613,67 @@ var init_js_net = __esm({
11435
11613
  }
11436
11614
  });
11437
11615
 
11616
+ // src/process/js/js-run.ts
11617
+ function stdioOf(how) {
11618
+ if (how === void 0) return "pipe";
11619
+ if (!STDIO3.has(how)) throw new JsCallError("EINVAL", "run");
11620
+ return how;
11621
+ }
11622
+ function limit(value2) {
11623
+ if (value2 === void 0 || value2 === Number.POSITIVE_INFINITY) return value2;
11624
+ if (!(value2 >= 0)) throw new JsCallError("EINVAL", "run");
11625
+ return value2;
11626
+ }
11627
+ function decodeRun(bytes, stdout, stderr) {
11628
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
11629
+ const size = view.getUint32(0, true);
11630
+ const outcome = JSON.parse(new TextDecoder().decode(bytes.subarray(4, 4 + size)));
11631
+ const out = bytes.slice(4 + size, 4 + size + outcome.out);
11632
+ const err = bytes.slice(4 + size + outcome.out, 4 + size + outcome.out + outcome.err);
11633
+ return {
11634
+ pid: outcome.pid,
11635
+ status: outcome.status,
11636
+ ...outcome.signal !== void 0 ? { signal: outcome.signal } : {},
11637
+ ...stdout === "pipe" ? { stdout: out } : {},
11638
+ ...stderr === "pipe" ? { stderr: err } : {},
11639
+ ...outcome.error ? { error: outcome.error } : {}
11640
+ };
11641
+ }
11642
+ function runSync(kernel, d, o) {
11643
+ const [file] = o.argv;
11644
+ if (file === void 0) throw new JsCallError("EINVAL", "run");
11645
+ const stdout = stdioOf(o.stdout);
11646
+ const stderr = stdioOf(o.stderr);
11647
+ const input = typeof o.input === "string" ? encoder2.encode(o.input) : o.input;
11648
+ const maxBuffer = limit(o.maxBuffer);
11649
+ const timeout = limit(o.timeout);
11650
+ const bytes = kernel.bytes({
11651
+ op: "proc-run",
11652
+ file,
11653
+ argv: [...o.argv],
11654
+ env: { ...o.env ?? d.env },
11655
+ cwd: o.cwd === void 0 ? d.cwd : d.resolve(o.cwd),
11656
+ stdin: stdioOf(o.stdin),
11657
+ ...input ? { input } : {},
11658
+ stdout,
11659
+ stderr,
11660
+ ...maxBuffer !== void 0 && maxBuffer !== Number.POSITIVE_INFINITY ? { maxBuffer } : {},
11661
+ ...maxBuffer === Number.POSITIVE_INFINITY ? { maxBuffer: Number.MAX_SAFE_INTEGER } : {},
11662
+ ...timeout !== void 0 && timeout !== Number.POSITIVE_INFINITY ? { timeoutMs: timeout } : {},
11663
+ killSignal: d.signal(o.killSignal ?? "SIGTERM")
11664
+ });
11665
+ return decodeRun(bytes, stdout, stderr);
11666
+ }
11667
+ var encoder2, STDIO3;
11668
+ var init_js_run = __esm({
11669
+ "src/process/js/js-run.ts"() {
11670
+ "use strict";
11671
+ init_js_kernel();
11672
+ encoder2 = new TextEncoder();
11673
+ STDIO3 = /* @__PURE__ */ new Set(["pipe", "ignore", "inherit"]);
11674
+ }
11675
+ });
11676
+
11438
11677
  // src/process/js/js-sync.ts
11439
11678
  function laneOf(lane) {
11440
11679
  if (!lane) return () => ({ ok: false, errno: "ENOSYS", message: "no sync lane" });
@@ -11450,7 +11689,7 @@ function syncOps(kernel, shared) {
11450
11689
  infos.set(fd, got);
11451
11690
  return got;
11452
11691
  };
11453
- const read2 = (fd, max = CHUNK2) => {
11692
+ const read2 = (fd, max = CHUNK) => {
11454
11693
  index2(max, "read");
11455
11694
  const emulated = readDevice(info(fd), max, shared.random);
11456
11695
  if (emulated) return emulated;
@@ -11458,7 +11697,7 @@ function syncOps(kernel, shared) {
11458
11697
  return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
11459
11698
  };
11460
11699
  const write2 = (fd, data) => {
11461
- const bytes = typeof data === "string" ? encoder2.encode(data) : data;
11700
+ const bytes = typeof data === "string" ? encoder3.encode(data) : data;
11462
11701
  const i = info(fd);
11463
11702
  if (writeDevice(i)) return;
11464
11703
  let at = 0;
@@ -11601,14 +11840,14 @@ function syncPathOps(kernel, resolve, statOf, open) {
11601
11840
  writeFile(path, data) {
11602
11841
  const file = open(path, { write: true, create: true, truncate: true });
11603
11842
  try {
11604
- file.write(0, typeof data === "string" ? encoder2.encode(data) : data);
11843
+ file.write(0, typeof data === "string" ? encoder3.encode(data) : data);
11605
11844
  } finally {
11606
11845
  file.close();
11607
11846
  }
11608
11847
  }
11609
11848
  };
11610
11849
  }
11611
- var encoder2, JsSyncKernel;
11850
+ var encoder3, JsSyncKernel;
11612
11851
  var init_js_sync = __esm({
11613
11852
  "src/process/js/js-sync.ts"() {
11614
11853
  "use strict";
@@ -11617,7 +11856,7 @@ var init_js_sync = __esm({
11617
11856
  init_sync_sab_bridge();
11618
11857
  init_js_io();
11619
11858
  init_js_kernel();
11620
- encoder2 = new TextEncoder();
11859
+ encoder3 = new TextEncoder();
11621
11860
  JsSyncKernel = class {
11622
11861
  lane;
11623
11862
  kernel;
@@ -11725,7 +11964,8 @@ function ttyOps(kernel) {
11725
11964
  await back.catch(() => void 0);
11726
11965
  }
11727
11966
  };
11728
- return { tty, restore };
11967
+ const modes = () => [...saved].reverse().map(([terminal, { fd, termios }]) => ({ terminal, fd, termios }));
11968
+ return { tty, restore, modes };
11729
11969
  }
11730
11970
  var BRKINT, INPCK, ISTRIP, ICRNL, IXON, ONLCR, CS8, ISIG, ICANON2, ECHO2, IEXTEN, VTIME, VMIN;
11731
11971
  var init_js_tty = __esm({
@@ -11816,14 +12056,14 @@ function websocketOp(kernel) {
11816
12056
  finish();
11817
12057
  };
11818
12058
  signal.addEventListener("abort", onAbort, { once: true });
11819
- let settled = false;
12059
+ let settled2 = false;
11820
12060
  let readDone = false;
11821
12061
  const release = () => {
11822
- if (!settled || !readDone || freed) return;
12062
+ if (!settled2 || !readDone || freed) return;
11823
12063
  finish();
11824
12064
  };
11825
12065
  kernel.blocking({ op: "net-ws-wait", handle }, stop.signal).then((r) => {
11826
- settled = true;
12066
+ settled2 = true;
11827
12067
  settle(r.json);
11828
12068
  release();
11829
12069
  }).catch(lose);
@@ -11871,7 +12111,7 @@ function websocketOp(kernel) {
11871
12111
  async write(chunk, controller) {
11872
12112
  stop.signal.throwIfAborted();
11873
12113
  const send = async (body) => {
11874
- if (settled) throw new JsCallError("EPIPE", "the websocket is closed");
12114
+ if (settled2) throw new JsCallError("EPIPE", "the websocket is closed");
11875
12115
  return await kernel.json({ op: "net-ws-send", handle, ...body });
11876
12116
  };
11877
12117
  let buffered = await send(typeof chunk === "string" ? { text: chunk } : { body: chunk });
@@ -11931,6 +12171,41 @@ function resolvePath(cwd, path) {
11931
12171
  }
11932
12172
  return `/${parts.join("/")}`;
11933
12173
  }
12174
+ function writer(kernel, info, pid) {
12175
+ const writes = /* @__PURE__ */ new Set();
12176
+ const sendAll = async (fd, data, i, w, signal) => {
12177
+ while (w.at < data.length) {
12178
+ const body = data.subarray(w.at, w.at + MAX_IO);
12179
+ w.len = body.length;
12180
+ try {
12181
+ w.at += signal ? await sendSome(kernel, fd, body, signal) : written(
12182
+ await kernel.blocking({ op: "fd-write", fd, body }, void 0, (id) => {
12183
+ if (w.op !== void 0) kernel.ack(w.op);
12184
+ w.op = id;
12185
+ }),
12186
+ body.length
12187
+ );
12188
+ if (w.op !== void 0) kernel.ack(w.op);
12189
+ w.op = void 0;
12190
+ } catch (err) {
12191
+ if (brokenPipe(err, i)) await kernel.call({ op: "proc-kill", pid, sig: SIG.PIPE });
12192
+ throw err;
12193
+ }
12194
+ }
12195
+ };
12196
+ const writeAll = async (fd, data, signal) => {
12197
+ const w = { fd, data, at: 0, len: 0 };
12198
+ if (!signal) writes.add(w);
12199
+ try {
12200
+ const i = await info(fd);
12201
+ if (writeDevice(i)) return;
12202
+ await sendAll(fd, data, i, w, signal);
12203
+ } finally {
12204
+ writes.delete(w);
12205
+ }
12206
+ };
12207
+ return { writes, writeAll };
12208
+ }
11934
12209
  function createContext(o) {
11935
12210
  const { kernel } = o;
11936
12211
  const infos = /* @__PURE__ */ new Map();
@@ -11955,36 +12230,23 @@ function createContext(o) {
11955
12230
  infos.set(fd, got);
11956
12231
  return got;
11957
12232
  };
11958
- const read2 = async (fd, max = CHUNK2, signal) => {
12233
+ const read2 = async (fd, max = CHUNK, signal) => {
11959
12234
  index2(max, "read");
11960
12235
  const emulated = readDevice(await info(fd), max, random);
11961
12236
  if (emulated) return emulated;
11962
12237
  return readPipe(kernel, fd, Math.min(max, MAX_IO), signal);
11963
12238
  };
11964
- const writeAll = async (fd, data, signal) => {
11965
- const i = await info(fd);
11966
- if (writeDevice(i)) return;
11967
- let at = 0;
11968
- while (at < data.length) {
11969
- const body = data.subarray(at, at + MAX_IO);
11970
- try {
11971
- at += signal ? await sendSome(kernel, fd, body, signal) : written(await kernel.blocking({ op: "fd-write", fd, body }), body.length);
11972
- } catch (err) {
11973
- if (brokenPipe(err, i)) await kernel.call({ op: "proc-kill", pid: o.pid, sig: SIG.PIPE });
11974
- throw err;
11975
- }
11976
- }
11977
- };
12239
+ const { writes, writeAll } = writer(kernel, info, o.pid);
11978
12240
  const write2 = (fd, data) => {
11979
- const bytes = typeof data === "string" ? encoder3.encode(data) : data;
12241
+ const bytes = typeof data === "string" ? encoder4.encode(data) : data;
11980
12242
  let settle;
11981
- const settled = new Promise((resolve2) => settle = resolve2);
11982
- pending.add(settled);
12243
+ const settled2 = new Promise((resolve2) => settle = resolve2);
12244
+ pending.add(settled2);
11983
12245
  return (async () => {
11984
12246
  try {
11985
12247
  await writeAll(fd, bytes);
11986
12248
  } finally {
11987
- pending.delete(settled);
12249
+ pending.delete(settled2);
11988
12250
  settle();
11989
12251
  }
11990
12252
  })();
@@ -12017,14 +12279,17 @@ function createContext(o) {
12017
12279
  return handle.file;
12018
12280
  };
12019
12281
  const fs = pathOps(kernel, resolve, statOf, open);
12020
- const sync = syncOps(new JsSyncKernel(o.lane ?? laneOf(void 0), kernel, unwind), {
12021
- pid: o.pid,
12022
- resolve,
12023
- random,
12024
- infos,
12025
- handles
12026
- });
12282
+ const lane = o.lane ?? laneOf(void 0);
12283
+ const syncKernel = new JsSyncKernel(lane, kernel, unwind);
12027
12284
  const terminal = ttyOps(kernel);
12285
+ const sync = {
12286
+ ...syncOps(syncKernel, { pid: o.pid, resolve, random, infos, handles }),
12287
+ run: (options) => runSync(syncKernel, { env: o.env, cwd: o.cwd, resolve, signal: signalNumber }, options),
12288
+ exit: (status2 = 0) => {
12289
+ exiting ??= status2 & 255;
12290
+ return exitAtOnce(lane, [...writes], terminal.modes(), exiting);
12291
+ }
12292
+ };
12028
12293
  const io = { read: read2, send: writeAll, close: (fd) => ctx.close(fd) };
12029
12294
  const children = childOps(kernel, io, { env: o.env, cwd: o.cwd, signal: signalNumber });
12030
12295
  const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
@@ -12198,24 +12463,26 @@ function pathOps(kernel, resolve, statOf, open) {
12198
12463
  async writeFile(path, data) {
12199
12464
  const file = await open(path, { write: true, create: true, truncate: true });
12200
12465
  try {
12201
- await file.write(0, typeof data === "string" ? encoder3.encode(data) : data);
12466
+ await file.write(0, typeof data === "string" ? encoder4.encode(data) : data);
12202
12467
  } finally {
12203
12468
  await file.close();
12204
12469
  }
12205
12470
  }
12206
12471
  };
12207
12472
  }
12208
- var JsExit, encoder3;
12473
+ var JsExit, encoder4;
12209
12474
  var init_js_context = __esm({
12210
12475
  "src/process/js/js-context.ts"() {
12211
12476
  "use strict";
12212
12477
  init_signals();
12213
12478
  init_sync_fs_wire();
12214
12479
  init_js_children();
12480
+ init_js_exit();
12215
12481
  init_js_fetch();
12216
12482
  init_js_io();
12217
12483
  init_js_kernel();
12218
12484
  init_js_net();
12485
+ init_js_run();
12219
12486
  init_js_sync();
12220
12487
  init_js_tty();
12221
12488
  init_js_websocket();
@@ -12227,83 +12494,7 @@ var init_js_context = __esm({
12227
12494
  this.status = status2;
12228
12495
  }
12229
12496
  };
12230
- encoder3 = new TextEncoder();
12231
- }
12232
- });
12233
-
12234
- // src/process/js/lockdown.ts
12235
- function chain(target) {
12236
- const out = [];
12237
- for (let at = target; at && at !== Object.prototype; ) {
12238
- out.push(at);
12239
- at = Object.getPrototypeOf(at);
12240
- }
12241
- return out;
12242
- }
12243
- function hide(target, names) {
12244
- for (const name2 of names) {
12245
- const holders = chain(target);
12246
- for (const holder of holders) {
12247
- if (Object.getOwnPropertyDescriptor(holder, name2)?.configurable) {
12248
- Reflect.deleteProperty(holder, name2);
12249
- }
12250
- }
12251
- const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name2));
12252
- const defined = Reflect.defineProperty(target, name2, {
12253
- value: void 0,
12254
- writable: false,
12255
- enumerable: false,
12256
- configurable: false
12257
- });
12258
- if (kept || !defined && Reflect.get(target, name2) !== void 0) {
12259
- throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
12260
- }
12261
- }
12262
- }
12263
- function vacate(target, names) {
12264
- for (const name2 of names) {
12265
- for (let at = target; at && at !== Object.prototype; ) {
12266
- if (Object.getOwnPropertyDescriptor(at, name2)?.configurable) Reflect.deleteProperty(at, name2);
12267
- at = Object.getPrototypeOf(at);
12268
- }
12269
- Reflect.defineProperty(target, name2, {
12270
- value: void 0,
12271
- writable: true,
12272
- enumerable: false,
12273
- configurable: true
12274
- });
12275
- if (Reflect.get(target, name2) !== void 0) {
12276
- throw new Error(`slicc-kernel: cannot withhold ${name2} from a JS program`);
12277
- }
12278
- }
12279
- }
12280
- function lockdown(scope2 = globalThis) {
12281
- hide(scope2, BLOCKED_GLOBALS);
12282
- vacate(scope2, OPEN_SLOTS);
12283
- const navigator = scope2.navigator;
12284
- if (navigator && typeof navigator === "object") hide(navigator, BLOCKED_NAVIGATOR);
12285
- }
12286
- var BLOCKED_GLOBALS, BLOCKED_NAVIGATOR, OPEN_SLOTS;
12287
- var init_lockdown = __esm({
12288
- "src/process/js/lockdown.ts"() {
12289
- "use strict";
12290
- BLOCKED_GLOBALS = [
12291
- "XMLHttpRequest",
12292
- "WebSocketStream",
12293
- "WebTransport",
12294
- "EventSource",
12295
- "importScripts",
12296
- "indexedDB",
12297
- "caches",
12298
- "cookieStore",
12299
- "Worker",
12300
- "SharedWorker",
12301
- "BroadcastChannel",
12302
- "postMessage",
12303
- "close"
12304
- ];
12305
- BLOCKED_NAVIGATOR = ["storage", "locks", "serviceWorker"];
12306
- OPEN_SLOTS = ["fetch", "WebSocket"];
12497
+ encoder4 = new TextEncoder();
12307
12498
  }
12308
12499
  });
12309
12500
 
@@ -12429,11 +12620,15 @@ var init_js_runtime = __esm({
12429
12620
  }
12430
12621
  });
12431
12622
 
12623
+ // src/process-worker.ts
12624
+ init_lockdown();
12625
+
12432
12626
  // src/process/process-entry.ts
12433
12627
  init_protocol();
12434
12628
  init_process_runtime();
12435
12629
  var loadWasi = () => Promise.resolve().then(() => (init_wasi_runtime(), wasi_runtime_exports));
12436
12630
  var loadJs = () => Promise.resolve().then(() => (init_js_runtime(), js_runtime_exports));
12631
+ var NOT_RUNNABLE2 = 126;
12437
12632
  function started(init, port2, run, wasi, js) {
12438
12633
  if (init.program?.abi === "js") {
12439
12634
  const jsInit = init;
@@ -12443,18 +12638,35 @@ function started(init, port2, run, wasi, js) {
12443
12638
  if (wasmInit.program?.abi === "wasi") return wasi().then((m) => m.runWasiProcess(wasmInit, port2));
12444
12639
  return run(wasmInit, port2);
12445
12640
  }
12446
- function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs) {
12447
- const failed5 = (err) => port2.postMessage({
12641
+ function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs, seal = () => {
12642
+ }) {
12643
+ const failed5 = (err, code2) => port2.postMessage({
12448
12644
  type: WASM_PROCESS_ERROR,
12449
- message: err instanceof Error ? err.stack ?? err.message : String(err)
12645
+ message: err instanceof Error ? err.stack ?? err.message : String(err),
12646
+ ...code2 === void 0 ? {} : { code: code2 }
12450
12647
  });
12648
+ let refused;
12649
+ const sealOnce = () => {
12650
+ if (refused === void 0) {
12651
+ try {
12652
+ seal();
12653
+ refused = null;
12654
+ } catch (error) {
12655
+ refused = { error };
12656
+ }
12657
+ }
12658
+ return refused;
12659
+ };
12451
12660
  return (data) => {
12452
12661
  const type = data?.type;
12662
+ if (type !== WASM_THREAD_INIT && type !== WASM_PROCESS_INIT) return;
12663
+ const refusal2 = sealOnce();
12453
12664
  if (type === WASM_THREAD_INIT) {
12665
+ if (refusal2) return failed5(refusal2.error);
12454
12666
  wasi().then((m) => m.runWasiThread(data, port2)).catch(failed5);
12455
12667
  return;
12456
12668
  }
12457
- if (type !== WASM_PROCESS_INIT) return;
12669
+ if (refusal2) return failed5(refusal2.error, NOT_RUNNABLE2);
12458
12670
  started(data, port2, run, wasi, js).then(
12459
12671
  (code2) => port2.postMessage({ type: WASM_PROCESS_EXIT, code: code2 }),
12460
12672
  failed5
@@ -12463,8 +12675,18 @@ function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs)
12463
12675
  }
12464
12676
 
12465
12677
  // src/process-worker.ts
12678
+ init_process_fds();
12466
12679
  var scope = globalThis;
12467
12680
  var post = scope.postMessage.bind(scope);
12468
- var onMessage = processEntry({ postMessage: (message2) => post(message2) });
12681
+ var onMessage = processEntry(
12682
+ { postMessage: (message2) => post(message2) },
12683
+ void 0,
12684
+ void 0,
12685
+ void 0,
12686
+ () => {
12687
+ pinRootKind();
12688
+ lockdown();
12689
+ }
12690
+ );
12469
12691
  scope.addEventListener("message", (event) => onMessage(event.data));
12470
12692
  //# sourceMappingURL=process-worker.js.map