Skip to content

Fix interpreter strict vars check to allow use-vars-declared globals#270

Merged
fglock merged 4 commits into
masterfrom
fix-interpreter-strict-vars
Mar 5, 2026
Merged

Fix interpreter strict vars check to allow use-vars-declared globals#270
fglock merged 4 commits into
masterfrom
fix-interpreter-strict-vars

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Mar 5, 2026

Summary

  • The BytecodeCompiler shouldBlockGlobalUnderStrictVars() was missing the allowIfAlreadyExists check that the JVM backend (EmitVariable.java) has
  • When a large file like ExifTool.pm (10K lines) falls back from JVM to interpreter compilation, CompilerFlagNode in the AST re-enables strict vars
  • But use vars declarations (which create globals at parse time) were not recognized by the interpreter's strict check, causing false requires explicit package name errors
  • The fix checks GlobalVariable.existsGlobalVariable/Array/Hash() before blocking access, mirroring the JVM backend logic

Impact

  • ExifTool tests: 0/600 -> 597/600 (99.5%)
  • Unit tests (JVM): 156/156 pass (no regressions)
  • Unit tests (interpreter): 156/156, 7078/7078 pass (no regressions)

Remaining 3 ExifTool failures

DNG test 3 and Nikon tests 8-9 crash with a null register NPE in WriteExif.pl's interpreter-compiled bytecode (Cannot read field "type" because "value" is null at MY_SCALAR opcode). These are EXIF write operations in a very large subroutine — a pre-existing interpreter register management issue, not related to this change.

Test plan

  • mvn test — 156/156 pass
  • make test-interpreter — 156/156, 7078/7078 pass
  • ExifTool full test suite — 597/600 pass (99.5%)

Generated with Devin

fglock and others added 4 commits March 5, 2026 19:20
The BytecodeCompiler shouldBlockGlobalUnderStrictVars() was missing
the allowIfAlreadyExists check that the JVM backend (EmitVariable.java)
has. When a large file like ExifTool.pm (10K lines) falls back from JVM
to interpreter compilation, CompilerFlagNode in the AST re-enables
strict vars. But use vars declarations (which create globals at parse
time) were not recognized by the interpreter strict check, causing
false 'requires explicit package name' errors.

The fix checks GlobalVariable.existsGlobalVariable/Array/Hash() before
blocking access, mirroring the JVM backend logic.

Impact: ExifTool tests go from 0/600 (all crashing) to 597/600 (99.5%).

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

Co-Authored-By: Devin <noreply@cognition.ai>
RuntimeScalar.set(null) could occur in large interpreter-compiled
subroutines (e.g., WriteExif.pl) when a register holds a null value
from a nested call chain. Treat null as undef, matching Perl semantics.

This fixes the remaining 3 ExifTool test crashes (DNG test 3, Nikon
tests 8-9), bringing ExifTool from 597/600 to 600/600 (100%).

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

Co-Authored-By: Devin <noreply@cognition.ai>
Null elements can enter RuntimeArray via delete(), sparse initialization,
or array extension. These nulls propagate through addToArray() and
setFromList() into RuntimeList, where scalar() or set() on them causes
NPEs.

Add null guards in RuntimeList.scalar() and setFromList() to treat
null elements as undef, matching Perl semantics.

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

Co-Authored-By: Devin <noreply@cognition.ai>
…captures, error message

- Add single-letter variable restriction to interpreter shouldBlockGlobalUnderStrictVars,
  mirroring EmitVariable.java: single Unicode letter vars cannot bypass strict just because
  they exist in GlobalVariable registry. Fixes uni/variables.t (115 failures to 0).
- Reject leading-zero capture variables ($01, $02) under strict in both BytecodeCompiler
  and EmitVariable. Fixes 12 re/pat.t failures (253 to 241).
- Fix open() error message to match Perl: Unknown open() mode. Fixes io/open.t (33 to 31).

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

Co-Authored-By: Devin <noreply@cognition.ai>
@fglock fglock merged commit 026161e into master Mar 5, 2026
2 checks passed
@fglock fglock deleted the fix-interpreter-strict-vars branch March 5, 2026 20: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