forked from JavaTX/JavaCompilerCore
415 lines
10 KiB
Java
415 lines
10 KiB
Java
|
package de.dhbwstuttgart.bytecode;
|
||
|
|
||
|
import java.awt.List;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Iterator;
|
||
|
|
||
|
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;
|
||
|
|
||
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||
|
import de.dhbwstuttgart.syntaxtree.*;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.Assign;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.Binary;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.Receiver;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.Return;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.Super;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.This;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.UnaryPlus;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
|
||
|
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
|
||
|
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||
|
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||
|
|
||
|
public class BytecodeGen implements ASTVisitor {
|
||
|
|
||
|
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||
|
// String methDesc;
|
||
|
|
||
|
String type;
|
||
|
// 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<>();
|
||
|
byte[] bytecode;
|
||
|
HashMap<String,byte[]> classFiles;
|
||
|
|
||
|
public BytecodeGen(HashMap<String,byte[]> classFiles) {
|
||
|
this.classFiles = classFiles;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(SourceFile sourceFile) {
|
||
|
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
||
|
BytecodeGen classGen = new BytecodeGen(classFiles);
|
||
|
cl.accept(classGen);
|
||
|
classGen.writeClass(cl.getClassName().toString());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void writeClass(String name) {
|
||
|
bytecode = cw.toByteArray();
|
||
|
classFiles.put(name, bytecode);
|
||
|
|
||
|
}
|
||
|
|
||
|
public HashMap<String,byte[]> getClassFiles() {
|
||
|
return classFiles;
|
||
|
}
|
||
|
@Override
|
||
|
public void visit(ClassOrInterface classOrInterface) {
|
||
|
// access flages??
|
||
|
cw.visit(Opcodes.V1_8, classOrInterface.getModifiers(), classOrInterface.getClassName().toString()
|
||
|
, null, classOrInterface.getSuperClass().toString(), null);
|
||
|
// for each field in the class
|
||
|
for(Field f : classOrInterface.getFieldDecl()) {
|
||
|
f.accept(this);
|
||
|
}
|
||
|
|
||
|
for(Constructor c : classOrInterface.getConstructors()) {
|
||
|
c.accept(this);
|
||
|
}
|
||
|
|
||
|
for(Method m : classOrInterface.getMethods()) {
|
||
|
m.accept(this);
|
||
|
}
|
||
|
cw.visitSource(classOrInterface.getClassName().toString()+".jav", null);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Constructor field) {
|
||
|
String methDesc = getConsDesc(field);
|
||
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", methDesc, null, null);
|
||
|
mv.visitCode();
|
||
|
|
||
|
BytecodeGenMethod gen = new BytecodeGenMethod(field, mv,paramsAndLocals,true);
|
||
|
|
||
|
mv.visitInsn(Opcodes.RETURN);
|
||
|
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
|
||
|
public void visit(Method method) {
|
||
|
// ParameterList pl = method.getParameterList();
|
||
|
String methDesc = getMethDesc(method);
|
||
|
// methDesc = "(";
|
||
|
// method.getParameterList().accept(this);
|
||
|
// 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();
|
||
|
|
||
|
BytecodeGenMethod gen = new BytecodeGenMethod(method, mv,paramsAndLocals,false);
|
||
|
|
||
|
}
|
||
|
|
||
|
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
|
||
|
public void visit(ParameterList formalParameters) {
|
||
|
Iterator<FormalParameter> itr = formalParameters.iterator();
|
||
|
int i = 1;
|
||
|
while(itr.hasNext()) {
|
||
|
FormalParameter fp = itr.next();
|
||
|
paramsAndLocals.put(fp.getName(), i);
|
||
|
fp.accept(this);
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(FormalParameter formalParameter) {
|
||
|
formalParameter.getType().accept(this);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(RefType refType) {
|
||
|
type = "L"+refType.toString()+";";
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(SuperWildcardType superWildcardType) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(TypePlaceholder typePlaceholder) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(ExtendsWildcardType extendsWildcardType) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(GenericRefType genericRefType) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
// ??
|
||
|
@Override
|
||
|
public void visit(FieldVar fieldVar) {
|
||
|
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
||
|
}
|
||
|
|
||
|
// access flages?? modifiers
|
||
|
@Override
|
||
|
public void visit(Field field) {
|
||
|
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType()+";", null, null);
|
||
|
fv.visitEnd();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(LambdaExpression lambdaExpression) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Assign assign) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Binary binary) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Block block) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(CastExpr castExpr) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(EmptyStmt emptyStmt) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(ForStmt forStmt) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(IfStmt ifStmt) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(InstanceOf instanceOf) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(LocalVar localVar) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(LocalVarDecl localVarDecl) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(MethodCall methodCall) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(NewClass methodCall) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(NewArray newArray) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Receiver receiver) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Return aReturn) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(ReturnVoid aReturn) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(StaticClassName staticClassName) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Super aSuper) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(This aThis) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(UnaryPlus unaryPlus) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(WhileStmt whileStmt) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(DoStmt whileStmt) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(Null aNull) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
// ???
|
||
|
@Override
|
||
|
public void visit(Literal literal) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(ArgumentList argumentList) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(GenericTypeVar genericTypeVar) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(GenericDeclarationList genericTypeVars) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(AssignToField assignLeftSide) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(AssignToLocal assignLeftSide) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void visit(SuperCall superCall) {
|
||
|
// TODO Auto-generated method stub
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|