@ai-ecoverse/slicc-kernel 1.16.0 → 1.17.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.
@@ -211,6 +211,7 @@ function createHelpers(Fs, ops) {
211
211
  }
212
212
  function truncate(node, size) {
213
213
  const s = node.live;
214
+ if (!s.orphan && statOf(node).readonly) throw new Fs.ErrnoError(ERRNO_BY_CODE.EROFS);
214
215
  if (s.openCount > 0) {
215
216
  if (size > 0) ensureLoaded(node);
216
217
  else s.loaded = true;
@@ -399,6 +400,14 @@ function createStreamOps(h) {
399
400
  return {
400
401
  open(stream) {
401
402
  if (!Fs.isFile(stream.node.mode)) return;
403
+ if ((stream.flags & 3) !== 0) {
404
+ try {
405
+ if (statOf(stream.node).readonly) throw new Fs.ErrnoError(ERRNO_BY_CODE.EROFS);
406
+ } catch (err) {
407
+ if (stream.fd !== void 0) Fs.closeStream?.(stream.fd);
408
+ throw err;
409
+ }
410
+ }
402
411
  stream.node.live.openCount++;
403
412
  held(stream, 1);
404
413
  },
@@ -741,7 +750,8 @@ function parseSyncFsStat(json) {
741
750
  ...typeof s.atimeMs === "number" ? { atimeMs: s.atimeMs } : {},
742
751
  ...typeof s.ctimeMs === "number" ? { ctimeMs: s.ctimeMs } : {},
743
752
  ...typeof s.ino === "number" ? { ino: s.ino } : {},
744
- ...typeof s.dev === "number" ? { dev: s.dev } : {}
753
+ ...typeof s.dev === "number" ? { dev: s.dev } : {},
754
+ ...s.readonly === true ? { readonly: true } : {}
745
755
  };
746
756
  }
747
757
  var SYNC_FS_REQUEST_TIMEOUT_MS;
@@ -1010,22 +1020,29 @@ var init_wasi_errno = __esm({
1010
1020
  EPROTONOSUPPORT: 66,
1011
1021
  EOPNOTSUPP: 138,
1012
1022
  EBADF: 8,
1023
+ EBUSY: 10,
1013
1024
  ECHILD: 12,
1014
1025
  EFAULT: 21,
1015
1026
  EINTR: 27,
1016
1027
  EINVAL: 28,
1017
1028
  EIO: 29,
1018
1029
  EMFILE: 33,
1030
+ ENODEV: 43,
1019
1031
  ENOENT: 44,
1020
1032
  ENOEXEC: 45,
1021
1033
  ENOSYS: 52,
1034
+ ENOTDIR: 54,
1022
1035
  ENOTTY: 59,
1023
1036
  ENXIO: 60,
1024
1037
  EPERM: 63,
1025
1038
  EPIPE: 64,
1026
1039
  ESPIPE: 70,
1027
1040
  ESRCH: 71,
1028
- ETIMEDOUT: 73
1041
+ ETIMEDOUT: 73,
1042
+ EFBIG: 22,
1043
+ ENOSPC: 51,
1044
+ EROFS: 69,
1045
+ ENOMEDIUM: 148
1029
1046
  };
1030
1047
  EIO2 = 29;
1031
1048
  }
@@ -1378,6 +1395,16 @@ function number(r) {
1378
1395
  if (!r.ok) return -wasiErrno(r.errno);
1379
1396
  return r.kind === "json" && typeof r.json === "number" ? r.json : -wasiErrno("EIO");
1380
1397
  }
1398
+ function flushed(beforeSpawn) {
1399
+ try {
1400
+ beforeSpawn();
1401
+ return 0;
1402
+ } catch (err) {
1403
+ const errno2 = err?.errno;
1404
+ if (typeof errno2 !== "number") throw err;
1405
+ return -errno2;
1406
+ }
1407
+ }
1381
1408
  function drain(Fs, stream) {
1382
1409
  const chunks = [];
1383
1410
  const buffer = new Uint8Array(65536);
@@ -1423,6 +1450,7 @@ function createProcessKernel(deps) {
1423
1450
  const { transport, Fs } = deps;
1424
1451
  const reaped = /* @__PURE__ */ new Map();
1425
1452
  const call2 = (req, label) => transport.call(req, Infinity, label);
1453
+ const at = (path) => path === "" || path.startsWith("/") ? path : `${Fs.cwd()}/${path}`;
1426
1454
  const slot = (fd, n, promote) => {
1427
1455
  const stream = fd >= 0 ? Fs.getStream(fd) : null;
1428
1456
  if (!stream) return { none: true };
@@ -1461,7 +1489,8 @@ function createProcessKernel(deps) {
1461
1489
  };
1462
1490
  return {
1463
1491
  spawn(file, argv, env, cwd, fds, actions) {
1464
- deps.beforeSpawn();
1492
+ const unflushed = flushed(deps.beforeSpawn);
1493
+ if (unflushed < 0) return unflushed;
1465
1494
  const promote = deps.stdioPromoter?.();
1466
1495
  const stdio = [0, 1, 2].map((n) => slot(fds[n] ?? -1, n, promote));
1467
1496
  const inherit = deps.inherit?.(actions) ?? [];
@@ -1489,7 +1518,8 @@ function createProcessKernel(deps) {
1489
1518
  return pid;
1490
1519
  },
1491
1520
  fork(state) {
1492
- deps.beforeSpawn();
1521
+ const unflushed = flushed(deps.beforeSpawn);
1522
+ if (unflushed < 0) return unflushed;
1493
1523
  const streams = deps.describeFork();
1494
1524
  const r = transport.call(
1495
1525
  { op: "proc-fork", state: { ...state, streams, cwd: Fs.cwd() } },
@@ -1528,6 +1558,13 @@ function createProcessKernel(deps) {
1528
1558
  pause() {
1529
1559
  return status(call2({ op: "sig-pause" }, "pause"));
1530
1560
  },
1561
+ mount(source, target, type, flags, data) {
1562
+ const req = { op: "mount", source, target: at(target), type, flags, data };
1563
+ return status(call2(req, `mount ${target}`));
1564
+ },
1565
+ umount2(target, flags) {
1566
+ return status(call2({ op: "umount", target: at(target), flags }, `umount ${target}`));
1567
+ },
1531
1568
  kill(pid, sig) {
1532
1569
  if (pid === deps.pid) {
1533
1570
  if (sig !== 0) deps.raise?.(sig);
@@ -1947,6 +1984,7 @@ function mountTable(mounts = []) {
1947
1984
  const lines = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
1948
1985
  for (const m of mounts) {
1949
1986
  const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
1987
+ if (m.state !== "ok") options.push(m.state);
1950
1988
  const access = options.includes("ro") ? [] : ["rw"];
1951
1989
  lines.push(
1952
1990
  `${field(m.source)} ${field(m.target)} ${m.type} ${[...access, ...options].join(",")} 0 0`
@@ -3056,6 +3094,7 @@ async function runWasmProcess(init, port, deps = {}) {
3056
3094
  const restartable = () => signals.restartable();
3057
3095
  const streams = new KernelStreams(running.FS, sys, { sigpipe, restartable });
3058
3096
  trackCloseOnExec(running.FS);
3097
+ quietQuit(running.FS);
3059
3098
  useMounts(running.FS, init.env, true);
3060
3099
  useProcfs(running.FS, sys, init.pid);
3061
3100
  if (init.fork) restoreForkedStreams(running.FS, streams, init.fork.streams ?? []);
@@ -3094,9 +3133,29 @@ async function runWasmProcess(init, port, deps = {}) {
3094
3133
  try {
3095
3134
  return runMain(running, init);
3096
3135
  } finally {
3097
- vfs.flush();
3136
+ try {
3137
+ vfs.flush();
3138
+ } catch {
3139
+ }
3098
3140
  }
3099
3141
  }
3142
+ function quietQuit(Fs) {
3143
+ const { quit, close } = Fs;
3144
+ if (!quit) return;
3145
+ Fs.quit = () => {
3146
+ Fs.close = (stream) => {
3147
+ try {
3148
+ close.call(Fs, stream);
3149
+ } catch {
3150
+ }
3151
+ };
3152
+ try {
3153
+ quit.call(Fs);
3154
+ } finally {
3155
+ Fs.close = close;
3156
+ }
3157
+ };
3158
+ }
3100
3159
  function hasStreams(module) {
3101
3160
  return typeof ownValue(module, "FS")?.getStream === "function";
3102
3161
  }
@@ -3624,6 +3683,13 @@ function entryOf(info) {
3624
3683
  append: ((info.flags ?? 0) & O_APPEND) !== 0
3625
3684
  };
3626
3685
  }
3686
+ function openAccess(existing, oflags, rights) {
3687
+ const readonly = existing?.readonly === true;
3688
+ const mutating = readonly ? OFLAGS.TRUNC : OFLAGS.CREAT | OFLAGS.TRUNC;
3689
+ const writable = (rights & RIGHTS.FD_WRITE) !== 0n || (oflags & mutating) !== 0;
3690
+ if (writable && readonly) throw new WasiError("EROFS");
3691
+ return { readable: (rights & RIGHTS.FD_READ) !== 0n || !writable, writable };
3692
+ }
3627
3693
  function promoteRequest(fd, f, handed) {
3628
3694
  const orphan = f.buffer.isOrphan();
3629
3695
  const joins = !orphan && handed.has(f.buffer);
@@ -4022,8 +4088,7 @@ var init_wasi_fds = __esm({
4022
4088
  return this.install({ type: "file", file: this.file(path, s, oflags, rights, fdflags) });
4023
4089
  }
4024
4090
  file(path, existing, oflags, rights, fdflags) {
4025
- const writable = (rights & RIGHTS.FD_WRITE) !== 0n || (oflags & (OFLAGS.CREAT | OFLAGS.TRUNC)) !== 0;
4026
- const readable = (rights & RIGHTS.FD_READ) !== 0n || !writable;
4091
+ const { readable, writable } = openAccess(existing, oflags, rights);
4027
4092
  let buffer = this.buffers.get(path);
4028
4093
  if (buffer) {
4029
4094
  if (oflags & OFLAGS.TRUNC) buffer.truncate(0);
@@ -4036,8 +4101,7 @@ var init_wasi_fds = __esm({
4036
4101
  return new LocalFile(buffer, readable, writable, (fdflags & FDFLAGS.APPEND) !== 0);
4037
4102
  }
4038
4103
  kernelFile(path, existing, oflags, rights, fdflags) {
4039
- const writable = (rights & RIGHTS.FD_WRITE) !== 0n || (oflags & (OFLAGS.CREAT | OFLAGS.TRUNC)) !== 0;
4040
- const readable = (rights & RIGHTS.FD_READ) !== 0n || !writable;
4104
+ const { readable, writable } = openAccess(existing, oflags, rights);
4041
4105
  const append = (fdflags & FDFLAGS.APPEND) !== 0;
4042
4106
  const flags = (writable ? readable ? O_RDWR4 : O_WRONLY3 : 0) | (append ? O_APPEND : 0);
4043
4107
  if (!existing) this.fs.writeFile(path, new Uint8Array(0));
@@ -4362,6 +4426,24 @@ var init_wasi_host = __esm({
4362
4426
  get cwd() {
4363
4427
  return this.fds.cwd() ?? this.startCwd;
4364
4428
  }
4429
+ sliccImports() {
4430
+ const { mem } = this;
4431
+ const path = (p, l) => {
4432
+ const text = mem.string(p, l);
4433
+ return text === "" || text.startsWith("/") ? text : normalize(`${this.cwd}/${text}`);
4434
+ };
4435
+ return wrap({
4436
+ mount: (sp, sl, tp, tl, fp, fl, flags, dp, dl) => void this.o.kernel.call({
4437
+ op: "mount",
4438
+ source: mem.string(sp, sl),
4439
+ target: path(tp, tl),
4440
+ type: mem.string(fp, fl),
4441
+ flags,
4442
+ data: mem.string(dp, dl)
4443
+ }),
4444
+ umount2: (tp, tl, flags) => void this.o.kernel.call({ op: "umount", target: path(tp, tl), flags })
4445
+ });
4446
+ }
4365
4447
  imports() {
4366
4448
  this.cache ??= wrap({
4367
4449
  ...this.processImports(),
@@ -4450,7 +4532,7 @@ var init_wasi_host = __esm({
4450
4532
  fd_datasync: (fd) => void this.sync(fd),
4451
4533
  fd_advise: (fd) => void fds.get(fd),
4452
4534
  fd_allocate: (fd, offset, len) => {
4453
- const file = this.positional(fd);
4535
+ const file = this.positional(fd, "write");
4454
4536
  const end = Number(offset + len);
4455
4537
  if (end > file.size()) file.truncate(end);
4456
4538
  }
@@ -4463,7 +4545,7 @@ var init_wasi_host = __esm({
4463
4545
  fd_fdstat_set_flags: (fd, flags) => void fds.setFlags(fd, (flags & FDFLAGS.NONBLOCK) !== 0, (flags & FDFLAGS.APPEND) !== 0),
4464
4546
  fd_fdstat_set_rights: (fd) => void fds.get(fd),
4465
4547
  fd_filestat_get: (fd, out) => void this.writeFilestat(out, this.fdFilestat(fd)),
4466
- fd_filestat_set_size: (fd, size) => void this.positional(fd).truncate(Number(size)),
4548
+ fd_filestat_set_size: (fd, size) => void this.positional(fd, "write").truncate(Number(size)),
4467
4549
  fd_filestat_set_times: (fd, atim, mtim, flags) => {
4468
4550
  const e = fds.get(fd);
4469
4551
  if (e.type === "file") {
@@ -6497,12 +6579,14 @@ function unsupportedImport(module, memory, extended = false, foreign = {}) {
6497
6579
  }
6498
6580
  return void 0;
6499
6581
  }
6500
- function linkImports(module, preview1, wasix, memory, threads, program = {}, foreign) {
6582
+ function linkImports(module, preview1, wasix, memory, threads, program = {}, foreign, slicc = {}) {
6501
6583
  for (const ns of Object.keys(program)) {
6502
- if (RESERVED.has(ns)) throw new Error(`the imports module may not define ${ns}`);
6584
+ if (RESERVED.has(ns) || ns === SLICC)
6585
+ throw new Error(`the imports module may not define ${ns}`);
6503
6586
  }
6504
6587
  const imports = {
6505
6588
  ...program,
6589
+ [SLICC]: { ...slicc },
6506
6590
  [PREVIEW1]: preview1,
6507
6591
  ...wasix ? { [WASIX]: { ...wasix } } : {},
6508
6592
  ...threads ? { wasi: { "thread-spawn": (arg) => threads.spawn(arg) } } : {}
@@ -6628,7 +6712,8 @@ async function instantiate(host, module, memory, threads, {
6628
6712
  () => memory ?? instance?.exports.memory,
6629
6713
  () => instance
6630
6714
  );
6631
- const hostImports = linkImports(module, preview1, wasix, memory, threads, extra, foreign);
6715
+ const slicc = traced(stats, "slicc", host.sliccImports());
6716
+ const hostImports = linkImports(module, preview1, wasix, memory, threads, extra, foreign, slicc);
6632
6717
  const imports = sync ? merge(hostImports, sync.linker.mainImports(module)) : hostImports;
6633
6718
  instance = await WebAssembly.instantiate(module, imports);
6634
6719
  stats?.phase("instantiate");
@@ -6804,7 +6889,7 @@ async function runWasiThread(init, port) {
6804
6889
  throw e;
6805
6890
  }
6806
6891
  }
6807
- var TRAPPED, PREVIEW1, WASIX, RESERVED, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
6892
+ var TRAPPED, PREVIEW1, WASIX, SLICC, RESERVED, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
6808
6893
  var init_wasi_runtime = __esm({
6809
6894
  "src/process/wasi/wasi-runtime.ts"() {
6810
6895
  "use strict";
@@ -6829,6 +6914,7 @@ var init_wasi_runtime = __esm({
6829
6914
  TRAPPED = 134;
6830
6915
  PREVIEW1 = "wasi_snapshot_preview1";
6831
6916
  WASIX = "wasix_32v1";
6917
+ SLICC = "slicc";
6832
6918
  RESERVED = RESERVED_NAMESPACES;
6833
6919
  noErrno = (key) => `imports ${key}: its result cannot carry ENOSYS, and this host does not provide it`;
6834
6920
  FALLBACK_MAXIMUM_PAGES = 32768;