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

This commit is contained in:
Martin Plümicke 2018-12-19 14:09:48 +01:00
commit a4eaaa748e
11 changed files with 252 additions and 16 deletions

View File

@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
@ -62,6 +63,8 @@ public class BytecodeGen implements ASTVisitor {
private String superClass; private String superClass;
private ArrayList<TypePlaceholder> tphsClass;
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... // 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<>(); HashMap<String, Integer> paramsAndLocals = new HashMap<>();
// stores generics and their bounds of class // stores generics and their bounds of class
@ -131,20 +134,44 @@ public class BytecodeGen implements ASTVisitor {
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()); superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
resultSet = rs; resultSet = rs;
tphExtractor.setResultSet(resultSet); tphExtractor.setResultSet(resultSet);
// Nur einmal ausführen!! // Nur einmal ausführen!!
if(!isVisited) { if(!isVisited) {
classOrInterface.accept(tphExtractor); classOrInterface.accept(tphExtractor);
getCommonTPHS(tphExtractor); getCommonTPHS(tphExtractor);
tphsClass = new ArrayList<>();
for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(t))
tphsClass.add(t);
}
ArrayList<TPHConstraint> consClass = new ArrayList<>();
for(TPHConstraint cons : tphExtractor.allCons) {
TypePlaceholder right = null;
for(TypePlaceholder tph : tphsClass) {
if(cons.getLeft().equals(tph.getName())) {
consClass.add(cons);
right = getTPH(cons.getRight());
}
}
if(right != null) {
tphsClass.add(right);
removeFromMethod(right.getName());
right = null;
}
}
String sig = null; String sig = null;
/* if class has generics then creates signature /* if class has generics then creates signature
* Signature looks like: * Signature looks like:
* <E:Ljava/...>Superclass * <E:Ljava/...>Superclass
*/ */
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() || if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() ||
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")) { classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs); || !tphsClass.isEmpty()) {
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass);
sig = signature.toString(); sig = signature.toString();
System.out.println("Signature: => " + sig); System.out.println("Signature: => " + sig);
} }
@ -176,6 +203,31 @@ public class BytecodeGen implements ASTVisitor {
} }
private void removeFromMethod(String name) {
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
ArrayList<String> toRemove = new ArrayList<>();
for(String tph : m.getTphs()) {
if(tph.equals(name)) {
toRemove.add(tph);
}
}
if(!toRemove.isEmpty()) {
m.getTphs().removeAll(toRemove);
return;
}
}
}
private TypePlaceholder getTPH(String name) {
for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) {
if(tph.getName().equals(name))
return tph;
}
throw new NoSuchElementException("TPH "+name +" does not exist");
}
private void getCommonTPHS(TPHExtractor tphExtractor) { private void getCommonTPHS(TPHExtractor tphExtractor) {
// Gemeinsame TPHs // Gemeinsame TPHs
ArrayList<TypePlaceholder> cTPHs = new ArrayList<>(); ArrayList<TypePlaceholder> cTPHs = new ArrayList<>();
@ -228,7 +280,7 @@ public class BytecodeGen implements ASTVisitor {
} }
String sig = null; String sig = null;
if(hasGen) { if(hasGen) {
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor); HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass);
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
sig = signature.toString(); sig = signature.toString();
} }
@ -307,7 +359,7 @@ public class BytecodeGen implements ASTVisitor {
System.out.println("ALL CONST: " + tphExtractor.allCons.size()); System.out.println("ALL CONST: " + tphExtractor.allCons.size());
tphExtractor.allCons.forEach(c->System.out.println(c.toString())); tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
System.out.println("----------------"); System.out.println("----------------");
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor); HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor, tphsClass);
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); // ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
sig = signature.toString(); sig = signature.toString();
@ -388,9 +440,21 @@ public class BytecodeGen implements ASTVisitor {
@Override @Override
public void visit(Field field) { public void visit(Field field) {
System.out.println("In Field ---"); System.out.println("In Field ---");
String des = "L";
if(resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
des += Type.getInternalName(Object.class);
} else {
des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
}
des +=";";
System.out.println(des);
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature());
System.out.println(sig);
if(sig.charAt(sig.length()-1) != (";").charAt(0)) {
sig +=";";
}
cw.visitField(field.modifier, field.getName(), cw.visitField(field.modifier, field.getName(),
"L"+resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";", des, sig,
resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature()),
null); null);
} }

