Skip to content

Fix glob slot access (*X{HASH}) in interpreter eval#212

Merged
fglock merged 1 commit into
masterfrom
fix/test-regressions
Feb 19, 2026
Merged

Fix glob slot access (*X{HASH}) in interpreter eval#212
fglock merged 1 commit into
masterfrom
fix/test-regressions

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Feb 19, 2026

Summary

Fixes glob slot access like *X{HASH} inside eval STRING when using JPERL_EVAL_USE_INTERPRETER=1.

Problem

When accessing glob slots like *X{HASH} inside eval STRING, the interpreter was incorrectly dereferencing the glob as a hash (returning %-) and then trying to access the "HASH" key, which caused "No group with name " errors when the glob was aliased to special variables like *-.

Example failure:

*X = *-;
'X'=~/(?<X>X)/;
eval '*X{HASH}{X} || 1'  # Error: No group with name <HASH>

Root Cause

The baseline compiler works correctly because RuntimeGlob overrides hashDerefGetNonStrict() to directly access glob slots via getGlobSlot(), bypassing hash dereference. The interpreter was using DEREF_HASH + HASH_GET which doesn't invoke this override.

Solution

Added GLOB_SLOT_GET opcode (230, before LASTOP to avoid generated section) that:

  1. Detects glob slot access patterns (*X{key}) in BytecodeCompiler.handleGeneralHashAccess()
  2. Emits a single operation calling glob.hashDerefGetNonStrict(key, package)
  3. Matches the baseline compiler's behavior exactly

Changes

  • Added GLOB_SLOT_GET opcode in manual section (before GENERATED_OPCODES_START)
  • Updated LASTOP from 229 to 230
  • Modified BytecodeCompiler.handleGeneralHashAccess() to detect glob slot patterns
  • Implemented SlowOpcodeHandler.executeGlobSlotGet()
  • Added handler in BytecodeInterpreter
  • Added disassembly support in InterpretedCode
  • Added documentation comment explaining where to add manual opcodes

Test Results

  • re/reg_namedcapture.t: 0/2 → 1/2 passing ✓

Notes

The opcode is placed in the manual section before LASTOP with clear documentation to prevent it from being overwritten by the opcode generation tool.

🤖 Generated with Claude Code

When accessing glob slots like *X{HASH} inside eval STRING, the interpreter
was incorrectly dereferencing the glob as a hash (returning %-) and then
trying to access the "HASH" key, which caused "No group with name <HASH>"
errors when the glob was aliased to special variables like *-.

The baseline compiler works correctly because RuntimeGlob overrides
hashDerefGetNonStrict() to directly access glob slots via getGlobSlot(),
bypassing hash dereference. The interpreter was using DEREF_HASH + HASH_GET
which doesn't invoke this override.

Solution: Added GLOB_SLOT_GET opcode (230, before LASTOP to avoid generated
section) that detects glob slot access patterns (*X{key}) in
BytecodeCompiler.handleGeneralHashAccess() and emits a single operation
calling glob.hashDerefGetNonStrict(key, package) to match the baseline behavior.

Added documentation comment explaining where to add manual opcodes to prevent
them from being overwritten by the opcode generation tool.

Fixes re/reg_namedcapture.t test 1 (0/2 -> 1/2 passing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@fglock fglock merged commit 3cd79cb into master Feb 19, 2026
2 checks passed
@fglock fglock deleted the fix/test-regressions branch February 19, 2026 15:48
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