Umstieg auf BCEL6 SourceCode. Einführen von DHBWInstructionFactory

This commit is contained in:
JanUlrich 2015-09-10 16:21:30 +02:00
parent ccd25ab865
commit bfe6b03605
16 changed files with 255 additions and 51 deletions

View File

@ -8,7 +8,7 @@
<classpathentry kind="lib" path="lib/junit-4.0.jar" sourcepath="/home/janulrich/.m2/repository/junit/junit/4.0/junit-4.0-sources.jar"/>
<classpathentry kind="lib" path="lib/cloning.jar"/>
<classpathentry kind="lib" path="lib/guava-10.0.1.jar"/>
<classpathentry kind="lib" path="lib/commons-bcel6-6.0-SNAPSHOT.jar"/>
<classpathentry kind="lib" path="lib/commons-bcel6-6.0-SNAPSHOT.jar" sourcepath="/home/janulrich/Development/intellijworkspace/bcel/src/main/java"/>
<classpathentry kind="lib" path="lib/bcel-6.0-SNAPSHOT.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -29,6 +29,7 @@ public class JavaToBCEL {
new BCELifier(new ClassParser(rootDirectory+"MethodCall.class").parse(), new FileOutputStream(new File(rootDirectory+"MethodCallCreator.java"))).start();
new BCELifier(new ClassParser(rootDirectory+"FieldDeclaration.class").parse(), new FileOutputStream(new File(rootDirectory+"FieldDeclarationCreator.java"))).start();
new BCELifier(new ClassParser(rootDirectory+"Null.class").parse(), new FileOutputStream(new File(rootDirectory+"NullCreator.java"))).start();
new BCELifier(new ClassParser(rootDirectory+"LocalVarAccess.class").parse(), new FileOutputStream(new File(rootDirectory+"LocalVarAccessCreator.java"))).start();
} catch (ClassFormatException | IOException e) {
e.printStackTrace();

View File

@ -0,0 +1,10 @@
package bcelifier;
public class LocalVarAccess {
Integer methode(Integer i){
Integer var;
var = 10 + i;
return var;
}
}

View File

@ -0,0 +1,61 @@
package bcelifier;
import org.apache.commons.bcel6.generic.*;
import org.apache.commons.bcel6.classfile.*;
import org.apache.commons.bcel6.*;
import java.io.*;
public class LocalVarAccessCreator implements Constants {
private InstructionFactory _factory;
private ConstantPoolGen _cp;
private ClassGen _cg;
public LocalVarAccessCreator() {
_cg = new ClassGen("bcelifier.LocalVarAccess", "java.lang.Object", "LocalVarAccess.java", ACC_PUBLIC | ACC_SUPER, new String[] { });
_cp = _cg.getConstantPool();
_factory = new InstructionFactory(_cg, _cp);
}
public void create(OutputStream out) throws IOException {
createMethod_0();
createMethod_1();
_cg.getJavaClass().dump(out);
}
private void createMethod_0() {
InstructionList il = new InstructionList();
MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] { }, "<init>", "bcelifier.LocalVarAccess", il, _cp);
InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
il.append(_factory.createInvoke("java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID));
method.setMaxStack();
method.setMaxLocals();
_cg.addMethod(method.getMethod());
il.dispose();
}
private void createMethod_1() {
InstructionList il = new InstructionList();
MethodGen method = new MethodGen(0, new ObjectType("java.lang.Integer"), new Type[] { new ObjectType("java.lang.Integer") }, new String[] { "arg0" }, "methode", "bcelifier.LocalVarAccess", il, _cp);
InstructionHandle ih_0 = il.append(new PUSH(_cp, 10));
il.append(_factory.createLoad(Type.OBJECT, 1));
il.append(_factory.createInvoke("java.lang.Integer", "intValue", Type.INT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
il.append(InstructionConstants.IADD);
il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
il.append(_factory.createStore(Type.OBJECT, 2));
InstructionHandle ih_11 = il.append(_factory.createLoad(Type.OBJECT, 2));
InstructionHandle ih_12 = il.append(_factory.createReturn(Type.OBJECT));
method.setMaxStack();
method.setMaxLocals();
_cg.addMethod(method.getMethod());
il.dispose();
}
public static void main(String[] args) throws Exception {
bcelifier.LocalVarAccessCreator creator = new bcelifier.LocalVarAccessCreator();
creator.create(new FileOutputStream("bcelifier.LocalVarAccess.class"));
}
}

View File

@ -1,5 +1,7 @@
package de.dhbwstuttgart.bytecode;
import org.apache.commons.bcel6.classfile.InnerClass;
import org.apache.commons.bcel6.classfile.InnerClasses;
import org.apache.commons.bcel6.generic.ClassGen;
import org.apache.commons.bcel6.generic.ConstantPoolGen;
@ -7,16 +9,22 @@ import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
public class ClassGenerator extends ClassGen{
private DHBWInstructionFactory factory = new DHBWInstructionFactory(this, this.getConstantPool());
private DHBWConstantPoolGen cp;
private DHBWInstructionFactory factory;
private TypeinferenceResultSet tiResult;
private int lambdaMethodeNr = 0;
public ClassGenerator(String name, String get_Name, String string,
short accPublic, String[] strings, TypeinferenceResultSet resultSet) {
super(name,get_Name,string,accPublic,strings);
super(name,get_Name,string,accPublic,strings, new DHBWConstantPoolGen());
this.tiResult = resultSet;
cp = (DHBWConstantPoolGen) super.getConstantPool();
factory = new DHBWInstructionFactory(this, cp);
}
public DHBWInstructionFactory getInstructionFactory() {
@ -27,4 +35,29 @@ public class ClassGenerator extends ClassGen{
return tiResult.getTypeOfPlaceholder(typePlaceholder);
}
public String createLambdaMethodName() {
return "lambda$methode$"+(lambdaMethodeNr++);
}
@Override
public DHBWConstantPoolGen getConstantPool(){
return this.cp;
}
@Override
public void setConstantPool(ConstantPoolGen gen){
throw new DebugException("Ungültige Operation. ClassGenerator muss ein DHBWConstantPool besitzen");
}
/**
* Anmerkung: Kann in diesem Zustand nur einmal aufgerufen werden.
* @param innerClassAttribute
*/
public void addInnerClass(InnerClass innerClassAttribute) {
//TODO: Muss vor dem ausführen von getJavaClass ausgeführt werden. getJavaClass überschreiben!
InnerClass[] innerClasses = new InnerClass[1];
innerClasses[0] = innerClassAttribute;
int innerClassesUTF8 = this.getConstantPool().addUtf8("InnerClassses");
this.addAttribute(new InnerClasses(innerClassesUTF8,1,innerClasses,this.getConstantPool().getConstantPool()));
}
}

View File

@ -0,0 +1,35 @@
package de.dhbwstuttgart.bytecode;
import java.util.HashMap;
import org.apache.commons.bcel6.classfile.Constant;
import org.apache.commons.bcel6.classfile.ConstantMethodHandle;
import org.apache.commons.bcel6.classfile.ConstantMethodType;
import org.apache.commons.bcel6.generic.ConstantPoolGen;
public class DHBWConstantPoolGen extends ConstantPoolGen{
private static final long serialVersionUID = -8282768548793548585L;
private final HashMap<Constant, Integer> constantTable = new HashMap<>();
//private static final String DELIMITER = "$";
/*
public int addConstantMethodType(ConstantMethodType methodType) {
if(constantTable.containsKey(methodType))return constantTable.get(methodType);
}
public int addConstantMethodHandle(ConstantMethodHandle methodHandle) {
if(constantTable.containsKey(methodHandle))return constantTable.get(methodHandle);
int ret = this.index;
return ret;
}
*/
public int addConstant(Constant c){
if(constantTable.containsKey(c))return constantTable.get(c);
int ret = this.index;
this.constants[this.index++] = c;
constantTable.put(c, ret);
return ret;
}
}

View File

@ -6,24 +6,28 @@ import java.util.ArrayList;
import org.apache.commons.bcel6.Constants;
import org.apache.commons.bcel6.classfile.BootstrapMethod;
import org.apache.commons.bcel6.classfile.ConstantInvokeDynamic;
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.generic.ClassGen;
import org.apache.commons.bcel6.generic.ConstantPoolGen;
import org.apache.commons.bcel6.generic.INVOKEDYNAMIC;
import org.apache.commons.bcel6.generic.InstructionFactory;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.LocalVariableInstruction;
import org.apache.commons.bcel6.generic.MethodGen;
import org.apache.commons.bcel6.generic.Type;
public class DHBWInstructionFactory extends InstructionFactory{
public DHBWInstructionFactory(ClassGen cg, ConstantPoolGen cp) {
super(cg, cp);
}
private DHBWConstantPoolGen cp;
private ClassGenerator cg;
private BootstrapMethod createBootstrapMethod(){
//TODO
return null;
public DHBWInstructionFactory(ClassGenerator cg, DHBWConstantPoolGen cp) {
super(cg, cp);
this.cp = cp;
this.cg = cg;
}
public INVOKEDYNAMIC createInvokeDynamic( MethodGen lambdaMethod ) {
@ -38,11 +42,22 @@ public class DHBWInstructionFactory extends InstructionFactory{
* #19 ()V
*
* #20 ist ein MethodHandle_info Structure
* TODO: Rausfinden, was es mit den Argumenten auf sich hat:
* -> Das sind Informationen die die Lambda Funktion zum Ausführen benötigt. (This-Referenz, Variablen, welche vom Lambda Ausdruck benutzt werden)
* Anmerkung: Bei der momentanen Implementierung der Lambda Ausdrücke wird nur this übergeben.
* Die Argumente werden der Bootstrap Methode beim Aufrufen übergeben: @see https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html#metafactory-java.lang.invoke.MethodHandles.Lookup-java.lang.String-java.lang.invoke.MethodType-java.lang.invoke.MethodType-java.lang.invoke.MethodHandle-java.lang.invoke.MethodType-
* TODO: Die korrekten Argumente anfügen.
* - samMethodType - Signature and return type of method to be implemented by the function object.
* - implMethod - A direct method handle describing the implementation method which should be called (with suitable adaptation of argument types, return types, and with captured arguments prepended to the invocation arguments) at invocation time.
* - instantiatedMethodType - The signature and return type that should be enforced dynamically at invocation time. This may be the same as samMethodType, or may be a specialization of it.
*/
ConstantMethodType lambdaMethodType = new ConstantMethodType(this.cp.addUtf8(lambdaMethod.getSignature()));
int implMethodKind = 7; // 7 = InvokeSpecial @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.5
ConstantMethodHandle implMethod = new ConstantMethodHandle(implMethodKind,cg.getConstantPool().addMethodref(lambdaMethod)); //Das zweite Argument ist der MethodRef zur LambdaMethode
//Argumentliste für die Bootstrap Methode zusammensetzen:
arguments.add(cp.addConstant(lambdaMethodType));
arguments.add(cp.addConstant(implMethod));
arguments.add(cp.addConstant(lambdaMethodType));
int innerClassIndex = cp.addClass("java.lang.invoke.MethodHandles$Lookup");
int innerClassName = cp.addUtf8("Lookup");
@ -52,6 +67,7 @@ public class DHBWInstructionFactory extends InstructionFactory{
InnerClass innerClassAttribute = new InnerClass(innerClassIndex, outerClassIndex, innerClassName,accessFlags);
//Diese InnereKlasse muss später im ClassFile vorkommen, da sie von der Bootstrap Methode benutzt wird.
//TODO: Dies kann man möglicherweise auslagern. Die ClassGen Klasse erweiter, welche sich dann die InnerenKlassen mertk, welche gebraucht werden
cg.addInnerClass(innerClassAttribute);
String bootstrapSignature = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;";
int lambdaMethodIndex = cp.addMethodref("java.lang.invoke.LambdaMetafactory", "metafactory", bootstrapSignature);
@ -62,18 +78,7 @@ public class DHBWInstructionFactory extends InstructionFactory{
}
BootstrapMethod bMethod = new BootstrapMethod(lambdaMethodIndex, arguments.size(), argumentsArray);
final short opcode = 186;
int index;
/*
int nargs = 0;
String signature = Type.getMethodSignature(ret_type, arg_types);
for (int i = 0; i < arg_types.length; i++) {
nargs += arg_types[i].getSize();
}
*/
//index = cp.addInvokeDynamic(bootstrap_index, name, signature);
//Adding invokeDynamic to Constant_Pool:
/*
* Spezifikation: @see https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
@ -87,11 +92,13 @@ public class DHBWInstructionFactory extends InstructionFactory{
/*
*
* TODO: Rausfinden, was es mit der Inneren Klasse auf sich hat
* Was es mit der Inneren Klasse auf sich hat:
* (public static final #48= #47 of #51; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
* Lösung: Ist wohl einfach nur nötig, um die Metafactory durch die Bootstrap-Methode aufzurufen
*
* TODO: Rausfinden was es mit dem NameAndType Eintrag in der InvokeDynamic_info Struktur auf sich hat:
* Für ein Runnable ()->{}; ist es: run:(LLambda3;)Ljava/lang/Runnable;
* Wieso das zusätzliche Argument vom Typ (this)
*
* TODO: bootstrap_methode den Klassenattributen hinzufügen
*
@ -99,13 +106,18 @@ public class DHBWInstructionFactory extends InstructionFactory{
int bootstrap_method_attr_index = bMethod.getBootstrapMethodRef();
//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(lambdaMethod.getName(), lambdaMethod.getType().getSignature());
int name_and_type_index = cp.addNameAndType(lambdaMethod.getName(), lambdaMethod.getSignature());
ConstantInvokeDynamic cInvokeDynamic = new ConstantInvokeDynamic(bootstrap_method_attr_index, name_and_type_index);
index = cp.addConstant(cInvokeDynamic, cp);
index = cp.addConstant(cInvokeDynamic);
return new INVOKEDYNAMIC(index);
}
public LocalVariableInstruction createLoad(org.apache.commons.bcel6.generic.Type bytecodeType, String variableName) {
int index = 1; //TODO: Hier muss ein Logger her, welcher aufzeichnet, an welcher Position welche Variable liegt.
return InstructionFactory.createLoad(bytecodeType, index);
}
}

View File

@ -20,6 +20,8 @@ import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.logger.Section;
import de.dhbwstuttgart.logger.SectionLogger;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.core.AClassOrInterface;
import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.parser.JavaClassName;
@ -75,7 +77,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
*/
public ByteCodeResult genByteCode(TypeinferenceResultSet resultSet) {
InstructionFactory _factory;
ConstantPoolGen _cp;
DHBWConstantPoolGen _cp;
ClassGenerator _cg;
SectionLogger logger = Logger.getSectionLogger(this.getClass().getName(), Section.CODEGEN);
@ -84,7 +86,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
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
_cp = _cg.getConstantPool();
_factory = new InstructionFactory(_cg, _cp);
_factory = new DHBWInstructionFactory(_cg, _cp);
//Die Felder in Methoden Felder und Konstruktoren aufteilen:
Menge<FieldDeclaration> fieldDeclarations = new Menge<>();

View File

@ -11,6 +11,7 @@ import org.apache.commons.bcel6.generic.MethodGen;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
@ -57,7 +58,7 @@ public class Constructor extends Method {
}
public void genByteCode(ClassGenerator cg, InstructionList fieldInitializations){
ConstantPoolGen _cp = cg.getConstantPool();
DHBWConstantPoolGen _cp = cg.getConstantPool();
InstructionList il = new InstructionList(); //sollte nicht new sein sondern aus Block kommen
Class parentClass = this.getParentClass();

View File

@ -18,6 +18,8 @@ import org.apache.commons.bcel6.generic.MethodGen;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.myexception.JVMCodeException;
@ -741,8 +743,8 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
}
public void genByteCode(ClassGenerator cg) {
ConstantPoolGen _cp = cg.getConstantPool();
InstructionFactory _factory = new InstructionFactory(cg, _cp);
DHBWConstantPoolGen _cp = cg.getConstantPool();
DHBWInstructionFactory _factory = new DHBWInstructionFactory(cg, _cp);
InstructionList il = new InstructionList();
Class parentClass = this.getParentClass();
@ -751,7 +753,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
String[] argumentNames = new String[]{};
if(this.parameterlist != null &&
this.parameterlist.size() > 0){
argumentTypes = new org.apache.commons.bcel6.generic.Type[this.parameterlist.size()];
argumentTypes = new org.apache.commons.bcel6.generic.Type[this.parameterlist.size()];
argumentNames = new String[this.parameterlist.size()];
int i = 0;
for(FormalParameter parameter : this.parameterlist){

View File

@ -7,6 +7,7 @@ import de.dhbwstuttgart.typeinference.Menge;
import java.util.Iterator;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
@ -144,5 +145,25 @@ public class ParameterList extends SyntaxTreeNode implements Iterable<FormalPara
return this.formalparameter.size();
}
public org.apache.commons.bcel6.generic.Type[] getBytecodeTypeList(ClassGenerator cg){
org.apache.commons.bcel6.generic.Type[] ret = new org.apache.commons.bcel6.generic.Type[formalparameter.size()];
int i = 0;
for(FormalParameter f : formalparameter){
ret[i] = f.getType().getBytecodeType(cg);
i++;
}
return ret;
}
public String[] getParameterNameArray() {
String[] ret = new String[formalparameter.size()];
int i = 0;
for(FormalParameter f : formalparameter){
ret[i] = f.getIdentifier();
i++;
}
return ret;
}
}
// ino.end

View File

@ -9,6 +9,7 @@ import org.apache.commons.bcel6.generic.ClassGen;
import org.apache.commons.bcel6.generic.ConstantPoolGen;
import org.apache.commons.bcel6.generic.InstructionFactory;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.MethodGen;
import org.apache.commons.bcel6.generic.INVOKEDYNAMIC;
import de.dhbwstuttgart.typeinference.Menge;
@ -230,23 +231,13 @@ public class LambdaExpression extends Expr{
ConstantPoolGen cp = cg.getConstantPool();
InstructionList il = new InstructionList();
/*
* 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;
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));
MethodGen lambdaMethod = new MethodGen(0, method_body.getType().getBytecodeType(cg),
params.getBytecodeTypeList(cg), params.getParameterNameArray(), cg.createLambdaMethodName(),
this.getParentClass().getName().toString(), new InstructionList(), cg.getConstantPool());
il.append(cg.getInstructionFactory().createInvokeDynamic(lambdaMethod));
cg.addMethod(lambdaMethod.getMethod());
return il;
}

View File

@ -5,9 +5,13 @@ package de.dhbwstuttgart.syntaxtree.statement;
import java.util.Enumeration;
import java.util.Hashtable;
import org.apache.commons.bcel6.Constants;
import org.apache.commons.bcel6.generic.ClassGen;
import org.apache.commons.bcel6.generic.InstructionList;
import org.apache.commons.bcel6.generic.ObjectType;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator;
import de.dhbwstuttgart.logger.Logger;
import de.dhbwstuttgart.myexception.CTypeReconstructionException;
import de.dhbwstuttgart.myexception.JVMCodeException;
@ -24,6 +28,7 @@ import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.SingleConstraint;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.unify.CSubstitutionSet;
@ -40,6 +45,7 @@ public class LocalOrFieldVar extends Expr
// ino.attribute.parserlog.25507.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
private boolean isFieldAccess = false;
// ino.method.LocalOrFieldVar.25510.definition
public LocalOrFieldVar(int offset, int variableLength)
@ -117,6 +123,11 @@ public class LocalOrFieldVar extends Expr
Type thisType = thisTypeAssumption.checkTYPE(assumptions, this);
this.setType(thisType);
//ret.add(new Constraint(thisTypeAssumption, this.getTypeVariable()));
//Rausfinden, ob es Feld oder Locale Variable ist:
for(FieldAssumption fAss : assumptions.getFieldVars(this.get_Name())){
if(this.getParentClass().equals(fAss.getParentClass()))this.isFieldAccess = true;
};
return ret;
}
@ -136,9 +147,13 @@ public class LocalOrFieldVar extends Expr
}
@Override
public void genByteCode(ClassGen _cg) {
// TODO Auto-generated method stub
public InstructionList genByteCode(ClassGenerator cg) {
InstructionList il = new InstructionList();
if(this.isFieldAccess){
il.append(cg.getInstructionFactory().createFieldAccess(this.getParentClass().getName().toString(), this.get_Name(), this.getType().getBytecodeType(cg), Constants.GETFIELD));
}
il.append(cg.getInstructionFactory().createLoad(this.getType().getBytecodeType(cg), this.get_Name()));
return il;
}
}

View File

@ -0,0 +1,5 @@
class Runnable{
method() { return ()-> this; }
}

View File

@ -0,0 +1,14 @@
package bytecode;
import org.junit.Test;
public class RunnableTest {
public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
public final static String testFile = "Runnable.jav";
public final static String outputFile = "Runnable.class";
@Test
public void test() {
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
}
}

View File

@ -8,5 +8,6 @@ public static void main(String[] args){
System.out.println(new Return().method());
new MethodCall().method();
System.out.println(new FieldDeclaration().field);
//new Runnable().method().run();
}
}