From 11e149110a02e35c4697db85edf985956c626ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Tue, 12 Apr 2016 20:06:22 +0200 Subject: [PATCH 1/7] - OLTest verbessert, ist aber nicht positiv, da Autoboxing fehlt --- .../bytecode/DHBWInstructionFactory.java | 6 +++--- .../syntaxtree/statement/LocalVarDecl.java | 2 +- .../syntaxtree/statement/MethodCall.java | 1 + test/bytecode/types/OL.jav | 2 +- test/bytecode/types/OLTest.java | 12 ++++++------ test/bytecode/types/Overloading.jav | 8 ++++++-- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index 853ddae1..c9a60d89 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -140,12 +140,12 @@ public class DHBWInstructionFactory extends InstructionFactory{ } public LocalVariableInstruction createLoad(org.apache.commons.bcel6.generic.Type bytecodeType, String variableName) { - return InstructionFactory.createLoad(bytecodeType, storeIndexes.get(variableName)); + return InstructionFactory.createLoad(bytecodeType, getStoreIndex(variableName)); } public Integer getStoreIndex(String variableName) { if(!storeIndexes.containsKey(variableName)){ - storeIndexes.put(variableName, storeIndexes.size()+1); + storeIndexes.put(variableName, storeIndexes.size()); } return storeIndexes.get(variableName); @@ -160,6 +160,6 @@ public class DHBWInstructionFactory extends InstructionFactory{ } public void resetStoreIndexes() { - storeIndexes = new HashMap<>(); + storeIndexes.clear(); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java index a5a319b0..ee4f4579 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java @@ -431,7 +431,7 @@ public class LocalVarDecl extends Statement implements TypeInsertable @Override public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) { - // TODO Auto-generated method stub + _cg.getInstructionFactory().getStoreIndex(get_Name()); return new InstructionList(); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index 7b7b82bb..affe569d 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -326,6 +326,7 @@ public class MethodCall extends Expr public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) { InstructionList il = new InstructionList(); DHBWInstructionFactory _factory = cg.getInstructionFactory(); + //TODO: später wiederherstelln? _factory.resetStoreIndexes(); il.append(receiver.get_Expr().genByteCode(cg, rs)); diff --git a/test/bytecode/types/OL.jav b/test/bytecode/types/OL.jav index 66e95aeb..f98887b2 100644 --- a/test/bytecode/types/OL.jav +++ b/test/bytecode/types/OL.jav @@ -7,7 +7,7 @@ class OL { class Main { - main(x) { + main(x) { ol; ol = new OL(); return ol.m(x); diff --git a/test/bytecode/types/OLTest.java b/test/bytecode/types/OLTest.java index 4b369283..a425b77b 100644 --- a/test/bytecode/types/OLTest.java +++ b/test/bytecode/types/OLTest.java @@ -33,13 +33,13 @@ public class OLTest extends SourceFileBytecodeTest{ URL url = file.toURL(); URL[] urls = new URL[]{url}; - Class stringVector = classLoader.loadClass("Integer"); + Integer integer = new Integer(1); Class[] params = new Class[1]; - params[0] = stringVector; + params[0] = integer.getClass(); Method method = cls.getDeclaredMethod("m", params); - method.invoke(obj, stringVector.newInstance()); + method.invoke(obj, integer); assertTrue(true); }catch(Exception e){ throw new RuntimeException(e); @@ -59,13 +59,13 @@ public class OLTest extends SourceFileBytecodeTest{ URL url = file.toURL(); URL[] urls = new URL[]{url}; - Class stringVector = classLoader.loadClass("Boolean"); + Boolean bool = new Boolean(true); Class[] params = new Class[1]; - params[0] = stringVector; + params[0] = bool.getClass(); Method method = cls.getDeclaredMethod("m", params); - method.invoke(obj, stringVector.newInstance()); + method.invoke(obj, bool); assertTrue(true); }catch(Exception e){ throw new RuntimeException(e); diff --git a/test/bytecode/types/Overloading.jav b/test/bytecode/types/Overloading.jav index 0c0fdb2b..66a2ad81 100644 --- a/test/bytecode/types/Overloading.jav +++ b/test/bytecode/types/Overloading.jav @@ -10,8 +10,12 @@ class Overloading{ } - main(String[] args) { - new Overloading().method(new Vector ()); + main(String[] args) { + ol; + ol = new Overloading(); + v; + v = new Vector (); + ol.method(v); } } \ No newline at end of file From dfe79a8030d18d2502bef99b9c49b0eeaae6300c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Wed, 13 Apr 2016 19:31:35 +0200 Subject: [PATCH 2/7] Equal Operator implementiert --- .../bytecode/DHBWInstructionFactory.java | 2 +- .../syntaxtree/operator/EqualOp.java | 49 ++++++++++++++++++- .../syntaxtree/operator/Operator.java | 8 ++- .../syntaxtree/statement/Binary.java | 22 +-------- test/bytecode/operators/AddOperator.jav | 9 ++++ test/bytecode/operators/AddOperatorTest.java | 32 ++++++++++++ test/bytecode/operators/EqualOperator.jav | 5 ++ .../bytecode/operators/EqualOperatorTest.java | 32 ++++++++++++ 8 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 test/bytecode/operators/AddOperator.jav create mode 100644 test/bytecode/operators/AddOperatorTest.java create mode 100644 test/bytecode/operators/EqualOperator.jav create mode 100644 test/bytecode/operators/EqualOperatorTest.java diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index c9a60d89..5cb13991 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -145,7 +145,7 @@ public class DHBWInstructionFactory extends InstructionFactory{ public Integer getStoreIndex(String variableName) { if(!storeIndexes.containsKey(variableName)){ - storeIndexes.put(variableName, storeIndexes.size()); + storeIndexes.put(variableName, storeIndexes.size()+1); } return storeIndexes.get(variableName); diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java index 184a8501..89285c6b 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/EqualOp.java @@ -3,16 +3,30 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.end // ino.module.EqualOp.8597.import import java.util.Iterator; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.GOTO; +import org.apache.commons.bcel6.generic.IF_ICMPNE; +import org.apache.commons.bcel6.generic.InstructionConstants; +import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.NOP; +import org.apache.commons.bcel6.generic.ObjectType; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.myexception.JVMCodeException; +import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; import de.dhbwstuttgart.syntaxtree.statement.Null; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.typeinference.Pair; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; +import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.unify.Unify; @@ -31,6 +45,39 @@ public class EqualOp extends RelOp super(offset, variableLength); } // ino.end + + @Override + public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { + DHBWInstructionFactory _factory = _cg.getInstructionFactory(); + + InstructionList linkeSeite = operator.expr1.genByteCode(_cg, rs); + linkeSeite.append(_factory.createInvoke("java.lang.Integer", "intValue", org.apache.commons.bcel6.generic.Type.INT, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); + + InstructionList rechteSeite = operator.expr2.genByteCode(_cg, rs); + rechteSeite.append(_factory.createInvoke("java.lang.Integer", "intValue", org.apache.commons.bcel6.generic.Type.INT, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); + + + if(operator.getReturnType().getName().equals(new JavaClassName("String"))){ + throw new TypeinferenceException("Zeichenketten zusammenfügen ist noch nicht unterstützt",this); + } + + linkeSeite.append(rechteSeite); + + //TODO: bytecode (Bis jetzt wird jeder Condition als EQUALS behandelt) + //TODO: bytecode autoboxing + + BranchInstruction if_icmpneInstruction = new IF_ICMPNE(null); + linkeSeite.append(if_icmpneInstruction); + linkeSeite.append(InstructionConstants.ICONST_1); + + BranchInstruction gotoInstruction = new GOTO(null); + + linkeSeite.append(gotoInstruction); + if_icmpneInstruction.setTarget(linkeSeite.append(InstructionConstants.ICONST_0)); + gotoInstruction.setTarget(linkeSeite.append(_factory.createInvoke("java.lang.Boolean", "valueOf", new ObjectType("java.lang.Boolean"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.BOOLEAN}, Constants.INVOKESTATIC))); + + return linkeSeite; + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java b/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java index 8639bb8f..4a2573ba 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/Operator.java @@ -5,8 +5,11 @@ package de.dhbwstuttgart.syntaxtree.operator; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.InstructionList; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.myexception.JVMCodeException; @@ -20,6 +23,7 @@ import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.OderConstraint; import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.SingleConstraint; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.UndConstraint; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; @@ -85,6 +89,8 @@ public abstract class Operator extends SyntaxTreeNode * @return */ public abstract HashMap getReturnTypes(TypeAssumptions ass); + + public abstract InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator); @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java b/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java index 035d4c0a..f0fd2d9d 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Binary.java @@ -229,27 +229,7 @@ public JavaCodeResult printJavaCode(ResultSet resultSet) { @Override public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) { - InstructionList linkeSeite = this.expr1.genByteCode(_cg, rs); - InstructionList rechteSeite = this.expr2.genByteCode(_cg, rs); - if(this.getReturnType().getName().equals(new JavaClassName("String"))){ - throw new TypeinferenceException("Zeichenketten zusammenfügen ist noch nicht unterstützt",this); - } - - linkeSeite.append(rechteSeite); - - //TODO: bytecode (Bis jetzt wird jeder Condition als EQUALS behandelt) - //TODO: bytecode autoboxing - - BranchInstruction if_icmpneInstruction = new IF_ICMPNE(null); - linkeSeite.append(if_icmpneInstruction); - linkeSeite.append(InstructionConstants.ICONST_1); - - BranchInstruction gotoInstruction = new GOTO(null); - - linkeSeite.append(gotoInstruction); - if_icmpneInstruction.setTarget(linkeSeite.append(InstructionConstants.ICONST_0)); - gotoInstruction.setTarget(linkeSeite.append(new NOP())); - return linkeSeite; + return op.genByteCode(_cg, rs, this); } } diff --git a/test/bytecode/operators/AddOperator.jav b/test/bytecode/operators/AddOperator.jav new file mode 100644 index 00000000..d7c79a23 --- /dev/null +++ b/test/bytecode/operators/AddOperator.jav @@ -0,0 +1,9 @@ +class AddOperator{ + Integer method(Integer x){ + return x + x; + } + + Double method(Double x){ + return x + x; + } +} \ No newline at end of file diff --git a/test/bytecode/operators/AddOperatorTest.java b/test/bytecode/operators/AddOperatorTest.java new file mode 100644 index 00000000..53fcc6be --- /dev/null +++ b/test/bytecode/operators/AddOperatorTest.java @@ -0,0 +1,32 @@ +package bytecode.operators; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.junit.Ignore; +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + +public class AddOperatorTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "AddOperator"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/operators/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } +} diff --git a/test/bytecode/operators/EqualOperator.jav b/test/bytecode/operators/EqualOperator.jav new file mode 100644 index 00000000..a51b512a --- /dev/null +++ b/test/bytecode/operators/EqualOperator.jav @@ -0,0 +1,5 @@ +class EqualOperator{ + Boolean method(Integer x, Integer y){ + return x == y; + } +} \ No newline at end of file diff --git a/test/bytecode/operators/EqualOperatorTest.java b/test/bytecode/operators/EqualOperatorTest.java new file mode 100644 index 00000000..b605799f --- /dev/null +++ b/test/bytecode/operators/EqualOperatorTest.java @@ -0,0 +1,32 @@ +package bytecode.operators; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.junit.Ignore; +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + +public class EqualOperatorTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "EqualOperator"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/operators/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } +} From 9a072014988dbb3c436d41df931b26795c168ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Thu, 14 Apr 2016 12:00:15 +0200 Subject: [PATCH 3/7] And, Or, Plus Operator implementiert --- .../syntaxtree/operator/AndOp.java | 11 ++++ .../syntaxtree/operator/OrOp.java | 54 +++++++++++++++ .../syntaxtree/operator/PlusOp.java | 65 +++++++++++++++++++ test/bytecode/operators/AddOperator.jav | 8 +-- test/bytecode/operators/OROperatorTest.java | 32 +++++++++ test/bytecode/operators/OrOperator.jav | 5 ++ 6 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 test/bytecode/operators/OROperatorTest.java create mode 100644 test/bytecode/operators/OrOperator.jav diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/AndOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/AndOp.java index fdb01d2c..41e960e2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/AndOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/AndOp.java @@ -3,11 +3,16 @@ package de.dhbwstuttgart.syntaxtree.operator; import de.dhbwstuttgart.typeinference.Menge; +import org.apache.commons.bcel6.generic.InstructionList; + +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; +import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.SingleConstraint; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; // ino.class.AndOp.24101.declaration @@ -25,6 +30,12 @@ public class AndOp extends LogOp } // ino.end + @Override + public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { + // TODO Auto-generated method stub + return null; + } + } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/OrOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/OrOp.java index 41bbdac9..3bf1c44f 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/OrOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/OrOp.java @@ -2,6 +2,19 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.end +import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.GOTO; +import org.apache.commons.bcel6.generic.IFEQ; +import org.apache.commons.bcel6.generic.IFNE; +import org.apache.commons.bcel6.generic.InstructionConstants; +import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.ObjectType; + +import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; +import de.dhbwstuttgart.syntaxtree.statement.Binary; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; // ino.class.OrOp.24282.declaration public class OrOp extends LogOp @@ -17,6 +30,47 @@ public class OrOp extends LogOp super(offset,variableLength); } // ino.end + + @Override + public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { + /* + 0: aload_1 + 1: invokevirtual #2 // Method java/lang/Boolean.booleanValue:()Z + 4: ifne 14 + 7: aload_2 + 8: invokevirtual #2 // Method java/lang/Boolean.booleanValue:()Z + 11: ifeq 18 + 14: iconst_1 + 15: goto 19 + 18: iconst_0 + 19: invokestatic #3 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean; + 22: areturn + */ + DHBWInstructionFactory _factory = _cg.getInstructionFactory(); + + InstructionList il = operator.get_Expr1().genByteCode(_cg, rs); + il.append(_factory.createInvoke("java.lang.Boolean", "booleanValue", org.apache.commons.bcel6.generic.Type.BOOLEAN, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); + + BranchInstruction firstTest = new IFNE(null); + il.append(firstTest); + + il.append(operator.get_Expr2().genByteCode(_cg, rs)); + il.append(_factory.createInvoke("java.lang.Boolean", "booleanValue", org.apache.commons.bcel6.generic.Type.BOOLEAN, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); + + BranchInstruction secondTest = new IFEQ(null); + il.append(secondTest); + + firstTest.setTarget(il.append(InstructionConstants.ICONST_1)); + + BranchInstruction gotoInstruction = new GOTO(null); + il.append(gotoInstruction); + + secondTest.setTarget(il.append(InstructionConstants.ICONST_0)); + + gotoInstruction.setTarget(il.append(_factory.createInvoke("java.lang.Boolean", "valueOf", new ObjectType("java.lang.Boolean"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.BOOLEAN}, Constants.INVOKESTATIC))); + + return il; + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java b/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java index e7d82823..2c2c44aa 100755 --- a/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java +++ b/src/de/dhbwstuttgart/syntaxtree/operator/PlusOp.java @@ -3,10 +3,27 @@ package de.dhbwstuttgart.syntaxtree.operator; // ino.end // ino.module.PlusOp.8609.import import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; +import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.generic.ArithmeticInstruction; +import org.apache.commons.bcel6.generic.BranchInstruction; +import org.apache.commons.bcel6.generic.GOTO; +import org.apache.commons.bcel6.generic.IADD; +import org.apache.commons.bcel6.generic.IFEQ; +import org.apache.commons.bcel6.generic.IFNE; +import org.apache.commons.bcel6.generic.InstructionConstants; +import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.InvokeInstruction; +import org.apache.commons.bcel6.generic.ObjectType; + +import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.statement.Binary; import de.dhbwstuttgart.syntaxtree.statement.Expr; +import de.dhbwstuttgart.syntaxtree.type.Type; @@ -25,5 +42,53 @@ public class PlusOp extends AddOp } // ino.end + @Override + public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs, Binary operator) { + // TODO Plus Operator ist bis jetzt nur für Integer implementiert + /* + 0: aload_1 + 1: invokevirtual #2 // Method java/lang/Integer.intValue:()I + 4: aload_1 + 5: invokevirtual #2 // Method java/lang/Integer.intValue:()I + 8: iadd + 9: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; + 12: areturn + */ + DHBWInstructionFactory _factory = _cg.getInstructionFactory(); + + String returnType = getReturnType(operator.get_Expr1(), operator.get_Expr2()); + + InstructionList il = getInstructionListForOperand(_cg, rs, operator.get_Expr1(), returnType); + + il.append(getInstructionListForOperand(_cg, rs, operator.get_Expr2(), returnType)); + + il.append(getOperator(returnType)); + + il.append(convertValueToObject(_factory, returnType)); + return il; + } + + private String getReturnType(Expr expr1, Expr expr2) { + return "java.lang.Integer"; + } + + private ArithmeticInstruction getOperator(String returnType) { + return new IADD(); + } + private InvokeInstruction convertValueToObject(DHBWInstructionFactory _factory, String returnType) { + if(returnType.equals("java.lang.Integer")){ + return _factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.commons.bcel6.generic.Type[] {org.apache.commons.bcel6.generic.Type.INT}, Constants.INVOKESTATIC); + }else{ + throw new NotImplementedException(); + } + } + + private InstructionList getInstructionListForOperand(ClassGenerator _cg, TypeinferenceResultSet rs, Expr operand, String returnType){ + InstructionList il = new InstructionList(); + il.append(operand.genByteCode(_cg, rs)); + il.append(_cg.getInstructionFactory().createInvoke("java.lang.Integer", "intValue", org.apache.commons.bcel6.generic.Type.INT, new org.apache.commons.bcel6.generic.Type[] {}, Constants.INVOKEVIRTUAL)); + return il; + } + } // ino.end diff --git a/test/bytecode/operators/AddOperator.jav b/test/bytecode/operators/AddOperator.jav index d7c79a23..ec305c05 100644 --- a/test/bytecode/operators/AddOperator.jav +++ b/test/bytecode/operators/AddOperator.jav @@ -1,9 +1,5 @@ class AddOperator{ - Integer method(Integer x){ - return x + x; - } - - Double method(Double x){ - return x + x; + Integer method(Integer x, Integer y){ + return x + y; } } \ No newline at end of file diff --git a/test/bytecode/operators/OROperatorTest.java b/test/bytecode/operators/OROperatorTest.java new file mode 100644 index 00000000..7c648e88 --- /dev/null +++ b/test/bytecode/operators/OROperatorTest.java @@ -0,0 +1,32 @@ +package bytecode.operators; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.junit.Ignore; +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + +public class OROperatorTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "OrOperator"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/operators/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } +} diff --git a/test/bytecode/operators/OrOperator.jav b/test/bytecode/operators/OrOperator.jav new file mode 100644 index 00000000..c10a96e2 --- /dev/null +++ b/test/bytecode/operators/OrOperator.jav @@ -0,0 +1,5 @@ +class OrOperator{ + Boolean method(Boolean x, Boolean y){ + return x || y; + } +} \ No newline at end of file From a23f77c33715cc438dc01229fd0cd7601c3f2bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Thu, 14 Apr 2016 14:36:18 +0200 Subject: [PATCH 4/7] =?UTF-8?q?-Test=20f=C3=BCr=20Variablen=20erstellt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytecode/DHBWInstructionFactory.java | 7 ++-- src/de/dhbwstuttgart/syntaxtree/Method.java | 5 +++ test/bytecode/Variable.jav | 8 +++++ test/bytecode/VariableTest.java | 35 +++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 test/bytecode/Variable.jav create mode 100644 test/bytecode/VariableTest.java diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index 5cb13991..bc5a3806 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -144,8 +144,9 @@ public class DHBWInstructionFactory extends InstructionFactory{ } public Integer getStoreIndex(String variableName) { - if(!storeIndexes.containsKey(variableName)){ - storeIndexes.put(variableName, storeIndexes.size()+1); + if(storeIndexes.get(variableName) == null){ + Integer index = storeIndexes.size()+1; + storeIndexes.put(variableName, index); } return storeIndexes.get(variableName); @@ -160,6 +161,6 @@ public class DHBWInstructionFactory extends InstructionFactory{ } public void resetStoreIndexes() { - storeIndexes.clear(); + //storeIndexes.clear(); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index ebed1381..9a59788a 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -610,6 +610,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable public void genByteCode(ClassGenerator cg, Class classObj) { List typeInterferenceResults = cg.getTypeinferenceResults().getTypeReconstructions(this, cg); + DHBWInstructionFactory _factory = cg.getInstructionFactory(); for(TypeinferenceResultSet t: typeInterferenceResults){ DHBWConstantPoolGen _cp = cg.getConstantPool(); @@ -626,6 +627,10 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable for(FormalParameter parameter : this.parameterlist){ argumentTypes[i] = parameter.getType().getBytecodeType(cg, t); argumentNames[i] = parameter.getIdentifier(); + + + _factory.getStoreIndex(parameter.getIdentifier()); + i++; } } diff --git a/test/bytecode/Variable.jav b/test/bytecode/Variable.jav new file mode 100644 index 00000000..ef9de331 --- /dev/null +++ b/test/bytecode/Variable.jav @@ -0,0 +1,8 @@ +class Variable{ + public Integer method(Integer parameter){ + Integer lokaleVariable; + lokaleVariable = 2; + + return parameter+lokaleVariable; + } +} \ No newline at end of file diff --git a/test/bytecode/VariableTest.java b/test/bytecode/VariableTest.java new file mode 100644 index 00000000..de387566 --- /dev/null +++ b/test/bytecode/VariableTest.java @@ -0,0 +1,35 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Vector; + +import org.junit.Test; + +import org.junit.Ignore; + +import bytecode.SourceFileBytecodeTest; + + +public class VariableTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "Variable"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } +} From 65a1038574595089cdd0279ba178f41165e08496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Thu, 14 Apr 2016 14:53:18 +0200 Subject: [PATCH 5/7] - Speichern einer lokalen Variable unter Verwenung der InstructionFactory --- src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java | 4 ++++ src/de/dhbwstuttgart/syntaxtree/statement/Assign.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index bc5a3806..6cf24c88 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -143,6 +143,10 @@ public class DHBWInstructionFactory extends InstructionFactory{ return InstructionFactory.createLoad(bytecodeType, getStoreIndex(variableName)); } + public LocalVariableInstruction createStore(org.apache.commons.bcel6.generic.Type bytecodeType, String variableName) { + return InstructionFactory.createStore(bytecodeType, getStoreIndex(variableName)); + } + public Integer getStoreIndex(String variableName) { if(storeIndexes.get(variableName) == null){ Integer index = storeIndexes.size()+1; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java index 9e863d01..9dfb6560 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java @@ -208,7 +208,7 @@ public class Assign extends Expr } */ //Es wird momentan immer von RefType ausgegangen: - il.append(new ASTORE(_factory.getStoreIndex(expr1.get_Name()))); + il.append(_factory.createStore(expr2.getType().getBytecodeType(cg, rs), expr1.get_Name())); return il; } From 5a7c2310a1a6c9e1438f41130b1aa0f1c73f733a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Tue, 19 Apr 2016 14:40:29 +0200 Subject: [PATCH 6/7] =?UTF-8?q?-Test=20f=C3=BCr=20Methodenaufrufe=20und=20?= =?UTF-8?q?Variablen=20erstellt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/bytecode/ASTBytecodeTest.java | 8 ------- test/bytecode/MethodAndVariable.jav | 18 ++++++++++++++++ test/bytecode/MethodsAndVariableTest.java | 26 +++++++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 test/bytecode/MethodAndVariable.jav create mode 100644 test/bytecode/MethodsAndVariableTest.java diff --git a/test/bytecode/ASTBytecodeTest.java b/test/bytecode/ASTBytecodeTest.java index 32fd8088..d2b4af70 100644 --- a/test/bytecode/ASTBytecodeTest.java +++ b/test/bytecode/ASTBytecodeTest.java @@ -56,10 +56,7 @@ public abstract class ASTBytecodeTest { String rootDirectory = getRootDirectory(); - System.out.println(rootDirectory); - JavaClass javaClass = result.getByteCode().getJavaClass(); - System.out.println(javaClass.toString()); javaClass.dump(new File(rootDirectory+javaClass.getClassName()+".class")); for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){ @@ -68,7 +65,6 @@ public abstract class ASTBytecodeTest { } }catch(Exception e){ - System.out.print(e.getMessage()); throw new RuntimeException(e); } } @@ -91,8 +87,4 @@ public abstract class ASTBytecodeTest { public String getTestName() { return "No Testname defined!"; } - - - - } diff --git a/test/bytecode/MethodAndVariable.jav b/test/bytecode/MethodAndVariable.jav new file mode 100644 index 00000000..2ae7002e --- /dev/null +++ b/test/bytecode/MethodAndVariable.jav @@ -0,0 +1,18 @@ +class MethodAndVariable{ + public Integer method(Integer parameter){ + Integer lokaleVariable; + lokaleVariable = 2; + + Integer lokaleVariable2; + lokaleVariable2 = method2(lokaleVariable); + + return parameter+lokaleVariable2; + } + + public Integer method2(Integer parameter){ + Integer lokaleVariable; + lokaleVariable = 2; + + return parameter+lokaleVariable; + } +} \ No newline at end of file diff --git a/test/bytecode/MethodsAndVariableTest.java b/test/bytecode/MethodsAndVariableTest.java new file mode 100644 index 00000000..8e0fd808 --- /dev/null +++ b/test/bytecode/MethodsAndVariableTest.java @@ -0,0 +1,26 @@ +package bytecode; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + + +public class MethodsAndVariableTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "MethodAndVariable"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; + } + + @Test + public void testConstruct() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + assertTrue(true); + } +} From 8bad95f7744ba10c1590b1f3d6ad40fbb38439b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Tue, 19 Apr 2016 15:24:43 +0200 Subject: [PATCH 7/7] -AndOperator erweitert --- test/bytecode/operators/AddOperatorTest.java | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/bytecode/operators/AddOperatorTest.java b/test/bytecode/operators/AddOperatorTest.java index 53fcc6be..edd2c3e2 100644 --- a/test/bytecode/operators/AddOperatorTest.java +++ b/test/bytecode/operators/AddOperatorTest.java @@ -29,4 +29,25 @@ public class AddOperatorTest extends SourceFileBytecodeTest{ Object obj = cls.newInstance(); assertTrue(true); } + + @Test + public void testTwoIntegers() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + + Integer x = new Integer(1); + Integer y = new Integer(2); + + Class[] params = new Class[]{ + x.getClass(), + y.getClass(), + }; + + Method method = cls.getDeclaredMethod("method", params); + Integer returnValue = (Integer) method.invoke(obj, x, y); + assertEquals(new Integer(3), returnValue); + } }