resetScriptDeclarations method
§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.",
);
}