diff --git a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java index 85509b57..bf5d7cd3 100644 --- a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java @@ -40,6 +40,7 @@ public class ClassGenerator extends ClassGen{ private Map extraClasses = new HashMap<>(); private List methodsNamesAndTypes = new LinkedList<>(); + private MethodGenerator methodGenerator; public ClassGenerator(String name, Type superClass, String string, short accessflags, String[] strings, TypeinferenceResults typeinferenceResults) { super(name,superClass.get_Name(),string,accessflags,strings, new DHBWConstantPoolGen()); @@ -171,11 +172,8 @@ public class ClassGenerator extends ClassGen{ @Override public void addMethod(Method m) { - String methodNameAndTypes = m.getReturnType().getSignature()+m.getName()+Arrays.toString(m.getArgumentTypes()); - //PL 1016-05-03 ersetzt: - //m.getName()+Arrays.toString(m.getArgumentTypes()); - //Hier sollten alle Maxima der Funktionstypen (arg-typ möglichst gross, - //return-Typ moeglichst klein) ermittelt werden (s. pppl 2008) + String methodNameAndTypes = m.getReturnType().toString()+m.getName()+Arrays.toString(m.getArgumentTypes()); + if(methodsNamesAndTypes.contains(methodNameAndTypes)){ return; @@ -184,5 +182,13 @@ public class ClassGenerator extends ClassGen{ methodsNamesAndTypes.add(methodNameAndTypes); super.addMethod(m); } - + + public void setMethodeGenerator(MethodGenerator methodGenerator) { + this.methodGenerator = methodGenerator; + } + + public MethodGenerator getMethodGenerator() { + return methodGenerator; + } + } diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index 8b4b9929..4fb3e8e9 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -139,23 +139,6 @@ public class DHBWInstructionFactory extends InstructionFactory{ return new INVOKEDYNAMIC(index); } - public static LocalVariableInstruction createLoad(org.apache.commons.bcel6.generic.Type bytecodeType, String variableName) { - 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 static Integer getStoreIndex(String variableName) { - if(storeIndexes.get(variableName) == null){ - Integer index = storeIndexes.size()+1; - storeIndexes.put(variableName, index); - } - - return storeIndexes.get(variableName); - } - public static Type createObjectType() { return new org.apache.commons.bcel6.generic.ObjectType("java.lang.Object"); } @@ -163,8 +146,4 @@ public class DHBWInstructionFactory extends InstructionFactory{ public Attribute createSignatureAttribute(String signature) { return new Signature(cp.addUtf8("Signature"),2,cp.addUtf8(signature),cp.getConstantPool()); } - - public void resetStoreIndexes() { - //storeIndexes.clear(); - } } diff --git a/src/de/dhbwstuttgart/bytecode/MethodGenerator.java b/src/de/dhbwstuttgart/bytecode/MethodGenerator.java index d374f3f6..88add712 100644 --- a/src/de/dhbwstuttgart/bytecode/MethodGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/MethodGenerator.java @@ -4,6 +4,9 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; import org.apache.commons.bcel6.classfile.Attribute; import org.apache.commons.bcel6.classfile.ConstantPool; @@ -16,7 +19,9 @@ import org.apache.commons.bcel6.classfile.Visitor; import org.apache.commons.bcel6.generic.BranchInstruction; import org.apache.commons.bcel6.generic.ConstantPoolGen; import org.apache.commons.bcel6.generic.Instruction; +import org.apache.commons.bcel6.generic.InstructionFactory; import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.LocalVariableInstruction; import org.apache.commons.bcel6.generic.MethodGen; import org.apache.commons.bcel6.generic.StackMapTableGen; import org.apache.commons.bcel6.generic.Type; @@ -30,15 +35,22 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Return; +import de.dhbwstuttgart.syntaxtree.statement.Statement; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; public class MethodGenerator extends MethodGen{ + private Map storeIndexes = new HashMap<>(); + public MethodGenerator(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name, - String class_name, InstructionList il, ConstantPoolGen cp) { + String class_name, InstructionList il, ConstantPoolGen cp) { super(access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp); + + for(String name: arg_names){ + getStoreIndex(name); + } } public Method createMethod(ClassGenerator cg, ParameterList parameter, de.dhbwstuttgart.syntaxtree.type.Type retType, Block block, TypeinferenceResultSet rs){ @@ -80,6 +92,23 @@ public class MethodGenerator extends MethodGen{ return method.getMethod(); } + public LocalVariableInstruction createLoad(org.apache.commons.bcel6.generic.Type bytecodeType, String variableName) { + 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; + storeIndexes.put(variableName, index); + } + + return storeIndexes.get(variableName); + } + } diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index c50f8416..717aa768 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -416,7 +416,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable ArrayList argumentNames = new ArrayList(); if(this.parameterlist != null && this.parameterlist.size() > 0){ - generateArgumentList(argumentTypes, argumentNames, cg, _factory, t); + generateArgumentList(argumentTypes, argumentNames, cg, t); } short constants = Constants.ACC_PUBLIC; @@ -426,15 +426,15 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable MethodGenerator method = new MethodGenerator(constants, returnType.getBytecodeType(cg, t), argumentTypes.toArray(new org.apache.commons.bcel6.generic.Type[parameterlist.size()]) , argumentNames.toArray(new String[parameterlist.size()]), this.get_Method_Name(), getParentClass().name, il, _cp); + cg.setMethodeGenerator(method); + cg.addMethod(method.createMethod(cg, getParameterList(), returnType, get_Block(), t)); } - private void generateArgumentList(ArrayList argumentTypes, ArrayList argumentNames, ClassGenerator cg, DHBWInstructionFactory _factory, TypeinferenceResultSet t) { + private void generateArgumentList(ArrayList argumentTypes, ArrayList argumentNames, ClassGenerator cg, TypeinferenceResultSet t) { for(FormalParameter parameter : this.parameterlist){ argumentTypes.add(parameter.getType().getBytecodeType(cg, t)); argumentNames.add(parameter.getIdentifier()); - - _factory.getStoreIndex(parameter.getIdentifier()); } } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java index 8b0997f9..810361ca 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java @@ -179,8 +179,7 @@ public class Assign extends Expr @Override public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) { DHBWInstructionFactory _factory = new DHBWInstructionFactory(cg, cg.getConstantPool()); - InstructionList il = expr2.genByteCode(cg, rs);//expr2 rechte expr - + InstructionList il = expr2.genByteCode(cg, rs);//expr2 rechte expr /* String expr2Type = expr2.getType().get_Name().toString(); @@ -207,7 +206,7 @@ public class Assign extends Expr } */ //Es wird momentan immer von RefType ausgegangen: - il.append(_factory.createStore(expr2.getType().getBytecodeType(cg, rs), expr1.get_Name())); + il.append(cg.getMethodGenerator().createStore(expr2.getType().getBytecodeType(cg, rs), expr1.get_Name())); return il; } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java b/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java index 2c632bb9..51984e6d 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java @@ -169,7 +169,7 @@ public class LocalOrFieldVarOrClassname extends Expr String name = this.get_Name(); - il.append(cg.getInstructionFactory().createLoad(byteCodeType, name)); + il.append(cg.getMethodGenerator().createLoad(byteCodeType, name)); return il; } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java index bfed3c5e..7ce4c55b 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LocalVarDecl.java @@ -376,7 +376,7 @@ public class LocalVarDecl extends Statement implements TypeInsertable @Override public InstructionList genByteCode(ClassGenerator _cg, TypeinferenceResultSet rs) { - _cg.getInstructionFactory().getStoreIndex(get_Name()); + _cg.getMethodGenerator().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 affe569d..7921b129 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -326,8 +326,6 @@ 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)); @@ -346,7 +344,7 @@ public class MethodCall extends Expr argumentTypen = new org.apache.commons.bcel6.generic.Type[this.getArgumentList().size()]; int i = 0; for(Expr argument : this.arglist.expr){ - _factory.getStoreIndex(argument.get_Name()); + cg.getMethodGenerator().getStoreIndex(argument.get_Name()); argumentTypen[i] = argument.getType().getBytecodeType(cg, rs); //Das Argument auf den Stack legen: diff --git a/test/bytecode/VariableMultimethods.jav b/test/bytecode/VariableMultimethods.jav new file mode 100644 index 00000000..ad5520f4 --- /dev/null +++ b/test/bytecode/VariableMultimethods.jav @@ -0,0 +1,14 @@ +class VariableMultimethods{ + public Integer method(Integer z, Integer x, Integer y){ + return x+y+z; + } + + public Integer method(Integer x, Integer y){ + return x+y; + } + + public Integer method(Integer y){ + return y; + } + +} \ No newline at end of file diff --git a/test/bytecode/VariableMultimethodsTest.java b/test/bytecode/VariableMultimethodsTest.java new file mode 100644 index 00000000..2990e25b --- /dev/null +++ b/test/bytecode/VariableMultimethodsTest.java @@ -0,0 +1,98 @@ +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 VariableMultimethodsTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "VariableMultimethods"; + 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); + } + + @Test + public void testOneArgument() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + + Integer y = 1; + + Class[] params = new Class[]{ + y.getClass() + }; + + Method method = cls.getDeclaredMethod("method", params); + Integer returnValue = (Integer) method.invoke(obj, y); + assertEquals(new Integer(1), returnValue); + } + + @Test + public void testTwoArgument() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + + Integer x = 1; + Integer y = 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); + } + + @Test + public void testThreeArgument() throws Exception{ + ClassLoader classLoader = getClassLoader(); + + Class cls = classLoader.loadClass(testName); + + Object obj = cls.newInstance(); + + Integer z = 1; + Integer x = 2; + Integer y = 4; + + Class[] params = new Class[]{ + z.getClass(), + x.getClass(), + y.getClass() + }; + + Method method = cls.getDeclaredMethod("method", params); + Integer returnValue = (Integer) method.invoke(obj, z, x, y); + assertEquals(new Integer(7), returnValue); + } +}