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

This commit is contained in:
JanUlrich 2018-08-06 16:40:08 +02:00
commit b9aee4da77
7 changed files with 91 additions and 19 deletions

View File

@ -69,7 +69,7 @@ public class BytecodeGenMethod implements StatementVisitor {
private SourceFile sf; private SourceFile sf;
private IStatement statement = null; private IStatement statement = null;
// private int numMethodCalls = 0; private boolean needDUP = false;
// for tests ** // for tests **
private String fieldName; private String fieldName;
@ -159,7 +159,7 @@ public class BytecodeGenMethod implements StatementVisitor {
// wird die lokale Var geladen. Sonst wird zuerst die lokale Var geladen. // wird die lokale Var geladen. Sonst wird zuerst die lokale Var geladen.
System.out.println(localVar.name); System.out.println(localVar.name);
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
if (isBinaryExp) { if (isBinaryExp) {
doUnboxing(getResolvedType(localVar.getType())); doUnboxing(getResolvedType(localVar.getType()));
} }
@ -195,6 +195,7 @@ public class BytecodeGenMethod implements StatementVisitor {
doBoxing(binaryType); doBoxing(binaryType);
isBinaryExp = false; isBinaryExp = false;
} }
System.out.println("ASSIGN TYPE R: " + getResolvedType(assign.rightSide.getType())); System.out.println("ASSIGN TYPE R: " + getResolvedType(assign.rightSide.getType()));
String typeOfRightSide = getResolvedType(assign.rightSide.getType()); String typeOfRightSide = getResolvedType(assign.rightSide.getType());
if(typeOfRightSide.contains("<")) { if(typeOfRightSide.contains("<")) {
@ -225,12 +226,18 @@ public class BytecodeGenMethod implements StatementVisitor {
// this case for while loops // this case for while loops
if (statement instanceof LoopStmt) if (statement instanceof LoopStmt)
mv.visitLabel(endLabel); mv.visitLabel(endLabel);
if(binary.lexpr instanceof UnaryExpr)
needDUP = true;
binary.lexpr.accept(this); binary.lexpr.accept(this);
if (!lexpType.equals(rexpType) && !lexpType.equals(largerType)) if (!lexpType.equals(rexpType) && !lexpType.equals(largerType))
doCast(lexpType, largerType); doCast(lexpType, largerType);
if(binary.rexpr instanceof UnaryExpr)
needDUP = true;
binary.rexpr.accept(this); binary.rexpr.accept(this);
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType)) if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
@ -273,10 +280,6 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
/*
* Diese Methode wird nicht mehr gebraucht, da es jetzt nicht möglich ist, dass
* solche Fälle: Integer -> Integer (OP) Short ,... usw, nicht vorkommen!
*/
private String getLargerType(String lexpType, String rexpType) { private String getLargerType(String lexpType, String rexpType) {
if (lexpType.equals(Type.getInternalName(String.class)) if (lexpType.equals(Type.getInternalName(String.class))
|| rexpType.equals(Type.getInternalName(String.class))) { || rexpType.equals(Type.getInternalName(String.class))) {
@ -828,7 +831,6 @@ public class BytecodeGenMethod implements StatementVisitor {
@Override @Override
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
unaryExpr.expr.accept(this); unaryExpr.expr.accept(this);
Operation op = unaryExpr.operation; Operation op = unaryExpr.operation;
@ -865,6 +867,10 @@ public class BytecodeGenMethod implements StatementVisitor {
// das wird später gemacht, da bytecode für cast noch nicht erzeugt wird // das wird später gemacht, da bytecode für cast noch nicht erzeugt wird
if (isIncOrDec && (unaryExpr.expr instanceof LocalVar)) { if (isIncOrDec && (unaryExpr.expr instanceof LocalVar)) {
if(needDUP) {
mv.visitInsn(Opcodes.DUP);
needDUP = false;
}
LocalVar local = (LocalVar) unaryExpr.expr; LocalVar local = (LocalVar) unaryExpr.expr;
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name)); mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name));
} }
@ -913,7 +919,10 @@ 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();
if(aReturn.retexpr instanceof UnaryExpr)
needDUP = true;
aReturn.retexpr.accept(this); aReturn.retexpr.accept(this);
if (isBinaryExp) { if (isBinaryExp) {
@ -1173,7 +1182,17 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(ArgumentList argumentList) { public void visit(ArgumentList argumentList) {
for (Expression al : argumentList.getArguments()) { for (Expression al : argumentList.getArguments()) {
statement = new ArgumentExpr(al); statement = new ArgumentExpr(al);
isBinaryExp = statement.isExprBinary();
if(al instanceof UnaryExpr)
needDUP = true;
al.accept(this); al.accept(this);
//TODO: teste, ob man das für unary braucht
if (isBinaryExp) {
BinaryExpr binary = (BinaryExpr) al;
String binaryType = getResolvedType(binary.getType());
doBoxing(binaryType);
isBinaryExp = false;
}
statement = null; statement = null;
} }
} }

View File

@ -20,6 +20,7 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResolvedType; import de.dhbwstuttgart.typeinference.result.ResolvedType;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@ -104,10 +105,13 @@ public class Signature {
Iterator<? extends GenericTypeVar> itr = method.getGenerics().iterator(); Iterator<? extends GenericTypeVar> itr = method.getGenerics().iterator();
// visits all formal type parameter and visits their bounds <T:...;B:...;...> // visits all formal type parameter and visits their bounds <T:...;B:...;...>
while(itr.hasNext()) { while(itr.hasNext()) {
System.out.println("HAS GENERICS!!");
GenericTypeVar g = itr.next(); GenericTypeVar g = itr.next();
getBoundsOfTypeVar(g,genericsAndBoundsMethod); getBoundsOfTypeVar(g,genericsAndBoundsMethod);
} }
//TODO: paramtrisierte Typen mit Generics, Type Variablen müssen definiert werden.
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt // 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 // z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
if(!isConstructor) { if(!isConstructor) {
@ -131,7 +135,9 @@ public class Signature {
if(hasTPHs(ref)) { if(hasTPHs(ref)) {
createSignatureForParameterizedType(ref); createSignatureForParameterizedType(ref);
} }
System.out.println("HAS WC = " + hasWC(ref));
if(hasWC(ref))
createSigForParamTypeWithWC(ref);
} }
} }
} }
@ -170,6 +176,10 @@ public class Signature {
RefType ref = (RefType) methodParamsAndTypes.get(paramName); RefType ref = (RefType) methodParamsAndTypes.get(paramName);
if(hasTPHs(ref)) if(hasTPHs(ref))
createSignatureForParameterizedType(ref); createSignatureForParameterizedType(ref);
System.out.println("HAS WC = " + hasWC(ref));
if(hasWC(ref))
createSigForParamTypeWithWC(ref);
} }
for(GenericInsertPair p:methodPairs) { for(GenericInsertPair p:methodPairs) {
@ -218,6 +228,34 @@ public class Signature {
// sw.visitEnd(); // sw.visitEnd();
} }
private void createSigForParamTypeWithWC(RefType ref) {
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
if(p instanceof WildcardType) {
if(((WildcardType) p).getInnerType() instanceof GenericRefType) {
String name = new TypeToSignature().visit((GenericRefType)((WildcardType) p).getInnerType());
if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) {
sw.visitFormalTypeParameter(name);
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
genericsAndBoundsMethod.put(name, Type.getInternalName(Object.class));
}
}
}
}
}
private boolean hasWC(RefType ref) {
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
System.out.println("HAS WCs: " + p.acceptTV(new TypeToString()));
System.out.println("HAS WCs: " + p.getClass());
if(p.acceptTV(new TypeToString()).contains("WC"))
return true;
}
return false;
}
private void createSignatureForParameterizedType(RefType ref) { private void createSignatureForParameterizedType(RefType ref) {
ArrayList<GenericInsertPair> allPairs = getAllPairs(ref); ArrayList<GenericInsertPair> allPairs = getAllPairs(ref);
allPairs.addAll(methodPairs); allPairs.addAll(methodPairs);
@ -347,7 +385,7 @@ public class Signature {
private boolean hasTPHs(RefType ref) { private boolean hasTPHs(RefType ref) {
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
System.out.println(p.acceptTV(new TypeToString())); System.out.println("HAS TPHs: " + p.acceptTV(new TypeToString()));
if(p.acceptTV(new TypeToString()).contains("WC")){ if(p.acceptTV(new TypeToString()).contains("WC")){
continue; continue;
} }

View File

@ -48,7 +48,7 @@ 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()); return "+" + superWildcardType.getInnerType().acceptTV(new TypeToSignature());
} }
@Override @Override
@ -60,7 +60,7 @@ 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()); return "-" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature());
} }
@Override @Override

