Merge branch 'bigRefactoring' into sat

This commit is contained in:
JanUlrich 2018-02-23 11:14:47 +01:00
commit 10b5d87119
36 changed files with 356 additions and 392 deletions

View File

@ -10,6 +10,10 @@ import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToString;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.statement.Literal;
@ -53,7 +57,6 @@ public class BytecodeGen implements ASTVisitor {
for(ClassOrInterface cl : sourceFile.getClasses()) { for(ClassOrInterface cl : sourceFile.getClasses()) {
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet); BytecodeGen classGen = new BytecodeGen(classFiles, resultSet);
cl.accept(classGen); cl.accept(classGen);
System.out.println("In CLASS: "+(cl.getClassName().toString()));
classGen.writeClass(cl.getClassName().toString()); classGen.writeClass(cl.getClassName().toString());
} }
} }
@ -79,9 +82,10 @@ public class BytecodeGen implements ASTVisitor {
public void visit(ClassOrInterface classOrInterface) { public void visit(ClassOrInterface classOrInterface) {
className = classOrInterface.getClassName().toString(); className = classOrInterface.getClassName().toString();
isInterface = (classOrInterface.getModifiers()&512)==512; cw.visitSource(className +".jav", null);
System.out.println("IS Interface = "+"modifiers= "+classOrInterface.getModifiers()+" ->"+(classOrInterface.getModifiers()&512) + isInterface);
isInterface = (classOrInterface.getModifiers()&512)==512;
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER; int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
String sig = null; String sig = null;
/* if class has generics then creates signature /* if class has generics then creates signature
@ -90,8 +94,6 @@ public class BytecodeGen implements ASTVisitor {
*/ */
if(classOrInterface.getGenerics().iterator().hasNext()) { if(classOrInterface.getGenerics().iterator().hasNext()) {
Signature signature = new Signature(classOrInterface, genericsAndBounds); Signature signature = new Signature(classOrInterface, genericsAndBounds);
System.out.println(signature.toString());
sig = signature.toString(); sig = signature.toString();
} }
// needs implemented Interfaces? // needs implemented Interfaces?
@ -100,8 +102,6 @@ public class BytecodeGen implements ASTVisitor {
// for each field in the class // for each field in the class
for(Field f : classOrInterface.getFieldDecl()) { for(Field f : classOrInterface.getFieldDecl()) {
System.out.println("get Fields");
System.out.println(f.getName());
f.accept(this); f.accept(this);
} }
@ -112,7 +112,6 @@ public class BytecodeGen implements ASTVisitor {
for(Method m : classOrInterface.getMethods()) { for(Method m : classOrInterface.getMethods()) {
m.accept(this); m.accept(this);
} }
cw.visitSource(classOrInterface.getClassName().toString()+".jav", null);
} }
@Override @Override
@ -121,24 +120,25 @@ public class BytecodeGen implements ASTVisitor {
String desc = null; String desc = null;
boolean hasGen = false; boolean hasGen = false;
for(String paramName : methodParamsAndTypes.keySet()) { for(String paramName : methodParamsAndTypes.keySet()) {
genericsAndBounds.containsKey(paramName); String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
hasGen = true; if(genericsAndBounds.containsKey(typeOfParam)) {
hasGen = true;
break;
}
} }
String sig = null; String sig = null;
if(hasGen) { if(hasGen) {
System.out.println("IM IN CONST HAS Gens");
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes); Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes);
sig = signature.toString(); sig = signature.toString();
System.out.println(sig);
} }
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen); NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
desc = constructor.accept(new DescriptorToString(resultSet)); desc = constructor.accept(new DescriptorToString(resultSet));
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
mv.visitCode(); mv.visitCode();
System.out.println("-----Constructor-----");
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,cw, BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,cw,
genericsAndBoundsMethod,genericsAndBounds,isInterface); genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
if(!field.getParameterList().iterator().hasNext()) { if(!field.getParameterList().iterator().hasNext()) {
mv.visitInsn(Opcodes.RETURN); mv.visitInsn(Opcodes.RETURN);
} }
@ -155,45 +155,40 @@ public class BytecodeGen implements ASTVisitor {
String methDesc = null; String methDesc = null;
// Method getModifiers() ? // Method getModifiers() ?
int acc = isInterface?Opcodes.ACC_ABSTRACT:0; int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier;
System.out.println("-----Method-----"); boolean hasGenInParameterList = genericsAndBounds.containsKey(resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()));
boolean hasGenInParameterList = genericsAndBounds.containsKey(method.getReturnType().acceptTV(new TypeToDescriptor()));
if(!hasGenInParameterList) { if(!hasGenInParameterList) {
for(String paramName : methodParamsAndTypes.keySet()) { for(String paramName : methodParamsAndTypes.keySet()) {
if(genericsAndBounds.containsKey(paramName)) { String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
if(genericsAndBounds.containsKey(typeOfParam)) {
hasGenInParameterList = true; hasGenInParameterList = true;
break; break;
} }
} }
} }
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP)
//than create the descriptor with the new syntax.
String sig = null; String sig = null;
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList; boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
// Wenn ReturnType has Generics?? Fun1<...> wie testet man das generic hat??
System.out.println(method.getReturnType().acceptTV(new TypeToString())); /* if method has generics or return type is TPH, create signature */
// if(method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) { if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
// Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet);
// sig = signature.toString();
// System.out.println(sig);
// }
/* if method has generics, create signature */
if(hasGen) {
// resultset hier zum testen // resultset hier zum testen
Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet); Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet);
sig = signature.toString(); sig = signature.toString();
System.out.println(sig);
} }
System.out.println(sig);
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen); NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
methDesc = meth.accept(new DescriptorToString(resultSet)); methDesc = meth.accept(new DescriptorToString(resultSet));
System.out.println("methDesc" + methDesc); MethodVisitor mv = cw.visitMethod(acc, method.getName(), methDesc, sig, null);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
mv.visitCode(); mv.visitCode();
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,genericsAndBounds,genericsAndBounds,isInterface); BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,
genericsAndBounds,genericsAndBounds,isInterface,classFiles);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
} }
@ -207,7 +202,7 @@ public class BytecodeGen implements ASTVisitor {
while(itr.hasNext()) { while(itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
paramsAndLocals.put(fp.getName(), i); paramsAndLocals.put(fp.getName(), i);
methodParamsAndTypes.put(fp.getName(), fp.getType()); methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
fp.accept(this); fp.accept(this);
i++; i++;
} }
@ -250,7 +245,6 @@ public class BytecodeGen implements ASTVisitor {
// ?? // ??
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
System.out.println("in fieldvar");
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString()); // cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null); FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null);
fv.visitEnd(); fv.visitEnd();
@ -259,7 +253,6 @@ public class BytecodeGen implements ASTVisitor {
// access flages?? modifiers // access flages?? modifiers
@Override @Override
public void visit(Field field) { public void visit(Field field) {
System.out.println("in field");
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType().toString().replace(".", "/")+";", null, null); FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType().toString().replace(".", "/")+";", null, null);
fv.visitEnd(); fv.visitEnd();
} }

