Skip to content

Fix eval interpreter catchup: package context, delete deref, statement modifier my, and more#243

Merged
fglock merged 2 commits intomasterfrom
fix-eval-interpreter-catchup
Feb 26, 2026
Merged

Fix eval interpreter catchup: package context, delete deref, statement modifier my, and more#243
fglock merged 2 commits intomasterfrom
fix-eval-interpreter-catchup

Conversation

@fglock
Copy link
Owner

@fglock fglock commented Feb 26, 2026

Summary

Relates to #93

This branch contains a series of fixes to bring the bytecode interpreter closer to full compatibility with the JVM backend, focused on enabling ExifTool to run correctly.

Key fixes in this PR:

  • VerifyError fallback to interpreter — When JVM bytecode verification fails (e.g. Canon.pm with 22 captured hashes causing locals[68]=top), automatically fall back to the interpreter backend
  • Package context in interpreter fallbackcompileToInterpreter() now passes EmitterContext to BytecodeCompiler.compile() so unqualified sub calls resolve in the correct package
  • delete $$ref{key} support — Arrow dereference handling in the interpreter's delete compiler (was hitting unimplemented slow path)
  • my $x = expr if COND fix — VOID context path in EmitLogicalOperator now extracts my declarations before the short-circuit jump, preventing Java null NPE when condition is false
  • Bytecode join operator — Fixed to use LIST context and properly build lists from ListNode elements
  • local *glob assignment — Fixed restore behavior when glob.set() aliases slots
  • Logical operator context propagation — Fixed for wantarray and RUNTIME context in eval
  • Lexical scalar assignment — Uses SET_SCALAR to preserve lvalue semantics and avoid aliasing bugs
  • Interpreter regressions — Fixed negation context, #line tracking, strict scoping, non-local control flow, and undefined sub errors
  • eval STRING improvements — Fixed $SIG{DIE}, exception handling, caller() PC tracking, and context propagation

ExifTool test results:

Before: Only test 1 passed, tests crashed on VerifyError
After: Tests 1, 4, 5, 7-15 pass (15 of 17 tests before VerboseInfo crash)

Test plan

  • ./gradlew test passes (all unit tests)
  • ExifTool.t tests 1, 4, 5, 7-15 pass
  • my $x = expr if COND correctly initializes $x to undef when condition is false
  • delete $$ref{key} works in interpreter mode
  • Package context correctly inherited in interpreter fallback

Generated with Devin

fglock and others added 2 commits February 26, 2026 21:19
When the JVM bytecode verifier rejects a generated class (e.g. due to
uninitialized local variable slots in complex subroutines), catch
VerifyError alongside MethodTooLargeException and compile the AST
to interpreter bytecode instead.

This unblocks ExifTool.pm module loading which triggers VerifyError
in anon787 (the module body with 22 captured hash variables).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
…t modifier my

Three fixes for the eval interpreter catchup:

1. Pass EmitterContext to BytecodeCompiler.compile() so interpreter fallback
   inherits the correct package context. Unqualified sub calls now resolve
   in the correct package instead of main::.

2. Handle delete with arrow dereference ($$ref{key} parsed as $ref->{key})
   in the interpreter bytecode compiler. Previously fell through to
   unimplemented slow path.

3. Fix 'my $x = expr if COND' in void context: extract the my declaration
   before the short-circuit jump so the variable is always initialized to
   undef, even when the condition is false.

Also update SubroutineParser to update placeholder in-place for
InterpretedCode subs, ensuring hash copies see the compiled code.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
@fglock fglock changed the title Fall back to interpreter on JVM VerifyError Fix eval interpreter catchup: package context, delete deref, statement modifier my, and more Feb 26, 2026
@fglock fglock merged commit e817c75 into master Feb 26, 2026
2 checks passed
@fglock fglock deleted the fix-eval-interpreter-catchup branch February 26, 2026 21:11
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.

1 participant