From fdae0442878efb258a48e1326f899c5b404ad75c Mon Sep 17 00:00:00 2001 From: volodya-lombrozo Date: Wed, 13 Mar 2024 14:38:26 +0300 Subject: [PATCH 01/10] feat(#488): handle all opcodes up to 53 instruction --- .../src/main/java/org/eolang/jeo/Bar.java | 5 +++++ src/it/spring-fat/pom.xml | 2 +- .../bytecode/BytecodeInstructionEntry.java | 7 +++++++ .../representation/bytecode/BytecodeClassTest.java | 13 +++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/it/custom-transformations/src/main/java/org/eolang/jeo/Bar.java b/src/it/custom-transformations/src/main/java/org/eolang/jeo/Bar.java index 8719670b7..2fd8b3f97 100644 --- a/src/it/custom-transformations/src/main/java/org/eolang/jeo/Bar.java +++ b/src/it/custom-transformations/src/main/java/org/eolang/jeo/Bar.java @@ -7,4 +7,9 @@ public int foo(int x) { } return 2; } + + public void sipush() { + short s = 256; + System.out.println(s); + } } \ No newline at end of file diff --git a/src/it/spring-fat/pom.xml b/src/it/spring-fat/pom.xml index f512d15a0..971b0db05 100644 --- a/src/it/spring-fat/pom.xml +++ b/src/it/spring-fat/pom.xml @@ -90,7 +90,7 @@ SOFTWARE. support many java features. We need to implement them and enable the test. --> - true + false diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java index d00c68284..c8b8b75f7 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java @@ -225,6 +225,13 @@ private enum Instruction { visitor.visitIntInsn(Opcodes.BIPUSH, (int) arguments.get(0)) ), + /** + * Push a short onto the stack as an integer value. + */ + SIPUSH(Opcodes.SIPUSH, (visitor, arguments) -> + visitor.visitIntInsn(Opcodes.SIPUSH, (int) arguments.get(0)) + ), + /** * Push a constant #index from a constant pool onto the stack. */ diff --git a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java index dcb970563..71fb2a3bc 100644 --- a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java +++ b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeClassTest.java @@ -193,4 +193,17 @@ void failsBecauseBytecodeIsBroken() { "We expect an exception here because the bytecode is broken" ); } + + @Test + void returnsShortValue() { + Assertions.assertDoesNotThrow( + () -> new BytecodeClass("ShortValue") + .withMethod("j$foo", "()S", Opcodes.ACC_PUBLIC) + .opcode(Opcodes.SIPUSH, 256) + .opcode(Opcodes.IRETURN) + .up() + .bytecode(), + "We expect no exception here because all instructions are valid" + ); + } } From 5df171499a7998b0c68ccdf907e544dc93185849 Mon Sep 17 00:00:00 2001 From: volodya-lombrozo Date: Wed, 13 Mar 2024 14:47:32 +0300 Subject: [PATCH 02/10] feat(#488): handle all opcodes up to 158 (ifle) --- .../bytecode/BytecodeInstructionEntry.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java index c8b8b75f7..7aa232ff4 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java @@ -341,13 +341,6 @@ private enum Instruction { visitor.visitInsn(Opcodes.SALOAD) ), - /** - * Add two integers. - */ - IADD(Opcodes.IADD, (visitor, arguments) -> - visitor.visitInsn(Opcodes.IADD) - ), - /** * Store int value into variable #index. */ @@ -507,6 +500,12 @@ private enum Instruction { visitor.visitInsn(Opcodes.SWAP) ), + /** + * Add two integers. + */ + IADD(Opcodes.IADD, (visitor, arguments) -> + visitor.visitInsn(Opcodes.IADD) + ), /** * Add two longs. */ From c0b6cbd94c64d29246df5a95d43eb0d50a997105 Mon Sep 17 00:00:00 2001 From: volodya-lombrozo Date: Wed, 13 Mar 2024 15:26:17 +0300 Subject: [PATCH 03/10] feat(#488): handle all opcodes up to 178 (getstatic) --- .../bytecode/BytecodeInstructionEntry.java | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java index 7aa232ff4..314fdf9e7 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstructionEntry.java @@ -31,6 +31,7 @@ import lombok.ToString; import org.eolang.jeo.representation.directives.OpcodeName; import org.eolang.jeo.representation.xmir.AllLabels; +import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @@ -961,6 +962,36 @@ private enum Instruction { ) ), + /** + * If the two integer values are equal, branch to instruction at branchoffset. + */ + IF_ICMPEQ(Opcodes.IF_ICMPEQ, (visitor, arguments) -> + visitor.visitJumpInsn( + Opcodes.IF_ICMPEQ, + (org.objectweb.asm.Label) arguments.get(0) + ) + ), + + /** + * If the two integer values are not equal, branch to instruction at branchoffset. + */ + IF_ICMPNE(Opcodes.IF_ICMPNE, (visitor, arguments) -> + visitor.visitJumpInsn( + Opcodes.IF_ICMPNE, + (org.objectweb.asm.Label) arguments.get(0) + ) + ), + + /** + * If value1 is less than value2, branch to instruction at branchoffset. + */ + IF_ICMPLT(Opcodes.IF_ICMPLT, (visitor, arguments) -> + visitor.visitJumpInsn( + Opcodes.IF_ICMPLT, + (org.objectweb.asm.Label) arguments.get(0) + ) + ), + /** * If value1 is greater than or equal to value2, branch to instruction at branchoffset. */ @@ -971,6 +1002,16 @@ private enum Instruction { ) ), + /** + * If value1 is greater than value2, branch to instruction at branchoffset. + */ + IF_ICMPGT(Opcodes.IF_ICMPGT, (visitor, arguments) -> + visitor.visitJumpInsn( + Opcodes.IF_ICMPGT, + (org.objectweb.asm.Label) arguments.get(0) + ) + ), + /** * If value1 is less than or equal to value2, branch to instruction at branchoffset. */ @@ -981,6 +1022,26 @@ private enum Instruction { ) ), + /** + * If references are equal, branch to instruction at branchoffset. + */ + IF_ACMPEQ(Opcodes.IF_ACMPEQ, (visitor, arguments) -> + visitor.visitJumpInsn( + Opcodes.IF_ACMPEQ, + (org.objectweb.asm.Label) arguments.get(0) + ) + ), + + /** + * If references are not equal, branch to instruction at branchoffset. + */ + IF_ACMPNE(Opcodes.IF_ACMPNE, (visitor, arguments) -> + visitor.visitJumpInsn( + Opcodes.IF_ACMPNE, + (org.objectweb.asm.Label) arguments.get(0) + ) + ), + /** * Goes to another instruction at branchoffset. */ @@ -991,6 +1052,62 @@ private enum Instruction { ) ), + /** + * Jump to subroutine at branchoffset + */ + JSR(Opcodes.JSR, (visitor, arguments) -> + visitor.visitJumpInsn( + Opcodes.JSR, + (org.objectweb.asm.Label) arguments.get(0) + ) + ), + + /** + * Return from subroutine. + */ + RET(Opcodes.RET, (visitor, arguments) -> + visitor.visitVarInsn( + Opcodes.RET, + (int) arguments.get(0) + ) + ), + + /** + * Access jump table by key match and jump. + * Continue execution from an address in the table at offset index + */ + TABLESWITCH(Opcodes.TABLESWITCH, (visitor, arguments) -> + visitor.visitTableSwitchInsn( + (int) arguments.get(0), + (int) arguments.get(1), + (org.objectweb.asm.Label) arguments.get(2), + arguments.subList(3, arguments.size()).stream() + .map(label -> (org.objectweb.asm.Label) label) + .toArray(org.objectweb.asm.Label[]::new) + ) + ), + + /** + * Access jump table by key match and jump. + * A target address is looked up from a table using a key and execution + * continues from the instruction at that address + */ + LOOKUPSWITCH(Opcodes.LOOKUPSWITCH, (visitor, arguments) -> { + final List