From 4fbcf87e0c23888c4e9ea9dd5a2701ac608d1241 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Fri, 23 Feb 2018 20:10:11 +0100 Subject: [PATCH] =?UTF-8?q?Methoden=20visit(assign)/visit(literal)=20angep?= =?UTF-8?q?asst=20und=20generiert=20bytecode=20f=C3=BCr=20Binaryexpression?= =?UTF-8?q?s.=20noch=20nicht=20fertig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytecode/BytecodeGenMethod.java | 145 +++++++++++++----- test/bytecode/AssignToLit.jav | 30 ++-- test/bytecode/For.jav | 26 ++-- test/bytecode/Op.jav | 12 ++ test/bytecode/OpTest.java | 7 + test/parser/OpratorTest.jav | 6 +- 6 files changed, 157 insertions(+), 69 deletions(-) create mode 100644 test/bytecode/Op.jav create mode 100644 test/bytecode/OpTest.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index b6a45bb1..df714015 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -43,30 +43,28 @@ public class BytecodeGenMethod implements StatementVisitor{ private MethodVisitor mv; private HashMap paramsAndLocals = new HashMap<>(); private String className; - private int lamCounter; + private int lamCounter = -1; private ClassWriter cw; private ResultSet resultSet; private boolean isInterface; HashMap genericsAndBoundsMethod; private HashMap genericsAndBounds; + private boolean isBinaryExp = false; //for tests ** private String fieldName; private String fieldDesc; private Expression rightSideTemp; -// private String where; private boolean isRightSideALambda = false; private KindOfLambda kindOfLambda; private HashMap classFiles; - private ArrayList varsFunInterface; + private ArrayList varsFunInterface = new ArrayList<>();; public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, HashMap genericsAndBounds, boolean isInterface, HashMap classFiles) { -// this.where = "<<<<<< NORMAL METHOD >>>>>>"; - this.className = className; this.resultSet = resultSet; this.m = m; @@ -77,9 +75,6 @@ public class BytecodeGenMethod implements StatementVisitor{ this.genericsAndBounds = genericsAndBounds; this.isInterface = isInterface; this.classFiles = classFiles; - this.lamCounter = -1; - - this.varsFunInterface = new ArrayList<>(); if(!isInterface) this.m.block.accept(this); @@ -89,13 +84,10 @@ public class BytecodeGenMethod implements StatementVisitor{ public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv, int indexOfFirstParamLam, boolean isInterface, HashMap classFiles) { -// this.where = "<<<<<< LAMBDA METHOD >>>>>>"; this.resultSet = resultSet; this.mv = mv; this.isInterface = isInterface; this.classFiles = classFiles; - this.lamCounter = -1; - this.varsFunInterface = new ArrayList<>(); Iterator itr = lambdaExpression.params.iterator(); int i = indexOfFirstParamLam; @@ -124,51 +116,61 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(SuperCall superCall) { superCall.receiver.accept(this); superCall.arglist.accept(this); -// mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface); } // ?? @Override public void visit(LocalVar localVar) { -// System.out.println("in Local Var: " + localVar.name); mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); + if(isBinaryExp) { + getVlaue(getResolvedType(localVar.getType())); + } } // ?? @Override public void visit(LocalVarDecl localVarDecl) { -// Integer i; -// paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1); -// System.out.println("In localVarDecl :: "+localVarDecl.getName()); + } @Override public void visit(Assign assign) { -// 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(assign.rightSide.getClass().equals(LambdaExpression.class)) { + if(assign.rightSide instanceof LambdaExpression) { isRightSideALambda = true; }else { isRightSideALambda = false; } - if(assign.lefSide.getClass().equals(AssignToField.class)) { + if(assign.rightSide instanceof BinaryExpr) + isBinaryExp = true; + + if(assign.lefSide instanceof AssignToField) { // load_0, ldc or .. then putfield this.rightSideTemp = assign.rightSide; - assign.lefSide.accept(this); }else { assign.rightSide.accept(this); - assign.lefSide.accept(this); } + if(isBinaryExp) { + doAssign(getResolvedType(assign.lefSide.getType())); + isBinaryExp = false; + } + assign.lefSide.accept(this); } @Override - public void visit(BinaryExpr binary) { - System.out.println("\t++ In Binary: "); - System.out.println(binary.operation.toString()); + binary.lexpr.accept(this); + binary.rexpr.accept(this); + switch (binary.operation.toString()) { + case "ADD": + mv.visitInsn(Opcodes.IADD); + break; + default: + break; + } + } @Override @@ -330,12 +332,6 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(MethodCall methodCall) { -// if(methodCall.receiver instanceof ExpressionReceiver){ -// System.out.print(((ExpressionReceiver) methodCall.receiver).expr + "\n"); -// }else{ -// System.out.print(((StaticClassName) methodCall.receiver).getType().toString() + "\n"); -// } - methodCall.receiver.accept(this); methodCall.arglist.accept(this); @@ -343,8 +339,6 @@ public class BytecodeGenMethod implements StatementVisitor{ genericsAndBoundsMethod,genericsAndBounds); String mDesc = method.accept(new DescriptorToString(resultSet)); -// System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); - // is methodCall.receiver functional Interface)? if(varsFunInterface.contains(methodCall.receiver.getType())) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), @@ -361,8 +355,6 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(NewClass methodCall) { -// System.out.println("In NewClass: "); -// System.out.println("\t\tname: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver); mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/")); mv.visitInsn(Opcodes.DUP); @@ -437,9 +429,53 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Literal literal) { Object value = literal.value; - switch (resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor())) { + String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor()); + if(this.isBinaryExp) { + getVlaue(typeOfLiteral); + }else { + doAssign(typeOfLiteral, value); + } + + + } + + private void getVlaue(String typeOfLiteral) { + switch (typeOfLiteral) { case "java/lang/String": - mv.visitLdcInsn(value); + break; + case "java/lang/Boolean": + break; + case "java/lang/Byte": + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", + "(B)Ljava/lang/Byte;", false); + break; + case "java/lang/Short": + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", + "(S)Ljava/lang/Short;", 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); + break; + case "java/lang/Float": + break; + case "java/lang/Double": + break; + case "java/lang/Character": + break; + default: + break; + } + } + + private void doAssign(String type, Object value) { + switch (type) { + case "java/lang/String": + mv.visitLdcInsn(String.valueOf(value)); break; case "java/lang/Boolean": visitBooleanLiteral((Boolean) value); @@ -479,8 +515,41 @@ public class BytecodeGenMethod implements StatementVisitor{ } } + private void doAssign(String type) { + switch (type) { + case "java/lang/String": + break; + case "java/lang/Boolean": + break; + case "java/lang/Byte": + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", + "(B)Ljava/lang/Byte;", false); + break; + case "java/lang/Short": + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", + "(S)Ljava/lang/Short;", false); + break; + case "java/lang/Integer": + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", + "(I)Ljava/lang/Integer;", false); + break; + case "java/lang/Long": + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", + "(J)Ljava/lang/Long;", false); + break; + case "java/lang/Float": + break; + case "java/lang/Double": + break; + case "java/lang/Character": + break; + default: + break; + } + } + private void visitCharLiteral(Character value) { - mv.visitIntInsn(Opcodes.BIPUSH, Character.getNumericValue(value.charValue())); + mv.visitIntInsn(Opcodes.BIPUSH, (int) value); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); } diff --git a/test/bytecode/AssignToLit.jav b/test/bytecode/AssignToLit.jav index 46ec2b91..873828ed 100644 --- a/test/bytecode/AssignToLit.jav +++ b/test/bytecode/AssignToLit.jav @@ -10,21 +10,21 @@ import java.lang.Character; class AssignToLit { void m(){ - String s = "Test"; - Boolean b = false; - Byte byte1 = 5; - Byte byte2 = 55; - Short short1 = 5; - Short short2 = 55; - Integer int1 = 5; - Integer int2 = 8888888; - Long long1 = 1; - Long long2 = 5; - Long long3 = 89989898; - Float float1 = 1; - Float float2 = 55; - Double d1 = 1; - Double d2 = 55; +// String s = "Test"; +// Boolean b = false; +// Byte byte1 = 5; +// Byte byte2 = 55; +// Short short1 = 5; +// Short short2 = 55; +// Integer int1 = 5; +// Integer int2 = 8888888; +// Long long1 = 1; +// Long long2 = 5; +// Long long3 = 89989898; +// Float float1 = 1; +// Float float2 = 55; +// Double d1 = 1; +// Double d2 = 55; Character c = 'A'; } } \ No newline at end of file diff --git a/test/bytecode/For.jav b/test/bytecode/For.jav index 04cb6a53..c4bd6677 100644 --- a/test/bytecode/For.jav +++ b/test/bytecode/For.jav @@ -2,19 +2,19 @@ import java.lang.Integer; import java.lang.Boolean; class For{ - m(Integer x){ - - Boolean b = true; - c = 5; - c++; - ++c; - c--; - --c; - while(x<2){ - x = x +1; - b = false; - } - return x; + Integer m(Integer x){ + var c = x + 2; +// Boolean b = true; +// c = 5; +// c++; +// ++c; +// c--; +// --c; +// while(x<2){ +// x = x +1; +// b = false; +// } + return c; // for(int i = 0;i<10;i++) { // x = x + 5; // } diff --git a/test/bytecode/Op.jav b/test/bytecode/Op.jav new file mode 100644 index 00000000..9c05b0a2 --- /dev/null +++ b/test/bytecode/Op.jav @@ -0,0 +1,12 @@ +import java.lang.Integer; + +class Op { + m(Integer a, Integer b) { + Integer c = a+b; +// d = a-b; +// e = a*b; +// f = a/b; + + return c; + } +} \ No newline at end of file diff --git a/test/bytecode/OpTest.java b/test/bytecode/OpTest.java new file mode 100644 index 00000000..cd8fee06 --- /dev/null +++ b/test/bytecode/OpTest.java @@ -0,0 +1,7 @@ +package bytecode; + +public class OpTest extends JavaTXCompilerTest { + public OpTest() { + this.fileName = "Op"; + } +} diff --git a/test/parser/OpratorTest.jav b/test/parser/OpratorTest.jav index f99734f6..2764adf4 100644 --- a/test/parser/OpratorTest.jav +++ b/test/parser/OpratorTest.jav @@ -3,9 +3,9 @@ import java.lang.Integer; class OpratorTest { m(Integer a, Integer b) { c = a+b; - d = a-b; - e = a*b; - f = a/b; +// d = a-b; +// e = a*b; +// f = a/b; return c; }