StackMapTable-Fix

This commit is contained in:
JanUlrich 2016-08-25 19:52:06 +02:00
parent dbe09c237c
commit aa6a6beb93
16 changed files with 202 additions and 34 deletions

Binary file not shown.

Binary file not shown.

View File

@ -157,7 +157,6 @@ public class MyCompiler implements MyCompilerAPI{
FunNInterface funN = new FunNInterface(i);
ret.add(funN.getPublicFieldAssumptions());
}
//Keine FunVoidInterfaces in den Assumptions.
for(int i = 0; i<6; i++){
FunVoidNInterface funN = new FunVoidNInterface(i);
ret.add(funN.getPublicFieldAssumptions());

View File

@ -893,7 +893,6 @@ public class SourceFile
ret.add(funN.getPublicFieldAssumptions());
}
return ret; //TODO: Diese TypeAssumptions mit basic-Assumptions ¼llen
}
// ino.end
@ -1030,13 +1029,11 @@ public class SourceFile
//for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this);
}
@Override
public SyntaxTreeNode getParent() {
return null;
}
@Override
public Menge<SyntaxTreeNode> getChildren() {
Menge<SyntaxTreeNode> ret = new Menge<SyntaxTreeNode>();
@ -1046,7 +1043,6 @@ public class SourceFile
return ret;
}
/**
* SourceFile stellt eine geparste Java-Datei dar. Mit dieser Methode wird der Name der eingelesenen Datei gesetzt.
* @param filename - Der Name der eingelesenen JavaDatei
@ -1056,16 +1052,12 @@ public class SourceFile
//this.filename = filename;
}
@Override
public int getOffset() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getVariableLength() {
// TODO Auto-generated method stub

View File

@ -235,10 +235,13 @@ public class LambdaExpression extends Expr{
il.append(var.createLoad(cg, rs)); //Hier kann noch der cg vom Lambda-Ausdruck verwendet werden
}
}
//Das sind die zusätzlich benötigten Parameter für den invokedynamic aufruf: (hier gehört auch noch das "this" dazu)
org.apache.bcel.generic.Type[] additionalParameters = lambdaMethodParams.getBytecodeTypeList(cg, rs);
for(FormalParameter param : params){
lambdaMethodParams.set_AddParameter(param);
}
//Im Anschluss wird der this Parameter wieder von den LambdaMethodParams entfernt!
lambdaMethodParams.formalparameter.remove(0);
/*
* Generieren der Methode
@ -283,7 +286,7 @@ public class LambdaExpression extends Expr{
int innerClassName = cp.addUtf8("Lookup");
int outerClassIndex = cp.addClass("java.lang.invoke.MethodHandles");
int accessFlags = Constants.ACC_FINAL + Constants.ACC_STATIC + Constants.ACC_PUBLIC;
int accessFlags = Const.ACC_FINAL + Const.ACC_STATIC + Const.ACC_PUBLIC;
InnerClass innerClassAttribute = new InnerClass(innerClassIndex, outerClassIndex, innerClassName,accessFlags);
cg.addInnerClass(innerClassAttribute);
@ -292,17 +295,11 @@ public class LambdaExpression extends Expr{
*/
String interfaceMethodName = "apply"; //Das ist ein Hack, funktioniert momentan, da nur FunN Interfaces für LambdaAusdrücke funktionieren
String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(lambdaType.getBytecodeType(cg, rs), additionalParameters);
//String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(lambdaType.getBytecodeType(cg, rs), additionalParameters);
String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(new org.apache.bcel.generic.ObjectType("Fun0"), additionalParameters);
il.append(cg.getInstructionFactory().createInvokeDynamic(interfaceMethodName,invokeDynamicType, bMethod));
return il;
}
private String getLambdaSignature(ClassGenerator cg, TypeinferenceResultSet rs){
String typeSignature = "(";
typeSignature+=this.getParentClass().getType().getBytecodeType(cg, rs).getSignature();
typeSignature += ")";
typeSignature += this.lambdaType.getBytecodeType(cg, rs).getSignature();
return typeSignature;
}
}

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import de.dhbwstuttgart.typeinference.FunNInterface;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.bytecode.ClassGenerator;
@ -152,22 +153,10 @@ public class FunN extends RefType {
return ret;
}
/*
public CMethodTypeAssumption toCMethodTypeAssumption() {
//CMethodTypeAssumption ret = new CMethodTypeAssumption(this, "apply", R, this.T.size(), 0,this.getOffset(),new Menge<Integer>(),null);
MethodAssumption ret = null;
Method method = new Method();
method.set_Method_Name(this.getName());
ParameterList paraList = new ParameterList();
method.setParameterList(this.get_ParaList().clone());
for(Type t : T){
//ret.addParaAssumption(TypeAssumptions.createCParaTypeAssumption(t.get_Name(), t));
}
return ret;
public FunNInterface getCorrespondingInterface(){
return null;
}
*/
/*
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet){

3
test/bytecode/Fun0.java Normal file
View File

@ -0,0 +1,3 @@
interface Fun0<A>{
A apply();
}

View File

@ -3,7 +3,7 @@ class LambdaExpr {
void method() {
lambda;
lambda = ()-> 1;
lambda = () -> 1;
}
}

View File

@ -0,0 +1,7 @@
class LambdaRunnable {
op = ()->method();
void method() {
}
}

View File

@ -0,0 +1,40 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Ignore;
import org.junit.Test;
import plugindevelopment.TypeInsertTester;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class LambdaRunnableTest extends SourceFileBytecodeTest{
@Override
protected void init() {
testName = "LambdaRunnable";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
}
@Test
public void testConstruct() throws Exception{
ClassLoader classLoader = getClassLoader();
Class cls = classLoader.loadClass(testName);
Object obj = cls.newInstance();
assertTrue(true);
}
}

16
test/bytecode/OL.jav Executable file
View File

@ -0,0 +1,16 @@
class OL {
m(Integer x) { return x + x; }
m(Boolean x) {return x || x; }
}
class Main {
main(x) {
ol;
ol = new OL();
return ol.m(x);
}
}

39
test/bytecode/OLTest.java Normal file
View File

@ -0,0 +1,39 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Test;
import plugindevelopment.TypeInsertTester;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.core.MyCompilerAPI;
import de.dhbwstuttgart.logger.LoggerConfiguration;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.parser.JavaParser.yyException;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
public class OLTest extends SourceFileBytecodeTest{
@Override
protected void init() {
testName = "OL";
rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
}
@Test
public void testConstruct() throws Exception{
ClassLoader classLoader = getClassLoader();
Class cls = classLoader.loadClass(testName);
Object obj = cls.newInstance();
assertTrue(true);
}
}

6
test/bytecode/Test.java Normal file
View File

@ -0,0 +1,6 @@
class Test{
public static void main(String[] args){
System.out.println(new Main().main(true));
new LambdaExpr().method();
}
}

8
test/bytecode/asdf.java Normal file
View File

@ -0,0 +1,8 @@
class ASDFTest{
public static void main(String[] args){
VariableMultimethods test = new VariableMultimethods();
System.out.println(test.method(test.method(1,2),test.method(3),0));
}
}

View File

@ -0,0 +1,66 @@
package bytecode.stackmaptable;
import junit.framework.TestCase;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.StackMapTableGen;
import java.util.List;
public class StackMapTableGenTests extends TestCase {
public static class StackMapTableTest {
public void method1(){}
Integer method2(Boolean b){
if(b){
return 1;
}else{
return 2;
}
}
public static void staticMethod1(){
int a = 1;
int b = 2;
while(true){
a = b;
}
}
}
private MethodGen getMethod(Class<?> cls, String name) throws ClassNotFoundException {
JavaClass jc = Repository.lookupClass(cls);
ConstantPoolGen cp = new ConstantPoolGen(jc.getConstantPool());
for (Method method : jc.getMethods()) {
if (method.getName().equals(name)) {
return new MethodGen(method, jc.getClassName(), cp);
}
}
fail("Method " + name + " not found in class " + cls);
return null;
}
public void testFrameSplittingTrivial() throws Exception{
MethodGen mg = getMethod(StackMapTableTest.class, "method1");
StackMapTableGen sg = new StackMapTableGen(mg,mg.getConstantPool());
List blocks = sg.splitIntoBlocks(mg.getInstructionList(), mg.getConstantPool());
assertTrue(blocks.size() == 1); //There is only one frame, because the method1 is empty
}
public void testStaticMethods() throws Exception{
MethodGen mg = getMethod(StackMapTableTest.class, "staticMethod1");
StackMapTableGen sg = new StackMapTableGen(mg,mg.getConstantPool());
try{
StackMap stackMap = sg.getStackMap();
assertTrue(stackMap.getStackMap().length > 0);
}catch(Exception e){
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,6 @@
class Test{
public static void main(String[] args){
System.out.println(new IfStatement().methode(true));
System.out.println(new IfStatement().methode(false));
}
}