@ai-ecoverse/slicc-kernel 1.32.2 → 1.33.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.
@@ -1319,7 +1319,7 @@ function sabViews(sab) {
1319
1319
  window: new Uint8Array(sab, SAB_HEADER_BYTES)
1320
1320
  };
1321
1321
  }
1322
- var SAB_HEADER_I32, SAB_HEADER_BYTES, SAB_I_STATE, SAB_I_SEQ, SAB_I_STATUS, SAB_I_TOTAL, SAB_I_CHUNK, SAB_I_OFFSET, SAB_I_REQ, SAB_I_PUB, SAB_I_SIGNALS, SAB_I_TIMERS, SAB_I_MEMORY, SAB_I_TOTAL_HI, SAB_I_OFFSET_HI, SAB_I_KILLED, U32, SAB_STATE_IDLE, SAB_STATE_PENDING, SAB_STATE_READY, SAB_STATUS_BYTES, SAB_STATUS_JSON, SAB_STATUS_VOID, SAB_STATUS_ERRNO, SAB_DEFAULT_WINDOW_BYTES, SAB_MIN_BYTES, SYNC_SAB_REQ_MSG, SYNC_SAB_NEXT_MSG, encoder, decoder;
1322
+ var SAB_HEADER_I32, SAB_HEADER_BYTES, SAB_I_STATE, SAB_I_SEQ, SAB_I_STATUS, SAB_I_TOTAL, SAB_I_CHUNK, SAB_I_OFFSET, SAB_I_REQ, SAB_I_PUB, SAB_I_SIGNALS, SAB_I_TIMERS, SAB_I_MEMORY, SAB_I_TOTAL_HI, SAB_I_OFFSET_HI, SAB_I_KILLED, SAB_I_ASYNC, SAB_I_STOP, U32, SAB_STATE_IDLE, SAB_STATE_PENDING, SAB_STATE_READY, SAB_STATUS_BYTES, SAB_STATUS_JSON, SAB_STATUS_VOID, SAB_STATUS_ERRNO, SAB_DEFAULT_WINDOW_BYTES, SAB_MIN_BYTES, SYNC_SAB_REQ_MSG, SYNC_SAB_NEXT_MSG, encoder, decoder;
1323
1323
  var init_sync_sab_wire = __esm({
1324
1324
  "src/realm/sync-sab-wire.ts"() {
1325
1325
  "use strict";
@@ -1339,6 +1339,8 @@ var init_sync_sab_wire = __esm({
1339
1339
  SAB_I_TOTAL_HI = 11;
1340
1340
  SAB_I_OFFSET_HI = 12;
1341
1341
  SAB_I_KILLED = 13;
1342
+ SAB_I_ASYNC = 14;
1343
+ SAB_I_STOP = 15;
1342
1344
  U32 = 2 ** 32;
1343
1345
  SAB_STATE_IDLE = 0;
1344
1346
  SAB_STATE_PENDING = 1;
@@ -2905,8 +2907,8 @@ var init_process_http = __esm({
2905
2907
  "use strict";
2906
2908
  HttpError = class extends Error {
2907
2909
  code;
2908
- constructor(code2, message) {
2909
- super(message);
2910
+ constructor(code2, message2) {
2911
+ super(message2);
2910
2912
  this.code = code2;
2911
2913
  }
2912
2914
  };
@@ -3695,8 +3697,8 @@ async function runWasmProcess(init, port2, deps = {}) {
3695
3697
  );
3696
3698
  const transport = signals.transport();
3697
3699
  const sys = kernelSys(transport);
3698
- const encoder2 = new TextEncoder();
3699
- const say = (fd) => (text) => sys.write(fd, encoder2.encode(`${text}
3700
+ const encoder3 = new TextEncoder();
3701
+ const say = (fd) => (text) => sys.write(fd, encoder3.encode(`${text}
3700
3702
  `));
3701
3703
  let ready;
3702
3704
  let failed2;
@@ -4874,11 +4876,11 @@ var init_wasi_memory = __esm({
4874
4876
  return at;
4875
4877
  }
4876
4878
  putStrings(list, ptrs, buf) {
4877
- const encoder2 = new TextEncoder();
4879
+ const encoder3 = new TextEncoder();
4878
4880
  const v = this.view();
4879
4881
  let at = buf;
4880
4882
  list.forEach((s, i) => {
4881
- const b = encoder2.encode(s);
4883
+ const b = encoder3.encode(s);
4882
4884
  v.setUint32(ptrs + i * 4, at, true);
4883
4885
  this.bytes(at, b.length).set(b);
4884
4886
  v.setUint8(at + b.length, 0);
@@ -4886,12 +4888,12 @@ var init_wasi_memory = __esm({
4886
4888
  });
4887
4889
  }
4888
4890
  putSizes(list, countPtr, sizePtr) {
4889
- const encoder2 = new TextEncoder();
4891
+ const encoder3 = new TextEncoder();
4890
4892
  const v = this.view();
4891
4893
  v.setUint32(countPtr, list.length, true);
4892
4894
  v.setUint32(
4893
4895
  sizePtr,
4894
- list.reduce((n, s) => n + encoder2.encode(s).length + 1, 0),
4896
+ list.reduce((n, s) => n + encoder3.encode(s).length + 1, 0),
4895
4897
  true
4896
4898
  );
4897
4899
  }
@@ -5572,8 +5574,11 @@ function base64(text) {
5572
5574
  }
5573
5575
  return btoa(binary);
5574
5576
  }
5577
+ function importSource(source) {
5578
+ return import(`data:text/javascript;base64,${base64(source)}`);
5579
+ }
5575
5580
  async function loadImports(source) {
5576
- const loaded = await import(`data:text/javascript;base64,${base64(source)}`);
5581
+ const loaded = await importSource(source);
5577
5582
  if (typeof loaded.createImports !== "function") {
5578
5583
  throw new Error("the imports module exports no createImports function");
5579
5584
  }
@@ -6401,12 +6406,12 @@ var init_wasix_linker = __esm({
6401
6406
  slot(fn, handle, name) {
6402
6407
  const known = this.slots.get(fn);
6403
6408
  if (known !== void 0) return known;
6404
- const index = this.table.length;
6409
+ const index2 = this.table.length;
6405
6410
  this.table.grow(1);
6406
- this.table.set(index, fn);
6407
- this.slots.set(fn, index);
6408
- this.publisher?.({ kind: "slot", index, handle, name });
6409
- return index;
6411
+ this.table.set(index2, fn);
6412
+ this.slots.set(fn, index2);
6413
+ this.publisher?.({ kind: "slot", index: index2, handle, name });
6414
+ return index2;
6410
6415
  }
6411
6416
  allocate(size, alignment) {
6412
6417
  if (size === 0) return 0;
@@ -7113,9 +7118,9 @@ var init_wasix_host = __esm({
7113
7118
  }
7114
7119
  dlImports() {
7115
7120
  const { mem, host } = this;
7116
- const failed2 = (message, buf, len) => {
7121
+ const failed2 = (message2, buf, len) => {
7117
7122
  if (len > 0) {
7118
- const bytes = new TextEncoder().encode(message).subarray(0, len - 1);
7123
+ const bytes = new TextEncoder().encode(message2).subarray(0, len - 1);
7119
7124
  mem.bytes(buf, bytes.length).set(bytes);
7120
7125
  mem.view().setUint8(buf + bytes.length, 0);
7121
7126
  }
@@ -7267,10 +7272,10 @@ function parseFunctionNames(payload) {
7267
7272
  if (end > payload.length) throw new RangeError("truncated name section");
7268
7273
  if (id === 1) {
7269
7274
  for (let count = leb(); count > 0; count--) {
7270
- const index = leb();
7275
+ const index2 = leb();
7271
7276
  const length = leb();
7272
7277
  if (at + length > end) throw new RangeError("truncated name section");
7273
- names.set(index, decoder3.decode(payload.subarray(at, at + length)));
7278
+ names.set(index2, decoder3.decode(payload.subarray(at, at + length)));
7274
7279
  at += length;
7275
7280
  }
7276
7281
  }
@@ -7294,7 +7299,7 @@ function nameFrame(line, module, name) {
7294
7299
  }
7295
7300
  function sidecarNames(read, path) {
7296
7301
  let names;
7297
- return (index) => {
7302
+ return (index2) => {
7298
7303
  if (!names) {
7299
7304
  try {
7300
7305
  names = parseFunctionNames(read(path));
@@ -7302,7 +7307,7 @@ function sidecarNames(read, path) {
7302
7307
  names = /* @__PURE__ */ new Map();
7303
7308
  }
7304
7309
  }
7305
- return names.get(index);
7310
+ return names.get(index2);
7306
7311
  };
7307
7312
  }
7308
7313
  var UNNAMED_FRAME, WASM_MODULE;
@@ -7767,6 +7772,706 @@ var init_wasi_runtime = __esm({
7767
7772
  }
7768
7773
  });
7769
7774
 
7775
+ // src/process/js/async-sab.ts
7776
+ async function changed(header, index2, seen, waitAsync = defaultWaitAsync) {
7777
+ const waited = waitAsync(header, index2, seen);
7778
+ if (waited.async) await waited.value;
7779
+ }
7780
+ function createAsyncSabTransport(sab, port2, waitAsync = defaultWaitAsync) {
7781
+ const { header, window } = sabViews(sab);
7782
+ let seq = 0;
7783
+ let tail = Promise.resolve();
7784
+ async function ready(id) {
7785
+ for (; ; ) {
7786
+ const published = Atomics.load(header, SAB_I_PUB);
7787
+ if (Atomics.load(header, SAB_I_STATE) === SAB_STATE_READY && Atomics.load(header, SAB_I_SEQ) === id) {
7788
+ return;
7789
+ }
7790
+ await changed(header, SAB_I_PUB, published, waitAsync);
7791
+ }
7792
+ }
7793
+ async function once(req) {
7794
+ const id = ++seq;
7795
+ let out = null;
7796
+ let status2 = 0;
7797
+ let offset = 0;
7798
+ Atomics.store(header, SAB_I_REQ, id);
7799
+ try {
7800
+ for (; ; ) {
7801
+ Atomics.store(header, SAB_I_STATE, SAB_STATE_PENDING);
7802
+ port2.postMessage(
7803
+ offset === 0 ? { type: SYNC_SAB_REQ_MSG, id, req } : { type: SYNC_SAB_NEXT_MSG, id, offset }
7804
+ );
7805
+ await ready(id);
7806
+ const total = loadU53(header, SAB_I_TOTAL, SAB_I_TOTAL_HI);
7807
+ const chunk = Atomics.load(header, SAB_I_CHUNK);
7808
+ const at = loadU53(header, SAB_I_OFFSET, SAB_I_OFFSET_HI);
7809
+ if (at !== offset || chunk < 0 || total < 0 || offset + chunk > total) {
7810
+ return { ok: false, errno: "EIO", message: "sync-sab: torn reply" };
7811
+ }
7812
+ if (out === null) {
7813
+ status2 = Atomics.load(header, SAB_I_STATUS);
7814
+ out = new Uint8Array(total);
7815
+ }
7816
+ out.set(window.subarray(0, chunk), offset);
7817
+ offset += chunk;
7818
+ if (offset >= total) break;
7819
+ if (chunk === 0) return { ok: false, errno: "EIO", message: "sync-sab: empty chunk" };
7820
+ }
7821
+ } finally {
7822
+ Atomics.store(header, SAB_I_REQ, 0);
7823
+ Atomics.store(header, SAB_I_STATE, SAB_STATE_IDLE);
7824
+ }
7825
+ return decodeSabResult(status2, out);
7826
+ }
7827
+ return {
7828
+ call(req) {
7829
+ const run = tail.then(() => once(req));
7830
+ tail = run.catch(() => void 0);
7831
+ return run;
7832
+ }
7833
+ };
7834
+ }
7835
+ var defaultWaitAsync;
7836
+ var init_async_sab = __esm({
7837
+ "src/process/js/async-sab.ts"() {
7838
+ "use strict";
7839
+ init_sync_sab_wire();
7840
+ defaultWaitAsync = (a, i, v) => Atomics.waitAsync(a, i, v);
7841
+ }
7842
+ });
7843
+
7844
+ // src/process/js/js-kernel.ts
7845
+ var JsCallError, JsKernel;
7846
+ var init_js_kernel = __esm({
7847
+ "src/process/js/js-kernel.ts"() {
7848
+ "use strict";
7849
+ init_signals();
7850
+ init_sync_sab_wire();
7851
+ init_async_sab();
7852
+ JsCallError = class extends Error {
7853
+ code;
7854
+ constructor(code2, what) {
7855
+ super(`${what}: ${code2}`);
7856
+ this.name = "JsCallError";
7857
+ this.code = code2;
7858
+ }
7859
+ };
7860
+ JsKernel = class {
7861
+ header;
7862
+ transport;
7863
+ waitAsync;
7864
+ onError;
7865
+ handlers = /* @__PURE__ */ new Map();
7866
+ ignored = 0;
7867
+ changing = Promise.resolve();
7868
+ pid = 0;
7869
+ reported = { caught: 0, ignored: 0 };
7870
+ watching = false;
7871
+ constructor(o) {
7872
+ this.header = new Int32Array(o.sab, 0, SAB_HEADER_I32);
7873
+ this.transport = o.transport;
7874
+ this.waitAsync = o.waitAsync;
7875
+ this.onError = o.onError;
7876
+ }
7877
+ async raw(req) {
7878
+ const result = await this.transport.call(req);
7879
+ this.deliver();
7880
+ return result;
7881
+ }
7882
+ async call(req) {
7883
+ const result = await this.raw(req);
7884
+ if (!result.ok) throw new JsCallError(result.errno, req.op);
7885
+ return result;
7886
+ }
7887
+ async json(req) {
7888
+ const result = await this.call(req);
7889
+ return result.ok && result.kind === "json" ? result.json : void 0;
7890
+ }
7891
+ async bytes(req) {
7892
+ const result = await this.call(req);
7893
+ return result.ok && result.kind === "bytes" ? result.bytes : new Uint8Array(0);
7894
+ }
7895
+ async blocking(req) {
7896
+ for (; ; ) {
7897
+ const id = await this.json({ op: "async-submit", req });
7898
+ const result = await this.settled(id);
7899
+ if (result.ok) return result;
7900
+ if (result.errno !== "EINTR") throw new JsCallError(result.errno, req.op);
7901
+ }
7902
+ }
7903
+ async settled(id) {
7904
+ for (; ; ) {
7905
+ const seen = Atomics.load(this.header, SAB_I_ASYNC);
7906
+ const taken = await this.raw({ op: "async-take", id });
7907
+ if (taken.ok || taken.errno !== "EAGAIN") return taken;
7908
+ await changed(this.header, SAB_I_ASYNC, seen, this.waitAsync);
7909
+ }
7910
+ }
7911
+ deliver() {
7912
+ const pending = Atomics.exchange(this.header, SAB_I_SIGNALS, 0);
7913
+ for (const sig of signalsIn(pending)) {
7914
+ const handler = this.handlers.get(sig);
7915
+ if (!handler) {
7916
+ if (!(this.ignored & sigbit(sig))) this.raise(sig);
7917
+ continue;
7918
+ }
7919
+ try {
7920
+ Promise.resolve(handler(sig)).catch(this.onError);
7921
+ } catch (err) {
7922
+ this.onError(err);
7923
+ }
7924
+ }
7925
+ }
7926
+ async watch() {
7927
+ if (this.watching) return;
7928
+ this.watching = true;
7929
+ for (; ; ) {
7930
+ await changed(this.header, SAB_I_SIGNALS, 0, this.waitAsync);
7931
+ this.deliver();
7932
+ }
7933
+ }
7934
+ async watchStops() {
7935
+ for (; ; ) {
7936
+ await changed(this.header, SAB_I_STOP, 0, this.waitAsync);
7937
+ this.freeze();
7938
+ }
7939
+ }
7940
+ freeze() {
7941
+ while (Atomics.load(this.header, SAB_I_STOP) === 1) Atomics.wait(this.header, SAB_I_STOP, 1);
7942
+ }
7943
+ setHandler(sig, handler) {
7944
+ if (sig === SIG.KILL || sig === SIG.STOP) {
7945
+ return Promise.reject(new JsCallError("EINVAL", "signal"));
7946
+ }
7947
+ const run = this.changing.then(() => this.change(sig, handler));
7948
+ this.changing = run.catch(() => void 0);
7949
+ return run;
7950
+ }
7951
+ async change(sig, handler) {
7952
+ const handlers = new Map(this.handlers);
7953
+ handlers.delete(sig);
7954
+ let ignored = this.ignored & ~sigbit(sig);
7955
+ if (handler === "ignore") ignored |= sigbit(sig);
7956
+ else if (handler !== "default") handlers.set(sig, handler);
7957
+ await this.report(handlers, ignored, handler === "default" ? sigbit(sig) : 0);
7958
+ this.handlers = handlers;
7959
+ this.ignored = ignored;
7960
+ if (handlers.size > 0) void this.watch();
7961
+ }
7962
+ raise(sig) {
7963
+ this.call({ op: "proc-kill", pid: this.pid, sig }).catch(this.onError);
7964
+ }
7965
+ async report(handlers, ignored, defaults) {
7966
+ let caught = 0;
7967
+ for (const sig of handlers.keys()) caught |= sigbit(sig);
7968
+ const same = caught === this.reported.caught && ignored === this.reported.ignored;
7969
+ if (same && defaults === 0) return;
7970
+ this.reported = { caught, ignored };
7971
+ await this.call({ op: "sig-mask", caught, ignored, ...defaults ? { defaults } : {} });
7972
+ }
7973
+ };
7974
+ }
7975
+ });
7976
+
7977
+ // src/process/js/js-context.ts
7978
+ function identityOf(answer2, fallback) {
7979
+ const id = answer2;
7980
+ return {
7981
+ pid: typeof id?.pid === "number" ? id.pid : fallback.pid,
7982
+ ppid: typeof id?.ppid === "number" ? id.ppid : fallback.ppid ?? 1
7983
+ };
7984
+ }
7985
+ function signalNumber(signal) {
7986
+ if (typeof signal === "number") {
7987
+ if (Number.isInteger(signal) && signal >= 1 && signal <= 31) return signal;
7988
+ throw new JsCallError("EINVAL", `signal ${signal}`);
7989
+ }
7990
+ const n = SIG[signal.slice(3)];
7991
+ if (n === void 0) throw new JsCallError("EINVAL", `signal ${signal}`);
7992
+ return n;
7993
+ }
7994
+ function resolvePath(cwd, path) {
7995
+ const parts = [];
7996
+ for (const part of (path.startsWith("/") ? path : `${cwd}/${path}`).split("/")) {
7997
+ if (part === "" || part === ".") continue;
7998
+ if (part === "..") parts.pop();
7999
+ else parts.push(part);
8000
+ }
8001
+ return `/${parts.join("/")}`;
8002
+ }
8003
+ function typeOf(info) {
8004
+ if (info.meta && "dir" in info.meta) return "directory";
8005
+ if (info.meta && "device" in info.meta) return "device";
8006
+ if (info.tty || info.kind === "tty") return "tty";
8007
+ if (info.kind === "socket") return "socket";
8008
+ return info.kind === "file" ? "file" : "pipe";
8009
+ }
8010
+ function flagsOf(o) {
8011
+ const write = o.write || o.append || o.truncate;
8012
+ const access = write ? o.read ? O_RDWR6 : O_WRONLY5 : 0;
8013
+ return access | (o.append ? O_APPEND3 : 0);
8014
+ }
8015
+ function createContext(o) {
8016
+ const { kernel } = o;
8017
+ const infos = /* @__PURE__ */ new Map();
8018
+ const handles = /* @__PURE__ */ new Map();
8019
+ const pending = /* @__PURE__ */ new Set();
8020
+ const random = o.random ?? ((bytes) => void crypto.getRandomValues(bytes));
8021
+ const resolve = (path) => resolvePath(o.cwd, path);
8022
+ const exit = (code2 = 0) => {
8023
+ o.exit(code2);
8024
+ throw new JsExit(code2);
8025
+ };
8026
+ const info = async (fd) => {
8027
+ const known = infos.get(fd);
8028
+ if (known) return known;
8029
+ const got = await kernel.json({ op: "fd-info", fd });
8030
+ infos.set(fd, got);
8031
+ return got;
8032
+ };
8033
+ const device = (i) => i.meta && "device" in i.meta ? i.meta : void 0;
8034
+ const read = async (fd, max = CHUNK) => {
8035
+ index(max, "read");
8036
+ const i = await info(fd);
8037
+ if (typeOf(i) === "directory") throw new JsCallError("EISDIR", "read");
8038
+ const dev = device(i);
8039
+ if (dev) {
8040
+ if (dev.access === "write") throw new JsCallError("EBADF", "read");
8041
+ if (dev.device === "null") return new Uint8Array(0);
8042
+ const out = new Uint8Array(Math.min(max, CHUNK));
8043
+ if (dev.device === "urandom") random(out);
8044
+ return out;
8045
+ }
8046
+ const r = await kernel.blocking({ op: "fd-read", fd, max: Math.min(max, MAX_IO) });
8047
+ return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
8048
+ };
8049
+ const writeAll = async (fd, data) => {
8050
+ const i = await info(fd);
8051
+ if (typeOf(i) === "directory") throw new JsCallError("EISDIR", "write");
8052
+ const dev = device(i);
8053
+ if (dev) {
8054
+ if (dev.access === "read") throw new JsCallError("EBADF", "write");
8055
+ if (dev.device === "full") throw new JsCallError("ENOSPC", "write");
8056
+ return;
8057
+ }
8058
+ let at = 0;
8059
+ while (at < data.length) {
8060
+ const body = data.subarray(at, at + MAX_IO);
8061
+ try {
8062
+ const r = await kernel.blocking({ op: "fd-write", fd, body });
8063
+ at += r.ok && r.kind === "json" && typeof r.json === "number" ? r.json : body.length;
8064
+ } catch (err) {
8065
+ const broken = err instanceof JsCallError && err.code === "EPIPE";
8066
+ if (broken && typeOf(i) !== "socket") {
8067
+ await kernel.call({ op: "proc-kill", pid: o.pid, sig: SIG.PIPE });
8068
+ }
8069
+ throw err;
8070
+ }
8071
+ }
8072
+ };
8073
+ const write = (fd, data) => {
8074
+ const bytes = typeof data === "string" ? encoder2.encode(data) : data;
8075
+ let settle;
8076
+ const settled = new Promise((resolve2) => settle = resolve2);
8077
+ pending.add(settled);
8078
+ return (async () => {
8079
+ try {
8080
+ await writeAll(fd, bytes);
8081
+ } finally {
8082
+ pending.delete(settled);
8083
+ settle();
8084
+ }
8085
+ })();
8086
+ };
8087
+ const writable = (fd) => new WritableStream({ write: (chunk) => write(fd, chunk) });
8088
+ const statOf = async (op, path) => {
8089
+ const abs = resolve(path);
8090
+ await kernel.call({ op: "fd-path-flush", path: abs });
8091
+ const s = parseSyncFsStat(await kernel.json({ op, path: abs }));
8092
+ if (!s) throw new JsCallError("EIO", op);
8093
+ return s;
8094
+ };
8095
+ const open = async (path, options = {}) => {
8096
+ const abs = resolve(path);
8097
+ const exclusive = options.create === true && options.exclusive === true;
8098
+ const existing = await statOf(exclusive ? "lstat" : "stat", abs).catch((err) => {
8099
+ if (err instanceof JsCallError && err.code === "ENOENT") return void 0;
8100
+ throw err;
8101
+ });
8102
+ if (existing && exclusive) throw new JsCallError("EEXIST", abs);
8103
+ if (!existing && !options.create) throw new JsCallError("ENOENT", abs);
8104
+ if (existing?.isDirectory) throw new JsCallError("EISDIR", abs);
8105
+ const fd = await kernel.json({
8106
+ op: "fd-open-vfs",
8107
+ path: abs,
8108
+ flags: flagsOf(options),
8109
+ position: 0,
8110
+ ...exclusive ? { exclusive: true } : options.create ? { create: true } : { existing: true },
8111
+ ...options.truncate ? { truncate: true } : {}
8112
+ });
8113
+ try {
8114
+ await kernel.call({ op: "fd-vfs-stat", fd });
8115
+ } catch (err) {
8116
+ await kernel.raw({ op: "fd-close", fd });
8117
+ throw err;
8118
+ }
8119
+ infos.set(fd, { kind: "file" });
8120
+ const handle = fileHandle(kernel, fd, abs, options.append === true, () => {
8121
+ infos.delete(fd);
8122
+ handles.delete(fd);
8123
+ });
8124
+ handles.set(fd, handle.invalidate);
8125
+ return handle.file;
8126
+ };
8127
+ const fs = pathOps(kernel, resolve, statOf, open);
8128
+ const ctx = {
8129
+ argv: o.argv,
8130
+ env: o.env,
8131
+ pid: o.pid,
8132
+ async ppid() {
8133
+ return identityOf(await kernel.json({ op: "proc-identity" }), o).ppid;
8134
+ },
8135
+ cwd: o.cwd,
8136
+ stdin: new ReadableStream(
8137
+ {
8138
+ async pull(controller) {
8139
+ const chunk = await read(0);
8140
+ if (chunk.length === 0) controller.close();
8141
+ else controller.enqueue(chunk);
8142
+ }
8143
+ },
8144
+ { highWaterMark: 0 }
8145
+ ),
8146
+ stdout: writable(1),
8147
+ stderr: writable(2),
8148
+ read,
8149
+ write,
8150
+ async close(fd) {
8151
+ handles.get(fd)?.();
8152
+ handles.delete(fd);
8153
+ infos.delete(fd);
8154
+ await kernel.call({ op: "fd-close", fd });
8155
+ },
8156
+ async fdStatus(fd) {
8157
+ const type = typeOf(await info(fd));
8158
+ return { type, tty: type === "tty", seekable: type === "file" };
8159
+ },
8160
+ isatty: async (fd) => typeOf(await info(fd)) === "tty",
8161
+ open,
8162
+ resolve,
8163
+ fs,
8164
+ signals: {
8165
+ on: async (signal, handler) => kernel.setHandler(signalNumber(signal), handler),
8166
+ ignore: async (signal) => kernel.setHandler(signalNumber(signal), "ignore"),
8167
+ reset: async (signal) => kernel.setHandler(signalNumber(signal), "default")
8168
+ },
8169
+ exit
8170
+ };
8171
+ const drain2 = async () => {
8172
+ for (; ; ) {
8173
+ await Promise.all([...pending]);
8174
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
8175
+ if (pending.size === 0) return;
8176
+ }
8177
+ };
8178
+ return { ctx, drain: drain2 };
8179
+ }
8180
+ function fileHandle(kernel, fd, path, append, forget) {
8181
+ let open = true;
8182
+ const live = () => {
8183
+ if (!open) throw new JsCallError("EBADF", path);
8184
+ };
8185
+ const file = {
8186
+ fd,
8187
+ path,
8188
+ async size() {
8189
+ live();
8190
+ const s = await kernel.json({ op: "fd-vfs-stat", fd });
8191
+ return s.size;
8192
+ },
8193
+ async read(position, length) {
8194
+ index(position, "read");
8195
+ index(length, "read");
8196
+ const parts = [];
8197
+ let got = 0;
8198
+ do {
8199
+ live();
8200
+ const max = Math.min(length - got, MAX_IO);
8201
+ if (max <= 0) break;
8202
+ const chunk = await kernel.bytes({ op: "fd-pread", fd, offset: position + got, max });
8203
+ if (chunk.length === 0) break;
8204
+ parts.push(chunk);
8205
+ got += chunk.length;
8206
+ } while (got < length);
8207
+ if (parts.length === 1) return parts[0];
8208
+ const out = new Uint8Array(got);
8209
+ let at = 0;
8210
+ for (const part of parts) {
8211
+ out.set(part, at);
8212
+ at += part.length;
8213
+ }
8214
+ return out;
8215
+ },
8216
+ async write(position, data) {
8217
+ index(position, "write");
8218
+ let at = 0;
8219
+ do {
8220
+ live();
8221
+ if (at >= data.length) break;
8222
+ const body = data.subarray(at, at + MAX_IO);
8223
+ const n = await kernel.json(
8224
+ append ? { op: "fd-write", fd, body } : { op: "fd-pwrite", fd, offset: position + at, body }
8225
+ );
8226
+ if (!(n > 0)) throw new JsCallError("EIO", "write");
8227
+ at += n;
8228
+ } while (at < data.length);
8229
+ return at;
8230
+ },
8231
+ async truncate(size) {
8232
+ live();
8233
+ index(size, "truncate");
8234
+ await kernel.call({ op: "fd-resize", fd, size });
8235
+ },
8236
+ async sync() {
8237
+ live();
8238
+ await kernel.call({ op: "fd-flush", fd });
8239
+ },
8240
+ async close() {
8241
+ live();
8242
+ open = false;
8243
+ forget();
8244
+ await kernel.call({ op: "fd-close", fd });
8245
+ }
8246
+ };
8247
+ return {
8248
+ file,
8249
+ invalidate: () => {
8250
+ open = false;
8251
+ }
8252
+ };
8253
+ }
8254
+ function index(n, what) {
8255
+ if (!Number.isSafeInteger(n) || n < 0) throw new JsCallError("EINVAL", what);
8256
+ }
8257
+ function pathOps(kernel, resolve, statOf, open) {
8258
+ return {
8259
+ stat: (path) => statOf("stat", path),
8260
+ lstat: (path) => statOf("lstat", path),
8261
+ exists: async (path) => await kernel.json({ op: "exists", path: resolve(path) }) === true,
8262
+ readdir: async (path) => await kernel.json({ op: "readdir", path: resolve(path) }),
8263
+ mkdir: async (path) => void await kernel.call({ op: "mkdir", path: resolve(path) }),
8264
+ rm: async (path) => void await kernel.call({ op: "rm", path: resolve(path) }),
8265
+ unlink: async (path) => void await kernel.call({ op: "unlink", path: resolve(path) }),
8266
+ rename: async (from, to) => void await kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
8267
+ symlink: async (target, path) => void await kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
8268
+ readlink: async (path) => String(await kernel.json({ op: "readlink", path: resolve(path) })),
8269
+ async readFile(path) {
8270
+ const abs = resolve(path);
8271
+ await kernel.call({ op: "fd-path-flush", path: abs });
8272
+ return kernel.bytes({ op: "read", path: abs });
8273
+ },
8274
+ async writeFile(path, data) {
8275
+ const file = await open(path, { write: true, create: true, truncate: true });
8276
+ try {
8277
+ await file.write(0, typeof data === "string" ? encoder2.encode(data) : data);
8278
+ } finally {
8279
+ await file.close();
8280
+ }
8281
+ }
8282
+ };
8283
+ }
8284
+ var JsExit, CHUNK, MAX_IO, O_WRONLY5, O_RDWR6, O_APPEND3, encoder2;
8285
+ var init_js_context = __esm({
8286
+ "src/process/js/js-context.ts"() {
8287
+ "use strict";
8288
+ init_signals();
8289
+ init_sync_fs_wire();
8290
+ init_js_kernel();
8291
+ JsExit = class extends Error {
8292
+ status;
8293
+ constructor(status2) {
8294
+ super(`exit ${status2}`);
8295
+ this.name = "JsExit";
8296
+ this.status = status2;
8297
+ }
8298
+ };
8299
+ CHUNK = 64 * 1024;
8300
+ MAX_IO = 1024 * 1024;
8301
+ O_WRONLY5 = 1;
8302
+ O_RDWR6 = 2;
8303
+ O_APPEND3 = 1024;
8304
+ encoder2 = new TextEncoder();
8305
+ }
8306
+ });
8307
+
8308
+ // src/process/js/lockdown.ts
8309
+ function chain(target) {
8310
+ const out = [];
8311
+ for (let at = target; at && at !== Object.prototype; ) {
8312
+ out.push(at);
8313
+ at = Object.getPrototypeOf(at);
8314
+ }
8315
+ return out;
8316
+ }
8317
+ function hide(target, names) {
8318
+ for (const name of names) {
8319
+ const holders = chain(target);
8320
+ for (const holder of holders) {
8321
+ if (Object.getOwnPropertyDescriptor(holder, name)?.configurable) {
8322
+ Reflect.deleteProperty(holder, name);
8323
+ }
8324
+ }
8325
+ const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name));
8326
+ const defined = Reflect.defineProperty(target, name, {
8327
+ value: void 0,
8328
+ writable: false,
8329
+ enumerable: false,
8330
+ configurable: false
8331
+ });
8332
+ if (kept || !defined && Reflect.get(target, name) !== void 0) {
8333
+ throw new Error(`slicc-kernel: cannot withhold ${name} from a JS program`);
8334
+ }
8335
+ }
8336
+ }
8337
+ function lockdown(scope2 = globalThis) {
8338
+ hide(scope2, BLOCKED_GLOBALS);
8339
+ const navigator = scope2.navigator;
8340
+ if (navigator && typeof navigator === "object") hide(navigator, BLOCKED_NAVIGATOR);
8341
+ }
8342
+ var BLOCKED_GLOBALS, BLOCKED_NAVIGATOR;
8343
+ var init_lockdown = __esm({
8344
+ "src/process/js/lockdown.ts"() {
8345
+ "use strict";
8346
+ BLOCKED_GLOBALS = [
8347
+ "fetch",
8348
+ "XMLHttpRequest",
8349
+ "WebSocket",
8350
+ "WebSocketStream",
8351
+ "WebTransport",
8352
+ "EventSource",
8353
+ "importScripts",
8354
+ "indexedDB",
8355
+ "caches",
8356
+ "cookieStore",
8357
+ "Worker",
8358
+ "SharedWorker",
8359
+ "BroadcastChannel",
8360
+ "postMessage",
8361
+ "close"
8362
+ ];
8363
+ BLOCKED_NAVIGATOR = ["storage", "locks", "serviceWorker"];
8364
+ }
8365
+ });
8366
+
8367
+ // src/process/js/js-runtime.ts
8368
+ var js_runtime_exports = {};
8369
+ __export(js_runtime_exports, {
8370
+ mainOf: () => mainOf,
8371
+ runJsProcess: () => runJsProcess,
8372
+ trapStrays: () => trapStrays
8373
+ });
8374
+ function trapStrays(scope2, fail) {
8375
+ if (typeof scope2.process?.on === "function") {
8376
+ scope2.process.on("unhandledRejection", fail);
8377
+ scope2.process.on("uncaughtException", fail);
8378
+ return;
8379
+ }
8380
+ scope2.addEventListener?.("unhandledrejection", (event) => {
8381
+ event.preventDefault();
8382
+ fail(event.reason);
8383
+ });
8384
+ scope2.addEventListener?.("error", (event) => {
8385
+ event.preventDefault();
8386
+ fail(event.error);
8387
+ });
8388
+ }
8389
+ async function settledStrays() {
8390
+ for (let turn = 0; turn < 2; turn++) await new Promise((resolve) => setTimeout(resolve, 0));
8391
+ }
8392
+ function message(err) {
8393
+ return err instanceof Error ? err.message : String(err);
8394
+ }
8395
+ function statusOf(value2) {
8396
+ return typeof value2 === "number" && Number.isInteger(value2) ? value2 & 255 : 0;
8397
+ }
8398
+ function mainOf(module) {
8399
+ const main = typeof module.default === "function" ? module.default : module.main;
8400
+ return typeof main === "function" ? main : void 0;
8401
+ }
8402
+ async function runJsProcess(init, port2, deps = {}) {
8403
+ const transport = createAsyncSabTransport(init.sab, port2, deps.waitAsync);
8404
+ let resolveExit;
8405
+ const exit = new Promise((resolve) => resolveExit = resolve);
8406
+ let exitedWith;
8407
+ const exited = (status3) => {
8408
+ exitedWith ??= status3;
8409
+ resolveExit(status3);
8410
+ };
8411
+ let failing;
8412
+ const fail = (err) => {
8413
+ if (err instanceof JsExit) return;
8414
+ failing ??= say(message(err)).then(() => exited(1));
8415
+ };
8416
+ const kernel = new JsKernel({
8417
+ sab: init.sab,
8418
+ transport,
8419
+ onError: fail,
8420
+ waitAsync: deps.waitAsync
8421
+ });
8422
+ void kernel.watchStops();
8423
+ const id = identityOf(await kernel.json({ op: "proc-identity" }), init);
8424
+ kernel.pid = id.pid;
8425
+ const { ctx, drain: drain2 } = createContext({
8426
+ kernel,
8427
+ argv: [init.argv0, ...init.args],
8428
+ env: init.env,
8429
+ pid: id.pid,
8430
+ ppid: id.ppid,
8431
+ cwd: init.cwd,
8432
+ exit: (status3) => exited(statusOf(status3))
8433
+ });
8434
+ const say = (text) => ctx.write(2, `${init.argv0}: ${text}
8435
+ `).catch(() => void 0);
8436
+ let main;
8437
+ trapStrays(deps.scope ?? globalThis, fail);
8438
+ try {
8439
+ (deps.lockdown ?? lockdown)();
8440
+ main = mainOf(await (deps.load ?? importSource)(init.program.glue));
8441
+ } catch (err) {
8442
+ await say(message(err));
8443
+ return NOT_RUNNABLE;
8444
+ }
8445
+ if (!main) {
8446
+ await say(`${init.program.path} exports no main function`);
8447
+ return NOT_RUNNABLE;
8448
+ }
8449
+ const program = main;
8450
+ const ran = Promise.resolve().then(() => program(ctx)).then(statusOf, async (err) => {
8451
+ if (err instanceof JsExit) return err.status;
8452
+ await say(message(err));
8453
+ return 1;
8454
+ });
8455
+ const status2 = await Promise.race([ran, exit]);
8456
+ await drain2();
8457
+ await settledStrays();
8458
+ await failing;
8459
+ if (exitedWith !== void 0) return exitedWith;
8460
+ return status2;
8461
+ }
8462
+ var NOT_RUNNABLE;
8463
+ var init_js_runtime = __esm({
8464
+ "src/process/js/js-runtime.ts"() {
8465
+ "use strict";
8466
+ init_wasi_imports();
8467
+ init_async_sab();
8468
+ init_js_context();
8469
+ init_js_kernel();
8470
+ init_lockdown();
8471
+ NOT_RUNNABLE = 126;
8472
+ }
8473
+ });
8474
+
7770
8475
  // src/node-process-worker.ts
7771
8476
  import { createRequire } from "node:module";
7772
8477
  import { parentPort } from "node:worker_threads";
@@ -7775,7 +8480,17 @@ import { parentPort } from "node:worker_threads";
7775
8480
  init_protocol();
7776
8481
  init_process_runtime();
7777
8482
  var loadWasi = () => Promise.resolve().then(() => (init_wasi_runtime(), wasi_runtime_exports));
7778
- function processEntry(port2, run = runWasmProcess, wasi = loadWasi) {
8483
+ var loadJs = () => Promise.resolve().then(() => (init_js_runtime(), js_runtime_exports));
8484
+ function started(init, port2, run, wasi, js) {
8485
+ if (init.program?.abi === "js") {
8486
+ const jsInit = init;
8487
+ return js().then((m) => m.runJsProcess(jsInit, port2));
8488
+ }
8489
+ const wasmInit = init;
8490
+ if (wasmInit.program?.abi === "wasi") return wasi().then((m) => m.runWasiProcess(wasmInit, port2));
8491
+ return run(wasmInit, port2);
8492
+ }
8493
+ function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs) {
7779
8494
  const failed2 = (err) => port2.postMessage({
7780
8495
  type: WASM_PROCESS_ERROR,
7781
8496
  message: err instanceof Error ? err.stack ?? err.message : String(err)
@@ -7787,9 +8502,7 @@ function processEntry(port2, run = runWasmProcess, wasi = loadWasi) {
7787
8502
  return;
7788
8503
  }
7789
8504
  if (type !== WASM_PROCESS_INIT) return;
7790
- const init = data;
7791
- const started = init.program?.abi === "wasi" ? wasi().then((m) => m.runWasiProcess(init, port2)) : run(init, port2);
7792
- started.then(
8505
+ started(data, port2, run, wasi, js).then(
7793
8506
  (code2) => port2.postMessage({ type: WASM_PROCESS_EXIT, code: code2 }),
7794
8507
  failed2
7795
8508
  );
@@ -7802,6 +8515,6 @@ scope.require ??= createRequire(import.meta.url);
7802
8515
  scope.__filename ??= new URL(import.meta.url).pathname;
7803
8516
  scope.__dirname ??= new URL(".", import.meta.url).pathname;
7804
8517
  var port = parentPort;
7805
- var onMessage = processEntry({ postMessage: (message) => port.postMessage(message) });
8518
+ var onMessage = processEntry({ postMessage: (message2) => port.postMessage(message2) });
7806
8519
  port.on("message", onMessage);
7807
8520
  //# sourceMappingURL=node-process-worker.js.map