View File

@ -1,5 +1,9 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.invoke.CallSite; import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
@ -15,12 +19,21 @@ import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureVisitor;
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.signature.TypeToString;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.statement.Literal;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@ -41,17 +54,18 @@ public class BytecodeGenMethod implements StatementVisitor{
private String fieldName; private String fieldName;
private String fieldDesc; private String fieldDesc;
private Expression rightSideTemp; private Expression rightSideTemp;
private String where; // private String where;
private boolean isRightSideALambda = false; private boolean isRightSideALambda = false;
private KindOfLambda kindOfLambda; private KindOfLambda kindOfLambda;
private HashMap<String, byte[]> classFiles;
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface; private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface;
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBoundsMethod, HashMap<String,String> genericsAndBounds, boolean isInterface) { HashMap<String,String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
this.where = "<<<<<< NORMAL METHOD >>>>>>"; // this.where = "<<<<<< NORMAL METHOD >>>>>>";
this.className = className; this.className = className;
this.resultSet = resultSet; this.resultSet = resultSet;
@ -62,29 +76,24 @@ public class BytecodeGenMethod implements StatementVisitor{
this.genericsAndBoundsMethod = genericsAndBoundsMethod; this.genericsAndBoundsMethod = genericsAndBoundsMethod;
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
this.isInterface = isInterface; this.isInterface = isInterface;
this.classFiles = classFiles;
this.lamCounter = -1; this.lamCounter = -1;
this.varsFunInterface = new ArrayList<>(); this.varsFunInterface = new ArrayList<>();
System.out.println("PARAMS = "+this.paramsAndLocals.size());
if(!isInterface) if(!isInterface)
this.m.block.accept(this); this.m.block.accept(this);
// System.out.println("PARAMS = "+this.paramsAndLocals.size());
// for(int i = 0; i<this.paramsAndLocals.size();i++) {
// System.out.println(this.paramsAndLocals.keySet().toArray()[i]);
// }
} }
public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv, public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv,
int indexOfFirstParamLam, boolean isInterface) { int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles) {
System.out.println("\t\t++++++IN LAMBDA -------");
this.where = "<<<<<< LAMBDA METHOD >>>>>>"; // this.where = "<<<<<< LAMBDA METHOD >>>>>>";
this.resultSet = resultSet; this.resultSet = resultSet;
this.mv = mv; this.mv = mv;
this.isInterface = isInterface; this.isInterface = isInterface;
this.classFiles = classFiles;
this.lamCounter = -1; this.lamCounter = -1;
this.varsFunInterface = new ArrayList<>(); this.varsFunInterface = new ArrayList<>();
@ -99,7 +108,6 @@ public class BytecodeGenMethod implements StatementVisitor{
} }
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
// return resultSet.resolveType(type).resolvedType.toString().replace(".", "/");
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor()); return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
} }
@ -107,10 +115,8 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(Block block) { public void visit(Block block) {
for(Statement stmt : block.getStatements()) { for(Statement stmt : block.getStatements()) {
System.out.println(where); // System.out.println(where);
System.out.println("Stmt : " + stmt.toString());
stmt.accept(this); stmt.accept(this);
System.out.println("--------------------------\n");
} }
} }
@ -125,7 +131,7 @@ public class BytecodeGenMethod implements StatementVisitor{
// ?? // ??
@Override @Override
public void visit(LocalVar localVar) { public void visit(LocalVar localVar) {
System.out.println("in Local Var: " + localVar.name); // System.out.println("in Local Var: " + localVar.name);
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
} }
// ?? // ??
@ -133,12 +139,12 @@ public class BytecodeGenMethod implements StatementVisitor{
public void visit(LocalVarDecl localVarDecl) { public void visit(LocalVarDecl localVarDecl) {
// Integer i; // Integer i;
// paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1); // paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1);
System.out.println("In localVarDecl :: "+localVarDecl.getName()); // System.out.println("In localVarDecl :: "+localVarDecl.getName());
} }
@Override @Override
public void visit(Assign assign) { public void visit(Assign assign) {
System.out.println("Assign : \nright = "+assign.rightSide + "\nLeft = " + assign.lefSide); // System.out.println("Assign : \nright = "+assign.rightSide + "\nLeft = " + assign.lefSide);
// if the right side is a lambda => the left side must be a functional interface // if the right side is a lambda => the left side must be a functional interface
if(assign.rightSide.getClass().equals(LambdaExpression.class)) { if(assign.rightSide.getClass().equals(LambdaExpression.class)) {
@ -147,7 +153,6 @@ public class BytecodeGenMethod implements StatementVisitor{
isRightSideALambda = false; isRightSideALambda = false;
} }
System.out.println("\t isRight Side lambda: " + isRightSideALambda);
if(assign.lefSide.getClass().equals(AssignToField.class)) { if(assign.lefSide.getClass().equals(AssignToField.class)) {
// load_0, ldc or .. then putfield // load_0, ldc or .. then putfield
this.rightSideTemp = assign.rightSide; this.rightSideTemp = assign.rightSide;
@ -159,17 +164,16 @@ public class BytecodeGenMethod implements StatementVisitor{
} }
@Override @Override
public void visit(BinaryExpr binary) { public void visit(BinaryExpr binary) {
System.out.println("\t++ In Binary: "); System.out.println("\t++ In Binary: ");
} }
@Override @Override
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
System.out.println("\n++ In Lambda: ");
this.lamCounter++; this.lamCounter++;
System.out.println("Lam Hs Gens: " + lambdaExpression.getGenerics().iterator().hasNext());
System.out.println("Lam Hs Gens: " + lambdaExpression.getReturnType().acceptTV(new TypeToString()));
Lambda lam = new Lambda(lambdaExpression); Lambda lam = new Lambda(lambdaExpression);
String lamDesc = lam.accept(new DescriptorToString(resultSet)); String lamDesc = lam.accept(new DescriptorToString(resultSet));
//Call site, which, when invoked, returns an instance of the functional interface to which //Call site, which, when invoked, returns an instance of the functional interface to which
@ -181,10 +185,20 @@ public class BytecodeGenMethod implements StatementVisitor{
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory",
"metafactory", mt.toMethodDescriptorString(), false); "metafactory", mt.toMethodDescriptorString(), false);
String methodName = "lambda$new$" + this.lamCounter; String methodName = "lambda$new$" + this.lamCounter;
// String typeErasure = "(Ljava/lang/Object;)Ljava/lang/Object;";
// 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 erasure
// Type arg1 = Type.getMethodType(typeErasure); Type arg1 = Type.getMethodType(typeErasure);
Type arg1 = Type.getMethodType(lamDesc); // Type arg1 = Type.getMethodType(lamDesc);
// real Type // real Type
Type arg3 = Type.getMethodType(lamDesc); Type arg3 = Type.getMethodType(lamDesc);
@ -209,20 +223,64 @@ public class BytecodeGenMethod implements StatementVisitor{
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType()); SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
// Desc: (this/nothing)TargetType // Desc: (this/nothing)TargetType
String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet)); String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet));
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2,arg3);
arg1, arg2,arg3);
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC, MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC,
methodName, arg3.toString(), null, null); methodName, arg3.toString(), null, null);
new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface); new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface,
classFiles);
mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitMaxs(0, 0);
mvLambdaBody.visitEnd(); mvLambdaBody.visitEnd();
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL); Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
generateBCForFunN(lambdaExpression,typeErasure);
} }
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
ClassWriter classWriter =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
SignatureWriter methSig = new SignatureWriter();
int numberOfParams = 0;
SignatureVisitor paramVisitor = methSig.visitParameterType();
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
while(itr.hasNext()) {
numberOfParams++;
// getBounds
paramVisitor.visitTypeVariable("T"+numberOfParams);
itr.next();
}
methSig.visitReturnType().visitTypeVariable("R");
// ")"+lam.getReturn.getBounds
Signature sig = new Signature(lambdaExpression,numberOfParams);
String name = "Fun"+numberOfParams;
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_INTERFACE+Opcodes.ACC_ABSTRACT, name,
sig.toString(), Type.getInternalName(Object.class), null);
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "apply",
methDesc, methSig.toString(), null);
mvApply.visitEnd();
writeClassFile(classWriter.toByteArray(),name);
}
public void writeClassFile(byte[] bytecode, String name) {
FileOutputStream output;
try {
System.out.println("generating "+name+ ".class file...");
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" +name+".class"));
output.write(bytecode);
output.close();
System.out.println(name+".class file generated");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override @Override
public void visit(CastExpr castExpr) { public void visit(CastExpr castExpr) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
@ -237,7 +295,6 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
System.out.println("in fieldVar " + fieldVar.fieldVarName + " ** receiver: "+fieldVar.receiver);
fieldName = fieldVar.fieldVarName; fieldName = fieldVar.fieldVarName;
fieldDesc = "L"+getResolvedType(fieldVar.getType())+";"; fieldDesc = "L"+getResolvedType(fieldVar.getType())+";";
@ -261,7 +318,7 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
System.out.println("++ IF-Statment: ");
} }
@Override @Override
@ -272,13 +329,11 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
System.out.println(" In Methodcall: (" +methodCall.name+")" ); // if(methodCall.receiver instanceof ExpressionReceiver){
System.out.print("\t\tMethod-Receiver: "); // System.out.print(((ExpressionReceiver) methodCall.receiver).expr + "\n");
if(methodCall.receiver instanceof ExpressionReceiver){ // }else{
System.out.print(((ExpressionReceiver) methodCall.receiver).expr + "\n"); // System.out.print(((StaticClassName) methodCall.receiver).getType().toString() + "\n");
}else{ // }
System.out.print(((StaticClassName) methodCall.receiver).getType().toString() + "\n");
}
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
methodCall.arglist.accept(this); methodCall.arglist.accept(this);
@ -287,14 +342,13 @@ public class BytecodeGenMethod implements StatementVisitor{
genericsAndBoundsMethod,genericsAndBounds); genericsAndBoundsMethod,genericsAndBounds);
String mDesc = method.accept(new DescriptorToString(resultSet)); String mDesc = method.accept(new DescriptorToString(resultSet));
System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); // System.out.println("is Vars empty: "+varsFunInterface.isEmpty());
// is methodCall.receiver functional Interface)? // is methodCall.receiver functional Interface)?
if(varsFunInterface.contains(methodCall.receiver.getType())) { if(varsFunInterface.contains(methodCall.receiver.getType())) {
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
methodCall.name, mDesc, false); methodCall.name, mDesc, false);
}else { }else {
System.out.println("mDesc = " + mDesc);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()),
methodCall.name, mDesc, isInterface); methodCall.name, mDesc, isInterface);
} }
@ -306,8 +360,8 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(NewClass methodCall) { public void visit(NewClass methodCall) {
System.out.println("In NewClass: "); // System.out.println("In NewClass: ");
System.out.println("\t\tname: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver); // System.out.println("\t\tname: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver);
mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/")); mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/"));
mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.DUP);
@ -330,8 +384,6 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(ExpressionReceiver receiver) { public void visit(ExpressionReceiver receiver) {
System.out.println(" in Receiver");
System.out.println(" expr : " + receiver.expr);
receiver.expr.accept(this); receiver.expr.accept(this);
} }
@ -353,7 +405,6 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(StaticClassName staticClassName) { public void visit(StaticClassName staticClassName) {
System.out.println("In StaticClassName: ");
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"), // mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"),
// staticClassName.toString(), staticClassName.getType().toString(), false); // staticClassName.toString(), staticClassName.getType().toString(), false);
mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()), mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()),
@ -362,19 +413,18 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(Super aSuper) { public void visit(Super aSuper) {
System.out.println(">> In Super: ");
} }
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
System.out.println("-> IN This");
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0);
} }
@Override @Override
public void visit(WhileStmt whileStmt) { public void visit(WhileStmt whileStmt) {
// TODO Auto-generated method stub whileStmt.expr.accept(this);
whileStmt.loopBlock.accept(this);
} }
@Override @Override
@ -385,17 +435,14 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(Literal literal) { public void visit(Literal literal) {
// value?
mv.visitLdcInsn(getResolvedType(literal.getType())); mv.visitLdcInsn(getResolvedType(literal.getType()));
} }
@Override @Override
public void visit(ArgumentList argumentList) { public void visit(ArgumentList argumentList) {
System.out.println("in ArgumentList: ");
for(Expression al : argumentList.getArguments()) { for(Expression al : argumentList.getArguments()) {
al.accept(this); al.accept(this);
} }
System.out.println("out from Argumentlist");
} }
@Override @Override
@ -414,7 +461,6 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override @Override
public void visit(AssignToLocal assignLeftSide) { public void visit(AssignToLocal assignLeftSide) {
System.out.println("In Assign To Local: ");
if(isRightSideALambda) if(isRightSideALambda)
varsFunInterface.add(assignLeftSide.localVar.getType()); varsFunInterface.add(assignLeftSide.localVar.getType());
paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1); paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1);

