Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2

Conflicts:
	test/bytecode/javFiles/VectorAdd.jav
This commit is contained in:
Martin Plümicke 2018-09-26 15:45:23 +02:00
commit 334b56234f
10 changed files with 164 additions and 102 deletions

View File

@ -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 // 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 // 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 TypeToDescriptor());
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
String methParamTypes = retType+method.name+"%%"; String methParamTypes = retType+method.name+"%%";
method.getParameterList().accept(this); method.getParameterList().accept(this);
@ -219,6 +220,7 @@ public class BytecodeGen implements ASTVisitor {
while(itr.hasNext()) { while(itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
} }
if(methodNameAndParamsT.contains(methParamTypes)) { if(methodNameAndParamsT.contains(methParamTypes)) {

View File

@ -9,6 +9,8 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.lang.reflect.Parameter; import java.lang.reflect.Parameter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -503,6 +505,18 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
this.lamCounter++; this.lamCounter++;
String typeErasure = "(";
Iterator<FormalParameter> 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); Lambda lam = new Lambda(lambdaExpression);
String lamDesc = lam.accept(new DescriptorToString(resultSet)); String lamDesc = lam.accept(new DescriptorToString(resultSet));
// Call site, which, when invoked, returns an instance of the functional // Call site, which, when invoked, returns an instance of the functional
@ -518,14 +532,6 @@ public class BytecodeGenMethod implements StatementVisitor {
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die // Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
// Typlöschung) // Typlöschung)
String typeErasure = "(";
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
while (itr.hasNext()) {
itr.next();
typeErasure += "L" + Type.getInternalName(Object.class) + ";";
}
typeErasure += ")L" + Type.getInternalName(Object.class) + ";";
// Type erasure // Type erasure
Type arg1 = Type.getMethodType(typeErasure); Type arg1 = Type.getMethodType(typeErasure);
// Type arg1 = Type.getMethodType(lamDesc); // Type arg1 = Type.getMethodType(lamDesc);
@ -565,7 +571,7 @@ public class BytecodeGenMethod implements StatementVisitor {
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL); Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
generateBCForFunN(lambdaExpression, typeErasure); // generateBCForFunN(lambdaExpression, typeErasure);
} }
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) { private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
@ -663,21 +669,30 @@ public class BytecodeGenMethod implements StatementVisitor {
String receiverName = getResolvedType(methodCall.receiver.getType()); String receiverName = getResolvedType(methodCall.receiver.getType());
System.out.println("Methods of " + receiverName + " "); System.out.println("Methods of " + receiverName + " ");
ClassLoader cLoader = ClassLoader.getSystemClassLoader(); 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; java.lang.reflect.Method methodRefl = null;
String clazz = receiverName.replace("/", "."); String clazz = receiverName.replace("/", ".");
try { try {
if(receiverName.contains("<")) { if(receiverName.contains("<")) {
clazz = clazz.substring(0, receiverName.indexOf("<")); clazz = clazz.substring(0, receiverName.indexOf("<"));
} }
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods(); java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
System.out.println("Methods of " + receiverName + " "); System.out.println("Methods of " + receiverName + " ");
for(java.lang.reflect.Method m : methods) { methodRefl = getMethod(methodCall.name,methods);
if(methodCall.name.equals(m.getName())) {
methodRefl = m;
break;
}
}
} catch (Exception e) { } catch (Exception e) {
// 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<methods.length; i++) {
// System.out.println(methods[i]);
// }
// methodRefl = getMethod(methodCall.name,methods);
// }catch (Exception e2) {
String superClass = ""; String superClass = "";
// TODO: Test SubMatrix.jav // TODO: Test SubMatrix.jav
while(true) { while(true) {
@ -708,10 +723,11 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
break; break;
} catch (Exception e2) { } catch (Exception e3) {
receiverName = superClass; receiverName = superClass;
continue; continue;
} }
// }
} }
} }
@ -761,10 +777,26 @@ public class BytecodeGenMethod implements StatementVisitor {
pos = checkCast.indexOf("<"); pos = checkCast.indexOf("<");
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos)); mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
} }
if(isBinaryExp)
doUnboxing(getResolvedType(methodCall.getType()));
} }
if(isBinaryExp)
doUnboxing(getResolvedType(methodCall.getType()));
}
/**
* @param name name of a method
* @param methods all methods of a class
* @return the method in the class file which its name equals the given methode name
*/
private java.lang.reflect.Method getMethod(String name, java.lang.reflect.Method[] methods) {
for(java.lang.reflect.Method m : methods) {
if(name.equals(m.getName())) {
return m;
}
}
return null;
} }
private String getMethodDesc(java.lang.reflect.Method methodRefl) { private String getMethodDesc(java.lang.reflect.Method methodRefl) {
@ -924,16 +956,16 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(Return aReturn) { public void visit(Return aReturn) {
statement = new ReturnStmt(aReturn.retexpr); statement = new ReturnStmt(aReturn.retexpr);
isBinaryExp = statement.isExprBinary(); isBinaryExp = statement.isExprBinary();
boolean isBinary = isBinaryExp;
if(aReturn.retexpr instanceof UnaryExpr) if(aReturn.retexpr instanceof UnaryExpr)
needDUP = true; needDUP = true;
aReturn.retexpr.accept(this); aReturn.retexpr.accept(this);
if (isBinaryExp) { if (isBinary) {
BinaryExpr binary = (BinaryExpr) aReturn.retexpr; BinaryExpr binary = (BinaryExpr) aReturn.retexpr;
doBoxing(getResolvedType(binary.getType())); doBoxing(getResolvedType(binary.getType()));
isBinaryExp = false; // isBinaryExp = false;
} }
mv.visitInsn(Opcodes.ARETURN); mv.visitInsn(Opcodes.ARETURN);
@ -1196,7 +1228,6 @@ public class BytecodeGenMethod implements StatementVisitor {
BinaryExpr binary = (BinaryExpr) al; BinaryExpr binary = (BinaryExpr) al;
String binaryType = getResolvedType(binary.getType()); String binaryType = getResolvedType(binary.getType());
doBoxing(binaryType); doBoxing(binaryType);
isBinaryExp = false;
} }
statement = null; statement = null;
} }

View File

@ -25,7 +25,5 @@ public class IfStatement extends AStatement{
mv.visitLabel(branchLabel); mv.visitLabel(branchLabel);
this.else_block.accept(bytecodeGenMethod); this.else_block.accept(bytecodeGenMethod);
// mv.visitLabel(endLabel);
// mv.visitJumpInsn(Opcodes.GOTO, endLabel);
} }
} }

