Found while fault-injecting #819, related to #814 and parent #465.
A compiled program can enter a class/block lexical environment and then return an uncaught abrupt completion without restoring the interpreter environment. The new allocation-failure replay executes var key={toString(){return "member"+37;}};var C=class{[key](){}["later"](){}}; through vm.run. When allocation fails while entering the key conversion callback, run returns OutOfMemory but machine.env still points at the class environment instead of its entry environment. The assertion fails in the Debug unit test; temporary roots and caller state must be restored before host handling and subsequent evaluation.
execLoop restores strictness and other execution flags and restores lexical depth for caught handlers; the non-suspendable run boundary currently has no corresponding environment-depth unwind for escaping errors. Function/generator activation boundaries have their own ownership and must not be redesigned for this fix.
Acceptance: use the existing environment-depth unwind path at the non-suspendable program boundary; cover uncaught throws, nested block/with/class environments, caught/finally paths, successful global declarations, allocation-failure replay, and subsequent evaluation on the same interpreter. Preserve precise-GC safety without introducing an allocation on the cleanup path. This is not yet fixed or validated.