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 @@ -314,7 +314,7 @@ private static RuntimeList executeCode(RuntimeCode runtimeCode, EmitterContext c
* @throws Exception if compilation fails
*/
private static RuntimeCode compileToExecutable(Node ast, EmitterContext ctx) throws Exception {
if (ctx.compilerOptions.useInterpreter) {
if (ctx.compilerOptions.useInterpreter || RuntimeCode.FORCE_INTERPRETER) {
// Interpreter path - returns InterpretedCode (extends RuntimeCode)
ctx.logDebug("Compiling to bytecode interpreter");
BytecodeCompiler compiler = new BytecodeCompiler(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,7 @@ public static RuntimeList execute(InterpretedCode code, RuntimeArray args, int c
case Opcodes.CHMOD, Opcodes.UNLINK, Opcodes.UTIME, Opcodes.RENAME, Opcodes.LINK,
Opcodes.READLINK, Opcodes.UMASK, Opcodes.GETC, Opcodes.FILENO, Opcodes.QX,
Opcodes.SYSTEM, Opcodes.CALLER, Opcodes.EACH, Opcodes.PACK, Opcodes.UNPACK,
Opcodes.VEC, Opcodes.LOCALTIME, Opcodes.GMTIME, Opcodes.RESET, Opcodes.CRYPT,
Opcodes.VEC, Opcodes.LOCALTIME, Opcodes.GMTIME, Opcodes.RESET, Opcodes.TIMES, Opcodes.CRYPT,
Opcodes.CLOSE, Opcodes.BINMODE, Opcodes.SEEK, Opcodes.EOF_OP, Opcodes.SYSREAD,
Opcodes.SYSWRITE, Opcodes.SYSOPEN, Opcodes.SOCKET, Opcodes.BIND, Opcodes.CONNECT,
Opcodes.LISTEN, Opcodes.WRITE, Opcodes.FORMLINE, Opcodes.PRINTF, Opcodes.ACCEPT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ static void visitBinaryOperator(BytecodeCompiler bytecodeCompiler, BinaryOperato
node.left.accept(bytecodeCompiler);
int filehandleReg = bytecodeCompiler.lastResultReg;

// Compile the content (right operand)
// Compile the content (right operand) in LIST context
int savedContext = bytecodeCompiler.currentCallContext;
bytecodeCompiler.currentCallContext = RuntimeContextType.LIST;
node.right.accept(bytecodeCompiler);
bytecodeCompiler.currentCallContext = savedContext;
int contentReg = bytecodeCompiler.lastResultReg;

// Emit PRINT or SAY with both registers
Expand Down Expand Up @@ -704,13 +707,18 @@ private static void compileBinaryAsListOp(BytecodeCompiler bytecodeCompiler, Bin
java.util.List<Integer> argRegs = new java.util.ArrayList<>();
argRegs.add(fhReg);

int savedContext = bytecodeCompiler.currentCallContext;
if (node.right instanceof ListNode argsList) {
for (Node arg : argsList.elements) {
bytecodeCompiler.currentCallContext = RuntimeContextType.LIST;
arg.accept(bytecodeCompiler);
bytecodeCompiler.currentCallContext = savedContext;
argRegs.add(bytecodeCompiler.lastResultReg);
}
} else {
bytecodeCompiler.currentCallContext = RuntimeContextType.LIST;
node.right.accept(bytecodeCompiler);
bytecodeCompiler.currentCallContext = savedContext;
argRegs.add(bytecodeCompiler.lastResultReg);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2608,7 +2608,7 @@ public static void visitOperator(BytecodeCompiler bytecodeCompiler, OperatorNode
op.equals("rename") || op.equals("link") || op.equals("readlink") ||
op.equals("umask") || op.equals("system") || op.equals("pack") ||
op.equals("unpack") || op.equals("vec") || op.equals("crypt") ||
op.equals("localtime") || op.equals("gmtime") || op.equals("caller") || op.equals("reset") ||
op.equals("localtime") || op.equals("gmtime") || op.equals("caller") || op.equals("reset") || op.equals("times") ||
op.equals("fileno") || op.equals("getc") || op.equals("qx") ||
op.equals("close") ||
op.equals("binmode") || op.equals("seek") ||
Expand Down Expand Up @@ -2670,6 +2670,7 @@ public static void visitOperator(BytecodeCompiler bytecodeCompiler, OperatorNode
case "localtime" -> Opcodes.LOCALTIME;
case "gmtime" -> Opcodes.GMTIME;
case "reset" -> Opcodes.RESET;
case "times" -> Opcodes.TIMES;
case "crypt" -> Opcodes.CRYPT;
case "close" -> Opcodes.CLOSE;
case "binmode" -> Opcodes.BINMODE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,7 @@ public String disassemble() {
case Opcodes.LOCALTIME:
case Opcodes.GMTIME:
case Opcodes.RESET:
case Opcodes.TIMES:
case Opcodes.CHMOD:
case Opcodes.UNLINK:
case Opcodes.UTIME:
Expand All @@ -1577,6 +1578,7 @@ public String disassemble() {
case Opcodes.LOCALTIME -> "localtime";
case Opcodes.GMTIME -> "gmtime";
case Opcodes.RESET -> "reset";
case Opcodes.TIMES -> "times";
case Opcodes.CHMOD -> "chmod";
case Opcodes.UNLINK -> "unlink";
case Opcodes.UTIME -> "utime";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public static int execute(int opcode, int[] bytecode, int pc, RuntimeBase[] regi
case Opcodes.LOCALTIME -> Time.localtime(args, ctx);
case Opcodes.GMTIME -> Time.gmtime(args, ctx);
case Opcodes.RESET -> Operator.reset(args, ctx);
case Opcodes.TIMES -> Time.times(ctx);
case Opcodes.CRYPT -> Crypt.crypt(args);
// I/O operators
case Opcodes.CLOSE -> IOOperator.close(ctx, argsArray);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/perlonjava/backend/bytecode/Opcodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -1811,6 +1811,10 @@ public class Opcodes {
* Format: LOAD_BYTE_STRING rd strIndex
*/
public static final short LOAD_BYTE_STRING = 372;
/**
* times: Format: TIMES rd argsReg ctx
*/
public static final short TIMES = 373;

private Opcodes() {
} // Utility class - no instantiation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,9 @@ public static RuntimeCode createRuntimeCode(
// For anonymous subs this is set by SubroutineNode constructor, but for named subs the block
// is passed directly here without going through SubroutineNode.
ast.setAnnotation("blockIsSubroutine", true);
if (ctx.compilerOptions.useInterpreter || RuntimeCode.FORCE_INTERPRETER) {
return compileToInterpreter(ast, ctx, useTryCatch);
}
try {
// Try compiler path
Class<?> generatedClass = createClassWithMethod(ctx, ast, useTryCatch);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ protected boolean removeEldestEntry(Map.Entry<Class<?>, MethodHandle> eldest) {
System.getenv("JPERL_DISASSEMBLE") != null;
public static boolean USE_INTERPRETER =
System.getenv("JPERL_INTERPRETER") != null;
public static final boolean FORCE_INTERPRETER =
System.getenv("JPERL_INTERPRETER") != null;
public static MethodType methodType = MethodType.methodType(RuntimeList.class, RuntimeArray.class, int.class);
// Temporary storage for anonymous subroutines and eval string compiler context
public static HashMap<String, Class<?>> anonSubs = new HashMap<>(); // temp storage for makeCodeObject()
Expand Down Expand Up @@ -186,6 +188,7 @@ public static void setUseInterpreter(boolean value) {
USE_INTERPRETER = value;
}


/**
* Get the current eval runtime context for accessing variable runtime values during parsing.
* This is called by SpecialBlockParser when setting up BEGIN blocks.
Expand Down