View File

@ -1,14 +0,0 @@
package de.dhbwstuttgart.bytecode;
public class ClassFile {
String name;
byte[] bytecode;
public ClassFile(String name, byte[] bytecode) {
this.name = name;
this.bytecode = bytecode;
}
}

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
import java.util.HashMap; import java.util.HashMap;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
import java.util.HashMap; import java.util.HashMap;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
import java.util.HashMap; import java.util.HashMap;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class SamMethod { public class SamMethod {

View File

@ -1,150 +0,0 @@
package de.dhbwstuttgart.bytecode;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
public class Test {
private static final String rootDirectory = System.getProperty("user.dir") + "/bin/de/dhbwstuttgart/bytecode/";
protected static ClassLoader getClassLoader() throws Exception {
File file = new File(rootDirectory);
URL url = file.toURI().toURL();
URL[] urls = new URL[] { url };
System.out.println(urls[0]);
return new URLClassLoader(urls);
}
public static void main(String[] args) {
// Test Lambda
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, "TestClass", null, "java/lang/Object", null);
cw.visitSource("TestClass.java", null);
// Create Constructor
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
// mv.visitMethodInsn(INVOKEDYNAMIC, "#0", "run", "()Ljava/lang/Runnable");
//Call site, which, when invoked, returns an instance of the functional interface to which
//the lambda is being converted
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
mt.toMethodDescriptorString());
Handle arg2 = new Handle(Opcodes.H_INVOKESTATIC, "TestClass", "lambda$0", "()V");
mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", bootstrap,
Type.getMethodType("()V"), arg2,
Type.getMethodType("()V"));
mv.visitVarInsn(Opcodes.ASTORE, 1);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Runnable", "run", "()V");
mv.visitInsn(Opcodes.RETURN);
// creates bridge method, contains lambdas body
MethodVisitor mvl = cw.visitMethod(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, "lambda$0",
"()V", null, null);
mvl.visitCode();
mvl.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mvl.visitLdcInsn("lambda");
mvl.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mvl.visitInsn(Opcodes.RETURN);
mvl.visitMaxs(2, 0);
mvl.visitEnd();
mv.visitMaxs(1, 2);
mv.visitEnd();
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
cw.visitEnd();
byte[] b = cw.toByteArray();
// Test if statement
/*
* ClassWriter cw = new
* ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
*
* cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_SUPER, "TestIf", null,
* "java/lang/Object", null); MethodVisitor mv =
* cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/lang/Boolean;)V", null,
* null); mv.visitCode();
*
* // Label l0 = new Label(); // mv.visitLabel(l0);
*
* mv.visitVarInsn(Opcodes.ALOAD, 0);
*
* mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
* "()V");
*
* // Label l1 = new Label(); // mv.visitLabel(l1);
* mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
* "java/lang/Boolean", "booleanValue", "()Z");
*
* Label label = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, label);
*
* mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out",
* "Ljava/io/PrintStream;"); mv.visitLdcInsn("1");
* mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
* "(Ljava/lang/String;)V");
*
* Label endLabel = new Label(); mv.visitJumpInsn(Opcodes.GOTO, endLabel);
*
* mv.visitLabel(label); mv.visitFieldInsn(Opcodes.GETSTATIC,
* "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn("0");
* mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
* "(Ljava/lang/String;)V");
*
*
*
* mv.visitLabel(endLabel); mv.visitInsn(Opcodes.RETURN);
*
* // Label l2 = new Label(); // mv.visitLabel(l2);
*
* // mv.visitLocalVariable("this", "LTestIf;", null, l0, l2, 0); //
* mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l2, 1);
* mv.visitMaxs(2, 2); mv.visitEnd();
*
* cw.visitEnd(); byte[] b = cw.toByteArray();
*/
FileOutputStream output;
try {
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/TestClass.class"));
output.write(b);
output.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -1,8 +0,0 @@
package de.dhbwstuttgart.bytecode;
public class TestClass {
public TestClass() {
Runnable lam = () -> System.out.println("lambda");
lam.run();
}
}

View File

@ -1,59 +0,0 @@
package de.dhbwstuttgart.bytecode;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
public class TestFields {
private static final String rootDirectory = System.getProperty("user.dir") + "/bin/de/dhbwstuttgart/bytecode/";
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, "TetsF", null, "java/lang/Object", null);
cw.visitSource("TetsF.java", null);
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, "z", Type.INT_TYPE.getDescriptor(), null, null);
fv.visitEnd();
FieldVisitor fvS = cw.visitField(Opcodes.ACC_PUBLIC, "s", "Ljava/lang/String;", null, null);
fvS.visitEnd();
// Create Constructor
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitLdcInsn("");
mv.visitFieldInsn(Opcodes.PUTFIELD, "TetsF", "s", "Ljava/lang/String;");
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
byte[] b = cw.toByteArray();
FileOutputStream output;
try {
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/TetsF.class"));
output.write(b);
output.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -1,11 +0,0 @@
package de.dhbwstuttgart.bytecode;
public class TestIf {
public TestIf(Boolean b) {
if(b) {
System.out.println("1");
}else {
System.out.println("0");
}
}
}

View File

@ -1,18 +0,0 @@
package de.dhbwstuttgart.bytecode;
public class TestMeth {
private int z;
public String s;
public TestMeth(int temp) {
this.z = temp;
}
public void m1(int a, int b) {
int y = m2(1,2,3,4);
}
public int m2(int a, int b, int x, int y) {
Integer c = 55;
Integer g;
return a+b+y+c;
}
}

View File

@ -1,6 +0,0 @@
package de.dhbwstuttgart.bytecode;
public class TetsF {
private int z;
public String s = "";
}

View File

@ -1,9 +1,16 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.descriptor;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.bytecode.Lambda;
import de.dhbwstuttgart.bytecode.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.NormalConstructor;
import de.dhbwstuttgart.bytecode.NormalMethod;
import de.dhbwstuttgart.bytecode.SamMethod;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@ -30,6 +37,8 @@ public class DescriptorToString implements DescriptorVisitor{
Iterator<FormalParameter> itr = method.getParameterList().iterator(); Iterator<FormalParameter> itr = method.getParameterList().iterator();
while(itr.hasNext()) { while(itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
// System.out.println(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature()));
// System.out.println("Parmetrisierte typ ? "+ ((RefType) fp.getType()).getParaList().size());
if(method.hasGen()) { if(method.hasGen()) {
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor()); String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) { if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) {
@ -39,7 +48,11 @@ public class DescriptorToString implements DescriptorVisitor{
}else { }else {
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
} }
}else { }
// else if(((RefType) fp.getType()).getParaList().size() > 0){
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "%").replace("<", "%%").replace(">", "%%")+ ";";
// }
else {
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
} }
} }
@ -71,16 +84,16 @@ public class DescriptorToString implements DescriptorVisitor{
while(itr.hasNext()) { while(itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
if(constructor.hasGen()) { if(constructor.hasGen()) {
System.out.println("Cons has Gens"); // System.out.println("Cons has Gens");
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor()); String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
System.out.println(fpDesc); // System.out.println(fpDesc);
if(constructor.getGenericsAndBounds().containsKey(fpDesc)){ if(constructor.getGenericsAndBounds().containsKey(fpDesc)){
desc += "L"+constructor.getGenericsAndBounds().get(fpDesc)+ ";"; desc += "L"+constructor.getGenericsAndBounds().get(fpDesc)+ ";";
}else { }else {
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
} }
}else { }else {
System.out.println("Cons has NOT Gens"); // System.out.println("Cons has NOT Gens");
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
} }
} }
@ -96,7 +109,6 @@ public class DescriptorToString implements DescriptorVisitor{
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";"; desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";";
} }
System.out.println("LamReturnType: "+lambdaExpression.getReturnType().acceptTV(new TypeToString()));
desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet); desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet);
return desc; return desc;
} }

