From 2add9f518cde4208c1d0e9f98b5a1156c5533e17 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 26 Sep 2018 13:46:34 +0200 Subject: [PATCH 1/2] Richtiger Bytecode fuer If-Statements wird erzeugt. modified: test/bytecode/FacultyTest.java FacultyTest geaendert. new file: test/bytecode/VectorAddTest.java VectorAddTest hinzugefuegt. --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 2 + .../bytecode/BytecodeGenMethod.java | 135 +++++++++++------- .../dhbwstuttgart/bytecode/IfStatement.java | 2 - test/bytecode/FacultyTest.java | 15 +- test/bytecode/VectorAddTest.java | 34 +++++ test/bytecode/javFiles/Faculty.jav | 13 +- test/bytecode/javFiles/VectorAdd.jav | 19 +++ 7 files changed, 153 insertions(+), 67 deletions(-) create mode 100644 test/bytecode/VectorAddTest.java create mode 100644 test/bytecode/javFiles/VectorAdd.jav diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 165c888c7..f54c6779e 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -212,6 +212,7 @@ public class BytecodeGen implements ASTVisitor { // TODO: check if the method is static => if static then the first param will be stored in pos 0 // else it will be stored in pos 1 and this will be stored in pos 0 String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); +// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); String methParamTypes = retType+method.name+"%%"; method.getParameterList().accept(this); @@ -219,6 +220,7 @@ public class BytecodeGen implements ASTVisitor { while(itr.hasNext()) { FormalParameter fp = itr.next(); methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; +// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";"; } if(methodNameAndParamsT.contains(methParamTypes)) { diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 2714965b3..45d6f7e7d 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -9,6 +9,8 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Parameter; +import java.net.URL; +import java.net.URLClassLoader; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -503,6 +505,18 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(LambdaExpression lambdaExpression) { this.lamCounter++; + String typeErasure = "("; + Iterator itr = lambdaExpression.params.iterator(); + while (itr.hasNext()) { + itr.next(); + typeErasure += "L" + Type.getInternalName(Object.class) + ";"; + } + + typeErasure += ")L" + Type.getInternalName(Object.class) + ";"; + + generateBCForFunN(lambdaExpression, typeErasure); + + Lambda lam = new Lambda(lambdaExpression); String lamDesc = lam.accept(new DescriptorToString(resultSet)); // Call site, which, when invoked, returns an instance of the functional @@ -518,20 +532,12 @@ public class BytecodeGenMethod implements StatementVisitor { // Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die // Typlöschung) - String typeErasure = "("; - Iterator itr = lambdaExpression.params.iterator(); - while (itr.hasNext()) { - itr.next(); - typeErasure += "L" + Type.getInternalName(Object.class) + ";"; - } - - typeErasure += ")L" + Type.getInternalName(Object.class) + ";"; // Type erasure Type arg1 = Type.getMethodType(typeErasure); // Type arg1 = Type.getMethodType(lamDesc); // real Type Type arg3 = Type.getMethodType(lamDesc); - + int staticOrSpecial = 0; int staticOrInstance = 0; int indexOfFirstParamLam = 0; @@ -565,7 +571,7 @@ public class BytecodeGenMethod implements StatementVisitor { cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL); - generateBCForFunN(lambdaExpression, typeErasure); +// generateBCForFunN(lambdaExpression, typeErasure); } private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) { @@ -663,55 +669,65 @@ public class BytecodeGenMethod implements StatementVisitor { String receiverName = getResolvedType(methodCall.receiver.getType()); System.out.println("Methods of " + receiverName + " "); ClassLoader cLoader = ClassLoader.getSystemClassLoader(); + // This will be used if the class is not standard class (not in API) +// ClassLoader cLoader2; java.lang.reflect.Method methodRefl = null; String clazz = receiverName.replace("/", "."); + try { if(receiverName.contains("<")) { clazz = clazz.substring(0, receiverName.indexOf("<")); } + java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods(); System.out.println("Methods of " + receiverName + " "); - for(java.lang.reflect.Method m : methods) { - if(methodCall.name.equals(m.getName())) { - methodRefl = m; - break; - } - } + methodRefl = getMethod(methodCall.name,methods); + } catch (Exception e) { - String superClass = ""; - // TODO: Test SubMatrix.jav - while(true) { - for(ClassOrInterface cl : sf.getClasses()) { - if(receiverName.equals(cl.getClassName().toString())) { - superClass = cl.getSuperClass().getName().toString(); - break; - } - } - System.out.println(superClass); - - if(superClass.equals("")) - break; - - try { - String superClazz = superClass.replace("/", "."); - if(superClass.contains("<")) { - superClazz = superClazz.substring(0, superClass.indexOf("<")); - } - java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods(); - System.out.println("Methods of " + superClass + " "); - - for(java.lang.reflect.Method m : methods) { - if(methodCall.name.equals(m.getName())) { - methodRefl = m; +// try { +// cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}); +// java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); +// System.out.println("Methods of " + receiverName + " "); +// for(int i = 0; i lambda = m.invoke(instanceOfClass).getClass(); - Method apply = lambda.getMethod("apply", Object.class); - - // Damit man auf die Methode zugreifen kann - apply.setAccessible(true); + Method m = classToTest.getDeclaredMethod("m", Integer.class); +// Class lambda = m.invoke(instanceOfClass).getClass(); +// Method apply = lambda.getMethod("apply", Object.class); +// +// // Damit man auf die Methode zugreifen kann +// apply.setAccessible(true); Integer i = 3; - Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i); +// Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i); + Integer result = (Integer) m.invoke(instanceOfClass,i); assertEquals(6, result); } diff --git a/test/bytecode/VectorAddTest.java b/test/bytecode/VectorAddTest.java new file mode 100644 index 000000000..68651a400 --- /dev/null +++ b/test/bytecode/VectorAddTest.java @@ -0,0 +1,34 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class VectorAddTest { + 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; + + @Test + public void generateBC() throws Exception { + path = System.getProperty("user.dir")+"/test/bytecode/javFiles/VectorAdd.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/"); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("VectorAdd"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } +} diff --git a/test/bytecode/javFiles/Faculty.jav b/test/bytecode/javFiles/Faculty.jav index 794022ab0..f9ff39d65 100644 --- a/test/bytecode/javFiles/Faculty.jav +++ b/test/bytecode/javFiles/Faculty.jav @@ -22,11 +22,12 @@ public class Faculty { // return 1; // } - if (x == 1) { - return x; - } - else { - return x * m(x-1); - } + if (x < 0) { + return 0; + }else if(x<2) { + return x; + } else { + return x * m(x-1); + } } } diff --git a/test/bytecode/javFiles/VectorAdd.jav b/test/bytecode/javFiles/VectorAdd.jav new file mode 100644 index 000000000..e14a1b7c2 --- /dev/null +++ b/test/bytecode/javFiles/VectorAdd.jav @@ -0,0 +1,19 @@ +import java.util.Vector; +import java.lang.Integer; +import java.lang.String; +//import java.lang.Byte; +//import java.lang.Boolean; + +public class VectorAdd { + + add(v1, v2) { + var ret = new Vector(); + var i = 0; + var erg; + while(i < v1.size()) { + erg = v1.elementAt(i) + v2.elementAt(i); + ret.addElement(erg); + } + return ret; + } +} \ No newline at end of file From d3d1d658b81dce2ff89e5d3bb606f5bbec09080a Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 26 Sep 2018 15:37:00 +0200 Subject: [PATCH 2/2] Bug 112 gefixt --- src/de/dhbwstuttgart/bytecode/signature/Signature.java | 9 ++++++++- .../bytecode/signature/TypeToSignature.java | 10 ++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index 600238952..ffcf5409e 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -231,8 +231,15 @@ public class Signature { private void createSigForParamTypeWithWC(RefType ref) { for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { if(p instanceof WildcardType) { + String name = null; if(((WildcardType) p).getInnerType() instanceof GenericRefType) { - String name = new TypeToSignature().visit((GenericRefType)((WildcardType) p).getInnerType()); + name = new TypeToSignature().visit((GenericRefType)((WildcardType) p).getInnerType()); + } + if(((WildcardType) p).getInnerType() instanceof TypePlaceholder) { + name = new TypeToSignature().visit((TypePlaceholder)((WildcardType) p).getInnerType()); + name = name.substring(1); + } + if(name != null) { if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) { sw.visitFormalTypeParameter(name); sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); diff --git a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java index 7d47406d6..247925507 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java @@ -48,7 +48,10 @@ public class TypeToSignature implements TypeVisitor { @Override public String visit(SuperWildcardType superWildcardType) { // throw new NotImplementedException(); - return "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature()); + String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature()); + if(superWildcardType.getInnerType() instanceof TypePlaceholder) + sig += ";"; + return sig; } @Override @@ -60,7 +63,10 @@ public class TypeToSignature implements TypeVisitor { @Override public String visit(ExtendsWildcardType extendsWildcardType) { // throw new NotImplementedException(); - return "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature()); + String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature()); + if(extendsWildcardType.getInnerType() instanceof TypePlaceholder) + sig += ";"; + return sig; } @Override