View File

@ -708,7 +708,13 @@ public class BytecodeGenMethod implements StatementVisitor {
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
fieldName = fieldVar.fieldVarName; fieldName = fieldVar.fieldVarName;
fieldDesc = "L" + getResolvedType(fieldVar.getType()) + ";"; fieldDesc = "L";
if(resultSet.resolveType(fieldVar.getType()).resolvedType instanceof TypePlaceholder) {
fieldDesc += Type.getInternalName(Object.class);
} else {
fieldDesc += resultSet.resolveType(fieldVar.getType()).resolvedType.acceptTV(new TypeToDescriptor());
}
fieldDesc +=";";
fieldVar.receiver.accept(this); fieldVar.receiver.accept(this);
// test (if) // test (if)
@ -1405,9 +1411,18 @@ public class BytecodeGenMethod implements StatementVisitor {
// array slot onto the top of the operand stack. // array slot onto the top of the operand stack.
assignLeftSide.field.receiver.accept(this); assignLeftSide.field.receiver.accept(this);
this.rightSideTemp.accept(this); this.rightSideTemp.accept(this);
String fDesc = "L";
if(resultSet.resolveType(assignLeftSide.field.getType()).resolvedType instanceof TypePlaceholder) {
fDesc += Type.getInternalName(Object.class);
} else {
fDesc += resultSet.resolveType(assignLeftSide.field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
}
fDesc +=";";
System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType())); System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType()));
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()),
assignLeftSide.field.fieldVarName, "L"+getResolvedType(assignLeftSide.field.getType())+";"); assignLeftSide.field.fieldVarName, fDesc);
} }
@Override @Override

View File

@ -41,11 +41,16 @@ public class Signature {
private ResultSet resultSet; private ResultSet resultSet;
private ArrayList<GenericInsertPair> commonPairs; private ArrayList<GenericInsertPair> commonPairs;
private HashMap<TPHConstraint,HashSet<String>> methodConstraints; private HashMap<TPHConstraint,HashSet<String>> methodConstraints;
private ArrayList<TypePlaceholder> tphsClass;
private ArrayList<TPHConstraint> consClass;
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,ArrayList<GenericInsertPair> commonPairs) { public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
ArrayList<GenericInsertPair> commonPairs, ArrayList<TypePlaceholder> tphsClass, ArrayList<TPHConstraint> consClass) {
this.classOrInterface = classOrInterface; this.classOrInterface = classOrInterface;
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
this.commonPairs = commonPairs; this.commonPairs = commonPairs;
this.tphsClass = tphsClass;
this.consClass = consClass;
sw = new SignatureWriter(); sw = new SignatureWriter();
createSignatureForClassOrInterface(); createSignatureForClassOrInterface();
} }
@ -367,7 +372,37 @@ public class Signature {
GenericTypeVar g = itr.next(); GenericTypeVar g = itr.next();
getBoundsOfTypeVar(g,genericsAndBounds); getBoundsOfTypeVar(g,genericsAndBounds);
} }
if(!commonPairs.isEmpty()) {
if(!consClass.isEmpty()) {
ArrayList<String> types = new ArrayList<>();
ArrayList<String> superTypes = new ArrayList<>();
for(TPHConstraint cons : consClass) {
types.add(cons.getLeft());
superTypes.add(cons.getRight());
}
for(TPHConstraint cons : consClass) {
String t = cons.getLeft()+"$";
String bound = cons.getRight()+"$";
sw.visitFormalTypeParameter(t);
sw.visitClassBound().visitTypeVariable(bound);
genericsAndBounds.put(t, bound);
}
for(TPHConstraint cons : consClass) {
if(!types.contains(cons.getRight())) {
String t = cons.getRight()+"$";
String bound = Type.getInternalName(Object.class);
sw.visitFormalTypeParameter(t);
sw.visitClassBound().visitClassType(bound);
genericsAndBounds.put(t, bound);
sw.visitClassBound().visitEnd();
}
}
}
/*if(!commonPairs.isEmpty()) {
ArrayList<TypePlaceholder> types = new ArrayList<>(); ArrayList<TypePlaceholder> types = new ArrayList<>();
ArrayList<TypePlaceholder> superTypes = new ArrayList<>(); ArrayList<TypePlaceholder> superTypes = new ArrayList<>();
@ -395,6 +430,14 @@ public class Signature {
} }
} }
} }
for(TypePlaceholder t : tphsClass) {
String n = t.getName()+"$";
String bound = Type.getInternalName(Object.class);
sw.visitFormalTypeParameter(n);
sw.visitClassBound().visitClassType(bound);
genericsAndBounds.put(n, bound);
sw.visitClassBound().visitEnd();
}*/
String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature()); String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature());
sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length()-1)); sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length()-1));
sw.visitEnd(); sw.visitEnd();

