From b84451659983271130305809b678f3f2cb4f9e88 Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Wed, 25 Feb 2026 13:33:33 +0100 Subject: [PATCH] Fix wantarray in eval STRING: pass outer context to apply() --- .../perlonjava/backend/bytecode/EvalStringHandler.java | 8 ++++++-- .../perlonjava/backend/bytecode/SlowOpcodeHandler.java | 8 +++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/perlonjava/backend/bytecode/EvalStringHandler.java b/src/main/java/org/perlonjava/backend/bytecode/EvalStringHandler.java index 13db3320e..065258fa4 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/EvalStringHandler.java +++ b/src/main/java/org/perlonjava/backend/bytecode/EvalStringHandler.java @@ -43,13 +43,15 @@ public class EvalStringHandler { * @param registers Current register array (for variable access) * @param sourceName Source name for error messages * @param sourceLine Source line for error messages + * @param callContext The calling context (VOID/SCALAR/LIST) for wantarray inside eval * @return RuntimeScalar result of evaluation (undef on error) */ public static RuntimeScalar evalString(String perlCode, InterpretedCode currentCode, RuntimeBase[] registers, String sourceName, - int sourceLine) { + int sourceLine, + int callContext) { try { // Step 1: Clear $@ at start of eval GlobalVariable.getGlobalVariable("main::@").set(""); @@ -196,8 +198,10 @@ public static RuntimeScalar evalString(String perlCode, } // Step 6: Execute the compiled code + // Use the true outer call context so wantarray() inside the eval body + // returns the correct value (undef for void, false for scalar, true for list). RuntimeArray args = new RuntimeArray(); // Empty @_ - RuntimeList result = evalCode.apply(args, RuntimeContextType.SCALAR); + RuntimeList result = evalCode.apply(args, callContext); // Step 7: Return scalar result return result.scalar(); diff --git a/src/main/java/org/perlonjava/backend/bytecode/SlowOpcodeHandler.java b/src/main/java/org/perlonjava/backend/bytecode/SlowOpcodeHandler.java index 09eb9aac0..37c82cb41 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/SlowOpcodeHandler.java +++ b/src/main/java/org/perlonjava/backend/bytecode/SlowOpcodeHandler.java @@ -252,13 +252,19 @@ public static int executeEvalString( } String perlCode = codeScalar.toString(); + // Read outer wantarray from register 2 (set by BytecodeInterpreter from the call site context). + // This is the true calling context (VOID/SCALAR/LIST) that wantarray() inside the + // eval body must reflect — exactly as evalStringWithInterpreter receives callContext. + int callContext = ((RuntimeScalar) registers[2]).getInt(); + // Call EvalStringHandler to parse, compile, and execute RuntimeScalar result = EvalStringHandler.evalString( perlCode, code, // Current InterpretedCode for context registers, // Current registers for variable access code.sourceName, - code.sourceLine + code.sourceLine, + callContext // True outer context for wantarray inside eval body ); registers[rd] = result;