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
// 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)) {

View File

@ -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<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);
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<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 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<methods.length; i++) {
// System.out.println(methods[i]);
// }
// methodRefl = getMethod(methodCall.name,methods);
// }catch (Exception e2) {
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);
break;
} catch (Exception e2) {
receiverName = superClass;
continue;
}
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;
break;
}
}
break;
} catch (Exception e3) {
receiverName = superClass;
continue;
}
// }
}
}
@ -761,10 +777,26 @@ public class BytecodeGenMethod implements StatementVisitor {
pos = checkCast.indexOf("<");
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) {
@ -924,16 +956,16 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(Return aReturn) {
statement = new ReturnStmt(aReturn.retexpr);
isBinaryExp = statement.isExprBinary();
boolean isBinary = isBinaryExp;
if(aReturn.retexpr instanceof UnaryExpr)
needDUP = true;
aReturn.retexpr.accept(this);
if (isBinaryExp) {
if (isBinary) {
BinaryExpr binary = (BinaryExpr) aReturn.retexpr;
doBoxing(getResolvedType(binary.getType()));
isBinaryExp = false;
// isBinaryExp = false;
}
mv.visitInsn(Opcodes.ARETURN);
@ -1196,7 +1228,6 @@ public class BytecodeGenMethod implements StatementVisitor {
BinaryExpr binary = (BinaryExpr) al;
String binaryType = getResolvedType(binary.getType());
doBoxing(binaryType);
isBinaryExp = false;
}
statement = null;
}

View File

@ -25,7 +25,5 @@ public class IfStatement extends AStatement{
mv.visitLabel(branchLabel);
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) {
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));

View File

@ -48,7 +48,10 @@ public class TypeToSignature implements TypeVisitor<String> {
@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<String> {
@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

View File

@ -32,16 +32,17 @@ public class FacultyTest {
classToTest = loader.loadClass("Faculty");
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);
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);
}

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,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);
}
}
}

View File

@ -4,16 +4,16 @@ import java.lang.String;
//import java.lang.Byte;
//import java.lang.Boolean;
public class vectorAdd {
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;
}
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;
}
}

View File

@ -1,9 +1,8 @@
package bytecode;
import static org.junit.Assert.assertEquals;
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;
@ -12,7 +11,7 @@ import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class vectorAddTest {
public class VectorAddTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
@ -23,30 +22,13 @@ public class vectorAddTest {
@Test
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);
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");
/*
classToTest = loader.loadClass("VectorAdd");
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);
*/
}
}