Fix interpreter eval STRING parity: stash.t, bop.t, benchmarks.t#224
Merged
Fix interpreter eval STRING parity: stash.t, bop.t, benchmarks.t#224
Conversation
… JVM path BITWISE_AND/OR/XOR_BINARY opcodes were calling bitwiseAndBinary/OrBinary/XorBinary (always-numeric) instead of bitwiseAnd/Or/Xor (context-sensitive). The JVM path maps & -> BitwiseOperators.bitwiseAnd() which checks if operands look like numbers and falls back to string bitwise ops if not. The interpreter was bypassing this check, causing strings with code points > 0xFF to silently produce wrong results instead of throwing the expected error. The *Binary variants are only correct for the explicit 'binary&', 'binary|', 'binary^' operators (use feature 'bitwise'). bop.t: 487/522 passing with and without JPERL_EVAL_USE_INTERPRETER=1 (was 480)
Two bugs fixed:
1. LIST_SLICE_FROM startIndex encoding mismatch:
CompileAssignment emits startIndex via emitInt() (single int slot), but
SlowOpcodeHandler.executeListSliceFrom() was reading it as 2 shorts
(high+low). This caused wrong startIndex values and out-of-bounds register
access when list assignment with array slurp ran inside eval STRING:
eval 'my ($x, \@A) = 1..4; for (1..1) { ($x, \@A) = (1,2,$x) } 1'
Fixed by reading startIndex as a single int to match emitInt().
2. visit(IdentifierNode) checked capturedVarIndices before local scope:
When eval STRING captured outer $x at register 3, and the eval declared
'my $x' (allocating a fresh register), subsequent references to $x inside
a for loop still resolved to the captured register 3 instead of the new
local register. Fixed by checking local variableScopes first, then falling
through to capturedVarIndices only if not found locally.
perf/benchmarks.t: 1960/1960 with and without JPERL_EVAL_USE_INTERPRETER=1
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
Fixes several interpreter mode (JPERL_EVAL_USE_INTERPRETER=1) regressions vs JVM compiler mode.
Changes
1. eval STRING package resolution (EvalStringHandler, InterpretedCode, BytecodeCompiler)
Store compile-time package in InterpretedCode.compilePackage; EvalStringHandler uses it instead of runtime InterpreterState.currentPackage, matching evalStringHelper behavior.
2. Bitwise &/|/^ context-sensitive dispatch (OpcodeHandlerExtended)
BITWISE_AND/OR/XOR_BINARY opcodes called always-numeric bitwiseAndBinary/OrBinary/XorBinary instead of context-sensitive bitwiseAnd/Or/Xor (which falls back to string ops for non-numeric operands).
3. LIST_SLICE_FROM startIndex encoding mismatch (SlowOpcodeHandler)
CompileAssignment emits startIndex via emitInt() (single int), but executeListSliceFrom() read it as 2 shorts. Caused out-of-bounds register access for list assignments with array slurp inside eval STRING.
4. visit(IdentifierNode) local scope shadowing (BytecodeCompiler)
capturedVarIndices was checked before local variableScopes, so my $x inside eval STRING could not shadow a captured outer $x.
Test Results