View File

@ -16,7 +16,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class Simplify { public class Simplify {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor) { public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor, ArrayList<TypePlaceholder> tphsClass) {
// 1. check if there are any simple cycles like L<R and R<L: // 1. check if there are any simple cycles like L<R and R<L:
// a) yes => set L=R and: // a) yes => set L=R and:
// * remove both constraints // * remove both constraints

View File

@ -0,0 +1,43 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class FieldTph {
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/FieldTph.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("FieldTph");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test() {
Field[] fields = classToTest.getFields();
assertEquals(1, fields.length);
}
}

View File

@ -0,0 +1,52 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class FieldTph2Test {
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/FieldTph2.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("FieldTph2");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test() throws Exception {
Field a = classToTest.getDeclaredField("a");
a.setAccessible(true);
Method m2 = classToTest.getDeclaredMethod("m2", Object.class);
m2.invoke(instanceOfClass, 1);
Method m = classToTest.getDeclaredMethod("m", Object.class);
Object result = m.invoke(instanceOfClass, 1);
assertEquals(1,result);
}
}

View File

@ -0,0 +1,4 @@
public class FieldTph {
a;
}

View File

@ -0,0 +1,12 @@
public class FieldTph2 {
a;
m(b){
b = a;
return b;
}
m2(c){
a = c;
}
}

View File

@ -5,6 +5,7 @@ package bytecode.simplifyalgo;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -68,7 +69,7 @@ public class CycleTest {
TPHConstraint k = new ExtendsConstraint("A", Type.getInternalName(Object.class), Relation.EXTENDS); TPHConstraint k = new ExtendsConstraint("A", Type.getInternalName(Object.class), Relation.EXTENDS);
result.put(k, equals); result.put(k, equals);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor); HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
boolean areEquals = SimpleCycle.areMapsEqual(result, sim); boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals); assertTrue(areEquals);
} }

View File

@ -2,6 +2,7 @@ package bytecode.simplifyalgo;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -76,7 +77,7 @@ public class SameLeftSide {
result.put(b, hs); result.put(b, hs);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor); HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
boolean areEquals = SimpleCycle.areMapsEqual(result, sim); boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals); assertTrue(areEquals);
} }
@ -93,7 +94,7 @@ public class SameLeftSide {
hs.add("B"); hs.add("B");
result.put(c, hs); result.put(c, hs);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor); HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor,new ArrayList<>());
boolean areEquals = SimpleCycle.areMapsEqual(result, sim); boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals); assertTrue(areEquals);
} }

View File

@ -2,6 +2,7 @@ package bytecode.simplifyalgo;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -45,7 +46,7 @@ public class SimpleCycle {
TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS); TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS);
result.put(k, equals); result.put(k, equals);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor); HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
boolean areEquals = areMapsEqual(result, sim); boolean areEquals = areMapsEqual(result, sim);
assertTrue(areEquals); assertTrue(areEquals);
} }