ReviewOS

zig-utils/zig-js

VM: restore lexical environment after uncaught program exits

#820
Closed chris opened this 11 days ago ·
11 days ago

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.

11 days ago

The candidate uses the existing environment-depth unwind at vm.run only, following the current GC-updated environment chain and allocating nothing during cleanup. It does not change suspendable/function activation lifecycle ownership.

Both new focused Debug tests pass: eight nested block/with/class/loop/catch/finally/success cases restore the exact entry environment and can evaluate again on the same interpreter, and allocation-failure replay now restores environment, temporary-root counts, private state and call depth. Unsuppressed ReleaseSafe+TSan also passes both tests. The adjacent #819 six-test suite and previous class-naming eight-test suite pass under TSan with no race/leak reports. Final corpus/fuzz validation is in progress before the separate commits are landed.

11 days ago

Pushed fix(vm): unwind lexical environments on program exit (#820), independently from #819. Final combined corpus shows zero measured regressions; 400 default and 300 verifier fuzz programs pass with zero failures. The focused Debug and unsuppressed TSan evidence above remains unchanged.

Full native Debug integration (2148 linked tests) is running. Combined-main CI 33209229291 is pending; this is not yet a completed green matrix.

11 days ago

The full native Debug suite for pushed descendant 4f7718d completed: 2147 passed, one platform skip, zero failures/leaks, 2148 linked tests, 743.9s across four native shards. This is terminal integration evidence for the program-exit fix, not just focused coverage. Current CI remains incomplete and includes the independently tracked #722 expected-400/got-401 corpus failure; no all-green matrix claim.

11 days ago

Closing with terminal combined-main integration evidence: CI 33211154123 at e24c4fa completed successfully: 53 successful checks, one skipped nightly-only check, zero failed/cancelled checks. The implementation fix(vm): unwind lexical environments on program exit (#820) is in that revision. This completes the pending integration condition alongside the scoped local/conformance evidence recorded above. Separately discovered Error-intrinsic, Array-realm, prototype-type and restriction-path defects remain open in #823, #824, #825 and #826; this closure does not claim those are fixed.

Sign in to comment on this issue.