Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -844,8 +844,14 @@ public static RuntimeList execute(InterpretedCode code, RuntimeArray args, int c
// bypassing RuntimeCode.apply() indirection chain
if (codeRef.type == RuntimeScalarType.CODE && codeRef.value instanceof InterpretedCode interpCode) {
// Direct call to interpreter - skip RuntimeCode.apply overhead
// Pass null for subroutineName to enable frame caching
result = BytecodeInterpreter.execute(interpCode, callArgs, context, null);
// Push args to argsStack for getCallerArgs() support (used by List::Util::any/all/etc.)
RuntimeCode.pushArgs(callArgs);
try {
// Pass null for subroutineName to enable frame caching
result = BytecodeInterpreter.execute(interpCode, callArgs, context, null);
} finally {
RuntimeCode.popArgs();
}
} else {
// Slow path for JVM-compiled code, symbolic references, etc.
result = RuntimeCode.apply(codeRef, "", callArgs, context);
Expand All @@ -860,7 +866,13 @@ public static RuntimeList execute(InterpretedCode code, RuntimeArray args, int c
callArgs = flow.getTailCallArgs();
// Use fast path for InterpretedCode
if (codeRef.type == RuntimeScalarType.CODE && codeRef.value instanceof InterpretedCode interpCode) {
result = BytecodeInterpreter.execute(interpCode, callArgs, context, null);
// Push args for tail call too
RuntimeCode.pushArgs(callArgs);
try {
result = BytecodeInterpreter.execute(interpCode, callArgs, context, null);
} finally {
RuntimeCode.popArgs();
}
} else {
result = RuntimeCode.apply(codeRef, "tailcall", callArgs, context);
}
Expand Down
17 changes: 15 additions & 2 deletions src/main/java/org/perlonjava/backend/bytecode/InterpretedCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,25 @@ public InterpreterState.InterpreterFrame getOrCreateFrame(String packageName, St
*/
@Override
public RuntimeList apply(RuntimeArray args, int callContext) {
return BytecodeInterpreter.execute(this, args, callContext);
// Push args for getCallerArgs() support (used by List::Util::any/all/etc.)
// This matches what RuntimeCode.apply() does for JVM-compiled subs
RuntimeCode.pushArgs(args);
try {
return BytecodeInterpreter.execute(this, args, callContext);
} finally {
RuntimeCode.popArgs();
}
}

@Override
public RuntimeList apply(String subroutineName, RuntimeArray args, int callContext) {
return BytecodeInterpreter.execute(this, args, callContext, subroutineName);
// Push args for getCallerArgs() support (used by List::Util::any/all/etc.)
RuntimeCode.pushArgs(args);
try {
return BytecodeInterpreter.execute(this, args, callContext, subroutineName);
} finally {
RuntimeCode.popArgs();
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/perlonjava/core/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public final class Configuration {
* Automatically populated by Gradle/Maven during build.
* DO NOT EDIT MANUALLY - this value is replaced at build time.
*/
public static final String gitCommitId = "ad0d59ddc";
public static final String gitCommitId = "bef8bcb54";

/**
* Git commit date of the build (ISO format: YYYY-MM-DD).
Expand Down
37 changes: 32 additions & 5 deletions src/main/java/org/perlonjava/runtime/perlmodule/ScalarUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.perlonjava.runtime.perlmodule;

import org.perlonjava.runtime.io.ClosedIOHandle;
import org.perlonjava.runtime.runtimetypes.*;

import static org.perlonjava.runtime.runtimetypes.RuntimeScalarType.*;
Expand Down Expand Up @@ -234,18 +235,44 @@ public static RuntimeList looks_like_number(RuntimeArray args, int ctx) {
}

/**
* Placeholder for the openhandle functionality.
* Checks if a value is an open filehandle.
* Returns the filehandle itself if it's open, undef otherwise.
*
* @param args The arguments passed to the method.
* @param args The arguments passed to the method (a single value).
* @param ctx The context in which the method is called.
* @return A RuntimeList indicating if the scalar is an open handle.
* @return The filehandle if open, undef otherwise.
*/
public static RuntimeList openhandle(RuntimeArray args, int ctx) {
if (args.size() != 1) {
throw new IllegalStateException("Bad number of arguments for openhandle() method");
}
// Placeholder for openhandle functionality
return new RuntimeScalar(false).getList();
RuntimeScalar arg = args.get(0);

// Check if it's a GLOB or GLOBREFERENCE (filehandle)
if (arg.type == GLOB || arg.type == GLOBREFERENCE) {
Object value = arg.value;

// Handle RuntimeGlob
if (value instanceof RuntimeGlob glob) {
RuntimeScalar io = glob.getIO();
if (io != null && io.value instanceof RuntimeIO runtimeIO) {
// Check if the handle is open (not a ClosedIOHandle)
if (!(runtimeIO.ioHandle instanceof ClosedIOHandle)) {
return arg.getList(); // Return the filehandle itself
}
}
}
// Handle RuntimeIO directly
else if (value instanceof RuntimeIO runtimeIO) {
if (!(runtimeIO.ioHandle instanceof ClosedIOHandle)) {
return arg.getList(); // Return the filehandle itself
}
}
}
// Check for blessed object with *{} overload (handled in Perl code)
// For now, just return undef for non-glob types

return new RuntimeScalar().getList(); // Return undef
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,12 @@ private static String translateUnicodeProperty(String property, boolean negated,
}
}

// Strip 'Is' prefix for Perl compatibility (e.g., IsPrint -> Print, IsDigit -> Digit)
// ICU4J doesn't recognize Is-prefixed property names, but they're valid in Perl
if (property.startsWith("Is") && property.length() > 2 && Character.isUpperCase(property.charAt(2))) {
property = property.substring(2);
}

// Map Perl block aliases to Unicode block names
if (property.equalsIgnoreCase("ASCII")) {
property = "Basic_Latin";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,17 @@ public static RuntimeArray getCallerArgs() {

/**
* Push @_ onto the args stack when entering a subroutine.
* Public so BytecodeInterpreter can use it when calling InterpretedCode directly.
*/
private static void pushArgs(RuntimeArray args) {
public static void pushArgs(RuntimeArray args) {
argsStack.get().push(args);
}

/**
* Pop @_ from the args stack when exiting a subroutine.
* Public so BytecodeInterpreter can use it when calling InterpretedCode directly.
*/
private static void popArgs() {
public static void popArgs() {
Deque<RuntimeArray> stack = argsStack.get();
if (!stack.isEmpty()) {
stack.pop();
Expand Down
2 changes: 2 additions & 0 deletions src/main/perl/lib/B.pm
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ sub perlstring {
# Escape special characters
$str =~ s/\\/\\\\/g;
$str =~ s/"/\\"/g;
$str =~ s/\$/\\\$/g; # Escape $ to prevent interpolation
$str =~ s/\@/\\\@/g; # Escape @ to prevent interpolation
$str =~ s/\n/\\n/g;
$str =~ s/\r/\\r/g;
$str =~ s/\t/\\t/g;
Expand Down
Loading