Bugs gefixt. Bytecode-Erzeugung für MethodCall ergänzt. Bytecode für Matrix-Test (Funktioniert noch nicht ganzErzeugung Signatures und Descriptors verbessert

This commit is contained in:
Fayez Abu Alia 2018-06-13 15:50:05 +02:00
parent ff2bca5ce5
commit b325e205a1
10 changed files with 899 additions and 76 deletions

View File

@ -45,6 +45,8 @@ public class BytecodeGen implements ASTVisitor {
private ResultSet resultSet;
private int indexOfFirstParam = 0;
private String superClass;
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,...
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
// stores generics and their bounds of class
@ -109,6 +111,7 @@ public class BytecodeGen implements ASTVisitor {
boolean isConsWithNoParamsVisited = false;
boolean isVisited = false;
for(ResultSet rs : listOfResultSets) {
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
resultSet = rs;
// Nur einmal ausführen!!
if(!isVisited) {
@ -206,7 +209,7 @@ public class BytecodeGen implements ASTVisitor {
desc = constructor.accept(new DescriptorToString(resultSet));
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
mv.visitCode();
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,cw,
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw,
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
if(!field.getParameterList().iterator().hasNext()) {
mv.visitInsn(Opcodes.RETURN);
@ -284,7 +287,7 @@ public class BytecodeGen implements ASTVisitor {
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
mv.visitCode();
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,method, mv,paramsAndLocals,cw,
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
mv.visitMaxs(0, 0);

View File

@ -29,6 +29,7 @@ import org.objectweb.asm.signature.SignatureWriter;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
import de.dhbwstuttgart.bytecode.utilities.Lambda;
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
@ -52,10 +53,11 @@ public class BytecodeGenMethod implements StatementVisitor {
private ClassWriter cw;
private ResultSet resultSet;
private boolean isInterface;
HashMap<String, String> genericsAndBoundsMethod;
private HashMap<String, String> genericsAndBoundsMethod;
private HashMap<String, String> genericsAndBounds;
private boolean isBinaryExp = false;
private String superClass;
private IStatement statement = null;
// for tests **
@ -69,11 +71,12 @@ public class BytecodeGenMethod implements StatementVisitor {
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
public BytecodeGenMethod(String className, ResultSet resultSet, Method m, MethodVisitor mv,
public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv,
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
this.className = className;
this.superClass = superClass;
this.resultSet = resultSet;
this.m = m;
this.mv = mv;
@ -106,7 +109,11 @@ public class BytecodeGenMethod implements StatementVisitor {
}
lambdaExpression.methodBody.accept(this);
}
public void isBinary(boolean isBinary) {
this.isBinaryExp =isBinary;
}
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
}
@ -122,7 +129,7 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(SuperCall superCall) {
superCall.receiver.accept(this);
superCall.arglist.accept(this);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.superClass, superCall.name, "()V",
isInterface);
}
@ -169,6 +176,11 @@ public class BytecodeGenMethod implements StatementVisitor {
doBoxing(binaryType);
isBinaryExp = false;
}
System.out.println("ASSIGN TYPE R: " + getResolvedType(assign.rightSide.getType()));
String typeOfRightSide = getResolvedType(assign.rightSide.getType());
if(typeOfRightSide.contains("<")) {
mv.visitTypeInsn(Opcodes.CHECKCAST, typeOfRightSide.substring(0, typeOfRightSide.indexOf('<')));
}
assign.lefSide.accept(this);
statement = null;
@ -623,14 +635,15 @@ public class BytecodeGenMethod implements StatementVisitor {
@Override
public void visit(MethodCall methodCall) {
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
methodCall.receiver.accept(this);
methodCall.arglist.accept(this);
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
genericsAndBoundsMethod, genericsAndBounds);
String mDesc = method.accept(new DescriptorToString(resultSet));
System.out.println("Methodcall Desc : " + mDesc);
// is methodCall.receiver functional Interface)?
if (varsFunInterface.contains(methodCall.receiver.getType())) {
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name,
@ -643,6 +656,9 @@ public class BytecodeGenMethod implements StatementVisitor {
// if(!methodCall.getType().toString().equals("V")) {
// mv.visitInsn(Opcodes.POP);
// }
if(isBinaryExp) {
doUnboxing(getResolvedType(methodCall.getType()));
}
}
@Override
@ -801,7 +817,7 @@ public class BytecodeGenMethod implements StatementVisitor {
statement = new LoopStmt(whileStmt.expr, whileStmt.loopBlock);
isBinaryExp = statement.isExprBinary();
whileStmt.expr.accept(this);
isBinaryExp = false;
// isBinaryExp = false;
statement = null;
}

View File

@ -18,6 +18,7 @@ public class LoopStmt extends AStatement {
@Override
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
bytecodeGenMethod.isBinary(false);
this.loopBlock.accept(bytecodeGenMethod);
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
mv.visitLabel(branchLabel);

View File

@ -145,9 +145,9 @@ public class DescriptorToString implements DescriptorVisitor{
public String visit(MethodFromMethodCall methodFromMethodCall) {
String desc = "(";
for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
String d = e.getType().acceptTV(new TypeToDescriptor());
String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(d.substring(0, 4).equals("TPH ")) {
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) {
desc += "L"+Type.getInternalName(Object.class)+ ";";
}else {
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
@ -160,19 +160,19 @@ public class DescriptorToString implements DescriptorVisitor{
}
}
if(resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.toString().equals("void")) {
String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
System.out.println("DescriptorToString retType = " + retType);
if(retType.equals("void")) {
desc += ")V";
}else if(resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()).substring(0, 4).equals("TPH ")){
}else if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){
desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else {
String ret = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(ret)) {
desc += ")L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(ret)+ ";";
}else if(methodFromMethodCall.getGenericsAndBounds().containsKey(ret)){
desc += ")L"+methodFromMethodCall.getGenericsAndBounds().get(ret)+ ";";
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {
desc += ")L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(retType)+ ";";
}else if(methodFromMethodCall.getGenericsAndBounds().containsKey(retType)){
desc += ")L"+methodFromMethodCall.getGenericsAndBounds().get(retType)+ ";";
}else {
desc += ")" + "L"+resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
desc += ")" + "L"+retType+ ";";
}
}
// desc = addReturnType(desc, methodFromMethodCall.getReturnType(), resultSet);

View File

@ -19,7 +19,9 @@ public class TypeToDescriptor implements TypeVisitor<String>{
@Override
public String visit(SuperWildcardType superWildcardType) {
throw new NotImplementedException();
System.out.println("\nWILDCARD ="+superWildcardType.getInnerType().toString().replace(".", "/"));
return superWildcardType.getInnerType().toString().replace(".", "/");
//throw new NotImplementedException();
}
@Override
@ -29,6 +31,7 @@ public class TypeToDescriptor implements TypeVisitor<String>{
@Override
public String visit(ExtendsWildcardType extendsWildcardType) {
System.out.println("\nWILDCARD extends ="+extendsWildcardType.getInnerType().toString().replace(".", "/"));
return extendsWildcardType.getInnerType().toString().replace(".", "/");
//throw new NotImplementedException();
}

View File

@ -102,51 +102,49 @@ public class Signature {
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
}
if(!methodPairs.isEmpty()) {
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
if(ret.substring(0,4).equals("TPH ")) {
String g = ret.substring(4)+"$";
if(genericsAndBounds.containsKey(g)) {
genericsAndBoundsMethod.put(g, genericsAndBounds.get(g));
}else {
sw.visitFormalTypeParameter(g);
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
}
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
if(ret.substring(0,4).equals("TPH ")) {
String g = ret.substring(4)+"$";
if(genericsAndBounds.containsKey(g)) {
genericsAndBoundsMethod.put(g, genericsAndBounds.get(g));
}else {
sw.visitFormalTypeParameter(g);
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
}
// Parameters
for(String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
String pT = t.acceptTV(new TypeToSignature());
// S.o
if(pT.substring(0,4).equals("TPH ")) {
String gP = pT.substring(4)+"$";
if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) {
sw.visitFormalTypeParameter(gP);
String bound = Type.getInternalName(Object.class);
boolean isTypeVar = false;
for(GenericInsertPair pair : methodPairs) {
if(pT.substring(4).equals(pair.TA1.getName())) {
bound = pair.TA2.getName()+"$";
isTypeVar = true;
break;
}
}
if(isTypeVar) {
sw.visitClassBound().visitTypeVariable(bound);
}else {
sw.visitClassBound().visitClassType(bound);
sw.visitClassBound().visitEnd();
}
genericsAndBoundsMethod.put(gP, bound);
}
// Parameters
for(String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
String pT = t.acceptTV(new TypeToSignature());
// S.o
if(pT.substring(0,4).equals("TPH ")) {
String gP = pT.substring(4)+"$";
if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) {
sw.visitFormalTypeParameter(gP);
String bound = Type.getInternalName(Object.class);
boolean isTypeVar = false;
for(GenericInsertPair pair : methodPairs) {
if(pT.substring(4).equals(pair.TA1.getName())) {
bound = pair.TA2.getName()+"$";
isTypeVar = true;
break;
}
}
if(isTypeVar) {
sw.visitClassBound().visitTypeVariable(bound);
}else {
sw.visitClassBound().visitClassType(bound);
sw.visitClassBound().visitEnd();
}
genericsAndBoundsMethod.put(gP, bound);
}
}
// methodPairs.forEach(p->{

View File

@ -0,0 +1,41 @@
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 Tph2Test {
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/Tph2.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("Tph2");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test() {
fail("Not yet implemented");
}
}

View File

@ -2,24 +2,24 @@ import java.util.Vector;
import java.lang.Integer;
import java.lang.Boolean;
class Matrix extends Vector<Vector<Integer>> {
public class Matrix extends Vector<Vector<Integer>> {
mul(m) {
var ret = new Matrix();
var i = 0;
while(i < size()) {
// var v1 = this.elementAt(i);
// var v2 = new Vector<Integer>();
// var j = 0;
// while(j < v1.size()) {
var v1 = this.elementAt(i);
var v2 = new Vector<Integer>();
var j = 0;
while(j < v1.size()) {
// var erg = 0;
// var k = 0;
// while(k < v1.size()) {
// 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);
// * m.elementAt(k).elementAt(j);
// k++; }
// v2.addElement(new Integer(erg));
j++; }
ret.addElement(v2);
i++;
}
return ret;

BIN
test/logFiles/.log.swp Normal file

Binary file not shown.

761
test/logFiles/log Normal file

File diff suppressed because one or more lines are too long