From 86e06a6e7ac3358f69d3643f56c3ce8d42c70415 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Tue, 22 Sep 2015 18:43:36 +0200 Subject: [PATCH] Erweitern des Bytecode Gen. --- notizen/stan/lambdaBytecode/Fun0.java | 3 + notizen/stan/lambdaBytecode/Fun1.java | 7 ++ notizen/stan/lambdaBytecode/GenericTest.java | 5 + notizen/stan/lambdaBytecode/Identity.java | 5 + notizen/stan/lambdaBytecode/InnerClass.java | 10 ++ notizen/stan/lambdaBytecode/Lambda1.decompile | 106 +++++++++++++++++ notizen/stan/lambdaBytecode/Lambda1.java | 12 ++ notizen/stan/lambdaBytecode/Lambda3.decompile | 110 ++++++++++++++++++ notizen/stan/lambdaBytecode/Lambda3.java | 12 ++ notizen/stan/lambdaBytecode/Lambda4.decompile | 104 +++++++++++++++++ notizen/stan/lambdaBytecode/Lambda4.java | 8 ++ notizen/stan/lambdaBytecode/Lambda5.java | 8 ++ notizen/stan/lambdaBytecode/Lambda5Test.java | 5 + notizen/stan/lambdaBytecode/Notizen.md | 37 ++++++ notizen/stan/lambdaBytecode/Runnable.java | 5 + notizen/stan/lambdaBytecode/Test.java | 8 ++ notizen/stan/lambdaBytecode/cat | 104 +++++++++++++++++ .../bytecode/ClassGenerator.java | 76 +++++++++++- .../bytecode/DHBWInstructionFactory.java | 29 ++++- .../bytecode/MethodGenerator.java | 37 +++++- .../bytecode/TypePlaceholderType.java | 14 ++- src/de/dhbwstuttgart/syntaxtree/Class.java | 16 +-- src/de/dhbwstuttgart/syntaxtree/Method.java | 28 +---- .../dhbwstuttgart/syntaxtree/SourceFile.java | 2 +- .../statement/LambdaExpression.java | 54 ++++++--- .../syntaxtree/statement/NewClass.java | 2 +- .../type}/FunN.java | 19 ++- .../syntaxtree/type/RefType.java | 11 +- .../syntaxtree/type/SuperWildcardType.java | 10 ++ .../dhbwstuttgart/syntaxtree/type/Type.java | 8 ++ .../syntaxtree/type/TypePlaceholder.java | 26 ++++- .../dhbwstuttgart/syntaxtree/type/Void.java | 7 ++ .../syntaxtree/type/WildcardType.java | 11 ++ .../typeinference/ByteCodeResult.java | 10 ++ .../dhbwstuttgart/typeinference/FunVoidN.java | 1 + src/de/dhbwstuttgart/typeinference/Menge.java | 13 +++ .../typeinference/TypeinferenceResultSet.java | 5 +- .../assumptions/TypeAssumptions.java | 2 +- test/bytecode/Identity.jav | 1 - test/bytecode/Return.jav | 2 +- test/bytecode/Test.java | 1 + 41 files changed, 852 insertions(+), 82 deletions(-) create mode 100644 notizen/stan/lambdaBytecode/Fun0.java create mode 100644 notizen/stan/lambdaBytecode/Fun1.java create mode 100644 notizen/stan/lambdaBytecode/GenericTest.java create mode 100644 notizen/stan/lambdaBytecode/Identity.java create mode 100644 notizen/stan/lambdaBytecode/InnerClass.java create mode 100644 notizen/stan/lambdaBytecode/Lambda1.decompile create mode 100644 notizen/stan/lambdaBytecode/Lambda1.java create mode 100644 notizen/stan/lambdaBytecode/Lambda3.decompile create mode 100644 notizen/stan/lambdaBytecode/Lambda3.java create mode 100644 notizen/stan/lambdaBytecode/Lambda4.decompile create mode 100644 notizen/stan/lambdaBytecode/Lambda4.java create mode 100644 notizen/stan/lambdaBytecode/Lambda5.java create mode 100644 notizen/stan/lambdaBytecode/Lambda5Test.java create mode 100644 notizen/stan/lambdaBytecode/Notizen.md create mode 100644 notizen/stan/lambdaBytecode/Runnable.java create mode 100644 notizen/stan/lambdaBytecode/Test.java create mode 100644 notizen/stan/lambdaBytecode/cat rename src/de/dhbwstuttgart/{typeinference => syntaxtree/type}/FunN.java (93%) diff --git a/notizen/stan/lambdaBytecode/Fun0.java b/notizen/stan/lambdaBytecode/Fun0.java new file mode 100644 index 00000000..a7e33f14 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Fun0.java @@ -0,0 +1,3 @@ +interface Fun0{ +A apply(); +} diff --git a/notizen/stan/lambdaBytecode/Fun1.java b/notizen/stan/lambdaBytecode/Fun1.java new file mode 100644 index 00000000..8a25b115 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Fun1.java @@ -0,0 +1,7 @@ +interface Fun1{ +A apply(B p); +} + +class TestFun1{ + A apply(A a){return a;} +} diff --git a/notizen/stan/lambdaBytecode/GenericTest.java b/notizen/stan/lambdaBytecode/GenericTest.java new file mode 100644 index 00000000..81701939 --- /dev/null +++ b/notizen/stan/lambdaBytecode/GenericTest.java @@ -0,0 +1,5 @@ +class GenericTest{ +GenericTest field; +void methode(A a, B b){ + } +} diff --git a/notizen/stan/lambdaBytecode/Identity.java b/notizen/stan/lambdaBytecode/Identity.java new file mode 100644 index 00000000..29727c19 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Identity.java @@ -0,0 +1,5 @@ +class Identity{ + +Fun1 op = (x)->x; + +} diff --git a/notizen/stan/lambdaBytecode/InnerClass.java b/notizen/stan/lambdaBytecode/InnerClass.java new file mode 100644 index 00000000..7c76b914 --- /dev/null +++ b/notizen/stan/lambdaBytecode/InnerClass.java @@ -0,0 +1,10 @@ +class InnerClass{ + +private class TestKlasse{ + void methode(){} +} + +void methode(){ +new TestKlasse().methode(); +} +} diff --git a/notizen/stan/lambdaBytecode/Lambda1.decompile b/notizen/stan/lambdaBytecode/Lambda1.decompile new file mode 100644 index 00000000..94ad5183 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda1.decompile @@ -0,0 +1,106 @@ +Classfile /home/janulrich/Development/eclipseworkspace/JavaCompilerCore/notizen/stan/lambdaBytecode/Lambda3.class + Last modified 20.08.2015; size 903 bytes + MD5 checksum acb53c553588f3c919f2b0e6359bbd94 +class Lambda3 + InnerClasses: + public static final #46= #45 of #49; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles + BootstrapMethods: + 0: #18 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + Method arguments: + #19 ()V + #20 invokestatic Lambda3.lambda$methode$0:()V + #19 ()V + minor version: 0 + major version: 52 + flags: ACC_SUPER +Constant pool: + #1 = Methodref #8.#16 // java/lang/Object."":()V + #2 = InvokeDynamic #0:#21 // #0:run:()Ljava/lang/Runnable; + #3 = Methodref #7.#22 // Lambda3.methode:()Ljava/lang/Runnable; + #4 = InterfaceMethodref #23.#24 // java/lang/Runnable.run:()V + #5 = Fieldref #25.#26 // java/lang/System.out:Ljava/io/PrintStream; + #6 = Methodref #27.#28 // java/io/PrintStream.println:()V + #7 = Class #29 // Lambda3 + #8 = Class #30 // java/lang/Object + #9 = Utf8 + #10 = Utf8 ()V + #11 = Utf8 Code + #12 = Utf8 methode + #13 = Utf8 ()Ljava/lang/Runnable; + #14 = Utf8 methode2 + #15 = Utf8 lambda$methode$0 + #16 = NameAndType #9:#10 // "":()V + #17 = Utf8 BootstrapMethods + #18 = MethodHandle #6:#31 // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + #19 = MethodType #10 // ()V + #20 = MethodHandle #6:#32 // invokestatic Lambda3.lambda$methode$0:()V + #21 = NameAndType #33:#13 // run:()Ljava/lang/Runnable; + #22 = NameAndType #12:#13 // methode:()Ljava/lang/Runnable; + #23 = Class #34 // java/lang/Runnable + #24 = NameAndType #33:#10 // run:()V + #25 = Class #35 // java/lang/System + #26 = NameAndType #36:#37 // out:Ljava/io/PrintStream; + #27 = Class #38 // java/io/PrintStream + #28 = NameAndType #39:#10 // println:()V + #29 = Utf8 Lambda3 + #30 = Utf8 java/lang/Object + #31 = Methodref #40.#41 // java/lang/invoke/LambdaMetafactory.metafactory:(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; + #32 = Methodref #7.#42 // Lambda3.lambda$methode$0:()V + #33 = Utf8 run + #34 = Utf8 java/lang/Runnable + #35 = Utf8 java/lang/System + #36 = Utf8 out + #37 = Utf8 Ljava/io/PrintStream; + #38 = Utf8 java/io/PrintStream + #39 = Utf8 println + #40 = Class #43 // java/lang/invoke/LambdaMetafactory + #41 = NameAndType #44:#48 // metafactory:(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; + #42 = NameAndType #15:#10 // lambda$methode$0:()V + #43 = Utf8 java/lang/invoke/LambdaMetafactory + #44 = Utf8 metafactory + #45 = Class #50 // java/lang/invoke/MethodHandles$Lookup + #46 = Utf8 Lookup + #47 = Utf8 InnerClasses + #48 = Utf8 (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; + #49 = Class #51 // java/lang/invoke/MethodHandles + #50 = Utf8 java/lang/invoke/MethodHandles$Lookup + #51 = Utf8 java/lang/invoke/MethodHandles +{ + Lambda3(); + Signature: ()V + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokespecial #1 // Method java/lang/Object."":()V + 4: return + + java.lang.Runnable methode(); + Signature: ()Ljava/lang/Runnable; + flags: + Code: + stack=1, locals=1, args_size=1 + 0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; + 5: areturn + + void methode2(); + Signature: ()V + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokevirtual #3 // Method methode:()Ljava/lang/Runnable; + 4: invokeinterface #4, 1 // InterfaceMethod java/lang/Runnable.run:()V + 9: return + + private static void lambda$methode$0(); + Signature: ()V + flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC + Code: + stack=1, locals=0, args_size=0 + 0: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream; + 3: invokevirtual #6 // Method java/io/PrintStream.println:()V + 6: return +} + + diff --git a/notizen/stan/lambdaBytecode/Lambda1.java b/notizen/stan/lambdaBytecode/Lambda1.java new file mode 100644 index 00000000..858e00b4 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda1.java @@ -0,0 +1,12 @@ + +class Lambda1{ + +Runnable methode(){ + return ()-> System.out.println(); +} + +void methode2(){ + methode().run(); +} + +} diff --git a/notizen/stan/lambdaBytecode/Lambda3.decompile b/notizen/stan/lambdaBytecode/Lambda3.decompile new file mode 100644 index 00000000..403a0596 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda3.decompile @@ -0,0 +1,110 @@ +Classfile /home/janulrich/Development/eclipseworkspace/JavaCompilerCore/notizen/stan/lambdaBytecode/Lambda3.class + Last modified 20.08.2015; size 963 bytes + MD5 checksum 11b76982e895a4f22c01832b3da258ef +class Lambda3 + InnerClasses: + public static final #48= #47 of #51; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles + BootstrapMethods: + 0: #18 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + Method arguments: + #19 ()V + #20 invokespecial Lambda3.lambda$methode$0:()V + #19 ()V + minor version: 0 + major version: 52 + flags: ACC_SUPER +Constant pool: + #1 = Methodref #8.#16 // java/lang/Object."":()V + #2 = InvokeDynamic #0:#21 // #0:run:(LLambda3;)Ljava/lang/Runnable; + #3 = Methodref #7.#22 // Lambda3.methode:()Ljava/lang/Runnable; + #4 = InterfaceMethodref #23.#24 // java/lang/Runnable.run:()V + #5 = Fieldref #25.#26 // java/lang/System.out:Ljava/io/PrintStream; + #6 = Methodref #27.#28 // java/io/PrintStream.println:(Ljava/lang/Object;)V + #7 = Class #29 // Lambda3 + #8 = Class #30 // java/lang/Object + #9 = Utf8 + #10 = Utf8 ()V + #11 = Utf8 Code + #12 = Utf8 methode + #13 = Utf8 ()Ljava/lang/Runnable; + #14 = Utf8 methode2 + #15 = Utf8 lambda$methode$0 + #16 = NameAndType #9:#10 // "":()V + #17 = Utf8 BootstrapMethods + #18 = MethodHandle #6:#31 // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + #19 = MethodType #10 // ()V + #20 = MethodHandle #7:#32 // invokespecial Lambda3.lambda$methode$0:()V + #21 = NameAndType #33:#34 // run:(LLambda3;)Ljava/lang/Runnable; + #22 = NameAndType #12:#13 // methode:()Ljava/lang/Runnable; + #23 = Class #35 // java/lang/Runnable + #24 = NameAndType #33:#10 // run:()V + #25 = Class #36 // java/lang/System + #26 = NameAndType #37:#38 // out:Ljava/io/PrintStream; + #27 = Class #39 // java/io/PrintStream + #28 = NameAndType #40:#41 // println:(Ljava/lang/Object;)V + #29 = Utf8 Lambda3 + #30 = Utf8 java/lang/Object + #31 = Methodref #42.#43 // java/lang/invoke/LambdaMetafactory.metafactory:(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; + #32 = Methodref #7.#44 // Lambda3.lambda$methode$0:()V + #33 = Utf8 run + #34 = Utf8 (LLambda3;)Ljava/lang/Runnable; + #35 = Utf8 java/lang/Runnable + #36 = Utf8 java/lang/System + #37 = Utf8 out + #38 = Utf8 Ljava/io/PrintStream; + #39 = Utf8 java/io/PrintStream + #40 = Utf8 println + #41 = Utf8 (Ljava/lang/Object;)V + #42 = Class #45 // java/lang/invoke/LambdaMetafactory + #43 = NameAndType #46:#50 // metafactory:(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; + #44 = NameAndType #15:#10 // lambda$methode$0:()V + #45 = Utf8 java/lang/invoke/LambdaMetafactory + #46 = Utf8 metafactory + #47 = Class #52 // java/lang/invoke/MethodHandles$Lookup + #48 = Utf8 Lookup + #49 = Utf8 InnerClasses + #50 = Utf8 (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; + #51 = Class #53 // java/lang/invoke/MethodHandles + #52 = Utf8 java/lang/invoke/MethodHandles$Lookup + #53 = Utf8 java/lang/invoke/MethodHandles +{ + Lambda3(); + Signature: ()V + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokespecial #1 // Method java/lang/Object."":()V + 4: return + + java.lang.Runnable methode(); + Signature: ()Ljava/lang/Runnable; + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokedynamic #2, 0 // InvokeDynamic #0:run:(LLambda3;)Ljava/lang/Runnable; + 6: areturn + + void methode2(); + Signature: ()V + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokevirtual #3 // Method methode:()Ljava/lang/Runnable; + 4: invokeinterface #4, 1 // InterfaceMethod java/lang/Runnable.run:()V + 9: return + + private void lambda$methode$0(); + Signature: ()V + flags: ACC_PRIVATE, ACC_SYNTHETIC + Code: + stack=2, locals=1, args_size=1 + 0: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream; + 3: aload_0 + 4: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V + 7: return +} + + diff --git a/notizen/stan/lambdaBytecode/Lambda3.java b/notizen/stan/lambdaBytecode/Lambda3.java new file mode 100644 index 00000000..7dddaeb7 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda3.java @@ -0,0 +1,12 @@ + +class Lambda3{ + +Runnable methode(){ + return ()-> System.out.println(this); +} + +void methode2(){ + methode().run(); +} + +} diff --git a/notizen/stan/lambdaBytecode/Lambda4.decompile b/notizen/stan/lambdaBytecode/Lambda4.decompile new file mode 100644 index 00000000..94ef6ea5 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda4.decompile @@ -0,0 +1,104 @@ +Classfile /home/janulrich/Development/eclipseworkspace/JavaCompilerCore/notizen/stan/lambdaBytecode/Lambda4.class + Last modified 03.09.2015; size 979 bytes + MD5 checksum f24040561dd183d0d75c91dbdd93f59c + Compiled from "Lambda4.java" +class Lambda4 + SourceFile: "Lambda4.java" + InnerClasses: + public static final #45= #44 of #48; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles + BootstrapMethods: + 0: #19 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + Method arguments: + #20 (Ljava/lang/Integer;)Ljava/lang/Integer; + #21 invokespecial Lambda4.lambda$methode$0:(Ljava/lang/Integer;)Ljava/lang/Integer; + #20 (Ljava/lang/Integer;)Ljava/lang/Integer; + minor version: 0 + major version: 52 + flags: ACC_SUPER +Constant pool: + #1 = Methodref #6.#17 // java/lang/Object."":()V + #2 = InvokeDynamic #0:#22 // #0:test:(LLambda4;)LTest; + #3 = Fieldref #23.#24 // java/lang/System.out:Ljava/io/PrintStream; + #4 = Methodref #25.#26 // java/io/PrintStream.println:(Ljava/lang/Object;)V + #5 = Class #27 // Lambda4 + #6 = Class #28 // java/lang/Object + #7 = Utf8 + #8 = Utf8 ()V + #9 = Utf8 Code + #10 = Utf8 LineNumberTable + #11 = Utf8 methode + #12 = Utf8 ()LTest; + #13 = Utf8 lambda$methode$0 + #14 = Utf8 (Ljava/lang/Integer;)Ljava/lang/Integer; + #15 = Utf8 SourceFile + #16 = Utf8 Lambda4.java + #17 = NameAndType #7:#8 // "":()V + #18 = Utf8 BootstrapMethods + #19 = MethodHandle #6:#29 // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + #20 = MethodType #14 // (Ljava/lang/Integer;)Ljava/lang/Integer; + #21 = MethodHandle #7:#30 // invokespecial Lambda4.lambda$methode$0:(Ljava/lang/Integer;)Ljava/lang/Integer; + #22 = NameAndType #31:#32 // test:(LLambda4;)LTest; + #23 = Class #33 // java/lang/System + #24 = NameAndType #34:#35 // out:Ljava/io/PrintStream; + #25 = Class #36 // java/io/PrintStream + #26 = NameAndType #37:#38 // println:(Ljava/lang/Object;)V + #27 = Utf8 Lambda4 + #28 = Utf8 java/lang/Object + #29 = Methodref #39.#40 // java/lang/invoke/LambdaMetafactory.metafactory:(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; + #30 = Methodref #5.#41 // Lambda4.lambda$methode$0:(Ljava/lang/Integer;)Ljava/lang/Integer; + #31 = Utf8 test + #32 = Utf8 (LLambda4;)LTest; + #33 = Utf8 java/lang/System + #34 = Utf8 out + #35 = Utf8 Ljava/io/PrintStream; + #36 = Utf8 java/io/PrintStream + #37 = Utf8 println + #38 = Utf8 (Ljava/lang/Object;)V + #39 = Class #42 // java/lang/invoke/LambdaMetafactory + #40 = NameAndType #43:#47 // metafactory:(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; + #41 = NameAndType #13:#14 // lambda$methode$0:(Ljava/lang/Integer;)Ljava/lang/Integer; + #42 = Utf8 java/lang/invoke/LambdaMetafactory + #43 = Utf8 metafactory + #44 = Class #49 // java/lang/invoke/MethodHandles$Lookup + #45 = Utf8 Lookup + #46 = Utf8 InnerClasses + #47 = Utf8 (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; + #48 = Class #50 // java/lang/invoke/MethodHandles + #49 = Utf8 java/lang/invoke/MethodHandles$Lookup + #50 = Utf8 java/lang/invoke/MethodHandles +{ + Lambda4(); + Signature: ()V + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokespecial #1 // Method java/lang/Object."":()V + 4: return + LineNumberTable: + line 4: 0 + + Test methode(); + Signature: ()LTest; + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokedynamic #2, 0 // InvokeDynamic #0:test:(LLambda4;)LTest; + 6: areturn + LineNumberTable: + line 6: 0 + + private java.lang.Integer lambda$methode$0(java.lang.Integer); + Signature: (Ljava/lang/Integer;)Ljava/lang/Integer; + flags: ACC_PRIVATE, ACC_SYNTHETIC + Code: + stack=2, locals=2, args_size=2 + 0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; + 3: aload_0 + 4: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V + 7: aload_1 + 8: areturn + LineNumberTable: + line 6: 0 +} diff --git a/notizen/stan/lambdaBytecode/Lambda4.java b/notizen/stan/lambdaBytecode/Lambda4.java new file mode 100644 index 00000000..a69ba86f --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda4.java @@ -0,0 +1,8 @@ +interface Test{ + Integer test(Integer i); +} +class Lambda4{ + Test methode(){ + return (i)->{System.out.println(this); return i;}; +} +} diff --git a/notizen/stan/lambdaBytecode/Lambda5.java b/notizen/stan/lambdaBytecode/Lambda5.java new file mode 100644 index 00000000..481bfaac --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda5.java @@ -0,0 +1,8 @@ +interface TestParam{ + A test(A i); +} +class Lambda5{ + TestParam methode(){ + return (i)->{System.out.println(this); return i;}; +} +} diff --git a/notizen/stan/lambdaBytecode/Lambda5Test.java b/notizen/stan/lambdaBytecode/Lambda5Test.java new file mode 100644 index 00000000..198cc0f9 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Lambda5Test.java @@ -0,0 +1,5 @@ +class Lambda5Test{ + public static void main(String[] args){ + Integer i = new Lambda5().methode().test(2); +} +} diff --git a/notizen/stan/lambdaBytecode/Notizen.md b/notizen/stan/lambdaBytecode/Notizen.md new file mode 100644 index 00000000..661abd82 --- /dev/null +++ b/notizen/stan/lambdaBytecode/Notizen.md @@ -0,0 +1,37 @@ +# Quellen +* http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html +* http://blog.takipi.com/erstellen-von-lambda-ausdrucken-scala-vs-java-8/ + +# Decompiler +* Es wird javap verwendet. Die Datei ~/bin/javap leitet den javap Befehl um. Muss angepasst werden, wenn man andere Version verwenden will. + +#Quellen +* Brian Götz zu Lambdas: http://wiki.jvmlangsummit.com/images/1/1e/2011_Goetz_Lambda.pdf + +# Doku +* 2 Möglichkeiten Lambda Ausdrücke zu kompilieren: Anonymous inner class, Invokedynamic + +## Invokedynamic +* Hat Argumente auf dem Stack liegen +* Indexbytes zeigen auf eine InvokeDynamic_Info structure, welche beinhaltet: + * Methodenname der bootstrap-Methode (Symbolic Reference) + * Mehrere Symbolic References auf statische Argumente der Bootstrap Methode + * Einen Methodenname und Deskriptor. +* Ausführung: + * Nach dem auflösen dieser Struktur stehen die Informationen des InvokeDynamic_Info zur Verfügung + * Anschließend wird ein invokevirtual auf die Bootstrap Methode ausgeführt + * Die Index Referenz für InvokeVirtual hat bestimmte Werte: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic + * Die Rückgabe der Bootstrap-Methode (CallSite) wird mittels invokevirtual ausgeführt. + +## Bootstrap Methods +* Ein Attribut im Classfile +* Gibt die Bootstrap Methoden an +* Die Angabe erfolgt durch Zeiger auf Method_Handle_info Strukturen im Konstantenpool +* Rückgabe der Bootstrap-Methode ist ein CallSite Objekt: https://docs.oracle.com/javase/7/docs/api/java/lang/invoke/CallSite.html + +## LambdaMetaFactory +* Stellt eine mögliche Bootstrap Methode dar + +# TODO: +* Matrix Beispiel muss funktionieren (verschachtelter Lambda Ausdruck) +* Automatisch Bytecode generieren, wenn alle Typen eingesetzt sind diff --git a/notizen/stan/lambdaBytecode/Runnable.java b/notizen/stan/lambdaBytecode/Runnable.java new file mode 100644 index 00000000..bcd3a42a --- /dev/null +++ b/notizen/stan/lambdaBytecode/Runnable.java @@ -0,0 +1,5 @@ +class Runnable{ + +Fun0 method() { return ()-> this; } + +} \ No newline at end of file diff --git a/notizen/stan/lambdaBytecode/Test.java b/notizen/stan/lambdaBytecode/Test.java new file mode 100644 index 00000000..2eb1e5af --- /dev/null +++ b/notizen/stan/lambdaBytecode/Test.java @@ -0,0 +1,8 @@ +/** + * Diese Klasse testet die generierte EmptyClass.class-Datei + */ +class Test{ +public static void main(String[] args){ + System.out.println(new Runnable().method().apply()); +} +} diff --git a/notizen/stan/lambdaBytecode/cat b/notizen/stan/lambdaBytecode/cat new file mode 100644 index 00000000..f886214b --- /dev/null +++ b/notizen/stan/lambdaBytecode/cat @@ -0,0 +1,104 @@ +Classfile /home/janulrich/Development/eclipseworkspace/JavaCompilerCore/notizen/stan/lambdaBytecode/Lambda1.class + Last modified 20.08.2015; size 903 bytes + MD5 checksum acb53c553588f3c919f2b0e6359bbd94 +class Lambda1 + InnerClasses: + public static final #46= #45 of #49; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles + BootstrapMethods: + 0: #18 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + Method arguments: + #19 ()V + #20 invokestatic Lambda1.lambda$methode$0:()V + #19 ()V + minor version: 0 + major version: 52 + flags: ACC_SUPER +Constant pool: + #1 = Methodref #8.#16 // java/lang/Object."":()V + #2 = InvokeDynamic #0:#21 // #0:run:()Ljava/lang/Runnable; + #3 = Methodref #7.#22 // Lambda1.methode:()Ljava/lang/Runnable; + #4 = InterfaceMethodref #23.#24 // java/lang/Runnable.run:()V + #5 = Fieldref #25.#26 // java/lang/System.out:Ljava/io/PrintStream; + #6 = Methodref #27.#28 // java/io/PrintStream.println:()V + #7 = Class #29 // Lambda1 + #8 = Class #30 // java/lang/Object + #9 = Utf8 + #10 = Utf8 ()V + #11 = Utf8 Code + #12 = Utf8 methode + #13 = Utf8 ()Ljava/lang/Runnable; + #14 = Utf8 methode2 + #15 = Utf8 lambda$methode$0 + #16 = NameAndType #9:#10 // "":()V + #17 = Utf8 BootstrapMethods + #18 = MethodHandle #6:#31 // invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(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; + #19 = MethodType #10 // ()V + #20 = MethodHandle #6:#32 // invokestatic Lambda1.lambda$methode$0:()V + #21 = NameAndType #33:#13 // run:()Ljava/lang/Runnable; + #22 = NameAndType #12:#13 // methode:()Ljava/lang/Runnable; + #23 = Class #34 // java/lang/Runnable + #24 = NameAndType #33:#10 // run:()V + #25 = Class #35 // java/lang/System + #26 = NameAndType #36:#37 // out:Ljava/io/PrintStream; + #27 = Class #38 // java/io/PrintStream + #28 = NameAndType #39:#10 // println:()V + #29 = Utf8 Lambda1 + #30 = Utf8 java/lang/Object + #31 = Methodref #40.#41 // java/lang/invoke/LambdaMetafactory.metafactory:(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; + #32 = Methodref #7.#42 // Lambda1.lambda$methode$0:()V + #33 = Utf8 run + #34 = Utf8 java/lang/Runnable + #35 = Utf8 java/lang/System + #36 = Utf8 out + #37 = Utf8 Ljava/io/PrintStream; + #38 = Utf8 java/io/PrintStream + #39 = Utf8 println + #40 = Class #43 // java/lang/invoke/LambdaMetafactory + #41 = NameAndType #44:#48 // metafactory:(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; + #42 = NameAndType #15:#10 // lambda$methode$0:()V + #43 = Utf8 java/lang/invoke/LambdaMetafactory + #44 = Utf8 metafactory + #45 = Class #50 // java/lang/invoke/MethodHandles$Lookup + #46 = Utf8 Lookup + #47 = Utf8 InnerClasses + #48 = Utf8 (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; + #49 = Class #51 // java/lang/invoke/MethodHandles + #50 = Utf8 java/lang/invoke/MethodHandles$Lookup + #51 = Utf8 java/lang/invoke/MethodHandles +{ + Lambda1(); + Signature: ()V + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokespecial #1 // Method java/lang/Object."":()V + 4: return + + java.lang.Runnable methode(); + Signature: ()Ljava/lang/Runnable; + flags: + Code: + stack=1, locals=1, args_size=1 + 0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; + 5: areturn + + void methode2(); + Signature: ()V + flags: + Code: + stack=1, locals=1, args_size=1 + 0: aload_0 + 1: invokevirtual #3 // Method methode:()Ljava/lang/Runnable; + 4: invokeinterface #4, 1 // InterfaceMethod java/lang/Runnable.run:()V + 9: return + + private static void lambda$methode$0(); + Signature: ()V + flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC + Code: + stack=1, locals=0, args_size=0 + 0: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream; + 3: invokevirtual #6 // Method java/io/PrintStream.println:()V + 6: return +} diff --git a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java index d5fe5220..e45e3009 100644 --- a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java @@ -1,15 +1,21 @@ package de.dhbwstuttgart.bytecode; +import java.util.Iterator; + 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.classfile.JavaClass; +import org.apache.commons.bcel6.classfile.Signature; import org.apache.commons.bcel6.generic.ClassGen; import org.apache.commons.bcel6.generic.ConstantPoolGen; +import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.exceptions.DebugException; @@ -20,11 +26,15 @@ public class ClassGenerator extends ClassGen{ private DHBWInstructionFactory factory; private TypeinferenceResultSet tiResult; private int lambdaMethodeNr = 0; + private Type superClass; + + private Menge usedTPHs = new Menge<>(); - public ClassGenerator(String name, String get_Name, String string, + public ClassGenerator(String name, Type superClass, String string, short accPublic, String[] strings, TypeinferenceResultSet resultSet) { - super(name,get_Name,string,accPublic,strings, new DHBWConstantPoolGen()); + super(name,superClass.get_Name(),string,accPublic,strings, new DHBWConstantPoolGen()); this.tiResult = resultSet; + this.superClass = superClass; cp = (DHBWConstantPoolGen) super.getConstantPool(); factory = new DHBWInstructionFactory(this, cp); @@ -36,6 +46,23 @@ public class ClassGenerator extends ClassGen{ return factory ; } + /** + * Versucht einen Type zu finden von dem dieser TPH ein Subtyp sein muss. + * @param toTPH + * @return Es gilt dann "toTPH extends Type" + */ + public org.apache.commons.bcel6.generic.Type getNearestType(TypePlaceholder toTPH){ + Type t = resolveTPH(toTPH); + if(t == null){ + return this.getInstructionFactory().createObjectType(); + }else if(t instanceof TypePlaceholder){ //Es muss sich in diesem Fall um einen TPH handeln: + //return getNearestType((TypePlaceholder) t); + return new TypePlaceholderType((TypePlaceholder) t); + }else{ + return t.getBytecodeType(this); + } + } + public Type resolveTPH(TypePlaceholder typePlaceholder) { return tiResult.getTypeOfPlaceholder(typePlaceholder); } @@ -77,4 +104,49 @@ public class ClassGenerator extends ClassGen{ this.addAttribute(bootstrapAttribute); return numberOfBootstrapMethods-1; } + + public void addUsedTPH(TypePlaceholder tph){ + if(! this.getUsedTPH().contains(tph, (a, b)->{ + return a.get_Name().equals(b.get_Name()); //Vergleich auf Namensgleichheit. Was anderes zählt im Bytecode nicht + })) + { //Nur wenn noch nicht vorhanden anfügen: + this.usedTPHs.add(tph); + } + } + + public Menge getUsedTPH() { + return usedTPHs; + } + + @Override + public JavaClass getJavaClass() { + //Hier werden die letzten Schritte vor der Klassengenerierung ausgeführt: + + //Signatur setzen: + String typeParameters = this.generateParameterSignature(); + String superClassSignature = this.superClass.getBytecodeSignature(this); + String classSignature = typeParameters + superClassSignature; + if(classSignature.length()>0){ + this.addAttribute(new Signature(cp.addUtf8("Signature"),2,cp.addUtf8(classSignature),cp.getConstantPool())); + } + + return super.getJavaClass(); + } + + private String generateParameterSignature(){ + String ret = ""; + if(this.getUsedTPH().size()>0){ + ret += "<"; + Iterator it = ((Menge)this.getUsedTPH().clone()).iterator(); + while(it.hasNext()){ + TypePlaceholder tph = it.next(); + //ret += tph.getBytecodeMethodSignature(this); + //ret += ":"; + ret += tph.getClassSignature(this); + } + ret += ">"; + } + return ret; + } + } diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index 2727e6a1..d9cfcdfd 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -10,6 +10,7 @@ import org.apache.commons.bcel6.classfile.ConstantMethodHandle; import org.apache.commons.bcel6.classfile.ConstantMethodType; import org.apache.commons.bcel6.classfile.InnerClass; import org.apache.commons.bcel6.classfile.Method; +import org.apache.commons.bcel6.classfile.Signature; import org.apache.commons.bcel6.generic.ClassGen; import org.apache.commons.bcel6.generic.ConstantPoolGen; import org.apache.commons.bcel6.generic.INVOKEDYNAMIC; @@ -19,6 +20,12 @@ import org.apache.commons.bcel6.generic.LocalVariableInstruction; import org.apache.commons.bcel6.generic.MethodGen; import org.apache.commons.bcel6.generic.Type; +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.type.FunN; + public class DHBWInstructionFactory extends InstructionFactory{ private DHBWConstantPoolGen cp; @@ -30,7 +37,15 @@ public class DHBWInstructionFactory extends InstructionFactory{ this.cg = cg; } - public INVOKEDYNAMIC createInvokeDynamic( String interfaceMethodName, String lambdaTypeSignature, MethodGen lambdaMethod ) { + /** + * + * @param interfaceMethodName - Momentan immer "apply" + * @param invokeDynamicMethodType - Der Methodentyp + * @param interfaceMethodType + * @param lambdaMethod + * @return + */ + public INVOKEDYNAMIC createInvokeDynamic( String interfaceMethodName, String invokeDynamicMethodType, FunN interfaceMethodType, 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); @@ -50,8 +65,8 @@ public class DHBWInstructionFactory extends InstructionFactory{ */ String lambdaTypeParameterList = "()"; - ConstantMethodType lambdaMethodType = new ConstantMethodType(this.cp.addUtf8("()LRunnable;")); - ConstantMethodType lambdaMethodType1 = new ConstantMethodType(this.cp.addUtf8("()Ljava/lang/Object;")); + ConstantMethodType lambdaMethodType1 = new ConstantMethodType(this.cp.addUtf8("()Ljava/lang/Object;")); //TODO: Hier den Grund finden, warum Object stehen muss. + ConstantMethodType lambdaMethodType = new ConstantMethodType(this.cp.addUtf8(interfaceMethodType.getBytecodeInvokeDynamicSignature(cg))); 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 @@ -82,7 +97,6 @@ public class DHBWInstructionFactory extends InstructionFactory{ } BootstrapMethod bMethod = new BootstrapMethod(lambdaMetafactoryHandle, arguments.size(), argumentsArray); - int index; /* @@ -111,9 +125,9 @@ public class DHBWInstructionFactory extends InstructionFactory{ int bootstrap_method_attr_index = cg.addBootstrapMethod(bMethod); //TODO: der Typ der Lambda Methode muss den Typ von this als erstes Argument enthalten, damit this innerhalb der Lambda Methode verwendet werden kann - int name_and_type_index = cp.addNameAndType(interfaceMethodName, lambdaTypeSignature); + int invokeDynamicFunktionstyp = cp.addNameAndType(interfaceMethodName, invokeDynamicMethodType); - ConstantInvokeDynamic cInvokeDynamic = new ConstantInvokeDynamic(bootstrap_method_attr_index, name_and_type_index); + ConstantInvokeDynamic cInvokeDynamic = new ConstantInvokeDynamic(bootstrap_method_attr_index, invokeDynamicFunktionstyp); index = cp.addConstant(cInvokeDynamic); @@ -125,4 +139,7 @@ public class DHBWInstructionFactory extends InstructionFactory{ return InstructionFactory.createLoad(bytecodeType, index); } + public Type createObjectType() { + return new org.apache.commons.bcel6.generic.ObjectType("java.lang.Object"); + } } diff --git a/src/de/dhbwstuttgart/bytecode/MethodGenerator.java b/src/de/dhbwstuttgart/bytecode/MethodGenerator.java index 235a1ac0..2b592a4b 100644 --- a/src/de/dhbwstuttgart/bytecode/MethodGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/MethodGenerator.java @@ -1,16 +1,51 @@ package de.dhbwstuttgart.bytecode; +import org.apache.commons.bcel6.classfile.Method; +import org.apache.commons.bcel6.classfile.Signature; import org.apache.commons.bcel6.generic.ConstantPoolGen; import org.apache.commons.bcel6.generic.InstructionList; import org.apache.commons.bcel6.generic.MethodGen; import org.apache.commons.bcel6.generic.Type; +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.statement.Block; +import de.dhbwstuttgart.syntaxtree.statement.Return; + public class MethodGenerator extends MethodGen{ 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); } - + + public Method createMethod(ClassGenerator cg, ParameterList parameter, de.dhbwstuttgart.syntaxtree.type.Type retType, Block block){ + MethodGen method = this; + DHBWInstructionFactory factory = cg.getInstructionFactory(); + + InstructionList blockInstructions = block.genByteCode(cg); + InstructionList il = this.getInstructionList(); + + il.append(blockInstructions);//Die vom Block generierten Instructions an die InstructionList der Methode anfügen + //Ein return Statement anfügen, falls nicht vorhanden: + if (block.get_Statement().size() == 0) { il.append(factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); } + else { + if (!(block.get_Statement().lastElement() instanceof Return)) { il.append(factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); } + } + + method.stripAttributes(true); + method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden) + method.setMaxLocals(); + //Die korrekte Signatur für die Methode anhängen. Hier sind dann auch die Parameter von RefTypes enthalten: + String paramTypesSig = "("; + for(FormalParameter p : parameter){ + paramTypesSig += p.getType().getBytecodeMethodSignature(cg); + } + paramTypesSig += ")"; + String retTypeSig = retType.getBytecodeMethodSignature(cg); + method.addAttribute(new Signature(cp.addUtf8("Signature"),2,cp.addUtf8(paramTypesSig+retTypeSig),cp.getConstantPool())); + + return method.getMethod(); + } } diff --git a/src/de/dhbwstuttgart/bytecode/TypePlaceholderType.java b/src/de/dhbwstuttgart/bytecode/TypePlaceholderType.java index 3c0d2929..33c54047 100644 --- a/src/de/dhbwstuttgart/bytecode/TypePlaceholderType.java +++ b/src/de/dhbwstuttgart/bytecode/TypePlaceholderType.java @@ -3,10 +3,20 @@ package de.dhbwstuttgart.bytecode; import org.apache.commons.bcel6.Constants; import org.apache.commons.bcel6.generic.ReferenceType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + public class TypePlaceholderType extends ReferenceType{ - public TypePlaceholderType(String name) { - super(Constants.T_REFERENCE, "T" + name + ";"); + private final TypePlaceholder tph; + + public TypePlaceholderType(TypePlaceholder tph) { + super(Constants.T_REFERENCE, "T" + tph.get_Name() + ";"); + this.tph = tph; + if(this.tph == null)throw new NullPointerException(); + } + + public TypePlaceholder getTPH() { + return tph; } } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index 908724e3..356e3298 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -84,7 +84,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I logger.debug("Test"); if(pkgName != null)throw new NotImplementedException(); - _cg = new ClassGenerator(name, superClass.get_Name(), name + ".java", Constants.ACC_PUBLIC , new String[] { }, resultSet); //letzter Parameter sind implementierte Interfaces + _cg = new ClassGenerator(name, this.getSuperClass(), name + ".java", Constants.ACC_PUBLIC , new String[] { }, resultSet); //letzter Parameter sind implementierte Interfaces _cp = _cg.getConstantPool(); _factory = new DHBWInstructionFactory(_cg, _cp); @@ -111,20 +111,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I c.genByteCode(_cg, fieldInitializations); } - String typeAttributeSignature = ""; - if(this.getGenericParameter() != null && this.getGenericParameter().size()>0){ - typeAttributeSignature = "<"; - for(GenericTypeVar gp : this.getGenericParameter()){ - typeAttributeSignature+=gp.getBytecodeSignature(_cg); - } - typeAttributeSignature+=">"; - } - String superClassSignature = this.getSuperClass().getBytecodeSignature(_cg); - String classSignature = typeAttributeSignature + superClassSignature; - if(classSignature.length()>0){ - _cg.addAttribute(new Signature(_cp.addUtf8("Signature"),2,_cp.addUtf8(classSignature),_cp.getConstantPool())); - } - ByteCodeResult code = new ByteCodeResult(_cg); return code; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index 7f92cb25..2a7c055b 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -766,32 +766,10 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable } //Methode generieren: - MethodGen method = new MethodGenerator(Constants.ACC_PUBLIC, this.getType().getBytecodeType(cg), argumentTypes , argumentNames, this.get_Method_Name(), parentClass.name, il, _cp); - method.stripAttributes(true); + MethodGenerator method = new MethodGenerator(Constants.ACC_PUBLIC, this.getType().getBytecodeType(cg), argumentTypes , argumentNames, this.get_Method_Name(), parentClass.name, il, _cp); - Block block = this.get_Block(); - InstructionList blockInstructions = block.genByteCode(cg); - - il.append(blockInstructions);//Die vom Block generierten Instructions an die InstructionList der Methode anfügen - - if (block.get_Statement().size() == 0) { il.append(_factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); } - else { - if (!(block.get_Statement().lastElement() instanceof Return)) { il.append(_factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); } - } - - method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden) - method.setMaxLocals(); - - //Die korrekte Signatur für die Methode anhängen. Hier sind dann auch die Parameter von RefTypes enthalten: - String paramTypesSig = "("; - for(FormalParameter p : this.parameterlist){ - paramTypesSig += p.getType().getBytecodeSignature(cg); - } - paramTypesSig += ")"; - String retTypeSig = this.getType().getBytecodeSignature(cg); - method.addAttribute(new Signature(_cp.addUtf8("Signature"),2,_cp.addUtf8(paramTypesSig+retTypeSig),_cp.getConstantPool())); - - cg.addMethod(method.getMethod()); + //Methode generieren und anfügen: + cg.addMethod(method.createMethod(cg, getParameterList(), getType(), get_Block())); } diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index f919d44c..f96cc32e 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -27,6 +27,7 @@ import de.dhbwstuttgart.syntaxtree.misc.DeclId; import de.dhbwstuttgart.syntaxtree.misc.UsedId; import de.dhbwstuttgart.syntaxtree.modifier.Modifiers; import de.dhbwstuttgart.syntaxtree.modifier.Public; +import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; @@ -34,7 +35,6 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typeinference.ByteCodeResult; import de.dhbwstuttgart.typeinference.ConstraintsSet; -import de.dhbwstuttgart.typeinference.FunN; import de.dhbwstuttgart.typeinference.FunNInterface; import de.dhbwstuttgart.typeinference.FunNMethod; import de.dhbwstuttgart.typeinference.Pair; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java index 2ed9a55e..68ad44a2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java @@ -15,6 +15,8 @@ import org.apache.commons.bcel6.generic.INVOKEDYNAMIC; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.MethodGenerator; +import de.dhbwstuttgart.bytecode.TypePlaceholderType; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.myexception.SCStatementException; @@ -26,6 +28,7 @@ import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; +import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.ObjectType; import de.dhbwstuttgart.syntaxtree.type.RefType; @@ -34,7 +37,6 @@ import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.WildcardType; import de.dhbwstuttgart.typeinference.ConstraintsSet; -import de.dhbwstuttgart.typeinference.FunN; import de.dhbwstuttgart.typeinference.FunVoidN; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.OderConstraint; @@ -55,6 +57,12 @@ import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet; */ public class LambdaExpression extends Expr{ + + /** + * Wird bei der TYPE Methode gesetzt. Speichert den errechneten Typ des LambdaAusdrucks + */ + private FunN lambdaType; + private Block method_body; private ParameterList params; @@ -186,10 +194,12 @@ public class LambdaExpression extends Expr{ } } if(typeIsVoid(retType)){//In diesem Fall, muss der Typ des LambdaAusdrucks FunVoid sein - ret.add(new SingleConstraint(new FunVoidN(modifiedParamTypes).TYPE(assumptions, this),this.getType().TYPE(assumptions, this))); + this.lambdaType = new FunVoidN(modifiedParamTypes); }else{ - ret.add(new SingleConstraint(new FunN(retType, modifiedParamTypes).TYPE(assumptions, this),this.getType().TYPE(assumptions, this))); + this.lambdaType = new FunN(retType, modifiedParamTypes); } + ret.add(new SingleConstraint(lambdaType.TYPE(assumptions, this),this.getType().TYPE(assumptions, this))); + return ret; } private boolean typeIsVoid(Type type){ @@ -232,28 +242,44 @@ public class LambdaExpression extends Expr{ ConstantPoolGen cp = cg.getConstantPool(); InstructionList il = new InstructionList(); - - MethodGen lambdaMethod = new MethodGen(0, method_body.getType().getBytecodeType(cg), - params.getBytecodeTypeList(cg), params.getParameterNameArray(), cg.createLambdaMethodName(), + org.apache.commons.bcel6.generic.Type[] paramTypes = params.getBytecodeTypeList(cg); + org.apache.commons.bcel6.generic.Type[] paramTypesTemp = new org.apache.commons.bcel6.generic.Type[paramTypes.length]; + for(int i = 0; i < paramTypes.length ; i++) { + if(paramTypes[i] instanceof TypePlaceholderType){ + //TODO: Das kann auch ein spezifischer Typ als Object sein + paramTypesTemp[i] = cg.getNearestType(((TypePlaceholderType)paramTypes[i]).getTPH()); + }else{ + paramTypesTemp[i] = paramTypes[i]; + } + } + paramTypes = paramTypesTemp; + org.apache.commons.bcel6.generic.Type retType = method_body.getType().getBytecodeType(cg); + if(retType instanceof TypePlaceholderType){ + //Die TypePlaceholderTypen aussortieren. Sie werden nur in der Signatur erwähnt. Kommen im Bytecode sonst eigentlich nicht vor + retType = cg.getNearestType(((TypePlaceholderType) retType).getTPH()); + } + MethodGenerator lambdaMethod = new MethodGenerator(0, retType, + paramTypes, params.getParameterNameArray(), cg.createLambdaMethodName(), this.getParentClass().getName().toString(), new InstructionList(), cg.getConstantPool()); - lambdaMethod.stripAttributes(true); - lambdaMethod.getInstructionList().append(this.method_body.genByteCode(cg)); + //lambdaMethod.stripAttributes(true); + //lambdaMethod.getInstructionList().append(this.method_body.genByteCode(cg)); lambdaMethod.setAccessFlags(Constants.ACC_PRIVATE+Constants.ACC_SYNTHETIC); String interfaceMethodName = "apply"; //Das ist ein Hack, funktioniert momentan, da nur FunN Interfaces für LambdaAusdrücke funktionieren il.append(InstructionFactory.createLoad( org.apache.commons.bcel6.generic.Type.OBJECT, 0)); - il.append(cg.getInstructionFactory().createInvokeDynamic(interfaceMethodName,this.getSAMSignature(cg),lambdaMethod)); + il.append(cg.getInstructionFactory().createInvokeDynamic(interfaceMethodName,this.getLambdaSignature(cg),lambdaType,lambdaMethod)); - lambdaMethod.setMaxLocals(); - lambdaMethod.setMaxStack(); - cg.addMethod(lambdaMethod.getMethod()); + cg.addMethod(lambdaMethod.createMethod(cg, params, method_body.getType(), method_body)); return il; } - private String getSAMSignature(ClassGenerator cg){ + private String getLambdaSignature(ClassGenerator cg){ String typeSignature = "("; - return "(LRunnable;)LFun0;"; + typeSignature+=this.getParentClass().getType().getBytecodeSignature(cg); + typeSignature += ")"; + typeSignature += this.lambdaType.getBytecodeSignature(cg); + return typeSignature; } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java index 8d0cb176..22fdf209 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java @@ -17,13 +17,13 @@ import de.dhbwstuttgart.myexception.SCStatementException; import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.misc.UsedId; +import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typeinference.ConstraintsSet; -import de.dhbwstuttgart.typeinference.FunN; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.SingleConstraint; diff --git a/src/de/dhbwstuttgart/typeinference/FunN.java b/src/de/dhbwstuttgart/syntaxtree/type/FunN.java similarity index 93% rename from src/de/dhbwstuttgart/typeinference/FunN.java rename to src/de/dhbwstuttgart/syntaxtree/type/FunN.java index ec84c8e9..23ae14d9 100755 --- a/src/de/dhbwstuttgart/typeinference/FunN.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/FunN.java @@ -1,16 +1,12 @@ -package de.dhbwstuttgart.typeinference; +package de.dhbwstuttgart.syntaxtree.type; import java.util.Iterator; import de.dhbwstuttgart.typeinference.Menge; - +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.ParameterList; -import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; -import de.dhbwstuttgart.syntaxtree.type.RefType; -import de.dhbwstuttgart.syntaxtree.type.Type; -import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; @@ -120,6 +116,17 @@ public class FunN extends RefType { return 0; } + public String getBytecodeInvokeDynamicSignature(ClassGenerator cg) { + String ret = "("; + for(Type t : T){ + ret+=t.getBytecodeMethodSignature(cg); + } + ret +=")"; + ret+= R.getBytecodeMethodSignature(cg); + return ret; + } + + /* public CMethodTypeAssumption toCMethodTypeAssumption() { //CMethodTypeAssumption ret = new CMethodTypeAssumption(this, "apply", R, this.T.size(), 0,this.getOffset(),new Menge(),null); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index f444b601..4c09c990 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -818,23 +818,28 @@ public class RefType extends ObjectType implements IMatchable } @Override - public String getBytecodeSignature(ClassGenerator cg) { + public String getBytecodeMethodSignature(ClassGenerator cg) { String paramString = ""; if(this.parameter != null && this.parameter.size()>0){ paramString+="<"; Iterator it = this.parameter.iterator(); while(it.hasNext()){ Type param = it.next(); - paramString+=param.getBytecodeType(cg).getSignature(); + paramString+=param.getBytecodeMethodSignature(cg); //if(it.hasNext()) //paramString+=";"; //kein Delimiter zwischen den Typen } paramString+=">"; } - String typeSignature = this.getBytecodeType(cg).getSignature(); + String typeSignature = this.getBytecodeSignature(cg); typeSignature = typeSignature.substring(0, typeSignature.length()-1); return typeSignature+paramString+";"; } + + @Override + public String getBytecodeSignature(ClassGenerator cg) { + return this.getBytecodeType(cg).getSignature(); + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java index bacd1cbe..34f3527f 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java @@ -159,4 +159,14 @@ public class SuperWildcardType extends WildcardType implements ITypeContainer, I return new de.dhbwstuttgart.bytecode.WildcardType(this.innerType.get_Name(), "-"); } + @Override + public String getBytecodeSignature(ClassGenerator cg) { + return this.innerType.getBytecodeSignature(cg); + } + + @Override + public String getBytecodeMethodSignature(ClassGenerator cg) { + return "-" + this.innerType.getBytecodeMethodSignature(cg); + } + } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/Type.java b/src/de/dhbwstuttgart/syntaxtree/type/Type.java index 6f2d83e6..8bec8732 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/Type.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/Type.java @@ -310,5 +310,13 @@ public abstract class Type extends SyntaxTreeNode implements IItemWithOffset public String getBytecodeSignature(ClassGenerator cg) { return this.getBytecodeType(cg).getSignature(); } + + public String getBytecodeMethodSignature(ClassGenerator cg) { + return this.getBytecodeSignature(cg); + } + + public String getClassSignature(ClassGenerator cg) { + return this.getBytecodeMethodSignature(cg); + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java index 91065f4c..4fff8991 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java @@ -434,10 +434,34 @@ public class TypePlaceholder extends ObjectType public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) { Type resolvedType = cg.resolveTPH(this); if(resolvedType instanceof TypePlaceholder){ - return new TypePlaceholderType(resolvedType.get_Name()); + cg.addUsedTPH((TypePlaceholder)resolvedType); + return new TypePlaceholderType((TypePlaceholder)resolvedType); } return resolvedType.getBytecodeType(cg); } + + @Override + public String getBytecodeSignature(ClassGenerator cg) { + return cg.resolveTPH(this).getBytecodeMethodSignature(cg); + } + + public String getBytecodeMethodSignature(ClassGenerator cg) { + return super.getBytecodeSignature(cg); + } + + @Override + public String getClassSignature(ClassGenerator cg) { + //Die Signaturen in der Klasse bauen sich für Generische Variabeln (also TPHs) folgendermaßen auf: "GVAR:SuperClass" + String ret = this.getBytecodeMethodSignature(cg); + ret = ret.substring(0, ret.length()-1) + ":"; //";" mit ":" ersetzen + org.apache.commons.bcel6.generic.Type nearestType = cg.getNearestType(this); + if(nearestType instanceof TypePlaceholderType){ //Handelt es sich um einen weiteren TPH als nächsten Typ, so ist es ein allgemeiner Typ und wir nehmen Object als Superklasse + ret += cg.getInstructionFactory().createObjectType().getSignature(); + }else{ + ret += nearestType.getSignature(); + } + return ret; + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/type/Void.java b/src/de/dhbwstuttgart/syntaxtree/type/Void.java index 8e575dff..2bd17d76 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/Void.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/Void.java @@ -85,5 +85,12 @@ public class Void extends RefType return org.apache.commons.bcel6.generic.Type.VOID; } + public String getBytecodeSignature(ClassGenerator cg) { + return this.getBytecodeType(cg).getSignature(); + } + + public String getBytecodeMethodSignature(ClassGenerator cg) { + return this.getBytecodeSignature(cg); + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java index e94f4a05..a2d35abf 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/WildcardType.java @@ -105,6 +105,17 @@ public class WildcardType extends Type{ return this.innerType.getBytecodeType(cg); } + @Override + public String getBytecodeSignature(ClassGenerator cg) { + return this.innerType.getBytecodeMethodSignature(cg); + } + + @Override + public String getBytecodeMethodSignature(ClassGenerator cg) { + return this.innerType.getBytecodeMethodSignature(cg); + } + + } diff --git a/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java b/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java index ec127bec..c036b5da 100644 --- a/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java +++ b/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java @@ -1,5 +1,8 @@ package de.dhbwstuttgart.typeinference; +import java.io.File; +import java.io.IOException; + import org.apache.commons.bcel6.generic.ClassGen; import de.dhbwstuttgart.typeinference.Menge; @@ -47,4 +50,11 @@ public class ByteCodeResult{ return true; } + /** + * Schreibt den Bytecode in die übergebene .class Datei + * @throws IOException + */ + public void writeClassToFile(File output) throws IOException{ + this.getByteCode().getJavaClass().dump(output); + } } diff --git a/src/de/dhbwstuttgart/typeinference/FunVoidN.java b/src/de/dhbwstuttgart/typeinference/FunVoidN.java index a48d36e2..2adfd1c5 100644 --- a/src/de/dhbwstuttgart/typeinference/FunVoidN.java +++ b/src/de/dhbwstuttgart/typeinference/FunVoidN.java @@ -7,6 +7,7 @@ import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; diff --git a/src/de/dhbwstuttgart/typeinference/Menge.java b/src/de/dhbwstuttgart/typeinference/Menge.java index aa2b2f43..86c2a2eb 100644 --- a/src/de/dhbwstuttgart/typeinference/Menge.java +++ b/src/de/dhbwstuttgart/typeinference/Menge.java @@ -3,7 +3,20 @@ package de.dhbwstuttgart.typeinference; import java.util.Set; import java.util.Vector; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + public class Menge extends Vector implements Set{ + public interface Equal{ + boolean equal(A a, A b); + } + + public boolean contains(A item, Equal eq) { + for(A test : this){ + if(eq.equal(item, test))return true; + } + return false; + } + } diff --git a/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java b/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java index f8fd20c8..8ceb950a 100755 --- a/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java @@ -115,8 +115,9 @@ public class TypeinferenceResultSet * Startet die Bytecodegenerierung dieser Lösung. * Dabei wird die codegen-Methode der inferierten Klasse mit diesem ResultSet aufgerufen. */ - public void codegen(){ - //TODO: Alles! + public ByteCodeResult codegen(){ + ByteCodeResult res = this.ownerOfResultSet.genByteCode(this); + return res; } } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java index 96a6cd8b..2c68bd87 100755 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeAssumptions.java @@ -10,12 +10,12 @@ import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; +import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.WildcardType; -import de.dhbwstuttgart.typeinference.FunN; import de.dhbwstuttgart.typeinference.FunNInterface; import de.dhbwstuttgart.typeinference.FunNMethod; import de.dhbwstuttgart.typeinference.exceptions.DebugException; diff --git a/test/bytecode/Identity.jav b/test/bytecode/Identity.jav index 0c5443cc..28bdd3d1 100644 --- a/test/bytecode/Identity.jav +++ b/test/bytecode/Identity.jav @@ -1,5 +1,4 @@ class Identity{ - op = (x)->x; } \ No newline at end of file diff --git a/test/bytecode/Return.jav b/test/bytecode/Return.jav index 36976731..7486dc49 100644 --- a/test/bytecode/Return.jav +++ b/test/bytecode/Return.jav @@ -1,7 +1,7 @@ class Return{ Integer method() { - return 5; + return 6; } diff --git a/test/bytecode/Test.java b/test/bytecode/Test.java index 1e879e4a..b09181bb 100644 --- a/test/bytecode/Test.java +++ b/test/bytecode/Test.java @@ -10,5 +10,6 @@ public static void main(String[] args){ System.out.println(new FieldDeclaration().field); System.out.println(new Runnable().method().apply()); Runnable r = new Runnable().method().apply(); + //Test t = new Identity().op.apply(this); } }