@ai-ecoverse/slicc-kernel 1.10.0 → 1.12.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.
@@ -730,6 +730,10 @@ var init_sync_fs_wire = __esm({
730
730
  });
731
731
 
732
732
  // src/realm/sync-sab-wire.ts
733
+ function publishMemory(sab, bytes) {
734
+ if (bytes > 0)
735
+ Atomics.store(new Int32Array(sab, 0, SAB_HEADER_I32), SAB_I_MEMORY, Math.ceil(bytes / 65536));
736
+ }
733
737
  function decodeSabResult(status2, payload) {
734
738
  switch (status2) {
735
739
  case SAB_STATUS_BYTES:
@@ -765,7 +769,7 @@ function sabViews(sab) {
765
769
  window: new Uint8Array(sab, SAB_HEADER_BYTES)
766
770
  };
767
771
  }
768
- 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_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;
772
+ 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_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;
769
773
  var init_sync_sab_wire = __esm({
770
774
  "src/realm/sync-sab-wire.ts"() {
771
775
  "use strict";
@@ -781,6 +785,7 @@ var init_sync_sab_wire = __esm({
781
785
  SAB_I_PUB = 7;
782
786
  SAB_I_SIGNALS = 8;
783
787
  SAB_I_TIMERS = 9;
788
+ SAB_I_MEMORY = 10;
784
789
  SAB_STATE_IDLE = 0;
785
790
  SAB_STATE_PENDING = 1;
786
791
  SAB_STATE_READY = 2;
@@ -817,6 +822,7 @@ function createSyncSabTransport(sab, port, deps = {}) {
817
822
  }
818
823
  return {
819
824
  call(req, timeoutMs, label) {
825
+ if (deps.memory) publishMemory(sab, deps.memory());
820
826
  const id = ++seq;
821
827
  const deadline = now() + timeoutMs;
822
828
  let out = null;
@@ -1916,28 +1922,50 @@ function mountTable() {
1916
1922
  "\n"
1917
1923
  );
1918
1924
  }
1919
- function useMounts(Fs) {
1920
- const { writeFile } = Fs;
1925
+ function accounts(env = {}) {
1926
+ const user = env.USER ?? "web_user";
1927
+ const name = NAME.test(user) && user !== "root" ? user : "user";
1928
+ const home = env.HOME || "/home";
1929
+ return {
1930
+ passwd: `root:x:0:0:root:/root:/bin/sh
1931
+ ${name}:x:1000:1000:${name}:${home}:/bin/bash
1932
+ `,
1933
+ group: `root:x:0:
1934
+ ${name}:x:1000:
1935
+ `
1936
+ };
1937
+ }
1938
+ function useMounts(Fs, env = {}) {
1939
+ const { writeFile, mkdirTree } = Fs;
1921
1940
  if (typeof Fs.open !== "function" || typeof writeFile !== "function") return;
1941
+ const { passwd, group } = accounts(env);
1942
+ const backing = { "/etc/mtab": "/proc/mounts" };
1922
1943
  try {
1923
1944
  writeFile.call(Fs, "/proc/mounts", mountTable());
1924
1945
  } catch {
1925
1946
  return;
1926
1947
  }
1948
+ try {
1949
+ mkdirTree.call(Fs, "/dev/.etc");
1950
+ writeFile.call(Fs, "/dev/.etc/passwd", passwd);
1951
+ writeFile.call(Fs, "/dev/.etc/group", group);
1952
+ backing["/etc/passwd"] = "/dev/.etc/passwd";
1953
+ backing["/etc/group"] = "/dev/.etc/group";
1954
+ } catch {
1955
+ }
1927
1956
  const open = Fs.open.bind(Fs);
1928
1957
  Fs.open = (path, flags, mode) => {
1929
- if (path !== "/etc/mtab" || (flags & (O_ACCMODE | O_CREAT2)) !== 0) {
1930
- return open(path, flags, mode);
1931
- }
1958
+ const instead = backing[path];
1959
+ if (!instead || (flags & (O_ACCMODE | O_CREAT2)) !== 0) return open(path, flags, mode);
1932
1960
  try {
1933
1961
  return open(path, flags, mode);
1934
1962
  } catch (e) {
1935
1963
  if (e?.errno !== wasiErrno("ENOENT")) throw e;
1936
- return open("/proc/mounts", flags, mode);
1964
+ return open(instead, flags, mode);
1937
1965
  }
1938
1966
  };
1939
1967
  }
1940
- var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, DIR_MODE, LINK_MODE, O_ACCMODE, O_CREAT2;
1968
+ var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, DIR_MODE, LINK_MODE, O_ACCMODE, O_CREAT2, NAME;
1941
1969
  var init_process_fds = __esm({
1942
1970
  "src/process/process-fds.ts"() {
1943
1971
  "use strict";
@@ -1965,6 +1993,7 @@ var init_process_fds = __esm({
1965
1993
  LINK_MODE = 41408;
1966
1994
  O_ACCMODE = 3;
1967
1995
  O_CREAT2 = 64;
1996
+ NAME = /^[a-z_][a-z0-9_-]*$/i;
1968
1997
  }
1969
1998
  });
1970
1999
 
@@ -2416,6 +2445,9 @@ function ttyNumber(tty) {
2416
2445
  const vt = tty && /^\/dev\/tty(\d+)$/.exec(tty);
2417
2446
  return vt ? 4 << 8 | Number(vt[1]) : 0;
2418
2447
  }
2448
+ function pages(bytes) {
2449
+ return Math.ceil(bytes / 4096);
2450
+ }
2419
2451
  function ticks(ms) {
2420
2452
  return Math.max(0, Math.floor(ms * HZ / 1e3));
2421
2453
  }
@@ -2443,8 +2475,8 @@ function pidStat(info, boot) {
2443
2475
  1,
2444
2476
  0,
2445
2477
  ticks(info.started - boot),
2446
- 0,
2447
- 0,
2478
+ info.memory,
2479
+ pages(info.memory),
2448
2480
  "18446744073709551615",
2449
2481
  ...Array(12).fill(0),
2450
2482
  17,
@@ -2475,6 +2507,8 @@ function pidStatus(info) {
2475
2507
  `Uid: ${ids}`,
2476
2508
  `Gid: ${ids}`,
2477
2509
  "FDSize: 64",
2510
+ `VmSize: ${Math.ceil(info.memory / KIB)} kB`,
2511
+ `VmRSS: ${Math.ceil(info.memory / KIB)} kB`,
2478
2512
  "Groups: ",
2479
2513
  `NSpid: ${info.pid}`,
2480
2514
  `NSpgid: ${info.pgid}`,
@@ -2494,12 +2528,16 @@ function pidFile(name, info, boot) {
2494
2528
  if (name === "comm") return `${commOf(info)}
2495
2529
  `;
2496
2530
  if (name === "stat") return pidStat(info, boot);
2497
- if (name === "statm") return "0 0 0 0 0 0 0\n";
2531
+ if (name === "statm") {
2532
+ const p = pages(info.memory);
2533
+ return `${p} ${p} 0 0 0 ${p} 0
2534
+ `;
2535
+ }
2498
2536
  return pidStatus(info);
2499
2537
  }
2500
- function memoryInfo(source) {
2538
+ function memoryInfo(source, used = 0) {
2501
2539
  const total = source.deviceMemory ? source.deviceMemory * KIB * KIB * KIB : FALLBACK_MEMORY;
2502
- const free = Math.max(0, total - (source.usedHeap ?? 0));
2540
+ const free = Math.max(0, total - used - (source.usedHeap ?? 0));
2503
2541
  const kb = (bytes) => `${Math.floor(bytes / KIB)} kB`;
2504
2542
  return [
2505
2543
  ["MemTotal", kb(total)],
@@ -2518,7 +2556,12 @@ function systemFile(name, listing, now, memory) {
2518
2556
  const up = Math.max(0, now - listing.boot) / 1e3;
2519
2557
  if (name === "uptime") return `${up.toFixed(2)} ${up.toFixed(2)}
2520
2558
  `;
2521
- if (name === "meminfo") return memoryInfo(memory);
2559
+ if (name === "meminfo") {
2560
+ return memoryInfo(
2561
+ memory,
2562
+ listing.processes.reduce((sum, p) => sum + p.memory, 0)
2563
+ );
2564
+ }
2522
2565
  const live = listing.processes.filter((p) => p.state !== "Z");
2523
2566
  if (name === "loadavg") {
2524
2567
  const last = Math.max(0, ...listing.processes.map((p) => p.pid));
@@ -2869,9 +2912,21 @@ function signalMasks(m) {
2869
2912
  if (!mask || caught === -1) return null;
2870
2913
  return { caught, ignored: mask(1), restart: mask(2) };
2871
2914
  }
2915
+ function reportGrowth(imports, publish) {
2916
+ const env = imports.env;
2917
+ const resize = env?.emscripten_resize_heap;
2918
+ if (!env || typeof resize !== "function") return;
2919
+ env.emscripten_resize_heap = (...args) => {
2920
+ const grown = resize(...args);
2921
+ publish();
2922
+ return grown;
2923
+ };
2924
+ }
2872
2925
  async function runWasmProcess(init, port, deps = {}) {
2873
2926
  const signals = new SignalGate(
2874
- createSyncSabTransport(init.sab, port),
2927
+ createSyncSabTransport(init.sab, port, {
2928
+ memory: () => memory?.buffer.byteLength ?? 0
2929
+ }),
2875
2930
  new Int32Array(init.sab, 0, SAB_HEADER_I32),
2876
2931
  {
2877
2932
  masks: () => signalMasks(module),
@@ -2926,9 +2981,11 @@ async function runWasmProcess(init, port, deps = {}) {
2926
2981
  sys,
2927
2982
  memory: () => memory
2928
2983
  });
2984
+ reportGrowth(imports, () => publishMemory(init.sab, memory?.buffer.byteLength ?? 0));
2929
2985
  return WebAssembly.instantiate(init.program.module, imports);
2930
2986
  }).then((instance) => {
2931
2987
  memory = wasmMemory(instance, imports);
2988
+ publishMemory(init.sab, memory?.buffer.byteLength ?? 0);
2932
2989
  done(instance, init.program.module);
2933
2990
  }, failed2);
2934
2991
  return {};
@@ -2960,6 +3017,8 @@ async function runWasmProcess(init, port, deps = {}) {
2960
3017
  const restartable = () => signals.restartable();
2961
3018
  const streams = new KernelStreams(running.FS, sys, { sigpipe, restartable });
2962
3019
  trackCloseOnExec(running.FS);
3020
+ useMounts(running.FS, init.env);
3021
+ useProcfs(running.FS, sys, init.pid);
2963
3022
  if (init.fork) restoreForkedStreams(running.FS, streams, init.fork.streams ?? []);
2964
3023
  else {
2965
3024
  wireKernelStdio(running.FS, streams);
@@ -2969,8 +3028,6 @@ async function runWasmProcess(init, port, deps = {}) {
2969
3028
  if (pipefs) streams.usePipes(pipefs);
2970
3029
  streams.useControllingTerminal();
2971
3030
  useDevFd(running.FS);
2972
- useMounts(running.FS);
2973
- useProcfs(running.FS, sys, init.pid);
2974
3031
  ownByRealmUser(running.FS);
2975
3032
  const livePath = (s) => liveNodePath(s.node);
2976
3033
  running.sliccKernel = createProcessKernel({
@@ -5214,8 +5271,8 @@ function align(n, to) {
5214
5271
  return Math.ceil(n / to) * to;
5215
5272
  }
5216
5273
  function growTo(memory, bytes) {
5217
- const pages = Math.ceil(bytes / PAGE) - memory.buffer.byteLength / PAGE;
5218
- if (pages > 0) memory.grow(pages);
5274
+ const pages2 = Math.ceil(bytes / PAGE) - memory.buffer.byteLength / PAGE;
5275
+ if (pages2 > 0) memory.grow(pages2);
5219
5276
  }
5220
5277
  function growTable(table, length) {
5221
5278
  if (table.length < length) table.grow(length - table.length);
@@ -6442,14 +6499,20 @@ function restoreExportedMemory(instance, imported, init) {
6442
6499
  fillMemory(instance.exports.memory, init.fork.memory);
6443
6500
  }
6444
6501
  function fillMemory(memory, copy) {
6445
- const pages = copy.byteLength / 65536 - memory.buffer.byteLength / 65536;
6446
- if (pages > 0) memory.grow(pages);
6502
+ const pages2 = copy.byteLength / 65536 - memory.buffer.byteLength / 65536;
6503
+ if (pages2 > 0) memory.grow(pages2);
6447
6504
  new Uint8Array(memory.buffer).set(copy);
6448
6505
  }
6506
+ function sizeOf(main) {
6507
+ return () => main.memory?.buffer.byteLength ?? 0;
6508
+ }
6509
+ function memoryOf(instance, imported) {
6510
+ return imported ?? instance.exports.memory;
6511
+ }
6449
6512
  function kernelOf(init, port, hooks = { masks: () => null, raise: () => {
6450
- } }) {
6513
+ } }, memory) {
6451
6514
  const transport = new SignalGate(
6452
- createSyncSabTransport(init.sab, port),
6515
+ createSyncSabTransport(init.sab, port, memory ? { memory } : {}),
6453
6516
  new Int32Array(init.sab, 0, SAB_HEADER_I32),
6454
6517
  hooks
6455
6518
  ).transport();
@@ -6562,7 +6625,8 @@ async function runWasiProcess(init, port) {
6562
6625
  call2({ op: "proc-kill", pid: init.pid, sig });
6563
6626
  throw new WasiExit(128 + sig);
6564
6627
  });
6565
- const { transport, sys, call: kernelCall, say } = kernelOf(init, port, signals);
6628
+ const main = {};
6629
+ const { transport, sys, call: kernelCall, say } = kernelOf(init, port, signals, sizeOf(main));
6566
6630
  const stats = init.env.SLICC_WASI_STATS === "1" ? new WasiStats() : void 0;
6567
6631
  const call2 = stats ? timedCalls(stats, kernelCall) : kernelCall;
6568
6632
  const { module } = init.program;
@@ -6602,6 +6666,8 @@ async function runWasiProcess(init, port) {
6602
6666
  ...program ? { program } : {}
6603
6667
  });
6604
6668
  restoreExportedMemory(instance, memory, init);
6669
+ main.memory = memoryOf(instance, memory);
6670
+ publishMemory(init.sab, sizeOf(main)());
6605
6671
  signals.bind(instance.exports);
6606
6672
  host.onRaise = (sig) => signals.raised(sig);
6607
6673
  const exports = instance.exports;