From e1c6369bcb2c25152d36a3d270fd203d599f944d Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 21 Mar 2018 13:08:39 +0100 Subject: [PATCH] =?UTF-8?q?Bytecode=20f=C3=BCr=20Post-/Preincrement=20und?= =?UTF-8?q?=20Post-/Predecrement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytecode/BytecodeGenMethod.java | 64 ++++++++++++++---- test/bytecode/PostIncTest.java | 18 ++++- test/bytecode/PreIncTest.java | 65 +++++++++++++++++++ test/bytecode/javFiles/PostInc.jav | 15 ----- test/bytecode/javFiles/PostIncDec.jav | 27 ++++++++ test/bytecode/javFiles/PreInc.jav | 28 ++++++++ 6 files changed, 187 insertions(+), 30 deletions(-) create mode 100644 test/bytecode/PreIncTest.java delete mode 100644 test/bytecode/javFiles/PostInc.jav create mode 100644 test/bytecode/javFiles/PostIncDec.jav create mode 100644 test/bytecode/javFiles/PreInc.jav diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index abf3e063..a27e40a6 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -175,10 +175,7 @@ public class BytecodeGenMethod implements StatementVisitor { isAssignStmt =false; } - /* - * Die folgeneden Fälle müssen noch betrachtet werden: - Long OPARATION Integer - * usw. - */ + @Override public void visit(BinaryExpr binary) { @@ -194,7 +191,7 @@ public class BytecodeGenMethod implements StatementVisitor { mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "", "()V", false); } - // tmp!! + Label endLabel = new Label(); // this case for while loops if(!isAssignStmt) @@ -687,35 +684,76 @@ public class BytecodeGenMethod implements StatementVisitor { String typeOfUnary = getResolvedType(unaryExpr.getType()); + boolean isIncOrDec = false; + switch (op) { case POSTDECREMENT: case POSTINCREMENT: - genBCForPostUnary(op, typeOfUnary); + if(isAssignStmt) + mv.visitInsn(Opcodes.DUP); + genBCForIncAndDec(op, typeOfUnary); + getValueOfIns(typeOfUnary); + isIncOrDec = true; + break; + case PREDECREMENT: + case PREINCREMENT: + genBCForIncAndDec(op, typeOfUnary); + getValueOfIns(typeOfUnary); + if(isAssignStmt) + mv.visitInsn(Opcodes.DUP); + isIncOrDec = true; + break; + + case MINUS: + doVisitNegIns(typeOfUnary); break; - default: break; } - getValueOfIns(typeOfUnary); - if(unaryExpr.expr instanceof LocalVar) { + + // Für Byte und Short muss noch einen Cast geben i2b, i2s + // das wird später gemacht, da bytecode für cast noch nicht erzeugt wird + + if(isIncOrDec && (unaryExpr.expr instanceof LocalVar)) { LocalVar local = (LocalVar) unaryExpr.expr; mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name)); } } - private void genBCForPostUnary(Operation op, String typeOfUnary) { - if(isAssignStmt) - mv.visitInsn(Opcodes.DUP); + private void doVisitNegIns(String typeOfUnary) { + switch (typeOfUnary) { + case "java/lang/Long": + mv.visitInsn(Opcodes.LNEG); + break; + case "java/lang/Double": + mv.visitInsn(Opcodes.DNEG); + break; + case "java/lang/Float": + mv.visitInsn(Opcodes.FNEG); + break; + default: + mv.visitInsn(Opcodes.INEG); + break; + } + + } + + private void genBCForIncAndDec(Operation op, String typeOfUnary) { + getVlaueIns(typeOfUnary); doAssign(typeOfUnary, 1.0, true); switch (op) { case POSTDECREMENT: - throw new NotImplementedException(); + case PREDECREMENT: + doVisitSubOpInsn(typeOfUnary); + break; case POSTINCREMENT: + case PREINCREMENT: doVisitAddOpInsn(typeOfUnary); break; + default: break; } diff --git a/test/bytecode/PostIncTest.java b/test/bytecode/PostIncTest.java index c96b994c..36e63816 100644 --- a/test/bytecode/PostIncTest.java +++ b/test/bytecode/PostIncTest.java @@ -24,13 +24,13 @@ public class PostIncTest { @BeforeClass public static void setUpBeforeClass() throws Exception { - path = System.getProperty("user.dir")+"/test/bytecode/javFiles/PostInc.jav"; + path = System.getProperty("user.dir")+"/test/bytecode/javFiles/PostIncDec.jav"; fileToTest = new File(path); compiler = new JavaTXCompiler(fileToTest); compiler.generateBytecode(); pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); - classToTest = loader.loadClass("PostInc"); + classToTest = loader.loadClass("PostIncDec"); instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); } @@ -47,5 +47,19 @@ public class PostIncTest { Integer res = (Integer) m.invoke(instanceOfClass); assertEquals(0, res); } + + @Test + public void testD1() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("d"); + Integer res = (Integer) m.invoke(instanceOfClass); + assertEquals(-1, res); + } + + @Test + public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("d2"); + Integer res = (Integer) m.invoke(instanceOfClass); + assertEquals(0, res); + } } diff --git a/test/bytecode/PreIncTest.java b/test/bytecode/PreIncTest.java new file mode 100644 index 00000000..434b88e1 --- /dev/null +++ b/test/bytecode/PreIncTest.java @@ -0,0 +1,65 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.BeforeClass; +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class PreIncTest { + private static String path; + private static File fileToTest; + private static JavaTXCompiler compiler; + private static ClassLoader loader; + private static Class classToTest; + private static String pathToClassFile; + private static Object instanceOfClass; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + path = System.getProperty("user.dir")+"/test/bytecode/javFiles/PreInc.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + compiler.generateBytecode(); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://" + pathToClassFile)}); + classToTest = loader.loadClass("PreInc"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + @Test + public void testM() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("m"); + Integer res = (Integer) m.invoke(instanceOfClass); + assertEquals(1, res); + } + + @Test + public void testM2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("m2"); + Integer res = (Integer) m.invoke(instanceOfClass); + assertEquals(1, res); + } + + @Test + public void testD() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("d"); + Integer res = (Integer) m.invoke(instanceOfClass); + assertEquals(-1, res); + } + + @Test + public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("d2"); + Integer res = (Integer) m.invoke(instanceOfClass); + assertEquals(-1, res); + } + +} diff --git a/test/bytecode/javFiles/PostInc.jav b/test/bytecode/javFiles/PostInc.jav deleted file mode 100644 index edae9402..00000000 --- a/test/bytecode/javFiles/PostInc.jav +++ /dev/null @@ -1,15 +0,0 @@ -import java.lang.Integer; - -public class PostInc { - m() { - var i = 0; - i++; - return i; - } - - m2() { - var i = 0; - var j = i++; - return j; - } -} \ No newline at end of file diff --git a/test/bytecode/javFiles/PostIncDec.jav b/test/bytecode/javFiles/PostIncDec.jav new file mode 100644 index 00000000..29c2ef17 --- /dev/null +++ b/test/bytecode/javFiles/PostIncDec.jav @@ -0,0 +1,27 @@ +import java.lang.Integer; + +public class PostIncDec { + m() { + var i = 0; + i++; + return i; + } + + m2() { + var i = 0; + var j = i++; + return j; + } + + d() { + var i = 0; + i--; + return i; + } + + d2() { + var i = 0; + var j = i--; + return j; + } +} \ No newline at end of file diff --git a/test/bytecode/javFiles/PreInc.jav b/test/bytecode/javFiles/PreInc.jav new file mode 100644 index 00000000..011501f1 --- /dev/null +++ b/test/bytecode/javFiles/PreInc.jav @@ -0,0 +1,28 @@ +import java.lang.Integer; + +public class PreInc { + m() { + var i = 0; + ++i; + return i; + } + + m2() { + var i = 0; + var j = ++i; + return j; + } + + d() { + var i = 0; + --i; + return i; + } + + d2() { + var i = 0; + var j = --i; + return j; + } + +} \ No newline at end of file