Implement dynamic scoping for regex match variables#249
Merged
Conversation
Match variables are now saved/restored per subroutine call using the existing DynamicVariableManager infrastructure, matching Perl behavior where regex match state is dynamically scoped to the enclosing block. JVM backend: Local.localSetup detects matchRegex/replaceRegex in AST and emits RuntimeRegexState.pushLocal(); localTeardown pops via DynamicVariableManager.popToLocalLevel(). Interpreter backend: BytecodeCompiler sets containsRegex flag on InterpretedCode; BytecodeInterpreter.execute() saves/restores in try/finally based on the flag. Proxy resolution: ScalarSpecialVariable.getList() now materializes the value eagerly, and RuntimeList.resolveMatchProxies() is called before local teardown at return boundaries so that return values like ($1, $2) capture the callee match state, not the restored caller state. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <noreply@cognition.ai>
When eval STRING runs, it creates temporary aliases in the global namespace so that BEGIN blocks inside the eval can access outer lexical variables. These aliases were not being cleaned up after compilation, causing `my` variable re-declarations in loops to pick up stale values via retrieveBeginScalar instead of creating fresh objects. This fix tracks the alias keys created during eval STRING compilation and removes them in the finally block after parsing/compilation is done. Fixes ExifTool test 22 (InsertTagValues) where `my` variables inside a while loop containing `eval $expr` were not being re-initialized on each iteration. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <noreply@cognition.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
DynamicVariableManager+DynamicStateinfrastructure (same aslocalvariables)Implementation
RuntimeRegexState— newDynamicStatethat saves/restores the 10 static fields onRuntimeRegexLocal.localSetup()detectsmatchRegex/replaceRegexops and emitsRuntimeRegexState.pushLocal();localTeardownpops viapopToLocalLevel()InterpretedCode.containsRegexflag set byBytecodeCompiler;BytecodeInterpreter.execute()saves/restores in try/finallyScalarSpecialVariable.getList()materializes eagerly;RuntimeList.resolveMatchProxies()called at return boundaries before teardownTest plan
return $1returns callee's match, caller's $1 restoredreturn ($1, $2)returns callee's matches, caller's $1/$2 restoredeval STRINGwith regex doesn't clobber caller's match varsGenerated with Devin