View File

@ -39,5 +39,12 @@ public class BinaryTest {
Integer res = (Integer) m2.invoke(instanceOfClass, 2,3); Integer res = (Integer) m2.invoke(instanceOfClass, 2,3);
assertEquals(6, res); assertEquals(6, res);
} }
@Test
public void testM3() throws Exception {
Method m3 = classToTest.getDeclaredMethod("m3", Integer.class);
Integer res = (Integer) m3.invoke(instanceOfClass, 2);
assertEquals(4, res);
}
} }

View File

@ -1,5 +1,6 @@
package bytecode; package bytecode;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.io.File; import java.io.File;
@ -20,15 +21,16 @@ public class MergeTest {
private static String pathToClassFile; private static String pathToClassFile;
private static Object instanceOfClass; private static Object instanceOfClass;
@Test @Test
public void generateBC() throws Exception { public void generateBC() throws Exception {
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Merge.jav"; path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Merge.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("Merge"); // classToTest = loader.loadClass("Merge");
//instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); //instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
//Method m = classToTest.getDeclaredMethod("m"); //Method m = classToTest.getDeclaredMethod("m");

View File

@ -10,4 +10,8 @@ public class BinaryInMeth {
m2(a,b){ m2(a,b){
return m(a+b); return m(a+b);
} }
m3(a) {
return m(++a);
}
} }

View File

@ -2,12 +2,14 @@ import java.util.List;
import java.lang.Integer; import java.lang.Integer;
import java.util.Collection; import java.util.Collection;
class Merge { class Merge {
merge(a, b) { merge(a, b) {
a.addAll(b); a.addAll(b);
return a; return a;
} }
/* /*
sort(in){ sort(in){
var firstHalf = in.subList(1,2); var firstHalf = in.subList(1,2);