Skip to content

local pass over engine internals: caller globals survive engine calls (#5)#6

Merged
InauguralPhysicist merged 1 commit into
mainfrom
local-pass
Jul 3, 2026
Merged

local pass over engine internals: caller globals survive engine calls (#5)#6
InauguralPhysicist merged 1 commit into
mainfrom
local-pass

Conversation

@InauguralPhysicist

Copy link
Copy Markdown
Contributor

The verification story (worth reading — the issue as filed was a non-repro)

Reproduce-before-believing turned up a surprise: the issue's own example (load_file, then pos is 42) does not reproduce — cross-module writes are insulated in that order. Declared before the load, the clobber is real and worse than filed: the caller's globals corrupt the engine's state (pos is 42 breaks the parse — 9 of 11 regression checks failed, including wrong match results). The order dependence is itself an upstream semantics wart, now filed as EigenScript#373 and logged in GAPS.md.

The fix

The mechanical local pass the issue prescribed (~150 first assignments across the four engine files), plus two hand-fixes for a pattern the mechanical rule misses: sibling if branches. A local on the first textual assignment doesn't dominate siblings — local c in the "char" opcode branch never executes when "any"/"class" run, so their bare c is still clobbered. Same shape for result in regex_vm_run (the anchored branch always returns). A dominance audit script flagged these; both fixed with per-branch local.

Regression test

tests/test_s9_scope.eigs — ten common engine working names (pos, c, n, out, parts, branches, ranges, results, i, j) declared as module globals before the engine loads, then re_compile/re_search/re_find_all, asserting the engine ran correctly and every global survived. Fails 9/11 on the unfixed tree; auto-wired via tests/run.sh's glob.

Gates

Suite 358/358 (347 original + 11 new).

Closes #5

🤖 Generated with Claude Code

Verification first refuted the issue as filed: its example declares the
global AFTER load_file, an order where cross-module writes are
insulated. Declared BEFORE the load — the realistic order — the clobber
is real and worse than filed: caller globals like `pos is 42` corrupt
the ENGINE's own parse/VM state (9 of 11 regression checks failed,
including the engine producing wrong results). The order dependence
itself is now upstream as EigenScript#373 (GAPS.md entry added).

The fix is the mechanical `local` pass the issue prescribed, over
regex_parse/regex_compile/regex_vm/regex.eigs (~150 first
assignments), plus two hand-fixes the mechanical rule misses — sibling
if-branches where the first textual assignment doesn't dominate the
others (`c` in the char/any/class opcode branches, `result` in
regex_vm_run's anchored/search split): a `local` in one branch never
executes when a sibling runs, so the sibling's bare assignment still
clobbered.

tests/test_s9_scope.eigs (11 checks, auto-picked-up by tests/run.sh)
declares ten engine-working names as module globals BEFORE loading the
engine and asserts they all survive re_compile/re_search/re_find_all —
fails 9/11 on the unfixed tree.

Suite: 358/358 (347 original + 11 new).

Closes #5

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@InauguralPhysicist InauguralPhysicist merged commit e95fd43 into main Jul 3, 2026
1 check passed
@InauguralPhysicist InauguralPhysicist deleted the local-pass branch July 3, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Engine internals don't use local — calling re_* can clobber caller globals with common names (c, pos, n, ranges, ...)

1 participant