diff --git a/notizen/stan/lambdaBytecode/Notizen.md b/notizen/stan/lambdaBytecode/Notizen.md index 661abd82..c234266b 100644 --- a/notizen/stan/lambdaBytecode/Notizen.md +++ b/notizen/stan/lambdaBytecode/Notizen.md @@ -35,3 +35,9 @@ # TODO: * Matrix Beispiel muss funktionieren (verschachtelter Lambda Ausdruck) * Automatisch Bytecode generieren, wenn alle Typen eingesetzt sind + +## StackMapTable +* Attribute für Codeattribut +* Wird für Sprünge im Bytecode benötigt +* Quelle: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.4 + diff --git a/notizen/stan/lambdaBytecode/cat b/notizen/stan/lambdaBytecode/cat deleted file mode 100644 index f886214b..00000000 --- a/notizen/stan/lambdaBytecode/cat +++ /dev/null @@ -1,104 +0,0 @@ -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/notizen/stan/stackmaptable/.Notizen.md.swp b/notizen/stan/stackmaptable/.Notizen.md.swp new file mode 100644 index 00000000..61f9c4c6 Binary files /dev/null and b/notizen/stan/stackmaptable/.Notizen.md.swp differ diff --git a/notizen/stan/stackmaptable/Notizen.md b/notizen/stan/stackmaptable/Notizen.md new file mode 100644 index 00000000..4050403e --- /dev/null +++ b/notizen/stan/stackmaptable/Notizen.md @@ -0,0 +1,10 @@ +# StackMapTable +* Attribute für Codeattribut +* Wird für Sprünge im Bytecode benötigt +* Quelle: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.4 + +## Generierung +* StackMapTable könnte generiert werden, indem im bytecode geschaut wird, wo Sprünge vorliegen. +* https://stackoverflow.com/questions/24927993/what-kind-of-java-code-requires-stackmap-frames#24930521 + * It is illegal to have code after an unconditional branch without a stack map frame being provided for it. + diff --git a/notizen/stan/stackmaptable/StackMapTest.java b/notizen/stan/stackmaptable/StackMapTest.java new file mode 100644 index 00000000..b2e02b35 --- /dev/null +++ b/notizen/stan/stackmaptable/StackMapTest.java @@ -0,0 +1,6 @@ +class StackMapTest{ + +void methode(){ +while(true){} +} +} diff --git a/notizen/stan/stackmaptable/StackMapTest2.java b/notizen/stan/stackmaptable/StackMapTest2.java new file mode 100644 index 00000000..b0851b00 --- /dev/null +++ b/notizen/stan/stackmaptable/StackMapTest2.java @@ -0,0 +1,8 @@ +class StackMapTest2{ + +void methode(){ +Integer i = 1; +while(System.out == null){ +i+=1;} +} +} diff --git a/notizen/stan/stackmaptable/StackMapTest3.java b/notizen/stan/stackmaptable/StackMapTest3.java new file mode 100644 index 00000000..420ac3c6 --- /dev/null +++ b/notizen/stan/stackmaptable/StackMapTest3.java @@ -0,0 +1,14 @@ +class StackMapTest3{ + +void methode(){ +Integer i = 1; +while(System.out == null){ +i+=1; +} +System.out.println(i); +StackMapTest3 o = new StackMapTest3(); +while(i<0){ +i++; +} +} +} diff --git a/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnify.java b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnify.java new file mode 100644 index 00000000..34e39738 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unify/interfaces/IUnify.java @@ -0,0 +1,14 @@ +package de.dhbwstuttgart.typeinference.unify.interfaces; + +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unifynew.Unifier; +import de.dhbwstuttgart.typinference.unify.model.MPair; + +/** + * Standard unification algorithm (e.g. Robinson, Paterson-Wegman, Martelli-Montanari, Ruzicka-Privara or Suciu) + * @author Florian Steurer + */ +public interface IUnify { + public Unifier unify(Set terms); +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java new file mode 100644 index 00000000..3631ed24 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/unifynew/MartelliMontanariUnify.java @@ -0,0 +1,80 @@ +package de.dhbwstuttgart.typeinference.unifynew; + +import java.util.HashSet; +import java.util.Set; + +import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; +import de.dhbwstuttgart.typinference.unify.model.MPair; +import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator; +import de.dhbwstuttgart.typinference.unify.model.Type; +import de.dhbwstuttgart.typinference.unify.model.TypeParams; + +/** + * Implementation of the Martelli-Montanari unification algorithm. + * @author Florian Steurer + */ +public class MartelliMontanariUnify implements IUnify { + + @Override + public Unifier unify(Set terms) { + // TODO Auto-generated method stub + return null; + } + + private boolean delete(MPair pair) { + return pair.getRhsType().equals(pair.getLhsType()); + } + + private Set decompose(MPair pair) { + Set result = new HashSet<>(); + + Type rhs = pair.getRhsType(); + Type lhs = pair.getLhsType(); + + if(!rhs.getName().equals(lhs.getName()) || rhs.getTypeParams().size() != lhs.getTypeParams().size()) + return null; // conflict + + TypeParams rhsTypeParams = rhs.getTypeParams(); + TypeParams lhsTypeParams = lhs.getTypeParams(); + + for(int i = 0; i < rhsTypeParams.size(); i++) + result.add(new MPair(rhsTypeParams.get(i), lhsTypeParams.get(i), PairOperator.EQUALSDOT)); + + return result; + } + + private MPair swap(MPair pair) { + Type rhs = pair.getRhsType(); + Type lhs = pair.getLhsType(); + + if(lhs.getTypeParams().size() != 0 && rhs.getTypeParams().size() == 0) + return new MPair(rhs, lhs, PairOperator.EQUALSDOT); + return pair; + } + + private Unifier eliminate(MPair pair) { + Type rhs = pair.getRhsType(); + Type lhs = pair.getLhsType(); + + TypeParams rhsTypeParams = rhs.getTypeParams(); + + for(Type t : rhsTypeParams) + if(lhs.equals(t)) + return new Unifier(); //identity-"unifier" + + return new Unifier(lhs, rhs); + } + + private boolean check(MPair pair) { + Type rhs = pair.getRhsType(); + Type lhs = pair.getLhsType(); + + TypeParams rhsTypeParams = rhs.getTypeParams(); + + for(Type t : rhsTypeParams) + if(lhs.equals(t)) + return false; + + return true; + } +} diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java index ecd56cf1..4528a934 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unifier.java @@ -13,6 +13,13 @@ public class Unifier implements Function { this.source = source; this.target = target; } + + /** + * Identity function as an "unifier". + */ + public Unifier() { + + } @Override public Type apply(Type t) { diff --git a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java index 33943e85..d8354f53 100644 --- a/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unifynew/Unify.java @@ -54,13 +54,18 @@ public class Unify { List>> pairSetsSet = calculatePairSets(eq2s, fc); // The sets of the "first level" - Set> sets = new HashSet>(); - sets.add(eq1s); // Add Eq1' + Set> sets = new HashSet>(); + + if(eq1s.size() != 0) + sets.add(eq1s); // Add Eq1' // Add the set of [a =. Theta | (a=. Theta) in Eq2'] - sets.add(eq2s.stream() + Set bufferSet = eq2s.stream() .filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType) - .collect(Collectors.toSet())); + .collect(Collectors.toSet()); + + if(bufferSet.size() != 0) + sets.add(bufferSet); /* Up to here, no cartesian products are calculated. * Around here, filters for pairs and sets can be applied */ @@ -69,13 +74,19 @@ public class Unify { // Calculate the inner cartesian products // Cartesian products of the second level + + // AddAll -> nur add for(List> pairSets : pairSetsSet) // Prüfen ob addAll stimmt oder ob hier eigentlich nur 1 set sein sollte - setOps.cartesianProduct(pairSets).forEach(x -> sets.add(new HashSet(x))); + sets.add(setOps.cartesianProduct(pairSets).stream().map(x -> new HashSet<>(x)).collect(Collectors.toSet())); + + System.out.println(sets); // Calculate the outer cartesian products // Cartesian products of the first level - Set> eqsSet = setOps.cartesianProduct(new ArrayList<>(sets)); + Set> eqsSet = setOps.cartesianProduct(new ArrayList<>(sets)); + + System.out.println(eqsSet); /* * Step 5: Substitution */ @@ -90,7 +101,8 @@ public class Unify { * Step 7: Filter result for solved pairs */ - throw new NotImplementedException(); + return null; + } protected Set applyTypeUnificationRules(Set eq, IFiniteClosure fc) { diff --git a/test/unify/UnifyTest.java b/test/unify/UnifyTest.java index 65f94d96..38d5a1b9 100644 --- a/test/unify/UnifyTest.java +++ b/test/unify/UnifyTest.java @@ -25,12 +25,14 @@ public class UnifyTest extends Unify { IFiniteClosure fc = fcb.getCollectionExample(); // Vector <. Vector + // Vector // A <. Number // Double <. B // B <. Object eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "A"), PairOperator.SMALLERDOT)); + eq.add(new MPair(tf.getSimpleType("Vector", tf.getSimpleType("Integer")), tf.getSimpleType("Vector", "C"), PairOperator.SMALLERDOT)); eq.add(new MPair(tf.getPlaceholderType("A"), tf.getSimpleType("Number"), PairOperator.SMALLERDOT)); - eq.add(new MPair(tf.getPlaceholderType("A"), tf.getPlaceholderType("C"), PairOperator.SMALLERDOT)); + //eq.add(new MPair(tf.getPlaceholderType("A"), tf.getPlaceholderType("C"), PairOperator.SMALLERDOT)); eq.add(new MPair(tf.getSimpleType("Double"), tf.getPlaceholderType("B"), PairOperator.SMALLERDOT)); eq.add(new MPair(tf.getPlaceholderType("B"), tf.getSimpleType("Object"), PairOperator.EQUALSDOT));