diff --git a/BCEL/bcelifier/JavaToBCEL.java b/BCEL/bcelifier/JavaToBCEL.java index ef1555d1..f4281a3c 100644 --- a/BCEL/bcelifier/JavaToBCEL.java +++ b/BCEL/bcelifier/JavaToBCEL.java @@ -30,6 +30,7 @@ public class JavaToBCEL { new BCELifier(new ClassParser(rootDirectory+"FieldDeclaration.class").parse(), new FileOutputStream(new File(rootDirectory+"FieldDeclarationCreator.java"))).start(); new BCELifier(new ClassParser(rootDirectory+"Null.class").parse(), new FileOutputStream(new File(rootDirectory+"NullCreator.java"))).start(); new BCELifier(new ClassParser(rootDirectory+"LocalVarAccess.class").parse(), new FileOutputStream(new File(rootDirectory+"LocalVarAccessCreator.java"))).start(); + new BCELifier(new ClassParser(rootDirectory+"Wildcard.class").parse(), new FileOutputStream(new File(rootDirectory+"WildcardCreator.java"))).start(); } catch (ClassFormatException | IOException e) { e.printStackTrace(); diff --git a/BCEL/bcelifier/Wildcard.java b/BCEL/bcelifier/Wildcard.java new file mode 100644 index 00000000..b65144ac --- /dev/null +++ b/BCEL/bcelifier/Wildcard.java @@ -0,0 +1,5 @@ +package bcelifier; + +public class Wildcard { + Wildcard a; +} diff --git a/BCEL/bcelifier/WildcardCreator.java b/BCEL/bcelifier/WildcardCreator.java new file mode 100644 index 00000000..6f83ff50 --- /dev/null +++ b/BCEL/bcelifier/WildcardCreator.java @@ -0,0 +1,50 @@ +package bcelifier; + +import org.apache.commons.bcel6.generic.*; +import org.apache.commons.bcel6.classfile.*; +import org.apache.commons.bcel6.*; +import java.io.*; + +public class WildcardCreator implements Constants { + private InstructionFactory _factory; + private ConstantPoolGen _cp; + private ClassGen _cg; + + public WildcardCreator() { + _cg = new ClassGen("bcelifier.Wildcard", "java.lang.Object", "Wildcard.java", ACC_PUBLIC | ACC_SUPER, new String[] { }); + + _cp = _cg.getConstantPool(); + _factory = new InstructionFactory(_cg, _cp); + } + + public void create(OutputStream out) throws IOException { + createFields(); + createMethod_0(); + _cg.getJavaClass().dump(out); + } + + private void createFields() { + FieldGen field; + + field = new FieldGen(0, new ObjectType("bcelifier.Wildcard"), "a", _cp); + _cg.addField(field.getField()); + } + + private void createMethod_0() { + InstructionList il = new InstructionList(); + MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] { }, "", "bcelifier.Wildcard", il, _cp); + + InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0)); + il.append(_factory.createInvoke("java.lang.Object", "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID)); + method.setMaxStack(); + method.setMaxLocals(); + _cg.addMethod(method.getMethod()); + il.dispose(); + } + + public static void main(String[] args) throws Exception { + bcelifier.WildcardCreator creator = new bcelifier.WildcardCreator(); + creator.create(new FileOutputStream("bcelifier.Wildcard.class")); + } +} diff --git a/lib/bcel-5.2-src.zip b/lib/bcel-5.2-src.zip new file mode 100644 index 00000000..09742615 Binary files /dev/null and b/lib/bcel-5.2-src.zip differ diff --git a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java index 800a7703..d5fe5220 100644 --- a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java @@ -1,5 +1,8 @@ package de.dhbwstuttgart.bytecode; +import org.apache.commons.bcel6.classfile.BootstrapMethod; +import org.apache.commons.bcel6.classfile.BootstrapMethods; +import org.apache.commons.bcel6.classfile.ConstantPool; import org.apache.commons.bcel6.classfile.InnerClass; import org.apache.commons.bcel6.classfile.InnerClasses; import org.apache.commons.bcel6.generic.ClassGen; @@ -25,6 +28,8 @@ public class ClassGenerator extends ClassGen{ cp = (DHBWConstantPoolGen) super.getConstantPool(); factory = new DHBWInstructionFactory(this, cp); + this.setMajor(52); //Java 8 Version 52.0 + this.setMinor(0); } public DHBWInstructionFactory getInstructionFactory() { @@ -55,9 +60,21 @@ public class ClassGenerator extends ClassGen{ */ public void addInnerClass(InnerClass innerClassAttribute) { //TODO: Muss vor dem ausführen von getJavaClass ausgeführt werden. getJavaClass überschreiben! - InnerClass[] innerClasses = new InnerClass[1]; - innerClasses[0] = innerClassAttribute; - int innerClassesUTF8 = this.getConstantPool().addUtf8("InnerClassses"); - this.addAttribute(new InnerClasses(innerClassesUTF8,1,innerClasses,this.getConstantPool().getConstantPool())); + int numberOfInnerClasses = 1; + InnerClass[] innerClasses = new InnerClass[numberOfInnerClasses]; + innerClasses[numberOfInnerClasses-1] = innerClassAttribute; + int innerClassesUTF8 = this.getConstantPool().addUtf8("InnerClasses"); + this.addAttribute(new InnerClasses(innerClassesUTF8,numberOfInnerClasses*8+2,innerClasses,this.getConstantPool().getConstantPool())); + } + + public int addBootstrapMethod(BootstrapMethod bMethod) { + int numberOfBootstrapMethods = 1; + int name_index = this.getConstantPool().addUtf8("BootstrapMethods"); + int length = 2 + numberOfBootstrapMethods * 4 + bMethod.getNumBootstrapArguments() * 2; + BootstrapMethod[] bootstrap_methods = new BootstrapMethod[numberOfBootstrapMethods]; + bootstrap_methods[numberOfBootstrapMethods-1] = bMethod; + BootstrapMethods bootstrapAttribute = new BootstrapMethods(name_index, length, bootstrap_methods, this.getConstantPool().getConstantPool()); + this.addAttribute(bootstrapAttribute); + return numberOfBootstrapMethods-1; } } diff --git a/src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java b/src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java index 9bcd75d9..db6c2d90 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java @@ -32,4 +32,5 @@ public class DHBWConstantPoolGen extends ConstantPoolGen{ constantTable.put(c, ret); return ret; } + } diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index f8ea3b3c..2727e6a1 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -30,7 +30,7 @@ public class DHBWInstructionFactory extends InstructionFactory{ this.cg = cg; } - public INVOKEDYNAMIC createInvokeDynamic( MethodGen lambdaMethod ) { + public INVOKEDYNAMIC createInvokeDynamic( String interfaceMethodName, String lambdaTypeSignature, MethodGen lambdaMethod ) { //Zuerst die Bootstrap-Methode erstellen: Diese müssen dann in ein BootstrapMethods-Attribut zusammengefasst und dem Classfile hinzugefügt werden //this.cp.addMethodref(lambdaMethod); @@ -49,12 +49,14 @@ public class DHBWInstructionFactory extends InstructionFactory{ * - instantiatedMethodType - The signature and return type that should be enforced dynamically at invocation time. This may be the same as samMethodType, or may be a specialization of it. */ - ConstantMethodType lambdaMethodType = new ConstantMethodType(this.cp.addUtf8(lambdaMethod.getSignature())); + String lambdaTypeParameterList = "()"; + ConstantMethodType lambdaMethodType = new ConstantMethodType(this.cp.addUtf8("()LRunnable;")); + ConstantMethodType lambdaMethodType1 = new ConstantMethodType(this.cp.addUtf8("()Ljava/lang/Object;")); int implMethodKind = 7; // 7 = InvokeSpecial @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.5 ConstantMethodHandle implMethod = new ConstantMethodHandle(implMethodKind,cg.getConstantPool().addMethodref(lambdaMethod)); //Das zweite Argument ist der MethodRef zur LambdaMethode //Argumentliste für die Bootstrap Methode zusammensetzen: - arguments.add(cp.addConstant(lambdaMethodType)); + arguments.add(cp.addConstant(lambdaMethodType1)); arguments.add(cp.addConstant(implMethod)); arguments.add(cp.addConstant(lambdaMethodType)); @@ -70,13 +72,16 @@ public class DHBWInstructionFactory extends InstructionFactory{ cg.addInnerClass(innerClassAttribute); String bootstrapSignature = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"; - int lambdaMethodIndex = cp.addMethodref("java.lang.invoke.LambdaMetafactory", "metafactory", bootstrapSignature); + int lambdaMetafactoryRefIndex = cp.addMethodref("java.lang.invoke.LambdaMetafactory", "metafactory", bootstrapSignature); + //reference kind 6 steht für invokestatic + int lambdaMetafactoryHandle = cp.addConstant(new ConstantMethodHandle(6, lambdaMetafactoryRefIndex)); int[] argumentsArray = new int[arguments.size()]; for(int i = 0; i0){ + paramString+="<"; + Iterator it = this.parameter.iterator(); + while(it.hasNext()){ + Type param = it.next(); + paramString+=param.getBytecodeType(cg); + //if(it.hasNext()) + //paramString+=";"; //kein Delimiter zwischen den Typen + } + paramString+=">"; + } + return new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName()+paramString); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java index 50f2d7d5..bacd1cbe 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java @@ -1,11 +1,12 @@ package de.dhbwstuttgart.syntaxtree.type; import de.dhbwstuttgart.typeinference.Menge; - +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; +import de.dhbwstuttgart.typeinference.exceptions.DebugException; /** * Stellt eine Wildcard mit unterer Grenze dar. @@ -153,5 +154,9 @@ public class SuperWildcardType extends WildcardType implements ITypeContainer, I return super.TYPE(ass, parent); } - + @Override + public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) { + return new de.dhbwstuttgart.bytecode.WildcardType(this.innerType.get_Name(), "-"); + } + } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java index 8fc40804..e94f4a05 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java @@ -1,11 +1,12 @@ package de.dhbwstuttgart.syntaxtree.type; import de.dhbwstuttgart.typeinference.Menge; - +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; +import de.dhbwstuttgart.typeinference.exceptions.DebugException; import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; /** @@ -99,6 +100,11 @@ public class WildcardType extends Type{ } } + @Override + public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) { + return this.innerType.getBytecodeType(cg); + } + } diff --git a/test/bytecode/Fun0.java b/test/bytecode/Fun0.java new file mode 100644 index 00000000..a7e33f14 --- /dev/null +++ b/test/bytecode/Fun0.java @@ -0,0 +1,3 @@ +interface Fun0{ +A apply(); +} diff --git a/test/bytecode/LambdaExpr.jav b/test/bytecode/LambdaExpr.jav index e5b1a122..26c9a0be 100644 --- a/test/bytecode/LambdaExpr.jav +++ b/test/bytecode/LambdaExpr.jav @@ -2,7 +2,8 @@ class LambdaExpr { void method() { - lambda; lambda = ()-> 1; + lambda; + lambda = ()-> 1; } } \ No newline at end of file diff --git a/test/bytecode/Runnable.jav b/test/bytecode/Runnable.jav index c88ce158..bcd3a42a 100644 --- a/test/bytecode/Runnable.jav +++ b/test/bytecode/Runnable.jav @@ -1,5 +1,5 @@ class Runnable{ -method() { return ()-> this; } +Fun0 method() { return ()-> this; } } \ No newline at end of file diff --git a/test/bytecode/Test.java b/test/bytecode/Test.java index 69ff36f6..5b917d36 100644 --- a/test/bytecode/Test.java +++ b/test/bytecode/Test.java @@ -3,11 +3,11 @@ */ class Test{ public static void main(String[] args){ - new EmptyClass(); + /*new EmptyClass(); new Assign(); System.out.println(new Return().method()); new MethodCall().method(); - System.out.println(new FieldDeclaration().field); - //new Runnable().method().run(); + System.out.println(new FieldDeclaration().field);*/ + System.out.println(new Runnable().method().apply()); } }