generate bytecode
This commit is contained in:
parent
995af3004a
commit
4c213eb3cf
@ -9,7 +9,6 @@ import org.objectweb.asm.ClassWriter;
|
|||||||
import org.objectweb.asm.FieldVisitor;
|
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 org.objectweb.asm.Type;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
@ -54,13 +53,17 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
// String methDesc;
|
// String methDesc;
|
||||||
|
|
||||||
String type;
|
String type;
|
||||||
|
|
||||||
|
String className;
|
||||||
|
|
||||||
// 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<>();
|
||||||
byte[] bytecode;
|
byte[] bytecode;
|
||||||
HashMap<String,byte[]> classFiles;
|
HashMap<String,byte[]> classFiles;
|
||||||
|
|
||||||
public BytecodeGen(HashMap<String,byte[]> classFiles) {
|
public BytecodeGen(HashMap<String,byte[]> classFiles) {
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
|
paramsAndLocals = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -83,11 +86,15 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void visit(ClassOrInterface classOrInterface) {
|
public void visit(ClassOrInterface classOrInterface) {
|
||||||
|
className = classOrInterface.getClassName().toString();
|
||||||
// access flages??
|
// access flages??
|
||||||
cw.visit(Opcodes.V1_8, classOrInterface.getModifiers(), classOrInterface.getClassName().toString()
|
cw.visit(Opcodes.V1_8, classOrInterface.getModifiers()+Opcodes.ACC_SUPER, classOrInterface.getClassName().toString()
|
||||||
, null, classOrInterface.getSuperClass().toString(), null);
|
, null, classOrInterface.getSuperClass().toString(), null);
|
||||||
|
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,67 +110,28 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Constructor field) {
|
public void visit(Constructor field) {
|
||||||
String methDesc = getConsDesc(field);
|
Descriptor desc = new Descriptor(field);
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", methDesc, null, null);
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc.getDesc(), null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
System.out.println("-----Constructor-----");
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(field, mv,paramsAndLocals,true);
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,field, mv,paramsAndLocals,desc.getDesc(),cw);
|
||||||
|
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getConsDesc(Constructor field) {
|
|
||||||
String methDesc;
|
|
||||||
methDesc = "(";
|
|
||||||
field.getParameterList().accept(this);
|
|
||||||
Iterator<FormalParameter> itr = field.getParameterList().iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
methDesc = methDesc + "L"+fp.getType().toString() + ";";
|
|
||||||
}
|
|
||||||
methDesc = methDesc + ")V";
|
|
||||||
return methDesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Method method) {
|
public void visit(Method method) {
|
||||||
// ParameterList pl = method.getParameterList();
|
method.getParameterList().accept(this);
|
||||||
String methDesc = getMethDesc(method);
|
Descriptor methDesc = new Descriptor(method);
|
||||||
// methDesc = "(";
|
System.out.println("-----Method-----");
|
||||||
// method.getParameterList().accept(this);
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc.getDesc(), null, null);
|
||||||
// methDesc = methDesc + ")" + method.getReturnType().toString();
|
|
||||||
|
|
||||||
// create method descriptor (p1,p2,...)RT
|
|
||||||
// String methDesc = "(";
|
|
||||||
|
|
||||||
// Iterator<FormalParameter> itr = pl.iterator();
|
|
||||||
// while(itr.hasNext()) {
|
|
||||||
// FormalParameter fp = itr.next();
|
|
||||||
//// fp.getType().accept(this);
|
|
||||||
// methDesc = methDesc + "L"+fp.getType().toString() + ";";
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
// methDesc = methDesc + ")" + method.getReturnType().toString();
|
|
||||||
|
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc, null, null);
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(method, mv,paramsAndLocals,false);
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,method, mv,paramsAndLocals,methDesc.getDesc(),cw);
|
||||||
|
mv.visitMaxs(0, 0);
|
||||||
}
|
mv.visitEnd();
|
||||||
|
|
||||||
private String getMethDesc(Method method) {
|
|
||||||
String methDesc;
|
|
||||||
methDesc = "(";
|
|
||||||
method.getParameterList().accept(this);
|
|
||||||
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
methDesc = methDesc + "L"+fp.getType().toString() + ";";
|
|
||||||
}
|
|
||||||
methDesc = methDesc + ")" + method.getReturnType().toString();
|
|
||||||
return methDesc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -215,13 +183,17 @@ 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);
|
||||||
|
fv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// access flages?? modifiers
|
// access flages?? modifiers
|
||||||
@Override
|
@Override
|
||||||
public void visit(Field field) {
|
public void visit(Field field) {
|
||||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType()+";", null, null);
|
System.out.println("in field");
|
||||||
|
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType().toString().replace(".", "/")+";", null, null);
|
||||||
fv.visitEnd();
|
fv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.invoke.CallSite;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
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 de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
@ -16,6 +25,7 @@ import de.dhbwstuttgart.syntaxtree.statement.Block;
|
|||||||
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
|
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
|
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
|
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
|
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
||||||
@ -38,31 +48,63 @@ import de.dhbwstuttgart.syntaxtree.statement.UnaryPlus;
|
|||||||
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
|
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
|
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
|
||||||
public class BytecodeGenMethod implements StatementVisitor{
|
public class BytecodeGenMethod implements StatementVisitor{
|
||||||
|
|
||||||
private Method m;
|
private Method m;
|
||||||
private MethodVisitor mv;
|
private MethodVisitor mv;
|
||||||
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||||
|
private String desc;
|
||||||
|
private String className;
|
||||||
|
private int lamCounter;
|
||||||
|
private ClassWriter cw;
|
||||||
|
|
||||||
public BytecodeGenMethod(Method m, MethodVisitor mv, HashMap<String, Integer> paramsAndLocals,
|
//for tests **
|
||||||
boolean isConstructor) {
|
private String fieldName;
|
||||||
if(isConstructor) {
|
private String fieldDesc;
|
||||||
|
private Expression rightSideTemp;
|
||||||
|
private String where;
|
||||||
|
|
||||||
// mv.visitVarInsn(Opcodes.ALOAD, 0);
|
public BytecodeGenMethod(String className, Method m, MethodVisitor mv, HashMap<String, Integer> paramsAndLocals,
|
||||||
// mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
|
String desc, ClassWriter cw) {
|
||||||
}
|
|
||||||
|
this.where = "NORMAL METHOD";
|
||||||
|
|
||||||
|
this.className = className;
|
||||||
this.m = m;
|
this.m = m;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.paramsAndLocals = paramsAndLocals;
|
this.paramsAndLocals = paramsAndLocals;
|
||||||
|
this.desc = desc;
|
||||||
|
this.cw = cw;
|
||||||
|
this.lamCounter = -1;
|
||||||
|
|
||||||
this.m.block.accept(this);
|
this.m.block.accept(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BytecodeGenMethod(LambdaExpression lambdaExpression, MethodVisitor mv,
|
||||||
|
HashMap<String, Integer> paramsAndLocals, String desc) {
|
||||||
|
System.out.println("++++++IN LAMBDA -------");
|
||||||
|
|
||||||
|
this.where = "&&&&&&&& LAMBDA METHOD";
|
||||||
|
|
||||||
|
this.mv = mv;
|
||||||
|
this.paramsAndLocals = paramsAndLocals;
|
||||||
|
this.desc = desc;
|
||||||
|
|
||||||
|
this.lamCounter = -1;
|
||||||
|
|
||||||
|
lambdaExpression.methodBody.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
@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("Stmt : " + stmt.toString());
|
||||||
stmt.accept(this);
|
stmt.accept(this);
|
||||||
|
System.out.println("--------------------------\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,39 +112,73 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
superCall.receiver.accept(this);
|
superCall.receiver.accept(this);
|
||||||
superCall.arglist.accept(this);
|
superCall.arglist.accept(this);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, "()V");
|
// mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false);
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, desc,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
|
System.out.println("in Local Var");
|
||||||
}
|
}
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
// TODO Auto-generated method stub
|
// Integer i;
|
||||||
Integer i;
|
paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1);
|
||||||
|
System.out.println("In localVarDecl");
|
||||||
}
|
}
|
||||||
// int c = 5;???
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Assign assign) {
|
public void visit(Assign assign) {
|
||||||
|
System.out.println("Assign : \nright = "+assign.rightSide + "\nLeft = " + assign.lefSide);
|
||||||
|
|
||||||
|
if(assign.lefSide.getClass().equals(AssignToField.class)) {
|
||||||
|
// load_0, ldc or .. then putfield
|
||||||
|
this.rightSideTemp = assign.rightSide;
|
||||||
|
assign.lefSide.accept(this);
|
||||||
|
}else {
|
||||||
assign.rightSide.accept(this);
|
assign.rightSide.accept(this);
|
||||||
// int index = paramsAndLocals.get(assign.lefSide.getName());
|
assign.lefSide.accept(this);
|
||||||
// mv.visitVarInsn(Opcodes.ASTORE, index);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Binary binary) {
|
public void visit(Binary binary) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println("++ In Binary: ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println("\n++ In Lambda: ");
|
||||||
|
this.lamCounter++;
|
||||||
|
//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(), false);
|
||||||
|
String methodName = "lambda$new$" + this.lamCounter;
|
||||||
|
// Type erasure
|
||||||
|
Type arg1 = Type.getMethodType("()V");
|
||||||
|
// real Type
|
||||||
|
Type arg3 = Type.getMethodType("()V");
|
||||||
|
Handle arg2 = new Handle(Opcodes.H_INVOKESTATIC, this.className, methodName,
|
||||||
|
arg3.toString(),false);
|
||||||
|
mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", bootstrap,
|
||||||
|
arg1, arg2,arg3);
|
||||||
|
|
||||||
|
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC,
|
||||||
|
methodName, arg3.toString(), null, null);
|
||||||
|
// new BytecodeGenLambda(lambdaExpression, mvLambdaBody);
|
||||||
|
|
||||||
|
new BytecodeGenMethod(lambdaExpression, mvLambdaBody, new HashMap<>(), arg3.toString());
|
||||||
|
mvLambdaBody.visitMaxs(0, 0);
|
||||||
|
mvLambdaBody.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -119,8 +195,19 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println("in fieldVar " + fieldVar.fieldVarName + " ** receiver: "+fieldVar.receiver);
|
||||||
|
|
||||||
|
fieldName = fieldVar.fieldVarName;
|
||||||
|
fieldDesc = fieldVar.getType().toString();
|
||||||
|
|
||||||
|
fieldVar.receiver.accept(this);
|
||||||
|
// test (if)
|
||||||
|
if(!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
|
||||||
|
mv.visitFieldInsn(Opcodes.GETFIELD,fieldVar.getType().toString(),fieldName ,fieldDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mv.visitFieldInsn(Opcodes.GETSTATIC, fieldVar.receiver.getType().toString().replace(".", "/"),
|
||||||
|
// fieldVar.fieldVarName, fieldVar.getType().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -131,8 +218,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IfStmt ifStmt) {
|
public void visit(IfStmt ifStmt) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println("++ IF-Statment: ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -143,13 +229,38 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
|
System.out.println(" In Methodcall: (" +methodCall.name+")" );
|
||||||
|
System.out.println(" Method-Receiver: "+methodCall.receiver.expr);
|
||||||
|
|
||||||
|
methodCall.receiver.accept(this);
|
||||||
|
methodCall.arglist.accept(this);
|
||||||
|
|
||||||
|
Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType());
|
||||||
|
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodCall.receiver.expr.getType().toString(),
|
||||||
|
methodCall.name, mDesc.getDesc(), false);
|
||||||
|
// test
|
||||||
|
if(!methodCall.getType().toString().equals("V")) {
|
||||||
|
mv.visitInsn(Opcodes.POP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewClass methodCall) {
|
public void visit(NewClass methodCall) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println("In NewClass: ");
|
||||||
|
System.out.println("name: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver);
|
||||||
|
|
||||||
|
mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/"));
|
||||||
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
// creates Descriptor
|
||||||
|
methodCall.arglist.accept(this);
|
||||||
|
String d = "(";
|
||||||
|
for(Expression e : methodCall.arglist.getArguments()) {
|
||||||
|
d = d + "L"+e.getType().toString().replace(".", "/") + ";";
|
||||||
|
}
|
||||||
|
d += ")V";
|
||||||
|
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", d, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -160,13 +271,14 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Receiver receiver) {
|
public void visit(Receiver receiver) {
|
||||||
|
System.out.println(" in Receiver");
|
||||||
|
System.out.println(" expr : " + receiver.expr);
|
||||||
receiver.expr.accept(this);
|
receiver.expr.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Return aReturn) {
|
public void visit(Return aReturn) {
|
||||||
// TODO Auto-generated method stub
|
mv.visitInsn(Opcodes.ARETURN);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -176,25 +288,27 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println("In StaticClassName: ");
|
||||||
|
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"),
|
||||||
|
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
||||||
|
mv.visitFieldInsn(Opcodes.GETSTATIC, staticClassName.getType().toString().replace(".", "/"),
|
||||||
|
fieldName, fieldDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Super aSuper) {
|
public void visit(Super aSuper) {
|
||||||
// TODO Auto-generated method stub
|
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(UnaryPlus unaryPlus) {
|
public void visit(UnaryPlus unaryPlus) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println("++ In UnaryPlus: ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -211,32 +325,36 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Null aNull) {
|
public void visit(Null aNull) {
|
||||||
// TODO Auto-generated method stub
|
mv.visitInsn(Opcodes.ACONST_NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Literal literal) {
|
public void visit(Literal literal) {
|
||||||
// TODO Auto-generated method stub
|
// value?
|
||||||
|
mv.visitLdcInsn(literal.getType().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArgumentList argumentList) {
|
public void visit(ArgumentList argumentList) {
|
||||||
// TODO Auto-generated method stub
|
for(Expression al : argumentList.getArguments()) {
|
||||||
|
al.accept(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToField assignLeftSide) {
|
public void visit(AssignToField assignLeftSide) {
|
||||||
// TODO Auto-generated method stub
|
// Loads the an object reference from the local variable
|
||||||
|
// array slot onto the top of the operand stack.
|
||||||
|
assignLeftSide.field.receiver.accept(this);
|
||||||
|
this.rightSideTemp.accept(this);
|
||||||
|
mv.visitFieldInsn(Opcodes.PUTFIELD, assignLeftSide.field.receiver.getType().toString(),
|
||||||
|
assignLeftSide.field.fieldVarName, assignLeftSide.field.getType().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToLocal assignLeftSide) {
|
public void visit(AssignToLocal assignLeftSide) {
|
||||||
// TODO Auto-generated method stub
|
paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1);
|
||||||
|
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
54
src/de/dhbwstuttgart/bytecode/Descriptor.java
Normal file
54
src/de/dhbwstuttgart/bytecode/Descriptor.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import java.awt.List;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
|
||||||
|
public class Descriptor {
|
||||||
|
String desc;
|
||||||
|
|
||||||
|
public Descriptor(Method method) {
|
||||||
|
desc = "(";
|
||||||
|
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
||||||
|
while(itr.hasNext()) {
|
||||||
|
FormalParameter fp = itr.next();
|
||||||
|
desc = desc + "L"+fp.getType().toString().replace(".", "/") + ";";
|
||||||
|
}
|
||||||
|
if(method.getReturnType().toString().equals("void")){
|
||||||
|
desc = desc + ")V";
|
||||||
|
}else {
|
||||||
|
desc = desc + ")" + "L"+method.getReturnType().toString().replace(".", "/")+";";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Descriptor(Constructor constructor) {
|
||||||
|
desc = "(";
|
||||||
|
Iterator<FormalParameter> itr = constructor.getParameterList().iterator();
|
||||||
|
while(itr.hasNext()) {
|
||||||
|
FormalParameter fp = itr.next();
|
||||||
|
desc = desc + "L"+fp.getType().toString().replace(".", "/") + ";";
|
||||||
|
}
|
||||||
|
desc = desc + ")V";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Descriptor(ArgumentList argList, RefTypeOrTPHOrWildcardOrGeneric returnType) {
|
||||||
|
desc = "(";
|
||||||
|
for(Expression e : argList.getArguments()) {
|
||||||
|
desc = desc + "L"+e.getType().toString().replace(".", "/") + ";";
|
||||||
|
}
|
||||||
|
desc = desc + ")"+returnType.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return this.desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user