@ai-ecoverse/slicc-kernel 1.146.2 → 1.146.4

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.
@@ -657,6 +657,10 @@ var init_ranged = __esm({
657
657
  pin() {
658
658
  this.pinned = true;
659
659
  this.pages.pin();
660
+ this.prefetch();
661
+ }
662
+ prefetch() {
663
+ this.fresh();
660
664
  this.fetch(this.pages.missing(0, this.pages.length));
661
665
  }
662
666
  reset(size) {
@@ -1095,6 +1099,7 @@ var init_wasi_files = __esm({
1095
1099
  maxFile;
1096
1100
  handle;
1097
1101
  moved;
1102
+ bound;
1098
1103
  constructor(fs, path, empty, maxFile, size, version, watch) {
1099
1104
  this.fs = fs;
1100
1105
  this.where = path;
@@ -1141,6 +1146,10 @@ var init_wasi_files = __esm({
1141
1146
  if (this.ranged) this.ranged.pin();
1142
1147
  else this.load();
1143
1148
  }
1149
+ prefetch() {
1150
+ if (this.ranged) this.ranged.prefetch();
1151
+ else this.load();
1152
+ }
1144
1153
  load() {
1145
1154
  const view = this.watch?.view;
1146
1155
  if (this.data && view && this.watch && !this.dirty) {
@@ -2062,6 +2071,9 @@ function errnoError(code2, path, direct) {
2062
2071
  const err = syncError(code2, `sync-sab bridge, '${path}'`);
2063
2072
  return direct ? Object.assign(err, { direct }) : err;
2064
2073
  }
2074
+ function holdSeen(seen) {
2075
+ return { gen: seen.gen, ino: seen.ino, ...seen.nofollow ? { nofollow: true } : {} };
2076
+ }
2065
2077
  function createSyncFsSabBridge(transport, opts = {}) {
2066
2078
  const direct = opts.direct ? { direct: true } : {};
2067
2079
  const timeoutMs2 = opts.timeoutMs ?? SYNC_FS_REQUEST_TIMEOUT_MS;
@@ -2234,9 +2246,7 @@ function createSyncFsSabBridge(transport, opts = {}) {
2234
2246
  hold: (path, held2, open, handle, want = 0, seen = {}) => {
2235
2247
  const mode = (held2 ? 1 : 0) | (open ? 2 : 0);
2236
2248
  if (mode === 3) {
2237
- const at = seen.gen !== void 0 ? { gen: seen.gen } : {};
2238
- const link = seen.nofollow ? { nofollow: true } : {};
2239
- return json2({ op: "hold", path, mode: mode | want, ...at, ...link }, path);
2249
+ return json2({ op: "hold", path, mode: mode | want, ...holdSeen(seen) }, path);
2240
2250
  }
2241
2251
  run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
2242
2252
  return void 0;
@@ -3923,6 +3933,15 @@ var init_wasi_fds = __esm({
3923
3933
  for (const p of this.buffers.keys()) if (within(p, path)) return true;
3924
3934
  return false;
3925
3935
  }
3936
+ replacing(path) {
3937
+ for (const [p, buffer] of this.buffers) {
3938
+ if (!within(p, path)) continue;
3939
+ try {
3940
+ buffer.prefetch();
3941
+ } catch {
3942
+ }
3943
+ }
3944
+ }
3926
3945
  unlinking(path, linked) {
3927
3946
  const buffer = this.buffers.get(path);
3928
3947
  if (buffer && this.survives(buffer, linked)) buffer.flush();
@@ -4059,10 +4078,9 @@ var init_wasi_fds = __esm({
4059
4078
  if (exclusive && !(oflags & OFLAGS.DIRECTORY) && this.madeAtOnce(path, mode)) {
4060
4079
  return this.regular(path, void 0, oflags, rights, fdflags, mode, true);
4061
4080
  }
4062
- if ((exclusive || nofollow) && this.isLink(path)) {
4063
- throw new WasiError(exclusive ? "EEXIST" : "ELOOP");
4064
- }
4065
- const s = this.statOrMissing(path);
4081
+ if (exclusive && !nofollow && this.isLink(path)) throw new WasiError("EEXIST");
4082
+ const s = nofollow ? this.lstatOrMissing(path) : this.statOrMissing(path);
4083
+ if (s?.isSymbolicLink) throw new WasiError(exclusive ? "EEXIST" : "ELOOP");
4066
4084
  if (exclusive && s) throw new WasiError("EEXIST");
4067
4085
  if (s?.escape !== void 0) {
4068
4086
  refuseWrite({ readonly: true }, oflags, rights);
@@ -4081,6 +4099,11 @@ var init_wasi_fds = __esm({
4081
4099
  return this.regular(path, s, oflags, rights, fdflags, mode);
4082
4100
  }
4083
4101
  nofollow = false;
4102
+ inos = /* @__PURE__ */ new WeakMap();
4103
+ otherFile(buffer, st) {
4104
+ const ino = this.inos.get(buffer);
4105
+ return ino !== void 0 && st?.ino !== void 0 && ino !== st.ino;
4106
+ }
4084
4107
  openSpecial(path, oflags, rights, fdflags, exclusive) {
4085
4108
  if (exclusive && namedDevice(path)) throw new WasiError("EEXIST");
4086
4109
  const device2 = deviceOf(path);
@@ -4138,6 +4161,7 @@ var init_wasi_fds = __esm({
4138
4161
  buffer = void 0;
4139
4162
  }
4140
4163
  buffer ??= this.sharing(path, existing);
4164
+ if (buffer && this.nofollow && this.otherFile(buffer, existing)) buffer = void 0;
4141
4165
  const want = wantOf(oflags, rights);
4142
4166
  if (buffer) {
4143
4167
  if (this.fs.owners) this.fs.access?.(path, want, "open");
@@ -4162,7 +4186,8 @@ var init_wasi_fds = __esm({
4162
4186
  const asked = (want & 4 ? HOLD_READ : 0) | (want & 2 ? HOLD_WRITE : 0) | (made ? HOLD_CREATED : 0);
4163
4187
  const handle = this.fs.hold?.(path, true, true, void 0, this.fs.owners ? asked : 0, {
4164
4188
  gen: st.gen,
4165
- ...this.nofollow ? { nofollow: true } : {}
4189
+ ...this.nofollow ? { nofollow: true } : {},
4190
+ ...st.ino !== void 0 ? { ino: st.ino } : {}
4166
4191
  });
4167
4192
  const io = handle !== void 0 && this.fs.pinned ? this.fs.pinned(handle) : this.fs;
4168
4193
  const view = this.fs.changes;
@@ -4181,7 +4206,9 @@ var init_wasi_fds = __esm({
4181
4206
  );
4182
4207
  const buffer = new FileBuffer(io, path, empty, st.maxFile, ranged, st.version, watch);
4183
4208
  buffer.moved = (missing2) => this.followRenames(missing2);
4209
+ buffer.bound = st;
4184
4210
  buffer.handle = handle;
4211
+ if (st.ino !== void 0) this.inos.set(buffer, st.ino);
4185
4212
  this.buffers.set(path, buffer);
4186
4213
  const id = this.identity(st);
4187
4214
  if (id !== void 0) this.know(buffer, id);
@@ -4264,6 +4291,14 @@ var init_wasi_fds = __esm({
4264
4291
  return false;
4265
4292
  }
4266
4293
  }
4294
+ lstatOrMissing(path) {
4295
+ try {
4296
+ return this.fs.lstat(path);
4297
+ } catch (e) {
4298
+ if (e.code === "ENOENT") return void 0;
4299
+ throw e;
4300
+ }
4301
+ }
4267
4302
  statOrMissing(path) {
4268
4303
  try {
4269
4304
  return this.fs.stat(path);
@@ -5987,6 +6022,7 @@ var init_wasi_host = __esm({
5987
6022
  const to = at(fd2, p2, l2);
5988
6023
  fds.flushPath(from);
5989
6024
  const replaced = fds.holdsUnder(to) ? linkedElsewhere(o.fs, to) : void 0;
6025
+ if (replaced === void 0) fds.replacing(to);
5990
6026
  const seq = o.fs.rename(from, to);
5991
6027
  fds.renamed(from, to, replaced);
5992
6028
  fds.ownRename(typeof seq === "number" ? seq : void 0);
@@ -6287,13 +6323,21 @@ var init_wasi_host = __esm({
6287
6323
  }
6288
6324
  localFilestat(file) {
6289
6325
  const { buffer } = file;
6290
- if (buffer.isOrphan()) return this.statOrphanable(file.path, file.size(), false, true);
6326
+ if (buffer.isOrphan()) {
6327
+ const bound2 = buffer.bound;
6328
+ if (!bound2) return this.statOrphanable(file.path, file.size(), false, true);
6329
+ return { ...this.sized(file.path, bound2, file.size()), nlink: 0n };
6330
+ }
6291
6331
  let s;
6292
6332
  try {
6293
6333
  s = this.o.fs.stat(file.path);
6294
6334
  } catch {
6295
6335
  s = this.keptStat(buffer.handle);
6296
6336
  }
6337
+ const bound = buffer.bound;
6338
+ if (s && bound?.ino !== void 0 && s.ino !== bound.ino) {
6339
+ s = this.keptStat(buffer.handle) ?? bound;
6340
+ }
6297
6341
  return this.sized(file.path, s, file.size());
6298
6342
  }
6299
6343
  keptStat(handle) {
@@ -7112,7 +7156,7 @@ var KERNEL_VERSION, OS_RELEASE;
7112
7156
  var init_version = __esm({
7113
7157
  "src/version.ts"() {
7114
7158
  "use strict";
7115
- KERNEL_VERSION = true ? "1.146.2" : "0.0.0-dev";
7159
+ KERNEL_VERSION = true ? "1.146.4" : "0.0.0-dev";
7116
7160
  OS_RELEASE = "6.0.0-slicc";
7117
7161
  }
7118
7162
  });
@@ -8540,6 +8584,7 @@ function renameFollower(Fs, bridgeOf, call2) {
8540
8584
  open,
8541
8585
  follow: follow3,
8542
8586
  track(node, on) {
8587
+ node.live.bound = on && node.live.stat?.ino !== void 0 ? node.live.stat : void 0;
8543
8588
  if (!on) {
8544
8589
  open.delete(node);
8545
8590
  return;
@@ -8565,6 +8610,35 @@ function followingOnce(write2, follow3) {
8565
8610
  write2();
8566
8611
  }
8567
8612
  }
8613
+ function openReplaced(h, dir, name2, moving) {
8614
+ let node;
8615
+ try {
8616
+ node = h.Fs.lookupNode?.(dir, name2);
8617
+ } catch {
8618
+ return void 0;
8619
+ }
8620
+ if (!node || node === moving || node.live?.openCount === 0 || !h.Fs.isFile(node.mode))
8621
+ return void 0;
8622
+ const st = freshStat(h, node);
8623
+ if ((st.nlink ?? 1) > 1) return void 0;
8624
+ const ranged = h.rangedOf(node);
8625
+ if (ranged) ranged.prefetch();
8626
+ else h.ensureLoaded(node);
8627
+ return { node, st };
8628
+ }
8629
+ function renamedOver(h, dir, name2, moving, rename) {
8630
+ const replaced = openReplaced(h, dir, name2, moving);
8631
+ rename();
8632
+ if (replaced) {
8633
+ h.rangedOf(replaced.node)?.pin();
8634
+ orphaned(h, replaced.node, replaced.st);
8635
+ }
8636
+ try {
8637
+ const existing = h.Fs.lookupNode?.(dir, name2);
8638
+ if (existing && existing !== moving) h.Fs.hashRemoveNode?.(existing);
8639
+ } catch {
8640
+ }
8641
+ }
8568
8642
  function renameThrough(h, node, from, to) {
8569
8643
  const seq = h.call(() => h.bridgeOf(node).rename(from, to));
8570
8644
  h.ownRename(h.bridgeOf(node), typeof seq === "number" ? seq : void 0);
@@ -8581,6 +8655,13 @@ function heldStream(h, stream, change) {
8581
8655
  }
8582
8656
  }
8583
8657
  }
8658
+ function adopted(node, st, asked) {
8659
+ const bound = node.live.openCount > 0 ? node.live.bound : void 0;
8660
+ if (bound && st.ino !== bound.ino) return false;
8661
+ filled(node.live, st, asked);
8662
+ node.mode = modeFromStat(st, exactIn(node));
8663
+ return true;
8664
+ }
8584
8665
  function createHelpers(Fs, ops) {
8585
8666
  const bridgeOf = (node) => node.mount.opts.bridge;
8586
8667
  const fileIo = (node) => pinnedIo2(bridgeOf(node), node.live.handle);
@@ -8637,8 +8718,7 @@ function createHelpers(Fs, ops) {
8637
8718
  if (!cachedStat(node, Fs.isDir(node.mode), view)) {
8638
8719
  const asked = { statGen: view?.now(), filledAt: performance.now() };
8639
8720
  const st = call2(() => bridgeOf(node).lstat(liveNodePath(linked.holder(node))));
8640
- filled(node.live, st, asked);
8641
- node.mode = modeFromStat(st, exactIn(node));
8721
+ if (!adopted(node, st, asked)) return node.live.bound;
8642
8722
  }
8643
8723
  return node.live.stat;
8644
8724
  }
@@ -8890,12 +8970,7 @@ function createNodeOps(h) {
8890
8970
  const from = liveNodePath(oldNode);
8891
8971
  const to = childPath(newDir, newName);
8892
8972
  flushNode(oldNode);
8893
- renameThrough(h, oldNode, from, to);
8894
- try {
8895
- const existing = Fs.lookupNode?.(newDir, newName);
8896
- if (existing && existing !== oldNode) Fs.hashRemoveNode?.(existing);
8897
- } catch {
8898
- }
8973
+ renamedOver(h, newDir, newName, oldNode, () => renameThrough(h, oldNode, from, to));
8899
8974
  oldNode.name = newName;
8900
8975
  oldNode.parent = newDir;
8901
8976
  oldNode.live.stat = void 0;
@@ -8975,7 +9050,7 @@ function appendThrough(h, stream, bytes) {
8975
9050
  }
8976
9051
  function holdLive(bridge, node, on, want) {
8977
9052
  const s = node.live;
8978
- const seen = on && s.stat ? { gen: s.stat.gen } : void 0;
9053
+ const seen = on && s.stat ? { gen: s.stat.gen, ...s.stat.ino !== void 0 ? { ino: s.stat.ino } : {} } : void 0;
8979
9054
  return bridge.hold?.(liveNodePath(node), on, true, s.handle, want, seen);
8980
9055
  }
8981
9056
  function dropOpen(s) {
@@ -11120,6 +11195,8 @@ var init_procfs = __esm({
11120
11195
  slicc_cwd_checks: (listing2) => `${listing2.cwdChecks ?? 0}
11121
11196
  `,
11122
11197
  slicc_rename_ack_busy: (listing2) => `${listing2.renameAcks?.busy ?? 0}
11198
+ `,
11199
+ slicc_stale_fds: (listing2) => `${listing2.staleFds ?? 0}
11123
11200
  `,
11124
11201
  slicc_rename_acks: (listing2) => {
11125
11202
  const samples = [...listing2.renameAcks?.ackMs ?? []].sort((a, b) => a - b);