Merge mit bytecode
This commit is contained in:
commit
fe35a1f56d
@ -40,6 +40,7 @@ public class ClassGenerator extends ClassGen{
|
||||
|
||||
private Map<String, ClassGenerator> extraClasses = new HashMap<>();
|
||||
private List<String> 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;
|
||||
@ -185,4 +183,12 @@ public class ClassGenerator extends ClassGen{
|
||||
super.addMethod(m);
|
||||
}
|
||||
|
||||
public void setMethodeGenerator(MethodGenerator methodGenerator) {
|
||||
this.methodGenerator = methodGenerator;
|
||||
}
|
||||
|
||||
public MethodGenerator getMethodGenerator() {
|
||||
return methodGenerator;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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<String, Integer> 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -416,7 +416,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
|
||||
ArrayList<String> argumentNames = new ArrayList<String>();
|
||||
|
||||
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<org.apache.commons.bcel6.generic.Type> argumentTypes, ArrayList<String> argumentNames, ClassGenerator cg, DHBWInstructionFactory _factory, TypeinferenceResultSet t) {
|
||||
private void generateArgumentList(ArrayList<org.apache.commons.bcel6.generic.Type> argumentTypes, ArrayList<String> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,6 @@ public class Assign extends Expr
|
||||
DHBWInstructionFactory _factory = new DHBWInstructionFactory(cg, cg.getConstantPool());
|
||||
InstructionList il = expr2.genByteCode(cg, rs);//expr2 rechte expr
|
||||
|
||||
|
||||
/*
|
||||
String expr2Type = expr2.getType().get_Name().toString();
|
||||
switch(expr2Type){
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
14
test/bytecode/VariableMultimethods.jav
Normal file
14
test/bytecode/VariableMultimethods.jav
Normal file
@ -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;
|
||||
}
|
||||
|
||||
}
|
98
test/bytecode/VariableMultimethodsTest.java
Normal file
98
test/bytecode/VariableMultimethodsTest.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user