Skip to content

Fix eval interpreter catchup: missing operators, local *glob, and ExifTool support#242

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

Fix eval interpreter catchup: missing operators, local *glob, and ExifTool support#242
fglock merged 3 commits intomasterfrom
fix-eval-interpreter-catchup

Conversation

@fglock
Copy link
Owner

@fglock fglock commented Feb 26, 2026

Summary

This PR continues the interpreter mode (JPERL_EVAL_USE_INTERPRETER=1) catch-up work, fixing multiple issues discovered while getting ExifTool to run in interpreter mode.

Missing bytecode operators for ExifTool

  • Binary operator handlers: binmode, seek, eof, printf, close, fileno, getc, tell, join — these were missing when the parser generates BinaryOperatorNode (2+ arg form)
  • $#array = value assignment via new SET_ARRAY_LAST_INDEX opcode
  • xor/^^ logical operator via new XOR_LOGICAL opcode
  • //= defined-or assignment via new DEFINED_OR_ASSIGN opcode
  • CONCAT defensive fix: coerce RuntimeList to scalar when encountered as operand

local *glob restore fix (uni/gv.t test 169, mro/method_caching.t)

  • Rewrote RuntimeGlob.dynamicSaveState/RestoreState with GlobSlotSnapshot to save/restore actual Java object references from global maps
  • Added InheritanceResolver.invalidateCache() on code slot restore to fix MRO cache regression

Other interpreter fixes

  • Negation context propagation
  • #line tracking in eval
  • Strict scoping for eval STRING
  • Non-local control flow handling
  • Undefined sub error messages
  • $SIG{__DIE__} and exception handling via WarnDie.catchEval
  • Lexical scalar assignment lvalue preservation
  • Logical or/|| in RUNTIME context
  • Context propagation and eval tracing

Result

ExifTool (Image-ExifTool-13.44/exiftool) now runs successfully in interpreter mode.

Test plan

  • ./gradlew classes testUnitParallel --parallel passes
  • ExifTool runs: cd Image-ExifTool-13.44 && JPERL_EVAL_USE_INTERPRETER=1 ../jperl -Ilib exiftool
  • ExifTool runs without env var (JVM fallback to interpreter for large methods)

Generated with Devin

fglock and others added 3 commits February 26, 2026 20:02
- Binary operator handlers: binmode, seek, eof, printf, close, fileno,
  getc, tell, join (as BinaryOperatorNode form)
- $#array = value assignment (SET_ARRAY_LAST_INDEX opcode)
- Logical xor/^^ operator (XOR_LOGICAL opcode)
- //= defined-or assignment (DEFINED_OR_ASSIGN opcode)
- CONCAT: handle RuntimeList operands via scalar coercion

ExifTool now runs successfully in interpreter mode.

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

Co-Authored-By: Devin <noreply@cognition.ai>
The compileJoinBinaryOp was only using lastResultReg from
node.right.accept(), which for a ListNode with multiple elements
(e.g. string interpolation "$x-$y") would only capture the last
element. Now properly iterates ListNode elements and emits
CREATE_LIST before JOIN.

This fixes a regression in re/regexp.t (1565→1784) caused by string
interpolation in eval strings producing empty/partial results.

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

Co-Authored-By: Devin <noreply@cognition.ai>
Array interpolation in eval strings (e.g. ">@array<") was getting
scalar context (array count) instead of list context (array elements)
because compileJoinBinaryOp didn't set LIST context for the right
operand when it wasn't a ListNode.

This fixes base/lex.t (-3 → +1) and re/regexp.t (1784 → 1786).

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

Co-Authored-By: Devin <noreply@cognition.ai>
@fglock fglock merged commit efb05ca into master Feb 26, 2026
2 checks passed
@fglock fglock deleted the fix-eval-interpreter-catchup branch February 26, 2026 20:08
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