forked from JavaTX/JavaCompilerCore
Richtiger Bytecode fuer If-Statements wird erzeugt.
modified: test/bytecode/FacultyTest.java FacultyTest geaendert. new file: test/bytecode/VectorAddTest.java VectorAddTest hinzugefuegt.
This commit is contained in:
parent
f46d26e53f
commit
2add9f518c
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
34
test/bytecode/VectorAddTest.java
Normal file
34
test/bytecode/VectorAddTest.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
19
test/bytecode/javFiles/VectorAdd.jav
Normal file
19
test/bytecode/javFiles/VectorAdd.jav
Normal file
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user