Bytecode kann für folgende Operationen +,-,*,/,% erzeugt werden

This commit is contained in:
Fayez Abu Alia 2018-02-28 15:59:21 +01:00
parent 6b57aacef0
commit 35b99a4095
2 changed files with 245 additions and 43 deletions

View File

@ -16,6 +16,7 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.statement.*;
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;
@ -107,7 +108,6 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override
public void visit(Block block) {
for(Statement stmt : block.getStatements()) {
// System.out.println(where);
stmt.accept(this);
}
}
@ -116,15 +116,20 @@ public class BytecodeGenMethod implements StatementVisitor{
public void visit(SuperCall superCall) {
superCall.receiver.accept(this);
superCall.arglist.accept(this);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class),
superCall.name, "()V",isInterface);
}
// ??
@Override
public void visit(LocalVar localVar) {
// wenn String + String zuerst wird ein StringBuilder initialisiert dann
// wird die lokale Var geladen. Sonst wird zuerst die lokale Var geladen.
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
if(isBinaryExp) {
getVlaue(getResolvedType(localVar.getType()));
getVlaueIns(getResolvedType(localVar.getType()));
}
}
// ??
@ -152,27 +157,175 @@ public class BytecodeGenMethod implements StatementVisitor{
assign.rightSide.accept(this);
}
if(isBinaryExp) {
doAssign(getResolvedType(assign.lefSide.getType()));
getValueOfIns(getResolvedType(assign.lefSide.getType()));
isBinaryExp = false;
}
assign.lefSide.accept(this);
}
/*
* Die folgeneden Fälle müssen noch betrachtet werden:
* - Long OPARATION Integer usw.
* */
@Override
public void visit(BinaryExpr binary) {
String typeOfBinary = getResolvedType(binary.getType());
if(typeOfBinary.equals(Type.getInternalName(String.class))) {
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
mv.visitInsn(Opcodes.DUP);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class),
"<init>", "()V", false);
}
binary.lexpr.accept(this);
binary.rexpr.accept(this);
switch (binary.operation.toString()) {
case "ADD":
mv.visitInsn(Opcodes.IADD);
doVisitAddOpInsn(typeOfBinary);
break;
case "SUB":
doVisitSubOpInsn(typeOfBinary);
break;
case "MUL":
doVisitMulOpInsn(typeOfBinary);
break;
case "DIV":
doVisitDivOpInsn(typeOfBinary);
break;
case "MOD":
doVisitModOpInsn(typeOfBinary);
break;
case "LESSTHAN":
doVisitLessOpInsn(typeOfBinary);
break;
default:
break;
}
}
// TODO
private void doVisitLessOpInsn(String typeOfBinary) {
switch (typeOfBinary) {
case "java/lang/Long":
mv.visitInsn(Opcodes.LCMP);
break;
case "java/lang/Double":
mv.visitInsn(Opcodes.DCMPG);
break;
case "java/lang/Float":
mv.visitInsn(Opcodes.FCMPG);
break;
default:
Label greaterEq = new Label();
mv.visitJumpInsn(Opcodes.IF_ICMPGE, greaterEq);
mv.visitInsn(Opcodes.ICONST_1);
Label lessThan = new Label();
mv.visitJumpInsn(Opcodes.GOTO, lessThan);
mv.visitLabel(greaterEq);
mv.visitInsn(Opcodes.ICONST_0);
mv.visitLabel(lessThan);
break;
}
}
private void doVisitModOpInsn(String typeOfBinary) {
switch (typeOfBinary) {
case "java/lang/Long":
mv.visitInsn(Opcodes.LREM);
break;
case "java/lang/Double":
mv.visitInsn(Opcodes.DREM);
break;
case "java/lang/Float":
mv.visitInsn(Opcodes.FREM);
break;
default:
mv.visitInsn(Opcodes.IREM);
break;
}
}
private void doVisitDivOpInsn(String typeOfBinary) {
switch (typeOfBinary) {
case "java/lang/Long":
mv.visitInsn(Opcodes.LDIV);
break;
case "java/lang/Double":
mv.visitInsn(Opcodes.DDIV);
break;
case "java/lang/Float":
mv.visitInsn(Opcodes.FDIV);
break;
default:
mv.visitInsn(Opcodes.IDIV);
break;
}
}
private void doVisitMulOpInsn(String typeOfBinary) {
switch (typeOfBinary) {
case "java/lang/Long":
mv.visitInsn(Opcodes.LMUL);
break;
case "java/lang/Double":
mv.visitInsn(Opcodes.DMUL);
break;
case "java/lang/Float":
mv.visitInsn(Opcodes.FMUL);
break;
default:
mv.visitInsn(Opcodes.IMUL);
break;
}
}
private void doVisitSubOpInsn(String typeOfBinary) {
switch (typeOfBinary) {
case "java/lang/Long":
mv.visitInsn(Opcodes.LSUB);
break;
case "java/lang/Double":
mv.visitInsn(Opcodes.DSUB);
break;
case "java/lang/Float":
mv.visitInsn(Opcodes.FSUB);
break;
default:
mv.visitInsn(Opcodes.ISUB);
break;
}
}
private void doVisitAddOpInsn(String typeOfBinary) {
switch (typeOfBinary) {
case "java/lang/Byte":
mv.visitInsn(Opcodes.IADD);
break;
case "java/lang/Short":
mv.visitInsn(Opcodes.IADD);
break;
case "java/lang/Integer":
mv.visitInsn(Opcodes.IADD);
break;
case "java/lang/Long":
mv.visitInsn(Opcodes.LADD);
break;
case "java/lang/Double":
mv.visitInsn(Opcodes.DADD);
break;
case "java/lang/Float":
mv.visitInsn(Opcodes.FADD);
break;
default:
break;
}
}
@Override
public void visit(LambdaExpression lambdaExpression) {
this.lamCounter++;
@ -429,41 +582,45 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override
public void visit(Literal literal) {
Object value = literal.value;
String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(this.isBinaryExp) {
getVlaue(typeOfLiteral);
}else {
doAssign(typeOfLiteral, value);
}
String typeOfLiteral = resultSet.resolveType(
literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
doAssign(typeOfLiteral, value);
}
private void getVlaue(String typeOfLiteral) {
switch (typeOfLiteral) {
private void getVlaueIns(String type) {
switch (type) {
case "java/lang/String":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class),
"append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
break;
case "java/lang/Boolean":
break;
case "java/lang/Byte":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
"(B)Ljava/lang/Byte;", false);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue",
"()B", false);
break;
case "java/lang/Short":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
"(S)Ljava/lang/Short;", false);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue",
"()S", false);
break;
case "java/lang/Integer":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue",
"()I", false);
break;
case "java/lang/Long":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
"(J)Ljava/lang/Long;", false);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue",
"()J", false);
break;
case "java/lang/Float":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue",
"()F", false);
break;
case "java/lang/Double":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue",
"()D", false);
break;
case "java/lang/Character":
break;
@ -482,24 +639,24 @@ public class BytecodeGenMethod implements StatementVisitor{
break;
case "java/lang/Byte":
visitByteLiteral(((Double) value).byteValue(),false);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
"(B)Ljava/lang/Byte;", false);
if(!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Short":
visitShortLiteral(((Double) value).shortValue(),false);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
"(S)Ljava/lang/Short;", false);
if(!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Integer":
//zweite Argument isLong
visitIntegerLiteral(((Double) value).intValue(), false);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
"(I)Ljava/lang/Integer;", false);
if(!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Long":
visitLongLiteral(((Double) value).longValue(), true);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
"(J)Ljava/lang/Long;", false);
if(!this.isBinaryExp)
getValueOfIns(type);
break;
case "java/lang/Float":
visitFloatLiteral(((Double) value).floatValue());
@ -515,11 +672,15 @@ public class BytecodeGenMethod implements StatementVisitor{
}
}
private void doAssign(String type) {
private void getValueOfIns(String type) {
switch (type) {
case "java/lang/String":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
"()Ljava/lang/String;", false);
break;
case "java/lang/Boolean":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
"(Z)Ljava/lang/Boolean;", false);
break;
case "java/lang/Byte":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
@ -538,10 +699,16 @@ public class BytecodeGenMethod implements StatementVisitor{
"(J)Ljava/lang/Long;", false);
break;
case "java/lang/Float":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
"(F)Ljava/lang/Float;", false);
break;
case "java/lang/Double":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
"(D)Ljava/lang/Double;", false);
break;
case "java/lang/Character":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
"(C)Ljava/lang/Character;", false);
break;
default:
break;
@ -550,8 +717,8 @@ public class BytecodeGenMethod implements StatementVisitor{
private void visitCharLiteral(Character value) {
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
"(C)Ljava/lang/Character;", false);
if(!this.isBinaryExp)
getValueOfIns(Type.getInternalName(Character.class));
}
private void visitDoubleLiteral(Double value) {
@ -562,8 +729,8 @@ public class BytecodeGenMethod implements StatementVisitor{
}else {
mv.visitLdcInsn(value);
}
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
"(D)Ljava/lang/Double;", false);
if(!this.isBinaryExp)
getValueOfIns(Type.getInternalName(Double.class));
}
private void visitFloatLiteral(Float value) {
@ -573,8 +740,8 @@ public class BytecodeGenMethod implements StatementVisitor{
}else {
mv.visitLdcInsn(value);
}
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
"(F)Ljava/lang/Float;", false);
if(!this.isBinaryExp)
getValueOfIns(Type.getInternalName(Float.class));
}
private void visitLongLiteral(Long value, boolean isLong) {
@ -622,6 +789,7 @@ public class BytecodeGenMethod implements StatementVisitor{
}else {
mv.visitInsn(Opcodes.ICONST_0);
}
// muss noch getestet werden.
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
"(Z)Ljava/lang/Boolean;", false);
}

View File

@ -1,12 +1,46 @@
import java.lang.Integer;
import java.lang.String;
import java.lang.Long;
import java.lang.Float;
import java.lang.Double;
import java.lang.Boolean;
class Op {
m(Integer a, Integer b) {
Integer c = a+b;
// d = a-b;
// e = a*b;
// f = a/b;
addInt(Integer a, Integer b) {
Integer c = a+b;
return c;
}
addString(String a, String b) {
String c = a+b;
return c;
}
addLong(Long a, Long b) {
Long c = a+b;
return c;
}
addFloat(Float a, Float b) {
Float c = a+b;
return c;
}
addDouble(Double a, Double b) {
Double c = a+b;
return c;
}
subInt(Integer a, Integer b) {
Integer c = a-b;
return c;
}
subLong(Long a, Long b) {
Long c = a-b;
return c;
}
subFloat(Float a, Float b) {
Float c = a-b;
return c;
}
subDouble(Double a, Double b) {
Double c = a-b;
return c;
}
}