forked from JavaTX/JavaCompilerCore
Bytecode für While-Schleifen
This commit is contained in:
parent
52a5fd7904
commit
dafcd2f125
@ -1,7 +1,9 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
@ -9,6 +11,7 @@ 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.bytecode.descriptor.DescriptorToString;
|
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
@ -23,6 +26,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
public class BytecodeGen implements ASTVisitor {
|
public class BytecodeGen implements ASTVisitor {
|
||||||
@ -30,9 +34,10 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||||||
|
|
||||||
String type;
|
String type;
|
||||||
|
|
||||||
String className;
|
String className;
|
||||||
private boolean isInterface;
|
private boolean isInterface;
|
||||||
|
private List<ResultSet> listOfResultSets;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private int indexOfFirstParam = 0;
|
private int indexOfFirstParam = 0;
|
||||||
|
|
||||||
@ -47,16 +52,18 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
byte[] bytecode;
|
byte[] bytecode;
|
||||||
HashMap<String,byte[]> classFiles;
|
HashMap<String,byte[]> classFiles;
|
||||||
|
|
||||||
public BytecodeGen(HashMap<String,byte[]> classFiles, ResultSet resultSet) {
|
ArrayList<String> methodNameAndParamsT = new ArrayList<>();
|
||||||
|
|
||||||
|
public BytecodeGen(HashMap<String,byte[]> classFiles, List<ResultSet> listOfResultSets) {
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.resultSet = resultSet;
|
this.listOfResultSets = listOfResultSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SourceFile sourceFile) {
|
public void visit(SourceFile sourceFile) {
|
||||||
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
||||||
System.out.println("in Class: " + cl.getClassName().toString());
|
System.out.println("in Class: " + cl.getClassName().toString());
|
||||||
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet);
|
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets);
|
||||||
cl.accept(classGen);
|
cl.accept(classGen);
|
||||||
classGen.writeClass(cl.getClassName().toString());
|
classGen.writeClass(cl.getClassName().toString());
|
||||||
}
|
}
|
||||||
@ -101,18 +108,27 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
|
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
|
||||||
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
||||||
|
|
||||||
// for each field in the class
|
|
||||||
for(Field f : classOrInterface.getFieldDecl()) {
|
for(Field f : classOrInterface.getFieldDecl()) {
|
||||||
f.accept(this);
|
f.accept(this);
|
||||||
}
|
}
|
||||||
|
// resultSet = listOfResultSets.get(0);
|
||||||
|
boolean isConsWithNoParamsVisited = false;
|
||||||
|
for(ResultSet rs : listOfResultSets) {
|
||||||
|
resultSet = rs;
|
||||||
|
|
||||||
|
for(Constructor c : classOrInterface.getConstructors()) {
|
||||||
|
if(!isConsWithNoParamsVisited)
|
||||||
|
c.accept(this);
|
||||||
|
if(!c.getParameterList().iterator().hasNext())
|
||||||
|
isConsWithNoParamsVisited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Method m : classOrInterface.getMethods()) {
|
||||||
|
m.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
for(Constructor c : classOrInterface.getConstructors()) {
|
|
||||||
c.accept(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Method m : classOrInterface.getMethods()) {
|
|
||||||
m.accept(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -146,13 +162,24 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Method method) {
|
public void visit(Method method) {
|
||||||
// TODO: check if the method is static => if static then the first param will be stored in pos 0
|
// TODO: check if the method is static => if static then the first param will be stored in pos 0
|
||||||
// else it will be stored in pos 1 and this will be stored in pos 0
|
// else it will be stored in pos 1 and this will be stored in pos 0
|
||||||
method.getParameterList().accept(this);
|
method.getParameterList().accept(this);
|
||||||
|
String methParamTypes = method.name+";";
|
||||||
|
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
||||||
|
while(itr.hasNext()) {
|
||||||
|
FormalParameter fp = itr.next();
|
||||||
|
methParamTypes = methParamTypes+ resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(methodNameAndParamsT.contains(methParamTypes)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
methodNameAndParamsT.add(methParamTypes);
|
||||||
|
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
|
||||||
String methDesc = null;
|
String methDesc = null;
|
||||||
|
|
||||||
// Method getModifiers() ?
|
// Method getModifiers() ?
|
||||||
@ -181,16 +208,17 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
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);
|
|
||||||
|
// System.out.println(methDesc);
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+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,
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,
|
||||||
genericsAndBounds,genericsAndBounds,isInterface,classFiles);
|
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,6 @@ 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.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
@ -58,9 +55,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
private String fieldName;
|
private String fieldName;
|
||||||
private String fieldDesc;
|
private String fieldDesc;
|
||||||
private Expression rightSideTemp;
|
private Expression rightSideTemp;
|
||||||
|
|
||||||
private boolean isRightSideALambda = false;
|
private boolean isRightSideALambda = false;
|
||||||
private KindOfLambda kindOfLambda;
|
private KindOfLambda kindOfLambda;
|
||||||
private HashMap<String, byte[]> classFiles;
|
private HashMap<String, byte[]> classFiles;
|
||||||
|
|
||||||
|
private boolean isAssignStmt = false;
|
||||||
|
private Statement loopBlock;
|
||||||
|
|
||||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Block block) {
|
public void visit(Block block) {
|
||||||
for (Statement stmt : block.getStatements()) {
|
for (Statement stmt : block.getStatements()) {
|
||||||
@ -142,6 +143,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Assign assign) {
|
public void visit(Assign assign) {
|
||||||
|
isAssignStmt = true;
|
||||||
|
|
||||||
// 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 instanceof LambdaExpression) {
|
if (assign.rightSide instanceof LambdaExpression) {
|
||||||
isRightSideALambda = true;
|
isRightSideALambda = true;
|
||||||
@ -151,6 +154,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
if (assign.rightSide instanceof BinaryExpr)
|
if (assign.rightSide instanceof BinaryExpr)
|
||||||
isBinaryExp = true;
|
isBinaryExp = true;
|
||||||
|
|
||||||
|
|
||||||
if (assign.lefSide instanceof AssignToField) {
|
if (assign.lefSide instanceof AssignToField) {
|
||||||
// load_0, ldc or .. then putfield
|
// load_0, ldc or .. then putfield
|
||||||
@ -159,10 +163,15 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
assign.rightSide.accept(this);
|
assign.rightSide.accept(this);
|
||||||
}
|
}
|
||||||
if (isBinaryExp) {
|
if (isBinaryExp) {
|
||||||
getValueOfIns(getResolvedType(assign.lefSide.getType()));
|
BinaryExpr binary = (BinaryExpr) assign.rightSide;
|
||||||
|
String lexpType = getResolvedType(binary.lexpr.getType());
|
||||||
|
String rexpType = getResolvedType(binary.rexpr.getType());
|
||||||
|
getValueOfIns(getLargerType(lexpType, rexpType));
|
||||||
isBinaryExp = false;
|
isBinaryExp = false;
|
||||||
}
|
}
|
||||||
assign.lefSide.accept(this);
|
assign.lefSide.accept(this);
|
||||||
|
|
||||||
|
isAssignStmt =false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -171,20 +180,34 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
|
// if(!areTypesValid(binary)) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
String lexpType = getResolvedType(binary.lexpr.getType());
|
||||||
|
String rexpType = getResolvedType(binary.rexpr.getType());
|
||||||
|
|
||||||
|
String largerType = getLargerType(lexpType,rexpType);
|
||||||
String typeOfBinary = getResolvedType(binary.getType());
|
String typeOfBinary = getResolvedType(binary.getType());
|
||||||
|
|
||||||
|
// if(!(largerType.equals(typeOfBinary)&&typeOfBinary.equals(Type.getInternalName(Number.class))&&typeOfBinary.equals(Type.getInternalName(Object.class)))) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
if (typeOfBinary.equals(Type.getInternalName(String.class))) {
|
if (typeOfBinary.equals(Type.getInternalName(String.class))) {
|
||||||
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
|
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn(Opcodes.DUP);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V",
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V",
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
// tmp!!
|
||||||
|
Label endLabel = new Label();
|
||||||
|
// this case for while loops
|
||||||
|
if(!isAssignStmt)
|
||||||
|
mv.visitLabel(endLabel);
|
||||||
|
|
||||||
binary.lexpr.accept(this);
|
binary.lexpr.accept(this);
|
||||||
|
|
||||||
String lexpType = getResolvedType(binary.lexpr.getType());
|
|
||||||
String rexpType = getResolvedType(binary.rexpr.getType());
|
|
||||||
|
|
||||||
String largerType = getLargerType(lexpType,rexpType);
|
|
||||||
|
|
||||||
if(!lexpType.equals(rexpType) &&
|
if(!lexpType.equals(rexpType) &&
|
||||||
!lexpType.equals(largerType))
|
!lexpType.equals(largerType))
|
||||||
doCast(lexpType, largerType);
|
doCast(lexpType, largerType);
|
||||||
@ -199,7 +222,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case ADD:
|
case ADD:
|
||||||
doVisitAddOpInsn(typeOfBinary);
|
doVisitAddOpInsn(largerType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUB:
|
case SUB:
|
||||||
@ -222,7 +245,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
case LESSEQUAL:
|
case LESSEQUAL:
|
||||||
case BIGGERTHAN:
|
case BIGGERTHAN:
|
||||||
case BIGGEREQUAL:
|
case BIGGEREQUAL:
|
||||||
doVisitRelOpInsn(op,largerType);
|
Label branchLabel = new Label();
|
||||||
|
doVisitRelOpInsn(op,largerType, branchLabel, endLabel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -232,6 +256,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getLargerType(String lexpType, String rexpType) {
|
private String getLargerType(String lexpType, String rexpType) {
|
||||||
|
if(lexpType.equals(Type.getInternalName(String.class)) ||
|
||||||
|
rexpType.equals(Type.getInternalName(String.class))) {
|
||||||
|
return Type.getInternalName(String.class);
|
||||||
|
} else
|
||||||
if(lexpType.equals(Type.getInternalName(Double.class)) ||
|
if(lexpType.equals(Type.getInternalName(Double.class)) ||
|
||||||
rexpType.equals(Type.getInternalName(Double.class))) {
|
rexpType.equals(Type.getInternalName(Double.class))) {
|
||||||
return Type.getInternalName(Double.class);
|
return Type.getInternalName(Double.class);
|
||||||
@ -275,9 +303,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doVisitRelOpInsn(Operator op, String typeOfBinary) {
|
private void doVisitRelOpInsn(Operator op, String typeOfBinary, Label branchLabel, Label endLabel) {
|
||||||
Label branchLabel = new Label();
|
|
||||||
Label endLabel = new Label();
|
|
||||||
|
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
@ -309,37 +335,52 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(isAssignStmt) {
|
||||||
|
mv.visitInsn(Opcodes.ICONST_1);
|
||||||
|
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
||||||
|
mv.visitLabel(branchLabel);
|
||||||
|
mv.visitInsn(Opcodes.ICONST_0);
|
||||||
|
mv.visitLabel(endLabel);
|
||||||
|
} else {
|
||||||
|
loopBlock.accept(this);
|
||||||
|
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
||||||
|
|
||||||
|
mv.visitLabel(branchLabel);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doVisitIfInRelOp(Operator op, Label branchLabel, Label endLabel) {
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case LESSTHAN:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFGE, branchLabel);
|
||||||
|
break;
|
||||||
|
case LESSEQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFGT, branchLabel);
|
||||||
|
break;
|
||||||
|
case BIGGERTHAN:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFLE, branchLabel);
|
||||||
|
break;
|
||||||
|
case BIGGEREQUAL:
|
||||||
|
mv.visitJumpInsn(Opcodes.IFLT, branchLabel);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(isAssignStmt) {
|
||||||
mv.visitInsn(Opcodes.ICONST_1);
|
mv.visitInsn(Opcodes.ICONST_1);
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
||||||
mv.visitLabel(branchLabel);
|
mv.visitLabel(branchLabel);
|
||||||
mv.visitInsn(Opcodes.ICONST_0);
|
mv.visitInsn(Opcodes.ICONST_0);
|
||||||
mv.visitLabel(endLabel);
|
mv.visitLabel(endLabel);
|
||||||
break;
|
} else {
|
||||||
|
loopBlock.accept(this);
|
||||||
|
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
||||||
|
|
||||||
|
mv.visitLabel(branchLabel);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void doVisitIfInRelOp(Operator op, Label greaterEq, Label lessThan) {
|
|
||||||
switch (op) {
|
|
||||||
case LESSTHAN:
|
|
||||||
mv.visitJumpInsn(Opcodes.IFGE, greaterEq);
|
|
||||||
break;
|
|
||||||
case LESSEQUAL:
|
|
||||||
mv.visitJumpInsn(Opcodes.IFGT, greaterEq);
|
|
||||||
break;
|
|
||||||
case BIGGERTHAN:
|
|
||||||
mv.visitJumpInsn(Opcodes.IFLE, greaterEq);
|
|
||||||
break;
|
|
||||||
case BIGGEREQUAL:
|
|
||||||
mv.visitJumpInsn(Opcodes.IFLT, greaterEq);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mv.visitInsn(Opcodes.ICONST_1);
|
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, lessThan);
|
|
||||||
mv.visitLabel(greaterEq);
|
|
||||||
mv.visitInsn(Opcodes.ICONST_0);
|
|
||||||
mv.visitLabel(lessThan);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -681,14 +722,19 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WhileStmt whileStmt) {
|
public void visit(WhileStmt whileStmt) {
|
||||||
|
this.loopBlock = whileStmt.loopBlock;
|
||||||
|
|
||||||
|
if(whileStmt.expr instanceof BinaryExpr)
|
||||||
|
isBinaryExp = true;
|
||||||
|
|
||||||
whileStmt.expr.accept(this);
|
whileStmt.expr.accept(this);
|
||||||
whileStmt.loopBlock.accept(this);
|
|
||||||
|
isBinaryExp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
// TODO Auto-generated method stub
|
whileStmt.expr.accept(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -916,7 +962,14 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
public void visit(AssignToLocal assignLeftSide) {
|
public void visit(AssignToLocal assignLeftSide) {
|
||||||
if (isRightSideALambda)
|
if (isRightSideALambda)
|
||||||
varsFunInterface.add(assignLeftSide.localVar.getType());
|
varsFunInterface.add(assignLeftSide.localVar.getType());
|
||||||
paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size() + 1);
|
int index = paramsAndLocals.size();
|
||||||
|
String var = assignLeftSide.localVar.name;
|
||||||
|
if(!paramsAndLocals.containsKey(var)) {
|
||||||
|
paramsAndLocals.put(var, index + 1);
|
||||||
|
}else {
|
||||||
|
paramsAndLocals.put(var, index);
|
||||||
|
}
|
||||||
|
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
||||||
// Debug:::
|
// Debug:::
|
||||||
|
|
||||||
|
@ -138,7 +138,8 @@ public class JavaTXCompiler {
|
|||||||
HashMap<String,byte[]> classFiles = new HashMap<>();
|
HashMap<String,byte[]> classFiles = new HashMap<>();
|
||||||
SourceFile sf = sourceFiles.get(f);
|
SourceFile sf = sourceFiles.get(f);
|
||||||
List<ResultSet> typeinferenceResult = this.typeInference();
|
List<ResultSet> typeinferenceResult = this.typeInference();
|
||||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
|
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult);
|
||||||
|
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
|
||||||
bytecodeGen.visit(sf);
|
bytecodeGen.visit(sf);
|
||||||
this.writeClassFile(bytecodeGen.getClassFiles());
|
this.writeClassFile(bytecodeGen.getClassFiles());
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ public class TYPEStmt implements StatementVisitor{
|
|||||||
receiver.expr.accept(this);
|
receiver.expr.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken());
|
private final RefType number = new RefType(ASTFactory.createClass(Integer.class).getClassName(), new NullToken());
|
||||||
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
|
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
|
||||||
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
|
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,7 +39,7 @@ public class GreaterEqualTest {
|
|||||||
public void testName() {
|
public void testName() {
|
||||||
assertEquals("GreaterEqual", classToTest.getName());
|
assertEquals("GreaterEqual", classToTest.getName());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
public void testIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
public void testIntegers() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
|
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
|
||||||
Boolean result = (Boolean) gE.invoke(instanceOfClass, 7, 5);
|
Boolean result = (Boolean) gE.invoke(instanceOfClass, 7, 5);
|
||||||
|
@ -59,14 +59,14 @@ public class OpTest {
|
|||||||
// assertEquals("ByteCode", result);
|
// assertEquals("ByteCode", result);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @Test
|
@Test
|
||||||
// public void testAddInt() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
public void testAddInt() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
// Method addInt = classToTest.getDeclaredMethod("addInt", Integer.class,Integer.class);
|
Method addInt = classToTest.getDeclaredMethod("addInt", Integer.class,Integer.class);
|
||||||
// Integer result = (Integer) addInt.invoke(instanceOfClass, 7,3);
|
Number result = (Number) addInt.invoke(instanceOfClass, 7,3);
|
||||||
// assertEquals(10, result);
|
assertEquals(10, result);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Test
|
// @Test
|
||||||
// public void testAddLong() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
// public void testAddLong() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
@ -159,35 +159,35 @@ public class OpTest {
|
|||||||
// assertEquals(10d, result);
|
// assertEquals(10d, result);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@Test
|
// @Test
|
||||||
public void testMulInt() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
// public void testMulInt() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
Method mulInt = classToTest.getDeclaredMethod("mulInt", Integer.class,Integer.class);
|
// Method mulInt = classToTest.getDeclaredMethod("mulInt", Integer.class,Integer.class);
|
||||||
Integer result = (Integer) mulInt.invoke(instanceOfClass, 7,3);
|
// Integer result = (Integer) mulInt.invoke(instanceOfClass, 7,3);
|
||||||
assertEquals(21, result);
|
// assertEquals(21, result);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
public void testMulLong() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
// public void testMulLong() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
Method mulLong = classToTest.getDeclaredMethod("mulLong", Long.class,Long.class);
|
// Method mulLong = classToTest.getDeclaredMethod("mulLong", Long.class,Long.class);
|
||||||
Long result = (Long) mulLong.invoke(instanceOfClass, 7L,3L);
|
// Long result = (Long) mulLong.invoke(instanceOfClass, 7L,3L);
|
||||||
assertEquals(21L, result);
|
// assertEquals(21L, result);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
public void testMulFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
// public void testMulFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
Method mulFloat = classToTest.getDeclaredMethod("mulFloat", Float.class,Float.class);
|
// Method mulFloat = classToTest.getDeclaredMethod("mulFloat", Float.class,Float.class);
|
||||||
Float result = (Float) mulFloat.invoke(instanceOfClass, 7f,3f);
|
// Float result = (Float) mulFloat.invoke(instanceOfClass, 7f,3f);
|
||||||
assertEquals(21f, result);
|
// assertEquals(21f, result);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
public void testMulDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
// public void testMulDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
Method mulDouble = classToTest.getDeclaredMethod("mulDouble", Double.class,Double.class);
|
// Method mulDouble = classToTest.getDeclaredMethod("mulDouble", Double.class,Double.class);
|
||||||
Double result = (Double) mulDouble.invoke(instanceOfClass, 7.0,3.0);
|
// Double result = (Double) mulDouble.invoke(instanceOfClass, 7.0,3.0);
|
||||||
assertEquals(21.0, result);
|
// assertEquals(21.0, result);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
44
test/bytecode/WhileTest.java
Normal file
44
test/bytecode/WhileTest.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class WhileTest {
|
||||||
|
private static String path;
|
||||||
|
private static File fileToTest;
|
||||||
|
private static JavaTXCompiler compiler;
|
||||||
|
private static ClassLoader loader;
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static String pathToClassFile;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/While.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode();
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("While");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Integer.class);
|
||||||
|
Integer result = (Integer) m.invoke(instanceOfClass, 0);
|
||||||
|
assertEquals(2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,7 @@ import java.lang.Float;
|
|||||||
import java.lang.Double;
|
import java.lang.Double;
|
||||||
|
|
||||||
public class GreaterEqual {
|
public class GreaterEqual {
|
||||||
|
|
||||||
gE(Integer a, Integer b){
|
gE(Integer a, Integer b){
|
||||||
var c = a>=b;
|
var c = a>=b;
|
||||||
return c;
|
return c;
|
||||||
|
@ -8,10 +8,13 @@ import java.lang.Short;
|
|||||||
import java.lang.Byte;
|
import java.lang.Byte;
|
||||||
|
|
||||||
public class Op {
|
public class Op {
|
||||||
// addInt(Integer a, Integer b) {
|
|
||||||
// Integer c = a+b;
|
addInt( a, b) {
|
||||||
// return c;
|
var c = a+b;
|
||||||
// }
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// addString(String a, String b) {
|
// addString(String a, String b) {
|
||||||
// String c = a+b;
|
// String c = a+b;
|
||||||
// return c;
|
// return c;
|
||||||
@ -51,25 +54,25 @@ public class Op {
|
|||||||
// return c;
|
// return c;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
mulInt(Integer a, Integer b) {
|
// mulInt(Integer a, Integer b) {
|
||||||
Integer c = a*b;
|
// Integer c = a*b;
|
||||||
return c;
|
// return c;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
mulLong(Long a, Long b) {
|
// mulLong(Long a, Long b) {
|
||||||
Long c = a*b;
|
// Long c = a*b;
|
||||||
return c;
|
// return c;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
mulFloat(Float a, Float b) {
|
// mulFloat(Float a, Float b) {
|
||||||
Float c = a*b;
|
// Float c = a*b;
|
||||||
return c;
|
// return c;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
mulDouble(Double a, Double b) {
|
// mulDouble(Double a, Double b) {
|
||||||
Double c = a*b;
|
// Double c = a*b;
|
||||||
return c;
|
// return c;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// add(Double a, Long b) {
|
// add(Double a, Long b) {
|
||||||
// Double c = a+b;
|
// Double c = a+b;
|
||||||
|
10
test/bytecode/javFiles/While.jav
Normal file
10
test/bytecode/javFiles/While.jav
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public class While {
|
||||||
|
m(x) {
|
||||||
|
while(x < 2) {
|
||||||
|
x = x+1;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user