View File

@ -231,8 +231,15 @@ public class Signature {
private void createSigForParamTypeWithWC(RefType ref) { private void createSigForParamTypeWithWC(RefType ref) {
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
if(p instanceof WildcardType) { if(p instanceof WildcardType) {
String name = null;
if(((WildcardType) p).getInnerType() instanceof GenericRefType) { 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)) { if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) {
sw.visitFormalTypeParameter(name); sw.visitFormalTypeParameter(name);
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));

View File

@ -48,7 +48,10 @@ public class TypeToSignature implements TypeVisitor<String> {
@Override @Override
public String visit(SuperWildcardType superWildcardType) { public String visit(SuperWildcardType superWildcardType) {
// throw new NotImplementedException(); // 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 @Override
@ -60,7 +63,10 @@ public class TypeToSignature implements TypeVisitor<String> {
@Override @Override
public String visit(ExtendsWildcardType extendsWildcardType) { public String visit(ExtendsWildcardType extendsWildcardType) {
// throw new NotImplementedException(); // 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 @Override

View File

@ -32,16 +32,17 @@ public class FacultyTest {
classToTest = loader.loadClass("Faculty"); classToTest = loader.loadClass("Faculty");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
Method m = classToTest.getDeclaredMethod("m"); Method m = classToTest.getDeclaredMethod("m", Integer.class);
Class<?> lambda = m.invoke(instanceOfClass).getClass(); // Class<?> lambda = m.invoke(instanceOfClass).getClass();
Method apply = lambda.getMethod("apply", Object.class); // Method apply = lambda.getMethod("apply", Object.class);
//
// Damit man auf die Methode zugreifen kann // // Damit man auf die Methode zugreifen kann
apply.setAccessible(true); // apply.setAccessible(true);
Integer i = 3; 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); assertEquals(6, result);
} }

View File

@ -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();
}
}

View File

@ -22,10 +22,11 @@ public class Faculty {
// return 1; // return 1;
// } // }
if (x == 1) { if (x < 0) {
return 0;
}else if(x<2) {
return x; return x;
} } else {
else {
return x * m(x-1); return x * m(x-1);
} }
} }

View File

@ -4,7 +4,7 @@ import java.lang.String;
//import java.lang.Byte; //import java.lang.Byte;
//import java.lang.Boolean; //import java.lang.Boolean;
public class vectorAdd { public class VectorAdd {
add(v1, v2) { add(v1, v2) {
var ret = new Vector(); var ret = new Vector();

View File

@ -1,9 +1,8 @@
package bytecode; package bytecode;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import java.io.File; import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
@ -12,7 +11,7 @@ import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
public class vectorAddTest { public class VectorAddTest {
private static String path; private static String path;
private static File fileToTest; private static File fileToTest;
private static JavaTXCompiler compiler; private static JavaTXCompiler compiler;
@ -23,30 +22,13 @@ public class vectorAddTest {
@Test @Test
public void generateBC() throws Exception { public void generateBC() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/vectorAdd.jav"; path = System.getProperty("user.dir")+"/test/bytecode/javFiles/VectorAdd.jav";
fileToTest = new File(path); fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest); compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/"); compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("vectorAdd"); classToTest = loader.loadClass("VectorAdd");
/*
instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
Method m = classToTest.getDeclaredMethod("m");
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 = 77;
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
assertEquals(77, result);
*/
} }
} }