From 2d8adb5c696e69b1aa88089bbba951d569f4dc56 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 26 Aug 2015 14:48:51 +0200 Subject: [PATCH] =?UTF-8?q?Beginn=20der=20Implementierung=20von=20Bytecode?= =?UTF-8?q?=20f=C3=BCr=20Lambda=20Expression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 5 ++-- src/de/dhbwstuttgart/syntaxtree/Class.java | 4 ++-- .../dhbwstuttgart/syntaxtree/Constructor.java | 5 +++- .../dhbwstuttgart/syntaxtree/SourceFile.java | 2 +- .../syntaxtree/SyntaxTreeNode.java | 6 +++-- .../syntaxtree/misc/ConstructorCall.java | 15 ++++++++---- .../statement/LambdaExpression.java | 24 ++++++++++++------- .../syntaxtree/statement/MethodCall.java | 4 +++- .../syntaxtree/statement/SuperCall.java | 3 +++ .../syntaxtree/statement/This.java | 13 +++++++--- .../TypeInsertTests/LambdaTest16.jav | 1 - .../LambdaTest2_2.java | 3 ++- 12 files changed, 58 insertions(+), 27 deletions(-) rename test/plugindevelopment/TypeInsertTests/{ => LargeSourceCodeTests}/LambdaTest2_2.java (83%) diff --git a/.classpath b/.classpath index a66c92d7..b02a00af 100755 --- a/.classpath +++ b/.classpath @@ -1,12 +1,13 @@ - + + - + diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index d00cca51..e2dec91b 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -1227,10 +1227,10 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I //Alle Methoden auf Konstruktoren durchsuchen und diese umwandeln: Menge tempFields = new Menge(); for(Field f : this.getFields()){ - if(f instanceof Method && !(f instanceof Constructor)){ + if(f instanceof Method && !(f instanceof Constructor)){ //Der Check, ob f ein Konstruktor ist eigentlich obsolet, da der Parser keinen Konstruktor generiert Method method = (Method)f; if(method.get_Method_Name().equals(this.getName().toString()) ){ - tempFields.add(new Constructor(method)); + tempFields.add(new Constructor(method, this)); }else{ tempFields.add(f); } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index e8f651b8..cf592857 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -38,11 +38,12 @@ public class Constructor extends Method { * Parser kann nicht zwischen einem Konstruktor und einer Methode unterscheiden. * Diese Klasse beherbegt den als Methode geparsten Konstruktor und wandelt sein verhalten zu dem eines Konstruktors ab. */ - public Constructor(Method methode){ + public Constructor(Method methode, Class parent){ super(methode.get_Method_Name(), methode.getType(), methode.getParameterList(),methode.get_Block(), methode.getGenericDeclarationList(), methode.getOffset()); //Sicherstellen, dass das erste Statement in der Methode ein SuperCall ist: if(this.get_Block().get_Statement().size() <1 || ! (this.get_Block().get_Statement().firstElement() instanceof SuperCall)){ this.get_Block().statements.add(0, new SuperCall(this.get_Block())); + this.parserPostProcessing(parent); } } @Override @@ -121,6 +122,8 @@ public class Constructor extends Method { return this.getType().getName(); } + + } /* diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 40e96d38..1210078c 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -1779,7 +1779,7 @@ public class SourceFile @Override public void parserPostProcessing(SyntaxTreeNode parent) { if(parent!=null)throw new DebugException("Eine SourceFile hat kein Elternelement im Syntaxbaum"); - super.parserPostProcessing(parent); + super.parserPostProcessing(this); //for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this); } diff --git a/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java b/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java index deb03d89..0d234b61 100644 --- a/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java +++ b/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java @@ -30,12 +30,14 @@ public abstract class SyntaxTreeNode implements IItemWithOffset{ * */ public void parserPostProcessing(SyntaxTreeNode parent) { + if(parent == null)throw new NullPointerException(); this.parent = parent; for(SyntaxTreeNode node : this.getChildren()) if(node!=null)node.parserPostProcessing(this); } public SyntaxTreeNode getParent() { + //if(this.parent == null)throw new NullPointerException(); return this.parent; } @@ -123,10 +125,10 @@ public abstract class SyntaxTreeNode implements IItemWithOffset{ } public GTVDeclarationContext getGTVDeclarationContext(){ - if(this.getParent()==null)return null; + if(this.getParent()==null) + throw new NullPointerException();//throw new DebugException("getGTVDeclarationContext auf unzulässiger Klasse aufgerufen"); return this.getParent().getGTVDeclarationContext(); } - } diff --git a/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java b/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java index 3ef7c81d..b772db27 100644 --- a/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.syntaxtree.misc; +import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.statement.MethodCall; import de.dhbwstuttgart.syntaxtree.statement.Receiver; @@ -16,10 +17,10 @@ import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; public class ConstructorCall extends MethodCall { public ConstructorCall(Receiver receiver, String methodName, ArgumentList argumentList, int offset){ - super(offset, 0); - this.set_Receiver(receiver); - this.set_Name(methodName); - this.set_ArgumentList(argumentList); + super(receiver, methodName, argumentList,offset); + //this.set_Receiver(receiver); + //this.set_Name(methodName); + //this.set_ArgumentList(argumentList); } /* @@ -38,4 +39,10 @@ public class ConstructorCall extends MethodCall ret.add(constraintsFromMethodAssumption(cAss, assumptions)); return ret; } + + @Override + public void parserPostProcessing(SyntaxTreeNode parent) { + super.parserPostProcessing(parent); + } + } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java index 62c3c761..3f9e747f 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.syntaxtree.statement; import java.util.Hashtable; +import org.apache.bcel.classfile.BootstrapMethod; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.generic.BIPUSH; import org.apache.bcel.generic.ClassGen; @@ -217,20 +218,25 @@ public class LambdaExpression extends Expr{ public InstructionList genByteCode(ClassGen cg) { ConstantPoolGen cp = cg.getConstantPool(); InstructionList il = new InstructionList(); + /* - * Bytecode: - * 0: invokedynamic #2, 0 //#2 führt zu einem InvokeDynamic im KP - wildes Referenzieren - * 5: astore_1 //Speichert wahrscheinlich den String meiner TestEXPR - * 6: return + * Invokedynamic 186 (0xBA) + * - Auf dem Operanten Stack liegen die Argumente + * + * InvokeDynamik_Info Structure auf den der Indexzeiger zeigen muss: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10 + * + * Ablauf: + * 1. Methode erstellen, mit dem Inhalt der Lambda-Expression //Dabei wird das This-Stat + * 2. Invokedynamic-Call erzeugen + * */ + new BootstrapMethod(); //---Variante 1 mit opcode---- - short opcode = 186;//opcode - was genau ist das? - il.append(new INVOKEDYNAMIC(opcode, 0));//Invokedynamic lässt sich bei mir weder automatisch noch manuell importieren + short opcode = 186; + int index = 0; //indexbyte 1 und 2 müssen ein Zeiger auf ein call site specifier im Konstantenpool sein (InvokeDynamic_Info). + il.append(new INVOKEDYNAMIC(opcode, index)); - //---Variante 2 mit Konstantenpool-Referenz--- - //int cpSize = cp.getSize()-1;//Vermutlich ist die benötigte Referenz das aktuellste Element? - //il.append(new INVOKEDYNAMIC((short) cpSize, 0)); return il; } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index 45f2716b..1ea8c297 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -299,11 +299,13 @@ public class MethodCall extends Expr return ret; } + /* @Override public void parserPostProcessing(SyntaxTreeNode parent) { super.parserPostProcessing(parent); } - + */ + @Override public InstructionList genByteCode(ClassGen _cg) { // TODO Auto-generated method stub diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java index eea3f491..6b354f2a 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java @@ -65,7 +65,10 @@ public class SuperCall extends ThisCall ((Constructor)p).get_Block().statements.firstElement().equals(this)){ //Constraints generieren: + if(this.arglist == null)this.arglist = new ArgumentList(); + MethodCall constructorCall = new ConstructorCall(new Receiver(new This(this)), className, arglist, this.getOffset()); + constructorCall.parserPostProcessing(this); ret.add(constructorCall.TYPEStmt(assumptions)); return ret; }else{ diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/This.java b/src/de/dhbwstuttgart/syntaxtree/statement/This.java index dfb5f32a..1f5ed185 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/This.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/This.java @@ -5,6 +5,11 @@ package de.dhbwstuttgart.syntaxtree.statement; import java.util.Hashtable; import org.apache.bcel.generic.ClassGen; +import org.apache.bcel.generic.InstructionFactory; +import org.apache.bcel.generic.InstructionHandle; +import org.apache.bcel.generic.InstructionList; +import org.apache.bcel.generic.MethodGen; +import org.apache.bcel.generic.ObjectType; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.logger.Logger; @@ -143,9 +148,11 @@ public class This extends Expr } @Override - public void genByteCode(ClassGen _cg) { - // TODO Auto-generated method stub - + public InstructionList genByteCode(ClassGen _cg) { + InstructionList il = new InstructionList(); + InstructionHandle ih_0 = il.append(InstructionFactory.createLoad(org.apache.bcel.generic.Type.OBJECT, 0)); + InstructionHandle ih_1 = il.append(InstructionFactory.createReturn(org.apache.bcel.generic.Type.OBJECT)); + return il; } } diff --git a/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav b/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav index 839afeb5..bc58f522 100644 --- a/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav +++ b/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav @@ -1,4 +1,3 @@ class Matrix2{ Fun1>, DF> op = (m)->(f)->{return f.apply(this,m);}; } - \ No newline at end of file diff --git a/test/plugindevelopment/TypeInsertTests/LambdaTest2_2.java b/test/plugindevelopment/TypeInsertTests/LargeSourceCodeTests/LambdaTest2_2.java similarity index 83% rename from test/plugindevelopment/TypeInsertTests/LambdaTest2_2.java rename to test/plugindevelopment/TypeInsertTests/LargeSourceCodeTests/LambdaTest2_2.java index 5503c7fe..662846f1 100644 --- a/test/plugindevelopment/TypeInsertTests/LambdaTest2_2.java +++ b/test/plugindevelopment/TypeInsertTests/LargeSourceCodeTests/LambdaTest2_2.java @@ -1,6 +1,7 @@ -package plugindevelopment.TypeInsertTests; +package plugindevelopment.TypeInsertTests.LargeSourceCodeTests; import de.dhbwstuttgart.typeinference.Menge; +import plugindevelopment.TypeInsertTests.MultipleTypesInsertTester; import org.junit.Test;