forked from JavaTX/JavaCompilerCore
Erster zusammengehackter Stand, bei dem Runnable.jav-Test funktioniert
This commit is contained in:
parent
bfe6b03605
commit
a9611fdd90
@ -30,6 +30,7 @@ public class JavaToBCEL {
|
||||
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();
|
||||
new BCELifier(new ClassParser(rootDirectory+"Wildcard.class").parse(), new FileOutputStream(new File(rootDirectory+"WildcardCreator.java"))).start();
|
||||
|
||||
} catch (ClassFormatException | IOException e) {
|
||||
e.printStackTrace();
|
||||
|
5
BCEL/bcelifier/Wildcard.java
Normal file
5
BCEL/bcelifier/Wildcard.java
Normal file
@ -0,0 +1,5 @@
|
||||
package bcelifier;
|
||||
|
||||
public class Wildcard<A> {
|
||||
Wildcard<? super String> a;
|
||||
}
|
50
BCEL/bcelifier/WildcardCreator.java
Normal file
50
BCEL/bcelifier/WildcardCreator.java
Normal file
@ -0,0 +1,50 @@
|
||||
package bcelifier;
|
||||
|
||||
import org.apache.commons.bcel6.generic.*;
|
||||
import org.apache.commons.bcel6.classfile.*;
|
||||
import org.apache.commons.bcel6.*;
|
||||
import java.io.*;
|
||||
|
||||
public class WildcardCreator implements Constants {
|
||||
private InstructionFactory _factory;
|
||||
private ConstantPoolGen _cp;
|
||||
private ClassGen _cg;
|
||||
|
||||
public WildcardCreator() {
|
||||
_cg = new ClassGen("bcelifier.Wildcard", "java.lang.Object", "Wildcard.java", ACC_PUBLIC | ACC_SUPER, new String[] { });
|
||||
|
||||
_cp = _cg.getConstantPool();
|
||||
_factory = new InstructionFactory(_cg, _cp);
|
||||
}
|
||||
|
||||
public void create(OutputStream out) throws IOException {
|
||||
createFields();
|
||||
createMethod_0();
|
||||
_cg.getJavaClass().dump(out);
|
||||
}
|
||||
|
||||
private void createFields() {
|
||||
FieldGen field;
|
||||
|
||||
field = new FieldGen(0, new ObjectType("bcelifier.Wildcard"), "a", _cp);
|
||||
_cg.addField(field.getField());
|
||||
}
|
||||
|
||||
private void createMethod_0() {
|
||||
InstructionList il = new InstructionList();
|
||||
MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] { }, "<init>", "bcelifier.Wildcard", 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();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
bcelifier.WildcardCreator creator = new bcelifier.WildcardCreator();
|
||||
creator.create(new FileOutputStream("bcelifier.Wildcard.class"));
|
||||
}
|
||||
}
|
BIN
lib/bcel-5.2-src.zip
Normal file
BIN
lib/bcel-5.2-src.zip
Normal file
Binary file not shown.
@ -1,5 +1,8 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
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.generic.ClassGen;
|
||||
@ -25,6 +28,8 @@ public class ClassGenerator extends ClassGen{
|
||||
|
||||
cp = (DHBWConstantPoolGen) super.getConstantPool();
|
||||
factory = new DHBWInstructionFactory(this, cp);
|
||||
this.setMajor(52); //Java 8 Version 52.0
|
||||
this.setMinor(0);
|
||||
}
|
||||
|
||||
public DHBWInstructionFactory getInstructionFactory() {
|
||||
@ -55,9 +60,21 @@ public class ClassGenerator extends ClassGen{
|
||||
*/
|
||||
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()));
|
||||
int numberOfInnerClasses = 1;
|
||||
InnerClass[] innerClasses = new InnerClass[numberOfInnerClasses];
|
||||
innerClasses[numberOfInnerClasses-1] = innerClassAttribute;
|
||||
int innerClassesUTF8 = this.getConstantPool().addUtf8("InnerClasses");
|
||||
this.addAttribute(new InnerClasses(innerClassesUTF8,numberOfInnerClasses*8+2,innerClasses,this.getConstantPool().getConstantPool()));
|
||||
}
|
||||
|
||||
public int addBootstrapMethod(BootstrapMethod bMethod) {
|
||||
int numberOfBootstrapMethods = 1;
|
||||
int name_index = this.getConstantPool().addUtf8("BootstrapMethods");
|
||||
int length = 2 + numberOfBootstrapMethods * 4 + bMethod.getNumBootstrapArguments() * 2;
|
||||
BootstrapMethod[] bootstrap_methods = new BootstrapMethod[numberOfBootstrapMethods];
|
||||
bootstrap_methods[numberOfBootstrapMethods-1] = bMethod;
|
||||
BootstrapMethods bootstrapAttribute = new BootstrapMethods(name_index, length, bootstrap_methods, this.getConstantPool().getConstantPool());
|
||||
this.addAttribute(bootstrapAttribute);
|
||||
return numberOfBootstrapMethods-1;
|
||||
}
|
||||
}
|
||||
|
@ -32,4 +32,5 @@ public class DHBWConstantPoolGen extends ConstantPoolGen{
|
||||
constantTable.put(c, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class DHBWInstructionFactory extends InstructionFactory{
|
||||
this.cg = cg;
|
||||
}
|
||||
|
||||
public INVOKEDYNAMIC createInvokeDynamic( MethodGen lambdaMethod ) {
|
||||
public INVOKEDYNAMIC createInvokeDynamic( String interfaceMethodName, String lambdaTypeSignature, 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);
|
||||
|
||||
@ -49,12 +49,14 @@ public class DHBWInstructionFactory extends InstructionFactory{
|
||||
* - 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()));
|
||||
String lambdaTypeParameterList = "()";
|
||||
ConstantMethodType lambdaMethodType = new ConstantMethodType(this.cp.addUtf8("()LRunnable;"));
|
||||
ConstantMethodType lambdaMethodType1 = new ConstantMethodType(this.cp.addUtf8("()Ljava/lang/Object;"));
|
||||
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(lambdaMethodType1));
|
||||
arguments.add(cp.addConstant(implMethod));
|
||||
arguments.add(cp.addConstant(lambdaMethodType));
|
||||
|
||||
@ -70,13 +72,16 @@ public class DHBWInstructionFactory extends InstructionFactory{
|
||||
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);
|
||||
int lambdaMetafactoryRefIndex = cp.addMethodref("java.lang.invoke.LambdaMetafactory", "metafactory", bootstrapSignature);
|
||||
//reference kind 6 steht für invokestatic
|
||||
int lambdaMetafactoryHandle = cp.addConstant(new ConstantMethodHandle(6, lambdaMetafactoryRefIndex));
|
||||
|
||||
int[] argumentsArray = new int[arguments.size()];
|
||||
for(int i = 0; i<arguments.size();i++){
|
||||
argumentsArray[i] = arguments.get(i);
|
||||
}
|
||||
BootstrapMethod bMethod = new BootstrapMethod(lambdaMethodIndex, arguments.size(), argumentsArray);
|
||||
BootstrapMethod bMethod = new BootstrapMethod(lambdaMetafactoryHandle, arguments.size(), argumentsArray);
|
||||
|
||||
|
||||
int index;
|
||||
|
||||
@ -104,9 +109,9 @@ public class DHBWInstructionFactory extends InstructionFactory{
|
||||
*
|
||||
*/
|
||||
|
||||
int bootstrap_method_attr_index = bMethod.getBootstrapMethodRef();
|
||||
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(lambdaMethod.getName(), lambdaMethod.getSignature());
|
||||
int name_and_type_index = cp.addNameAndType(interfaceMethodName, lambdaTypeSignature);
|
||||
|
||||
ConstantInvokeDynamic cInvokeDynamic = new ConstantInvokeDynamic(bootstrap_method_attr_index, name_and_type_index);
|
||||
|
||||
|
16
src/de/dhbwstuttgart/bytecode/MethodGenerator.java
Normal file
16
src/de/dhbwstuttgart/bytecode/MethodGenerator.java
Normal file
@ -0,0 +1,16 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
16
src/de/dhbwstuttgart/bytecode/WildcardType.java
Normal file
16
src/de/dhbwstuttgart/bytecode/WildcardType.java
Normal file
@ -0,0 +1,16 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import org.apache.commons.bcel6.Constants;
|
||||
import org.apache.commons.bcel6.classfile.Utility;
|
||||
import org.apache.commons.bcel6.generic.ObjectType;
|
||||
import org.apache.commons.bcel6.generic.ReferenceType;
|
||||
import org.apache.commons.bcel6.generic.Type;
|
||||
|
||||
public class WildcardType extends ReferenceType{
|
||||
|
||||
public WildcardType(String class_name, String preString) {
|
||||
super(Constants.T_REFERENCE, preString + "L" + class_name.replace('.', '/') + ";");
|
||||
this.type = Constants.T_UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
@ -20,6 +20,7 @@ import de.dhbwstuttgart.logger.Logger;
|
||||
import de.dhbwstuttgart.bytecode.ClassGenerator;
|
||||
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen;
|
||||
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory;
|
||||
import de.dhbwstuttgart.bytecode.MethodGenerator;
|
||||
import de.dhbwstuttgart.core.IItemWithOffset;
|
||||
import de.dhbwstuttgart.core.MyCompiler;
|
||||
import de.dhbwstuttgart.myexception.JVMCodeException;
|
||||
@ -764,7 +765,8 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
|
||||
}
|
||||
|
||||
//Methode generieren:
|
||||
MethodGen method = new MethodGen(Constants.ACC_PUBLIC, this.getType().getBytecodeType(cg), argumentTypes , argumentNames, this.get_Method_Name(), parentClass.name, il, _cp);
|
||||
MethodGen method = new MethodGenerator(Constants.ACC_PUBLIC, this.getType().getBytecodeType(cg), argumentTypes , argumentNames, this.get_Method_Name(), parentClass.name, il, _cp);
|
||||
method.stripAttributes(true);
|
||||
|
||||
Block block = this.get_Block();
|
||||
InstructionList blockInstructions = block.genByteCode(cg);
|
||||
|
@ -2,6 +2,7 @@ package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.apache.bcel.Constants;
|
||||
import org.apache.commons.bcel6.classfile.BootstrapMethod;
|
||||
import org.apache.commons.bcel6.classfile.ConstantPool;
|
||||
import org.apache.commons.bcel6.generic.BIPUSH;
|
||||
@ -235,11 +236,24 @@ public class LambdaExpression extends Expr{
|
||||
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());
|
||||
lambdaMethod.stripAttributes(true);
|
||||
lambdaMethod.getInstructionList().append(this.method_body.genByteCode(cg));
|
||||
|
||||
il.append(cg.getInstructionFactory().createInvokeDynamic(lambdaMethod));
|
||||
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));
|
||||
|
||||
lambdaMethod.setMaxLocals();
|
||||
lambdaMethod.setMaxStack();
|
||||
cg.addMethod(lambdaMethod.getMethod());
|
||||
|
||||
return il;
|
||||
}
|
||||
|
||||
private String getSAMSignature(ClassGenerator cg){
|
||||
String typeSignature = "(";
|
||||
return "(LRunnable;)LFun0;";
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.Menge;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.ClassGenerator;
|
||||
import de.dhbwstuttgart.parser.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
import de.dhbwstuttgart.typeinference.JavaCodeResult;
|
||||
@ -156,4 +156,9 @@ public class ExtendsWildcardType extends WildcardType implements ITypeContainer,
|
||||
this.innerType = (ObjectType) this.innerType.TYPE(ass, parent);
|
||||
return super.TYPE(ass, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) {
|
||||
return new de.dhbwstuttgart.bytecode.WildcardType(this.innerType.get_Name(), "+");
|
||||
}
|
||||
}
|
||||
|
@ -814,7 +814,21 @@ public class RefType extends ObjectType implements IMatchable
|
||||
}
|
||||
|
||||
public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) {
|
||||
return new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName());
|
||||
String paramString = "";
|
||||
boolean printParameterList = false; //Die ParameterListe wird wohl nicht in allen Fällen gebraucht
|
||||
if(printParameterList &&
|
||||
this.parameter != null && this.parameter.size()>0){
|
||||
paramString+="<";
|
||||
Iterator<Type> it = this.parameter.iterator();
|
||||
while(it.hasNext()){
|
||||
Type param = it.next();
|
||||
paramString+=param.getBytecodeType(cg);
|
||||
//if(it.hasNext())
|
||||
//paramString+=";"; //kein Delimiter zwischen den Typen
|
||||
}
|
||||
paramString+=">";
|
||||
}
|
||||
return new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName()+paramString);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.Menge;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.ClassGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
import de.dhbwstuttgart.typeinference.JavaCodeResult;
|
||||
import de.dhbwstuttgart.typeinference.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
|
||||
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
|
||||
|
||||
/**
|
||||
* Stellt eine Wildcard mit unterer Grenze dar.
|
||||
@ -153,5 +154,9 @@ public class SuperWildcardType extends WildcardType implements ITypeContainer, I
|
||||
return super.TYPE(ass, parent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) {
|
||||
return new de.dhbwstuttgart.bytecode.WildcardType(this.innerType.get_Name(), "-");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.Menge;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.ClassGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
import de.dhbwstuttgart.typeinference.JavaCodeResult;
|
||||
import de.dhbwstuttgart.typeinference.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
|
||||
import de.dhbwstuttgart.typeinference.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
|
||||
|
||||
/**
|
||||
@ -99,6 +100,11 @@ public class WildcardType extends Type{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) {
|
||||
return this.innerType.getBytecodeType(cg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
3
test/bytecode/Fun0.java
Normal file
3
test/bytecode/Fun0.java
Normal file
@ -0,0 +1,3 @@
|
||||
interface Fun0<A>{
|
||||
A apply();
|
||||
}
|
@ -2,7 +2,8 @@ class LambdaExpr {
|
||||
|
||||
void method() {
|
||||
|
||||
lambda; lambda = ()-> 1;
|
||||
lambda;
|
||||
lambda = ()-> 1;
|
||||
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
class Runnable{
|
||||
|
||||
method() { return ()-> this; }
|
||||
Fun0<Runnable> method() { return ()-> this; }
|
||||
|
||||
}
|
@ -3,11 +3,11 @@
|
||||
*/
|
||||
class Test{
|
||||
public static void main(String[] args){
|
||||
new EmptyClass();
|
||||
/*new EmptyClass();
|
||||
new Assign();
|
||||
System.out.println(new Return().method());
|
||||
new MethodCall().method();
|
||||
System.out.println(new FieldDeclaration().field);
|
||||
//new Runnable().method().run();
|
||||
System.out.println(new FieldDeclaration().field);*/
|
||||
System.out.println(new Runnable().method().apply());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user