@ai-ecoverse/slicc-kernel 1.6.0 → 1.6.1

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.
@@ -469,7 +469,7 @@ function createLiveVfsPlugin(Fs) {
469
469
  };
470
470
  }
471
471
  function ownedBy(plugin, node) {
472
- return !!node && plugin.mounts.has(node.mount);
472
+ return !!node?.live && plugin.mounts.has(node.mount);
473
473
  }
474
474
  function flushLiveVfs(Fs, plugin) {
475
475
  for (const head of Fs.nameTable ?? []) {
@@ -495,7 +495,7 @@ function invalidateLiveVfs(Fs, plugin) {
495
495
  s.stat = void 0;
496
496
  s.listed = void 0;
497
497
  if (s.openCount === 0) {
498
- if (node !== node.mount.root) drop.push(node);
498
+ if (node !== node.mount.root && !node.mounted) drop.push(node);
499
499
  } else if (s.loaded && !s.dirty) {
500
500
  s.data = void 0;
501
501
  s.len = 0;
@@ -516,6 +516,7 @@ function describeMountError(err) {
516
516
  return typeof errno2 === "number" ? `errno ${errno2}` : String(err);
517
517
  }
518
518
  function mountLiveVfsDirs(Fs, bridge, dirs, warn) {
519
+ if (Fs.root?.memfs) Fs.root.node_ops = Fs.root.memfs;
519
520
  if (typeof Fs.filesystems !== "object" || !Fs.filesystems) {
520
521
  throw new Error(
521
522
  "the module was linked without filesystem support, so the VFS cannot be mounted (link it with -sFORCE_FILESYSTEM=1)"
@@ -536,6 +537,55 @@ function mountLiveVfsDirs(Fs, bridge, dirs, warn) {
536
537
  }
537
538
  return { plugin, mounted };
538
539
  }
540
+ function liveRoot(Fs, bridge) {
541
+ const root = Fs.root;
542
+ const plugin = Fs.filesystems.SLICC_LIVE_FS;
543
+ if (!root || !plugin) return;
544
+ root.mount.opts = { root: "/", bridge };
545
+ root.live = { len: 0, loaded: false, dirty: false, openCount: 0 };
546
+ plugin.mounts.add(root.mount);
547
+ invalidateLiveVfs(Fs, plugin);
548
+ guardRenames(Fs);
549
+ const memfs = root.memfs ?? root.node_ops;
550
+ const live = plugin.node_ops;
551
+ root.memfs = memfs;
552
+ const own = (name) => Object.hasOwn(root.contents ?? {}, name);
553
+ root.node_ops = {
554
+ ...memfs,
555
+ lookup: (parent, name) => live.lookup(parent, name),
556
+ mknod: (parent, name, mode, dev) => live.mknod(parent, name, mode, dev),
557
+ unlink: (parent, name) => live.unlink(parent, name),
558
+ rmdir: (parent, name) => (own(name) ? memfs : live).rmdir(parent, name),
559
+ symlink: (parent, name, target) => live.symlink(parent, name, target),
560
+ rename: (node, dir, name) => (node.live ? live : memfs).rename(node, dir, name),
561
+ readdir(node) {
562
+ const names = new Set(memfs.readdir(node));
563
+ for (const name of live.readdir(node)) names.add(name);
564
+ return [...names];
565
+ }
566
+ };
567
+ }
568
+ function crosses(Fs, from, to) {
569
+ const parentOf = (path) => Fs.lookupPath?.(path, { parent: true }).node;
570
+ const name = from.replace(/\/+$/, "").split("/").pop() ?? "";
571
+ try {
572
+ const fromDir = parentOf(from);
573
+ const node = fromDir && Fs.lookupNode?.(fromDir, name);
574
+ const dir = parentOf(to);
575
+ return !!node && !!dir && !!node.live !== !!dir.live;
576
+ } catch {
577
+ return false;
578
+ }
579
+ }
580
+ function guardRenames(Fs) {
581
+ const rename = Fs.rename?.bind(Fs);
582
+ if (!rename || Fs.sliccRename) return;
583
+ Fs.sliccRename = true;
584
+ Fs.rename = (from, to) => {
585
+ if (crosses(Fs, from, to)) throw new Fs.ErrnoError(ERRNO_BY_CODE.EXDEV);
586
+ rename(from, to);
587
+ };
588
+ }
539
589
  var ERRNO_BY_CODE, EIO, S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END;
540
590
  var init_live_vfs_fs = __esm({
541
591
  "src/realm/live-vfs-fs.ts"() {
@@ -580,7 +630,7 @@ function topLevelDirs(bridge, warn) {
580
630
  names = bridge.readdir("/");
581
631
  } catch (err) {
582
632
  warn(`cannot list the VFS root, nothing mounted: ${String(err)}`);
583
- return [];
633
+ return void 0;
584
634
  }
585
635
  const candidates = names.filter((name) => name && !name.includes("/") && !MODULE_OWNED_DIRS.has(name)).map((name) => `/${name}`);
586
636
  for (const dir of SYNTHETIC_DIRS) if (!candidates.includes(dir)) candidates.push(dir);
@@ -595,7 +645,9 @@ function topLevelDirs(bridge, warn) {
595
645
  }
596
646
  function mountVfsIntoEmscripten(Fs, deps) {
597
647
  const { bridge, warn } = deps;
598
- const { plugin, mounted } = mountLiveVfsDirs(Fs, bridge, topLevelDirs(bridge, warn), warn);
648
+ const dirs = topLevelDirs(bridge, warn);
649
+ const { plugin, mounted } = mountLiveVfsDirs(Fs, bridge, dirs ?? [], warn);
650
+ if (dirs) liveRoot(Fs, bridge);
599
651
  try {
600
652
  Fs.chdir(deps.cwd);
601
653
  } catch (err) {
@@ -1626,6 +1678,28 @@ function wrapCloexecSyscalls(imports, glue, deps) {
1626
1678
  }
1627
1679
  }
1628
1680
  }
1681
+ function persistsItself(stream) {
1682
+ const type = stream.node.mount?.type;
1683
+ return typeof type?.syncfs === "function";
1684
+ }
1685
+ function syncFsync(imports, fs) {
1686
+ for (const namespace of Object.values(imports)) {
1687
+ const original = namespace?.fd_sync;
1688
+ if (typeof original !== "function" || !original.isAsync) continue;
1689
+ namespace.fd_sync = (fd) => {
1690
+ const stream = fs()?.getStream(fd);
1691
+ if (!stream) return EBADF;
1692
+ if (persistsItself(stream)) return original(fd);
1693
+ try {
1694
+ const result = stream.stream_ops.fsync?.(stream);
1695
+ return typeof result === "number" ? result : 0;
1696
+ } catch (err) {
1697
+ const { errno: errno2, code: code2 } = err;
1698
+ return typeof errno2 === "number" ? errno2 : wasiErrno(String(code2));
1699
+ }
1700
+ };
1701
+ }
1702
+ }
1629
1703
  function wasmMemory(instance, imports) {
1630
1704
  const isMemory = (v) => v instanceof WebAssembly.Memory;
1631
1705
  const exported = Object.values(instance.exports).find(isMemory);
@@ -1720,7 +1794,7 @@ function useDevFd(Fs) {
1720
1794
  return fstat.call(Fs, fd);
1721
1795
  };
1722
1796
  }
1723
- var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, DIR_MODE, LINK_MODE;
1797
+ var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, DIR_MODE, LINK_MODE;
1724
1798
  var init_process_fds = __esm({
1725
1799
  "src/process/process-fds.ts"() {
1726
1800
  "use strict";
@@ -1743,6 +1817,7 @@ var init_process_fds = __esm({
1743
1817
  ioctl: "__syscall_ioctl",
1744
1818
  setitimer: "_setitimer_js"
1745
1819
  };
1820
+ EBADF = 8;
1746
1821
  DIR_MODE = 16749;
1747
1822
  LINK_MODE = 41408;
1748
1823
  }
@@ -2403,6 +2478,7 @@ async function runWasmProcess(init, port, deps = {}) {
2403
2478
  }
2404
2479
  }
2405
2480
  });
2481
+ syncFsync(imports, () => ownValue(module, "FS"));
2406
2482
  return WebAssembly.instantiate(init.program.module, imports);
2407
2483
  }).then((instance) => {
2408
2484
  memory = wasmMemory(instance, imports);