@ai-ecoverse/slicc-kernel 1.129.0 → 1.130.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.
@@ -254,7 +254,7 @@ var init_cpu_clock = __esm({
254
254
  });
255
255
 
256
256
  // src/kernel/protocol.ts
257
- var WASM_PROCESS_INIT, WASM_PROCESS_EXIT, WASM_PROCESS_ERROR, WASM_PROCESS_READY, WASM_THREAD_SPAWN, WASM_THREAD_INIT, WASM_THREAD_EXIT, WASM_MAX_THREADS, WASM_DEFAULT_THREADS;
257
+ var WASM_PROCESS_INIT, WASM_PROCESS_EXIT, WASM_PROCESS_ERROR, WASM_PROCESS_READY, WASM_THREAD_SPAWN, WASM_THREAD_INIT, WASM_THREAD_EXIT, WASM_MAX_THREADS, WASM_DEFAULT_THREADS, JS_THREAD_SPAWN, JS_THREAD_INIT, JS_THREAD_EXIT, JS_THREAD_NO_MEMORY, JS_THREAD_CRASHED;
258
258
  var init_protocol = __esm({
259
259
  "src/kernel/protocol.ts"() {
260
260
  "use strict";
@@ -267,6 +267,11 @@ var init_protocol = __esm({
267
267
  WASM_THREAD_EXIT = "wasm-thread-exit";
268
268
  WASM_MAX_THREADS = 256;
269
269
  WASM_DEFAULT_THREADS = 64;
270
+ JS_THREAD_SPAWN = "js-thread-spawn";
271
+ JS_THREAD_INIT = "js-thread-init";
272
+ JS_THREAD_EXIT = "js-thread-exit";
273
+ JS_THREAD_NO_MEMORY = 256;
274
+ JS_THREAD_CRASHED = 257;
270
275
  }
271
276
  });
272
277
 
@@ -2659,7 +2664,7 @@ var KERNEL_VERSION, OS_RELEASE;
2659
2664
  var init_version = __esm({
2660
2665
  "src/version.ts"() {
2661
2666
  "use strict";
2662
- KERNEL_VERSION = true ? "1.129.0" : "0.0.0-dev";
2667
+ KERNEL_VERSION = true ? "1.130.0" : "0.0.0-dev";
2663
2668
  OS_RELEASE = "6.0.0-slicc";
2664
2669
  }
2665
2670
  });
@@ -17280,9 +17285,7 @@ function createContext(o) {
17280
17285
  argv: o.argv,
17281
17286
  env: o.env,
17282
17287
  pid: o.pid,
17283
- async ppid() {
17284
- return identityOf(await kernel.json({ op: "proc-identity" }), o).ppid;
17285
- },
17288
+ ppid: async () => identityOf(await kernel.json({ op: "proc-identity" }), o).ppid,
17286
17289
  cwd: o.cwd,
17287
17290
  stdin: readable2(read2),
17288
17291
  stdout: writable2(1),
@@ -17327,6 +17330,7 @@ function createContext(o) {
17327
17330
  websocket: websocketOp(kernel),
17328
17331
  tty: terminal.tty,
17329
17332
  exit,
17333
+ thread: o.thread,
17330
17334
  onUncaught: (listener) => listen(strays.exception, listener),
17331
17335
  onUnhandledRejection: (listener) => listen(strays.rejection, listener)
17332
17336
  };
@@ -17558,11 +17562,100 @@ var init_js_context = __esm({
17558
17562
  }
17559
17563
  });
17560
17564
 
17565
+ // src/process/js/js-thread.ts
17566
+ function outOfMemory(err) {
17567
+ return err instanceof RangeError && OOM.test(err.message);
17568
+ }
17569
+ function optionsOf(options) {
17570
+ if (options === void 0) return {};
17571
+ if (typeof options !== "object" || options === null || Array.isArray(options)) {
17572
+ throw new JsCallError("EINVAL", "thread.spawn");
17573
+ }
17574
+ const { transfer } = options;
17575
+ if (transfer !== void 0 && !Array.isArray(transfer)) {
17576
+ throw new JsCallError("EINVAL", "thread.spawn");
17577
+ }
17578
+ return options;
17579
+ }
17580
+ function started(port2, control) {
17581
+ const exited = Promise.withResolvers();
17582
+ return new Promise((resolve, reject) => {
17583
+ const thread = (tid) => Object.freeze({
17584
+ tid,
17585
+ port: port2,
17586
+ exited: exited.promise,
17587
+ async terminate() {
17588
+ control.postMessage({ terminate: true });
17589
+ await exited.promise;
17590
+ }
17591
+ });
17592
+ control.onmessage = (event) => {
17593
+ const said = event.data;
17594
+ if ("tid" in said) resolve(thread(said.tid));
17595
+ else if ("errno" in said) {
17596
+ control.close();
17597
+ port2.close();
17598
+ reject(new JsCallError(said.errno, "thread.spawn", said.message));
17599
+ } else if ("exited" in said) {
17600
+ control.close();
17601
+ exited.resolve(said.exited);
17602
+ }
17603
+ };
17604
+ });
17605
+ }
17606
+ function threadContext(post2, start2) {
17607
+ const spawn = (options) => {
17608
+ let asked;
17609
+ try {
17610
+ asked = optionsOf(options);
17611
+ } catch (err) {
17612
+ return Promise.reject(err);
17613
+ }
17614
+ const channel = new NativeChannel();
17615
+ const control = new NativeChannel();
17616
+ const transfer = [...asked.transfer ?? []];
17617
+ const msg = {
17618
+ type: JS_THREAD_SPAWN,
17619
+ data: asked.data,
17620
+ port: channel.port2,
17621
+ control: control.port2,
17622
+ transfer
17623
+ };
17624
+ try {
17625
+ post2.postMessage(msg, [channel.port2, control.port2, ...transfer]);
17626
+ } catch (err) {
17627
+ channel.port1.close();
17628
+ control.port1.close();
17629
+ return Promise.reject(err);
17630
+ }
17631
+ return started(channel.port1, control.port1);
17632
+ };
17633
+ return Object.freeze({
17634
+ tid: start2?.tid ?? 0,
17635
+ port: start2?.port,
17636
+ data: start2?.data,
17637
+ NO_MEMORY: JS_THREAD_NO_MEMORY,
17638
+ CRASHED: JS_THREAD_CRASHED,
17639
+ spawn
17640
+ });
17641
+ }
17642
+ var NativeChannel, OOM;
17643
+ var init_js_thread = __esm({
17644
+ "src/process/js/js-thread.ts"() {
17645
+ "use strict";
17646
+ init_protocol();
17647
+ init_js_kernel();
17648
+ NativeChannel = globalThis.MessageChannel;
17649
+ OOM = /out of memory|Array buffer allocation failed|Cannot allocate Wasm memory/i;
17650
+ }
17651
+ });
17652
+
17561
17653
  // src/process/js/js-runtime.ts
17562
17654
  var js_runtime_exports = {};
17563
17655
  __export(js_runtime_exports, {
17564
17656
  mainOf: () => mainOf,
17565
17657
  runJsProcess: () => runJsProcess,
17658
+ runJsThread: () => runJsThread,
17566
17659
  trapStrays: () => trapStrays
17567
17660
  });
17568
17661
  function trapStrays(scope2, stray) {
@@ -17593,7 +17686,15 @@ function mainOf(module) {
17593
17686
  const main = typeof module.default === "function" ? module.default : module.main;
17594
17687
  return typeof main === "function" ? main : void 0;
17595
17688
  }
17596
- async function runJsProcess(init, port2, deps = {}) {
17689
+ function runJsProcess(init, port2, deps = {}) {
17690
+ return runJs(init, port2, deps, void 0);
17691
+ }
17692
+ function runJsThread(init, port2, deps = {}) {
17693
+ const { thread, ...rest2 } = init;
17694
+ return runJs(rest2, port2, deps, thread);
17695
+ }
17696
+ async function runJs(init, port2, deps, thread) {
17697
+ const failed5 = (err) => thread && outOfMemory(err) ? JS_THREAD_NO_MEMORY : 1;
17597
17698
  const transport = createAsyncSabTransport(init.sab, port2, deps.waitAsync);
17598
17699
  let resolveExit;
17599
17700
  const exit = new Promise((resolve) => resolveExit = resolve);
@@ -17605,7 +17706,7 @@ async function runJsProcess(init, port2, deps = {}) {
17605
17706
  let failing;
17606
17707
  const fail = (err) => {
17607
17708
  if (err instanceof JsExit) return;
17608
- failing ??= say(message(err)).then(() => exited(1));
17709
+ failing ??= (thread ? Promise.resolve() : say(message(err))).then(() => exited(failed5(err)));
17609
17710
  };
17610
17711
  const kernel = new JsKernel({
17611
17712
  sab: init.sab,
@@ -17626,7 +17727,8 @@ async function runJsProcess(init, port2, deps = {}) {
17626
17727
  cwd: init.cwd,
17627
17728
  exit: (status3) => exited(statusOf(status3)),
17628
17729
  lane: laneOf(init.lane),
17629
- strays
17730
+ strays,
17731
+ thread: threadContext(port2, thread)
17630
17732
  });
17631
17733
  const say = (text) => ctx.write(2, `${init.argv0}: ${text}
17632
17734
  `).catch(() => void 0);
@@ -17657,8 +17759,8 @@ async function runJsProcess(init, port2, deps = {}) {
17657
17759
  const program = main;
17658
17760
  const ran = Promise.resolve().then(() => program(ctx)).then(statusOf, async (err) => {
17659
17761
  if (err instanceof JsExit) return err.status;
17660
- await say(message(err));
17661
- return 1;
17762
+ if (!thread) await say(message(err));
17763
+ return failed5(err);
17662
17764
  });
17663
17765
  const status2 = await Promise.race([ran, exit]);
17664
17766
  await drain2();
@@ -17671,11 +17773,13 @@ var NOT_RUNNABLE;
17671
17773
  var init_js_runtime = __esm({
17672
17774
  "src/process/js/js-runtime.ts"() {
17673
17775
  "use strict";
17776
+ init_protocol();
17674
17777
  init_wasi_imports();
17675
17778
  init_async_sab();
17676
17779
  init_js_context();
17677
17780
  init_js_kernel();
17678
17781
  init_js_sync();
17782
+ init_js_thread();
17679
17783
  init_lockdown();
17680
17784
  NOT_RUNNABLE = 126;
17681
17785
  }
@@ -17691,7 +17795,7 @@ init_process_runtime();
17691
17795
  var loadWasi = () => Promise.resolve().then(() => (init_wasi_runtime(), wasi_runtime_exports));
17692
17796
  var loadJs = () => Promise.resolve().then(() => (init_js_runtime(), js_runtime_exports));
17693
17797
  var NOT_RUNNABLE2 = 126;
17694
- function started(init, port2, run, wasi, js) {
17798
+ function started2(init, port2, run, wasi, js) {
17695
17799
  if (init.program?.abi === "js") {
17696
17800
  const jsInit = init;
17697
17801
  return js().then((m) => m.runJsProcess(jsInit, port2));
@@ -17721,8 +17825,19 @@ function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs,
17721
17825
  };
17722
17826
  return (data) => {
17723
17827
  const type = data?.type;
17724
- if (type !== WASM_THREAD_INIT && type !== WASM_PROCESS_INIT) return;
17828
+ if (type !== WASM_THREAD_INIT && type !== WASM_PROCESS_INIT && type !== JS_THREAD_INIT) return;
17725
17829
  const refusal2 = sealOnce();
17830
+ if (type === JS_THREAD_INIT) {
17831
+ if (refusal2) return failed5(refusal2.error);
17832
+ js().then((m) => {
17833
+ if (!m.runJsThread) throw new Error("this process worker runs no JS threads");
17834
+ return m.runJsThread(data, port2);
17835
+ }).then(
17836
+ (code2) => port2.postMessage({ type: JS_THREAD_EXIT, code: code2 }),
17837
+ failed5
17838
+ );
17839
+ return;
17840
+ }
17726
17841
  const init = data;
17727
17842
  if (type === WASM_THREAD_INIT || init?.program?.abi !== "js") useLocalClock(init?.sab);
17728
17843
  if (type === WASM_THREAD_INIT) {
@@ -17731,7 +17846,7 @@ function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs,
17731
17846
  return;
17732
17847
  }
17733
17848
  if (refusal2) return failed5(refusal2.error, NOT_RUNNABLE2);
17734
- started(data, port2, run, wasi, js).then(
17849
+ started2(data, port2, run, wasi, js).then(
17735
17850
  (code2) => port2.postMessage({ type: WASM_PROCESS_EXIT, code: code2 }),
17736
17851
  failed5
17737
17852
  );
@@ -17743,7 +17858,7 @@ init_process_fds();
17743
17858
  var scope = globalThis;
17744
17859
  var post = scope.postMessage.bind(scope);
17745
17860
  var onMessage = processEntry(
17746
- { postMessage: (message2) => post(message2) },
17861
+ { postMessage: (message2, transfer) => post(message2, transfer ?? []) },
17747
17862
  void 0,
17748
17863
  void 0,
17749
17864
  void 0,