resetScriptDeclarations method

void resetScriptDeclarations()

§U28 / TODO #14 — Evict script-declared entries from the current global environment so a follower executeBundle call starts with the same name-set the first build saw.

Walks _globalEnvironment.values and removes any key not present in _baselineValueKeys (the snapshot captured at the end of the last _initEnvironment). Bridge registrations (_bridgedClasses, _bridgedClassesLookupByType, _bridgedEnums) are NOT touched.

It additionally clears the process-global native-side accumulator via D4.resetNativeAccumulators — the D4 _nativeToInterpreted Expando and its registration counter. That Expando is the genuine cross-build accumulator (OPEN B.12 / §U28): its entries are pinned by framework objects the embedder keeps alive across /build cycles, so unlike the per-call-fresh _values map it does NOT self-clear. Dropping it here is what makes the reset API more than a no-op for the §U28 wedge.

Architectural note

As of the 2026‑05‑28 audit (interpreter_unfixable.md §U28), executeBundle and execute already call _initEnvironment on every invocation, which constructs a brand-new Environment. The previous environment is dropped on the floor by the next build, so script declarations do NOT accumulate across /build cycles in _values. The _values eviction below is therefore a forward-compatibility hook (frees GC roots earlier; survives any future change to the per-call fresh-environment invariant). The native-accumulator clear, by contrast, addresses real cross-build state — see OPEN B.12.

No-op on the _values half if no execution has happened yet (no global environment to walk) or if no baseline was captured; the native-accumulator clear runs unconditionally.

Implementation

void resetScriptDeclarations() {
  // Cross-build native state (OPEN B.12): clear unconditionally — it is
  // process-global and not tied to this runner's environment lifecycle.
  D4.resetNativeAccumulators();

  final env = _globalEnvironment;
  final baseline = _baselineValueKeys;
  if (env == null || baseline == null) return;
  final toRemove = <String>[];
  for (final key in env.values.keys) {
    if (!baseline.contains(key)) {
      toRemove.add(key);
    }
  }
  for (final key in toRemove) {
    env.removeLocalValue(key);
  }
  Logger.debug(
    "[D4rtRunner.resetScriptDeclarations] Removed ${toRemove.length} "
    "script-declared entries; ${env.values.length} bridge/stdlib "
    "entries preserved; native accumulator cleared.",
  );
}