View File

@ -1,4 +1,10 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.descriptor;
import de.dhbwstuttgart.bytecode.Lambda;
import de.dhbwstuttgart.bytecode.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.NormalConstructor;
import de.dhbwstuttgart.bytecode.NormalMethod;
import de.dhbwstuttgart.bytecode.SamMethod;
public interface DescriptorVisitor { public interface DescriptorVisitor {
public String visit(NormalMethod method); public String visit(NormalMethod method);

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.descriptor;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;

View File

@ -1,16 +1,21 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.signature;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter; import org.objectweb.asm.signature.SignatureWriter;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
@ -49,6 +54,29 @@ public class Signature {
createSignatureForConsOrMethod(this.method,false); createSignatureForConsOrMethod(this.method,false);
} }
public Signature(LambdaExpression lambdaExpression,int numberOfParams) {
sw = new SignatureWriter();
createSignatureForFunN(lambdaExpression, numberOfParams);
}
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) {
sw.visitFormalTypeParameter("R");
// getBounds vom Return-Type
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
for(int i = 0;i<numberOfParams;i++) {
int j = i+1;
sw.visitFormalTypeParameter("T"+ j);
// getBounds von Params
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
}
// TODO: prüfe ob Return-Type = void,
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));;
sw.visitEnd();
}
/** /**
* Creates signature for a method or constructor with @see {@link SignatureWriter} * Creates signature for a method or constructor with @see {@link SignatureWriter}
* Signature looks like: * Signature looks like:
@ -96,16 +124,17 @@ public class Signature {
} }
switch (type) { switch (type) {
case "RT": case "RT":
sv.visitClassType(t.acceptTV(new TypeToDescriptor())); sv.visitClassType(t.acceptTV(new TypeToSignature()));
break; break;
case "GRT": case "GRT":
GenericRefType g = (GenericRefType) t; GenericRefType g = (GenericRefType) t;
sv.visitTypeVariable(g.getParsedName()); sv.visitTypeVariable(g.acceptTV(new TypeToSignature()));
break; break;
case "TPH": case "TPH":
System.out.println(resultSet.resolveType(t).resolvedType.acceptTV(new TypeToDescriptor())); RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
// sv.visitInterface().visitClassType(resultSet.resolveType(t).resolvedType.acceptTV(new TypeToDescriptor())+"<Ljava/lang/Integer;Ljava/lang/Integer;>;"); sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature()));
// sv.visitClassType(r.acceptTV(new TypeToSignature()));
// System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
break; break;
default: default:
if(!isParameterType) if(!isParameterType)
@ -141,6 +170,7 @@ public class Signature {
while(bItr.hasNext()) { while(bItr.hasNext()) {
RefTypeOrTPHOrWildcardOrGeneric b =bItr.next(); RefTypeOrTPHOrWildcardOrGeneric b =bItr.next();
String boundDesc = b.acceptTV(new TypeToDescriptor()); String boundDesc = b.acceptTV(new TypeToDescriptor());
// System.out.println("GetBounds: " + boundDesc);
// Ensure that <...> extends java.lang.Object OR ... // Ensure that <...> extends java.lang.Object OR ...
sw.visitClassBound().visitClassType(boundDesc); sw.visitClassBound().visitClassType(boundDesc);
genAndBounds.put(g.getParsedName(), boundDesc); genAndBounds.put(g.getParsedName(), boundDesc);

View File

@ -0,0 +1,53 @@
package de.dhbwstuttgart.bytecode.signature;
import java.util.Iterator;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
public class TypeToSignature implements TypeVisitor<String> {
@Override
public String visit(RefType refType) {
// return refType.toString().replace(".", "/");
String params = "";
if(refType.getParaList().size()>0){
params += "<";
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = refType.getParaList().iterator();
while(it.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
params += "L"+param.toString().replace(".", "/");
if(it.hasNext())params += ";";
}
params += ";>";
}
return refType.getName().toString().replace(".", "/") + params+";";
}
@Override
public String visit(SuperWildcardType superWildcardType) {
throw new NotImplementedException();
}
@Override
public String visit(TypePlaceholder typePlaceholder) {
return typePlaceholder.toString().replace(".", "/");
}
@Override
public String visit(ExtendsWildcardType extendsWildcardType) {
throw new NotImplementedException();
}
@Override
public String visit(GenericRefType genericRefType) {
return genericRefType.getParsedName().replace(".", "/");
}
}

View File

@ -1,4 +1,4 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode.signature;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;

View File

@ -29,14 +29,17 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
@Override @Override
public String toString(){ public String toString(){
String params = "<"; String params = "";
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator(); if(parameter.size()>0){
while(it.hasNext()){ params += "<";
RefTypeOrTPHOrWildcardOrGeneric param = it.next(); Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
params += param.toString(); while(it.hasNext()){
if(it.hasNext())params += ", "; RefTypeOrTPHOrWildcardOrGeneric param = it.next();
params += param.toString();
if(it.hasNext())params += ", ";
}
params += ">";
} }
params += ">";
return this.name.toString() + params; return this.name.toString() + params;
} }

View File

@ -199,7 +199,7 @@ public class TYPEStmt implements StatementVisitor{
//@see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2 //@see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben //Expression muss zu Numeric Convertierbar sein. also von Numeric erben
RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), unaryExpr.getOffset()); RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), unaryExpr.getOffset());
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERDOT));
//The type of the postfix increment expression is the type of the variable //The type of the postfix increment expression is the type of the variable
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT));
}else{ }else{

8
test/bytecode/ATest.java Normal file
View File

@ -0,0 +1,8 @@
package bytecode;
public class ATest extends JavaTXCompilerTest {
public ATest() {
fileName = "Example";
}
}

View File

@ -1,7 +1,7 @@
public class DuMethod{ public class DuMethod{
method(a){ method(a){
return a; return a+a;
} }
method(a){ method(a){

View File

@ -0,0 +1,7 @@
package bytecode;
public class DuMethodTest extends JavaTXCompilerTest{
public DuMethodTest() {
this.fileName = "DuMethod";
}
}

View File

@ -0,0 +1,7 @@
public class Example {
public m(Integer x) {
// String x = "X";
return x;
}
}

View File

@ -0,0 +1,3 @@
public class Exceptions {
// m(Integer i) throws
}

13
test/bytecode/For.jav Normal file
View File

@ -0,0 +1,13 @@
class For{
m(Integer x){
Boolean b = true;
while(x<2){
x = x +1;
b = false;
}
return x;
// for(int i = 0;i<10;i++) {
// x = x + 5;
// }
}
}

View File

@ -0,0 +1,9 @@
package bytecode;
public class ForTest extends JavaTXCompilerTest {
public ForTest() {
this.fileName = "For";
}
}

8
test/bytecode/Import.jav Normal file
View File

@ -0,0 +1,8 @@
import java.util.Vector;
class Import {
void methode(){
Vector v = new Vector<>();
v.add("X");
}
}

View File

@ -0,0 +1,7 @@
package bytecode;
public class ImportTest extends JavaTXCompilerTest{
public ImportTest() {
this.fileName = "Import";
}
}

View File

@ -34,17 +34,16 @@ public class JavaTXCompilerTest {
filesToTest.add(new File(rootDirectory+fileName+".jav")); filesToTest.add(new File(rootDirectory+fileName+".jav"));
System.out.println(rootDirectory+fileName+".jav"); System.out.println(rootDirectory+fileName+".jav");
JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);
System.out.println("test");
for(File f : filesToTest){ for(File f : filesToTest){
String content = readFile(f.getPath(), StandardCharsets.UTF_8); String content = readFile(f.getPath(), StandardCharsets.UTF_8);
List<ResultSet> typeinferenceResult = compiler.typeInference(); List<ResultSet> typeinferenceResult = compiler.typeInference();
HashMap<String,byte[]> bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0)); HashMap<String,byte[]> bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0));
for(ResultPair ep : typeinferenceResult.get(0).results) { // for(ResultPair ep : typeinferenceResult.get(0).results) {
System.out.println(ep.getLeft() + " ->" + ep.getRight()); // System.out.println(ep.getLeft() + " ->" + ep.getRight());
} // }
String name = ""; String name;
int pos = f.getName().lastIndexOf("."); int pos = f.getName().lastIndexOf(".");
if(pos != -1) { if(pos != -1) {
name = f.getName().substring(0, pos); name = f.getName().substring(0, pos);
@ -67,8 +66,8 @@ public class JavaTXCompilerTest {
for(String name : classFiles.keySet()) { for(String name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name); byte[] bytecode = classFiles.get(name);
try { try {
System.out.println("generating"+name+ ".class file"); System.out.println("generating "+name+ ".class file ...");
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class")); output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" +name+".class"));
output.write(bytecode); output.write(bytecode);
output.close(); output.close();
System.out.println(name+".class file generated"); System.out.println(name+".class file generated");

View File

@ -9,7 +9,3 @@ class LamAssign {
return lam1; return lam1;
} }
} }
interface Fun1<A,B>{
A apply(B b);
}

View File

@ -0,0 +1,11 @@
import java.util.Vector;
class OverlaodGen {
void method(Vector<Integer> v) {
// Integer i = v.get(0);
}
void method(Vector<String> v) {
// String s = v.get(0);
}
}

View File

@ -0,0 +1,7 @@
package bytecode;
public class OverlaodGenTest extends JavaTXCompilerTest {
public OverlaodGenTest() {
this.fileName = "OverlaodGen";
}
}

View File

@ -0,0 +1,7 @@
package bytecode;
public class TestIfTest extends JavaTXCompilerTest{
public TestIfTest() {
this.fileName = "IfTest";
}
}