From 3233ccd8452d62f77e037e3beb6da90f85b622a4 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Sun, 18 Mar 2018 16:08:52 +0100 Subject: [PATCH] =?UTF-8?q?Overloading=20funktioniert.=20Erzeugt=20Bytecod?= =?UTF-8?q?e=20f=C3=BCr=20Postincrement=20(f=C3=BCr=20Integers).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytecode/BytecodeGenMethod.java | 73 ++++++++++++------- test/bytecode/MatrixTest.java | 40 ++++++++++ test/bytecode/OverloadingTest.java | 57 +++++++++++++++ test/bytecode/PostIncTest.java | 51 +++++++++++++ test/bytecode/javFiles/Matrix.jav | 27 +++++++ test/bytecode/javFiles/Overloading.jav | 18 +++++ test/bytecode/javFiles/PostInc.jav | 15 ++++ 7 files changed, 256 insertions(+), 25 deletions(-) create mode 100644 test/bytecode/MatrixTest.java create mode 100644 test/bytecode/OverloadingTest.java create mode 100644 test/bytecode/PostIncTest.java create mode 100644 test/bytecode/javFiles/Matrix.jav create mode 100644 test/bytecode/javFiles/Overloading.jav create mode 100644 test/bytecode/javFiles/PostInc.jav diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index d00e7d01..abf3e063 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -15,6 +15,7 @@ import java.util.Iterator; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator; +import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr.Operation; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Handle; @@ -180,9 +181,6 @@ public class BytecodeGenMethod implements StatementVisitor { */ @Override public void visit(BinaryExpr binary) { -// if(!areTypesValid(binary)) { -// return; -// } String lexpType = getResolvedType(binary.lexpr.getType()); String rexpType = getResolvedType(binary.rexpr.getType()); @@ -190,10 +188,6 @@ public class BytecodeGenMethod implements StatementVisitor { String largerType = getLargerType(lexpType,rexpType); String typeOfBinary = getResolvedType(binary.getType()); -// if(!(largerType.equals(typeOfBinary)&&typeOfBinary.equals(Type.getInternalName(Number.class))&&typeOfBinary.equals(Type.getInternalName(Object.class)))) { -// return; -// } - if (typeOfBinary.equals(Type.getInternalName(String.class))) { mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class)); mv.visitInsn(Opcodes.DUP); @@ -688,7 +682,43 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(UnaryExpr unaryExpr) { - System.out.println(unaryExpr.operation.toString()); + unaryExpr.expr.accept(this); + Operation op = unaryExpr.operation; + + String typeOfUnary = getResolvedType(unaryExpr.getType()); + + switch (op) { + case POSTDECREMENT: + case POSTINCREMENT: + genBCForPostUnary(op, typeOfUnary); + break; + + default: + break; + } + getValueOfIns(typeOfUnary); + if(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); + getVlaueIns(typeOfUnary); + doAssign(typeOfUnary, 1.0, true); + + switch (op) { + case POSTDECREMENT: + throw new NotImplementedException(); + + case POSTINCREMENT: + doVisitAddOpInsn(typeOfUnary); + break; + default: + break; + } } @Override @@ -741,8 +771,8 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(Literal literal) { Object value = literal.value; String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor()); - - doAssign(typeOfLiteral, value); + // Name der Methode muss geƤndert werden + doAssign(typeOfLiteral, value, false); } @@ -780,7 +810,7 @@ public class BytecodeGenMethod implements StatementVisitor { } } - private void doAssign(String type, Object value) { + private void doAssign(String type, Object value, boolean isOperator) { switch (type) { case "java/lang/String": mv.visitLdcInsn(String.valueOf(value)); @@ -790,24 +820,16 @@ public class BytecodeGenMethod implements StatementVisitor { break; case "java/lang/Byte": visitByteLiteral(((Double) value).byteValue(), false); - if (!this.isBinaryExp) - getValueOfIns(type); break; case "java/lang/Short": visitShortLiteral(((Double) value).shortValue(), false); - if (!this.isBinaryExp) - getValueOfIns(type); break; case "java/lang/Integer": // zweite Argument isLong visitIntegerLiteral(((Double) value).intValue(), false); - if (!this.isBinaryExp) - getValueOfIns(type); break; case "java/lang/Long": visitLongLiteral(((Double) value).longValue(), true); - if (!this.isBinaryExp) - getValueOfIns(type); break; case "java/lang/Float": visitFloatLiteral(((Double) value).floatValue()); @@ -821,6 +843,12 @@ public class BytecodeGenMethod implements StatementVisitor { default: break; } + + if(!type.equals("java/lang/String")&&!type.equals("java/lang/Boolean")) { + if (!this.isBinaryExp && !isOperator) + getValueOfIns(type); + } + } private void getValueOfIns(String type) { @@ -861,8 +889,7 @@ public class BytecodeGenMethod implements StatementVisitor { private void visitCharLiteral(Character value) { mv.visitIntInsn(Opcodes.BIPUSH, (int) value); - if (!this.isBinaryExp) - getValueOfIns(Type.getInternalName(Character.class)); + } private void visitDoubleLiteral(Double value) { @@ -873,8 +900,6 @@ public class BytecodeGenMethod implements StatementVisitor { } else { mv.visitLdcInsn(value); } - if (!this.isBinaryExp) - getValueOfIns(Type.getInternalName(Double.class)); } private void visitFloatLiteral(Float value) { @@ -884,8 +909,6 @@ public class BytecodeGenMethod implements StatementVisitor { } else { mv.visitLdcInsn(value); } - if (!this.isBinaryExp) - getValueOfIns(Type.getInternalName(Float.class)); } private void visitLongLiteral(Long value, boolean isLong) { diff --git a/test/bytecode/MatrixTest.java b/test/bytecode/MatrixTest.java new file mode 100644 index 00000000..98884151 --- /dev/null +++ b/test/bytecode/MatrixTest.java @@ -0,0 +1,40 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.BeforeClass; +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class MatrixTest { + 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/Matrix.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("Matrix"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + @Test + public void test() { + fail("Not yet implemented"); + } + +} diff --git a/test/bytecode/OverloadingTest.java b/test/bytecode/OverloadingTest.java new file mode 100644 index 00000000..4cdaf39d --- /dev/null +++ b/test/bytecode/OverloadingTest.java @@ -0,0 +1,57 @@ +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 OverloadingTest { + 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; + + private static Class classOL2; + private static Object instanceOfClassOL2; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Overloading.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("Overloading"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + + classOL2 = loader.loadClass("Overloading2"); + instanceOfClassOL2 = classOL2.getDeclaredConstructor().newInstance(); + } + + @Test + public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method meth = classToTest.getDeclaredMethod("test", classToTest); + String res = (String) meth.invoke(instanceOfClass, instanceOfClass); + assertEquals("\"Overloading\"", res); + } + + @Test + public void test2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method meth = classToTest.getDeclaredMethod("test", classOL2); + String res = (String) meth.invoke(instanceOfClass, instanceOfClassOL2); + assertEquals("\"Overloading2\"", res); + } + +} diff --git a/test/bytecode/PostIncTest.java b/test/bytecode/PostIncTest.java new file mode 100644 index 00000000..c96b994c --- /dev/null +++ b/test/bytecode/PostIncTest.java @@ -0,0 +1,51 @@ +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 PostIncTest { + 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/PostInc.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"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + @Test + public void testM1() 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(0, res); + } + +} diff --git a/test/bytecode/javFiles/Matrix.jav b/test/bytecode/javFiles/Matrix.jav new file mode 100644 index 00000000..8120a7c5 --- /dev/null +++ b/test/bytecode/javFiles/Matrix.jav @@ -0,0 +1,27 @@ +import java.util.Vector; +import java.lang.Integer; +import java.lang.Boolean; + +class Matrix extends Vector> { + mul(m) { + var ret = new Matrix(); + var i = 0; + while(i < size()) { + var v1 = this.elementAt(i); + var v2 = new Vector(); + var j = 0; + while(j < v1.size()) { + var erg = 0; + var k = 0; + while(k < v1.size()) { + erg = erg + v1.elementAt(k) + * m.elementAt(k).elementAt(j); + k++; } + v2.addElement(new Integer(erg)); + j++; } + ret.addElement(v2); + i++; + } + return ret; + } +} diff --git a/test/bytecode/javFiles/Overloading.jav b/test/bytecode/javFiles/Overloading.jav new file mode 100644 index 00000000..fb48fe0f --- /dev/null +++ b/test/bytecode/javFiles/Overloading.jav @@ -0,0 +1,18 @@ +import java.lang.String; + +public class Overloading{ + + test(x){ + return x.methode(); + } + + methode(){ + return "Overloading"; + } +} + +public class Overloading2{ + methode(){ + return "Overloading2"; + } +} \ No newline at end of file diff --git a/test/bytecode/javFiles/PostInc.jav b/test/bytecode/javFiles/PostInc.jav new file mode 100644 index 00000000..edae9402 --- /dev/null +++ b/test/bytecode/javFiles/PostInc.jav @@ -0,0 +1,15 @@ +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