Skip to content

Commit fde7b02

Browse files
committed
Fix wantarray in eval STRING: pass outer context to apply()
EvalStringHandler.evalString() was hardcoding RuntimeContextType.SCALAR when executing the eval body, so wantarray() inside eval STRING always returned false (scalar) regardless of the actual call site context. Fix: read registers[2] (the outer wantarray set by BytecodeInterpreter) and pass it as callContext to evalString() and apply(), so wantarray() inside the eval body correctly returns undef (void), false (scalar), or true (list) matching the outer call site. Result: op/eval.t passes 153/153 in both JVM and interpreter modes.
1 parent 326c11e commit fde7b02

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

src/main/java/org/perlonjava/backend/bytecode/EvalStringHandler.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ public class EvalStringHandler {
4343
* @param registers Current register array (for variable access)
4444
* @param sourceName Source name for error messages
4545
* @param sourceLine Source line for error messages
46+
* @param callContext The calling context (VOID/SCALAR/LIST) for wantarray inside eval
4647
* @return RuntimeScalar result of evaluation (undef on error)
4748
*/
4849
public static RuntimeScalar evalString(String perlCode,
4950
InterpretedCode currentCode,
5051
RuntimeBase[] registers,
5152
String sourceName,
52-
int sourceLine) {
53+
int sourceLine,
54+
int callContext) {
5355
try {
5456
// Step 1: Clear $@ at start of eval
5557
GlobalVariable.getGlobalVariable("main::@").set("");
@@ -196,8 +198,10 @@ public static RuntimeScalar evalString(String perlCode,
196198
}
197199

198200
// Step 6: Execute the compiled code
201+
// Use the true outer call context so wantarray() inside the eval body
202+
// returns the correct value (undef for void, false for scalar, true for list).
199203
RuntimeArray args = new RuntimeArray(); // Empty @_
200-
RuntimeList result = evalCode.apply(args, RuntimeContextType.SCALAR);
204+
RuntimeList result = evalCode.apply(args, callContext);
201205

202206
// Step 7: Return scalar result
203207
return result.scalar();

src/main/java/org/perlonjava/backend/bytecode/SlowOpcodeHandler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,19 @@ public static int executeEvalString(
252252
}
253253
String perlCode = codeScalar.toString();
254254

255+
// Read outer wantarray from register 2 (set by BytecodeInterpreter from the call site context).
256+
// This is the true calling context (VOID/SCALAR/LIST) that wantarray() inside the
257+
// eval body must reflect — exactly as evalStringWithInterpreter receives callContext.
258+
int callContext = ((RuntimeScalar) registers[2]).getInt();
259+
255260
// Call EvalStringHandler to parse, compile, and execute
256261
RuntimeScalar result = EvalStringHandler.evalString(
257262
perlCode,
258263
code, // Current InterpretedCode for context
259264
registers, // Current registers for variable access
260265
code.sourceName,
261-
code.sourceLine
266+
code.sourceLine,
267+
callContext // True outer context for wantarray inside eval body
262268
);
263269

264270
registers[rd] = result;

0 commit comments

Comments
 (0)