resetScriptDeclarations method

void resetScriptDeclarations()

§U28 / TODO #14 — Evict script-declared entries from the current _moduleLoader.globalEnvironment so a follower execute* / executeBundle* call starts with the same name-set the last _initModule produced.

Walks _moduleLoader.globalEnvironment.values and removes every key not present in _baselineValueKeys (the snapshot captured at the end of _initModule). 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), execute* already calls _initModule on every invocation, which constructs a brand-new ModuleLoader backed by a brand-new Environment. The previous environment is dropped on the floor by the next call, so script declarations do NOT accumulate across executes 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-loader invariant). The native-accumulator clear, by contrast, addresses real cross-build state — see OPEN B.12.

No-op on the _values half if _moduleLoader has not been initialised yet (_hasExecutedOnce is false) 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 instance's module lifecycle.
  D4.resetNativeAccumulators();

  if (!_hasExecutedOnce) return;
  final baseline = _baselineValueKeys;
  if (baseline == null) return;
  final env = _moduleLoader.globalEnvironment;
  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(
    "[D4rt.resetScriptDeclarations] Removed ${toRemove.length} "
    "script-declared entries; ${env.values.length} stdlib entries "
    "preserved; native accumulator cleared.",
  );
}