forked from JavaTX/JavaCompilerCore
Merge branch 'bytecode' into refactoring
This commit is contained in:
commit
133740d1f8
BIN
BCEL/bcelifier/IntLiteral.class
Normal file
BIN
BCEL/bcelifier/IntLiteral.class
Normal file
Binary file not shown.
7
BCEL/bcelifier/IntLiteral.java
Normal file
7
BCEL/bcelifier/IntLiteral.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bcelifier;
|
||||
|
||||
public class IntLiteral {
|
||||
Integer methode(){
|
||||
return 50000;
|
||||
}
|
||||
}
|
56
BCEL/bcelifier/IntLiteralCreator.java
Normal file
56
BCEL/bcelifier/IntLiteralCreator.java
Normal file
@ -0,0 +1,56 @@
|
||||
package bcelifier;
|
||||
|
||||
import org.apache.bcel.generic.*;
|
||||
import org.apache.bcel.classfile.*;
|
||||
import org.apache.bcel.*;
|
||||
import java.io.*;
|
||||
|
||||
public class IntLiteralCreator implements Constants {
|
||||
private InstructionFactory _factory;
|
||||
private ConstantPoolGen _cp;
|
||||
private ClassGen _cg;
|
||||
|
||||
public IntLiteralCreator() {
|
||||
_cg = new ClassGen("bcelifier.IntLiteral", "java.lang.Object", "IntLiteral.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.IntLiteral", 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"), Type.NO_ARGS, new String[] { }, "methode", "bcelifier.IntLiteral", il, _cp);
|
||||
|
||||
InstructionHandle ih_0 = il.append(new PUSH(_cp, 50000));
|
||||
il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
|
||||
InstructionHandle ih_5 = 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.IntLiteralCreator creator = new bcelifier.IntLiteralCreator();
|
||||
creator.create(new FileOutputStream("bcelifier.IntLiteral.class"));
|
||||
}
|
||||
}
|
37
BCEL/bcelifier/JavaToBCEL.java
Normal file
37
BCEL/bcelifier/JavaToBCEL.java
Normal file
@ -0,0 +1,37 @@
|
||||
package bcelifier;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.OpenOption;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.apache.bcel.classfile.ClassFormatException;
|
||||
import org.apache.bcel.classfile.ClassParser;
|
||||
import org.apache.bcel.classfile.JavaClass;
|
||||
import org.apache.bcel.util.BCELifier;
|
||||
|
||||
public class JavaToBCEL {
|
||||
|
||||
public final static String rootDirectory = System.getProperty("user.dir")+"/BCEL/bcelifier/";
|
||||
|
||||
public static void main(String args[]){
|
||||
new JavaToBCEL();
|
||||
}
|
||||
|
||||
public JavaToBCEL(){
|
||||
try {
|
||||
new BCELifier(new ClassParser(rootDirectory+"Lambda1.class").parse(), new FileOutputStream(new File(rootDirectory+"Lambda1Creator.java"))).start();
|
||||
new BCELifier(new ClassParser(rootDirectory+"This.class").parse(), new FileOutputStream(new File(rootDirectory+"ThisCreator.java"))).start();
|
||||
new BCELifier(new ClassParser(rootDirectory+"IntLiteral.class").parse(), new FileOutputStream(new File(rootDirectory+"IntLiteralCreator.java"))).start();
|
||||
new BCELifier(new ClassParser(rootDirectory+"MethodCall.class").parse(), new FileOutputStream(new File(rootDirectory+"MethodCallCreator.java"))).start();
|
||||
|
||||
} catch (ClassFormatException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
BIN
BCEL/bcelifier/Lambda1.class
Normal file
BIN
BCEL/bcelifier/Lambda1.class
Normal file
Binary file not shown.
BIN
BCEL/bcelifier/Lambda1.class.toGenerate
Normal file
BIN
BCEL/bcelifier/Lambda1.class.toGenerate
Normal file
Binary file not shown.
8
BCEL/bcelifier/Lambda1.java
Normal file
8
BCEL/bcelifier/Lambda1.java
Normal file
@ -0,0 +1,8 @@
|
||||
package bcelifier;
|
||||
|
||||
public class Lambda1 {
|
||||
|
||||
Runnable methode(){
|
||||
return ()->System.out.println(this);
|
||||
}
|
||||
}
|
70
BCEL/bcelifier/Lambda1Creator.java
Normal file
70
BCEL/bcelifier/Lambda1Creator.java
Normal file
@ -0,0 +1,70 @@
|
||||
package bcelifier;
|
||||
|
||||
import org.apache.bcel.generic.*;
|
||||
import org.apache.bcel.classfile.*;
|
||||
import org.apache.bcel.*;
|
||||
import java.io.*;
|
||||
|
||||
public class Lambda1Creator implements Constants {
|
||||
private InstructionFactory _factory;
|
||||
private ConstantPoolGen _cp;
|
||||
private ClassGen _cg;
|
||||
|
||||
public Lambda1Creator() {
|
||||
_cg = new ClassGen("bcelifier.Lambda1", "java.lang.Object", "Lambda1.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();
|
||||
createMethod_2();
|
||||
_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.Lambda1", 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.Runnable"), Type.NO_ARGS, new String[] { }, "methode", "bcelifier.Lambda1", il, _cp);
|
||||
|
||||
InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
|
||||
InstructionHandle ih_1 = il.append(_factory.createReturn(Type.OBJECT));
|
||||
method.setMaxStack();
|
||||
method.setMaxLocals();
|
||||
_cg.addMethod(method.getMethod());
|
||||
il.dispose();
|
||||
}
|
||||
|
||||
private void createMethod_2() {
|
||||
InstructionList il = new InstructionList();
|
||||
MethodGen method = new MethodGen(ACC_PRIVATE | ACC_SYNTHETIC, Type.VOID, Type.NO_ARGS, new String[] { }, "lambda$methode$0", "bcelifier.Lambda1", il, _cp);
|
||||
|
||||
InstructionHandle ih_0 = il.append(_factory.createFieldAccess("java.lang.System", "out", new ObjectType("java.io.PrintStream"), Constants.GETSTATIC));
|
||||
il.append(_factory.createLoad(Type.OBJECT, 0));
|
||||
il.append(_factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL));
|
||||
InstructionHandle ih_7 = 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.Lambda1Creator creator = new bcelifier.Lambda1Creator();
|
||||
creator.create(new FileOutputStream("bcelifier.Lambda1.class"));
|
||||
}
|
||||
}
|
BIN
BCEL/bcelifier/MethodCall.class
Normal file
BIN
BCEL/bcelifier/MethodCall.class
Normal file
Binary file not shown.
12
BCEL/bcelifier/MethodCall.java
Normal file
12
BCEL/bcelifier/MethodCall.java
Normal file
@ -0,0 +1,12 @@
|
||||
package bcelifier;
|
||||
|
||||
public class MethodCall {
|
||||
void methode(){
|
||||
}
|
||||
|
||||
void methode2(Runnable r){
|
||||
methode();
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
|
70
BCEL/bcelifier/MethodCallCreator.java
Normal file
70
BCEL/bcelifier/MethodCallCreator.java
Normal file
@ -0,0 +1,70 @@
|
||||
package bcelifier;
|
||||
|
||||
import org.apache.bcel.generic.*;
|
||||
import org.apache.bcel.classfile.*;
|
||||
import org.apache.bcel.*;
|
||||
import java.io.*;
|
||||
|
||||
public class MethodCallCreator implements Constants {
|
||||
private InstructionFactory _factory;
|
||||
private ConstantPoolGen _cp;
|
||||
private ClassGen _cg;
|
||||
|
||||
public MethodCallCreator() {
|
||||
_cg = new ClassGen("bcelifier.MethodCall", "java.lang.Object", "MethodCall.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();
|
||||
createMethod_2();
|
||||
_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.MethodCall", 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, Type.VOID, Type.NO_ARGS, new String[] { }, "methode", "bcelifier.MethodCall", il, _cp);
|
||||
|
||||
InstructionHandle ih_0 = il.append(_factory.createReturn(Type.VOID));
|
||||
method.setMaxStack();
|
||||
method.setMaxLocals();
|
||||
_cg.addMethod(method.getMethod());
|
||||
il.dispose();
|
||||
}
|
||||
|
||||
private void createMethod_2() {
|
||||
InstructionList il = new InstructionList();
|
||||
MethodGen method = new MethodGen(0, Type.VOID, new Type[] { new ObjectType("java.lang.Runnable") }, new String[] { "arg0" }, "methode2", "bcelifier.MethodCall", il, _cp);
|
||||
|
||||
InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
|
||||
il.append(_factory.createInvoke("bcelifier.MethodCall", "methode", Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
|
||||
InstructionHandle ih_4 = il.append(_factory.createLoad(Type.OBJECT, 1));
|
||||
il.append(_factory.createInvoke("java.lang.Runnable", "run", Type.VOID, Type.NO_ARGS, Constants.INVOKEINTERFACE));
|
||||
InstructionHandle ih_10 = 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.MethodCallCreator creator = new bcelifier.MethodCallCreator();
|
||||
creator.create(new FileOutputStream("bcelifier.MethodCall.class"));
|
||||
}
|
||||
}
|
BIN
BCEL/bcelifier/This.class
Normal file
BIN
BCEL/bcelifier/This.class
Normal file
Binary file not shown.
8
BCEL/bcelifier/This.java
Normal file
8
BCEL/bcelifier/This.java
Normal file
@ -0,0 +1,8 @@
|
||||
package bcelifier;
|
||||
|
||||
public class This {
|
||||
|
||||
This methode(){
|
||||
return this;
|
||||
}
|
||||
}
|
55
BCEL/bcelifier/ThisCreator.java
Normal file
55
BCEL/bcelifier/ThisCreator.java
Normal file
@ -0,0 +1,55 @@
|
||||
package bcelifier;
|
||||
|
||||
import org.apache.bcel.generic.*;
|
||||
import org.apache.bcel.classfile.*;
|
||||
import org.apache.bcel.*;
|
||||
import java.io.*;
|
||||
|
||||
public class ThisCreator implements Constants {
|
||||
private InstructionFactory _factory;
|
||||
private ConstantPoolGen _cp;
|
||||
private ClassGen _cg;
|
||||
|
||||
public ThisCreator() {
|
||||
_cg = new ClassGen("bcelifier.This", "java.lang.Object", "<Unknown>", 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.This", 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("bcelifier.This"), Type.NO_ARGS, new String[] { }, "methode", "bcelifier.This", il, _cp);
|
||||
|
||||
InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
|
||||
InstructionHandle ih_1 = 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.ThisCreator creator = new bcelifier.ThisCreator();
|
||||
creator.create(new FileOutputStream("bcelifier.This.class"));
|
||||
}
|
||||
}
|
80
src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java
Normal file
80
src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java
Normal file
@ -0,0 +1,80 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.awt.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.bcel.classfile.BootstrapMethod;
|
||||
import org.apache.bcel.classfile.ConstantInvokeDynamic;
|
||||
import org.apache.bcel.classfile.Method;
|
||||
import org.apache.bcel.generic.ClassGen;
|
||||
import org.apache.bcel.generic.ConstantPoolGen;
|
||||
import org.apache.bcel.generic.INVOKEDYNAMIC;
|
||||
import org.apache.bcel.generic.InstructionFactory;
|
||||
import org.apache.bcel.generic.MethodGen;
|
||||
import org.apache.bcel.generic.Type;
|
||||
|
||||
public class DHBWInstructionFactory extends InstructionFactory{
|
||||
|
||||
public DHBWInstructionFactory(ClassGen cg, ConstantPoolGen cp) {
|
||||
super(cg, cp);
|
||||
}
|
||||
|
||||
private BootstrapMethod createBootstrapMethod(){
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
public INVOKEDYNAMIC createInvokeDynamic( MethodGen lambdaMethod ) {
|
||||
//Zuerst die Bootstrap-Methode erstellen: Diese müssen dann in ein BootstrapMethods-Attribut zusammengefasst und dem Classfile hinzugefügt werden
|
||||
int lambdaMethodIndex = this.cp.addMethodref(lambdaMethod);
|
||||
|
||||
ArrayList arguments = new ArrayList<Integer>();
|
||||
|
||||
BootstrapMethod bMethod = new BootstrapMethod(lambdaMethodIndex, arguments.size(), (int[])arguments.toArray());
|
||||
|
||||
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
|
||||
*
|
||||
* CONSTANT_InvokeDynamic_info structure:
|
||||
* - a symbolic reference to a method handle (bootstrap_method_attr_index)
|
||||
* - a method name and a method descriptor (name_and_type_index)
|
||||
*
|
||||
* @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* TODO: Rausfinden, 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
|
||||
*
|
||||
* 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;
|
||||
*
|
||||
* TODO: bootstrap_methode den Klassenattributen hinzufügen
|
||||
*
|
||||
*/
|
||||
|
||||
int bootstrap_method_attr_index = bMethod.getBootstrapMethodRef();
|
||||
int name_and_type_index = cp.addNameAndType(lambdaMethod.getName(), lambdaMethod.getType().getSignature());
|
||||
|
||||
ConstantInvokeDynamic cInvokeDynamic = new ConstantInvokeDynamic(bootstrap_method_attr_index, name_and_type_index);
|
||||
|
||||
index = cp.addConstant(cInvokeDynamic, cp);
|
||||
|
||||
return new INVOKEDYNAMIC(opcode, index);
|
||||
}
|
||||
|
||||
}
|
@ -860,22 +860,14 @@ public class MyCompiler implements MyCompilerAPI
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteCodeResult generateBytecode() {
|
||||
/*
|
||||
* TODO Für das Bytecode-Team:
|
||||
* - generateBytecode-Methode implementieren
|
||||
* - Sich einen passenden Container für den Bytecode überlegen
|
||||
* - Dieser wird von generateBytecode zurückgeliefert und sollte die Möglichkeit zum schreiben von Bytecode in eine Datei bieten.
|
||||
* - wird der Rückgabetyp von generateBytecode in MyCompiler geändert, so muss auch der Rückgabetyp im Interface MyCompilerAPI geändert werden
|
||||
*/
|
||||
try {
|
||||
SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement();
|
||||
Class parsedClass = parsedFile.KlassenVektor.firstElement();
|
||||
return parsedClass.genByteCode();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
public Menge<ByteCodeResult> generateBytecode() {
|
||||
//SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement();
|
||||
//Class parsedClass = parsedFile.KlassenVektor.firstElement();
|
||||
Menge<ByteCodeResult> ret = new Menge<>();
|
||||
for(SourceFile sf : this.m_AbstractSyntaxTree){
|
||||
ret.addAll(sf.generateBytecode());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
// ino.end
|
||||
|
@ -122,6 +122,11 @@ public interface MyCompilerAPI
|
||||
*/
|
||||
public SourceFile parse(String sourceCode) throws ParserError;
|
||||
|
||||
public ByteCodeResult generateBytecode();
|
||||
/**
|
||||
* Generiert für jede geparste Klasse im SourceFile ein ByteCodeResult.
|
||||
* Dafür müssen die Schritte Parsen und typeReconstruction ausgeführt werden.
|
||||
* @return
|
||||
*/
|
||||
public Menge<ByteCodeResult> generateBytecode();
|
||||
}
|
||||
// ino.end
|
||||
|
@ -1455,7 +1455,7 @@ case 98:
|
||||
case 99:
|
||||
// line 912 "./../src/de/dhbwstuttgart/parser/JavaParser.jay"
|
||||
{
|
||||
Constructor CON = new Constructor(null); /*TODO: Der Parser kann sowieso nicht zwischen einem Konstruktor und einer Methode unterscheiden. Das hier kann wegfallen...*/
|
||||
Constructor CON = new Constructor(null,null); /*TODO: Der Parser kann sowieso nicht zwischen einem Konstruktor und einer Methode unterscheiden. Das hier kann wegfallen...*/
|
||||
DeclId DIDCon = new DeclId();
|
||||
DIDCon.set_Name(((UsedId)yyVals[-2+yyTop]).get_Name_1Element());
|
||||
CON.set_DeclId(DIDCon);
|
||||
@ -1465,7 +1465,7 @@ case 99:
|
||||
case 100:
|
||||
// line 920 "./../src/de/dhbwstuttgart/parser/JavaParser.jay"
|
||||
{
|
||||
Constructor CONpara = new Constructor(null);
|
||||
Constructor CONpara = new Constructor(null,null);
|
||||
DeclId DIconpara = new DeclId();
|
||||
DIconpara.set_Name(((UsedId)yyVals[-3+yyTop]).get_Name_1Element());
|
||||
CONpara.set_DeclId(DIconpara);
|
||||
|
@ -910,7 +910,7 @@ block : '{' '}'
|
||||
|
||||
constructordeclarator : simplename '(' ')'
|
||||
{
|
||||
Constructor CON = new Constructor(null); //TODO: Der Parser kann sowieso nicht zwischen einem Konstruktor und einer Methode unterscheiden. Das hier kann wegfallen...
|
||||
Constructor CON = new Constructor(null,null); //TODO: Der Parser kann sowieso nicht zwischen einem Konstruktor und einer Methode unterscheiden. Das hier kann wegfallen...
|
||||
DeclId DIDCon = new DeclId();
|
||||
DIDCon.set_Name($1.get_Name_1Element());
|
||||
CON.set_DeclId(DIDCon);
|
||||
@ -918,7 +918,7 @@ constructordeclarator : simplename '(' ')'
|
||||
}
|
||||
| simplename '('formalparameterlist')'
|
||||
{
|
||||
Constructor CONpara = new Constructor(null);
|
||||
Constructor CONpara = new Constructor(null,null);
|
||||
DeclId DIconpara = new DeclId();
|
||||
DIconpara.set_Name($1.get_Name_1Element());
|
||||
CONpara.set_DeclId(DIconpara);
|
||||
|
@ -72,13 +72,13 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
|
||||
private ClassGen _cg;
|
||||
|
||||
//Method created with BCEL to generate ByteCode
|
||||
public ByteCodeResult genByteCode() throws IOException {
|
||||
public ByteCodeResult genByteCode() {
|
||||
|
||||
SectionLogger logger = Logger.getSectionLogger(this.getClass().getName(), Section.CODEGEN);
|
||||
logger.debug("Test");
|
||||
|
||||
if(pkgName != null)throw new NotImplementedException();
|
||||
_cg = new ClassGen(name, superClass.get_Name(), name + ".java", Constants.ACC_PUBLIC , new String[] { }); //new String necessary?
|
||||
_cg = new ClassGen(name, superClass.get_Name(), name + ".java", Constants.ACC_PUBLIC , new String[] { }); //letzter Parameter sind implementierte Interfaces
|
||||
_cp = _cg.getConstantPool();
|
||||
_factory = new InstructionFactory(_cg, _cp);
|
||||
|
||||
@ -88,12 +88,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
|
||||
|
||||
ByteCodeResult code = new ByteCodeResult(_cg);
|
||||
return code;
|
||||
|
||||
//ByteCodeResult bc = new ByteCodeResult();
|
||||
//_cg = new ClassGen(pkgName.get_Name() + "/" + name, superClass.get_Name(), name + ".java", Constants.ACC_PUBLIC , new String[] { });
|
||||
//_cg zur<EFBFBD>ckgeben
|
||||
//bc.append(BCELByteCodeOutput);
|
||||
//return _cg;
|
||||
}
|
||||
|
||||
private Menge<Type> superif = new Menge<Type>();
|
||||
@ -477,7 +471,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
|
||||
*/
|
||||
if(m.get_Method_Name().equals("<init>"))throw new TypeinferenceException("<init> ist kein gültiger Methodenname", m);
|
||||
if((m.get_Method_Name().equals(this.getName()))) {
|
||||
Constructor constructor = new Constructor(m);
|
||||
Constructor constructor = new Constructor(m, this);
|
||||
tempFields.add(constructor); //Den Konstruktor anstatt der Methode anfügen
|
||||
}else{
|
||||
//Handelt es sich um keinen Konstruktor, dann die Methode unverändert den Feldern hinzufügen:
|
||||
@ -1251,7 +1245,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
|
||||
if(!constructorVorhanden){//Falls kein Konstruktor vorhanden ist, muss noch der Standardkonstruktor angefügt werden:
|
||||
Block konstruktorBlock = new Block();
|
||||
konstruktorBlock.statements.add(new SuperCall(konstruktorBlock));
|
||||
Constructor standardKonstruktor = new Constructor(Method.createEmptyMethod(konstruktorBlock,this.getName().toString(), this));
|
||||
Constructor standardKonstruktor = new Constructor(Method.createEmptyMethod(konstruktorBlock,this.getName().toString(), this), this);
|
||||
//Constructor standardKonstruktor = new Constructor(Method.createEmptyMethod(this.getName().toString(), this));
|
||||
|
||||
this.addField(standardKonstruktor);
|
||||
|
@ -746,7 +746,23 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
|
||||
InstructionList il = new InstructionList();
|
||||
Class parentClass = this.getParentClass();
|
||||
|
||||
MethodGen method = new MethodGen(Constants.ACC_PUBLIC, this.getType().getBytecodeType(), org.apache.bcel.generic.Type.NO_ARGS , new String[] { }, this.get_Method_Name(), parentClass.name, il, _cp);
|
||||
//Die Argumentliste generieren:
|
||||
org.apache.bcel.generic.Type[] argumentTypes = org.apache.bcel.generic.Type.NO_ARGS;
|
||||
String[] argumentNames = new String[]{};
|
||||
if(this.parameterlist != null &&
|
||||
this.parameterlist.size() > 0){
|
||||
argumentTypes = new org.apache.bcel.generic.Type[this.parameterlist.size()];
|
||||
argumentNames = new String[this.parameterlist.size()];
|
||||
int i = 0;
|
||||
for(FormalParameter parameter : this.parameterlist){
|
||||
argumentTypes[i] = parameter.getType().getBytecodeType();
|
||||
argumentNames[i] = parameter.getIdentifier();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//Methode generieren:
|
||||
MethodGen method = new MethodGen(Constants.ACC_PUBLIC, this.getType().getBytecodeType(), argumentTypes , argumentNames, this.get_Method_Name(), parentClass.name, il, _cp);
|
||||
|
||||
Block block = this.get_Block();
|
||||
InstructionList blockInstructions = block.genByteCode(cg);
|
||||
@ -759,7 +775,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
|
||||
}
|
||||
|
||||
method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden)
|
||||
|
||||
method.setMaxLocals();
|
||||
cg.addMethod(method.getMethod());
|
||||
|
||||
}
|
||||
|
@ -139,6 +139,10 @@ public class ParameterList extends SyntaxTreeNode implements Iterable<FormalPara
|
||||
public Menge<? extends SyntaxTreeNode> getChildren() {
|
||||
return formalparameter;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.formalparameter.size();
|
||||
}
|
||||
|
||||
}
|
||||
// ino.end
|
||||
|
@ -3,12 +3,15 @@ package de.dhbwstuttgart.syntaxtree;
|
||||
// ino.end
|
||||
|
||||
// ino.module.SourceFile.8722.import
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.Menge;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import de.dhbwstuttgart.logger.Logger;
|
||||
@ -29,6 +32,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Type;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.typeinference.ByteCodeResult;
|
||||
import de.dhbwstuttgart.typeinference.ConstraintsSet;
|
||||
import de.dhbwstuttgart.typeinference.FunN;
|
||||
import de.dhbwstuttgart.typeinference.FunNInterface;
|
||||
@ -1368,7 +1372,7 @@ public class SourceFile
|
||||
}
|
||||
//basicAssumptions.addMethodIntersectionType(new CIntersectionType(constructor));
|
||||
constructorMethod.parameterlist = paraList;
|
||||
Constructor constructor = new Constructor(constructorMethod);
|
||||
Constructor constructor = new Constructor(constructorMethod, parentClass);
|
||||
constructor.parserPostProcessing(parentClass);
|
||||
parentClass.addField(constructor);
|
||||
}
|
||||
@ -1825,5 +1829,17 @@ public class SourceFile
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bisher wird nur der Bytecode der Klassen generiert. Nicht der Interfaces.
|
||||
* @return
|
||||
*/
|
||||
public Collection<? extends ByteCodeResult> generateBytecode() {
|
||||
Menge<ByteCodeResult> ret = new Menge<>();
|
||||
for(Class cl : this.KlassenVektor){
|
||||
ret.add(cl.genByteCode());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
// ino.end
|
||||
|
@ -4,10 +4,14 @@ package de.dhbwstuttgart.syntaxtree.statement;
|
||||
// ino.module.IntLiteral.8635.import
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.apache.bcel.Constants;
|
||||
import org.apache.bcel.generic.BIPUSH;
|
||||
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.ObjectType;
|
||||
import org.apache.bcel.generic.PUSH;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.Menge;
|
||||
import de.dhbwstuttgart.logger.Logger;
|
||||
@ -137,8 +141,14 @@ public class IntLiteral extends Literal
|
||||
public InstructionList genByteCode(ClassGen cg) {
|
||||
InstructionFactory _factory = new InstructionFactory(cg, cg.getConstantPool());
|
||||
InstructionList il = new InstructionList();
|
||||
il.append(new BIPUSH(new Integer(get_Int()).byteValue()));
|
||||
return il;
|
||||
|
||||
/*
|
||||
* Der jetzige Compiler kann keine primitiven Typen. Ein int-Literal ist daher eine Instanz von java.lang.Integer
|
||||
*/
|
||||
il.append(new PUSH(cg.getConstantPool(), this.get_Int()));
|
||||
il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new org.apache.bcel.generic.Type[] { org.apache.bcel.generic.Type.INT }, Constants.INVOKESTATIC));
|
||||
|
||||
return il;
|
||||
}
|
||||
}
|
||||
// ino.end
|
||||
|
@ -308,7 +308,8 @@ public class MethodCall extends Expr
|
||||
|
||||
@Override
|
||||
public InstructionList genByteCode(ClassGen _cg) {
|
||||
// TODO Auto-generated method stub
|
||||
//Herausfinden, ob eine Methode oder ein Interface aufgerufen wird:
|
||||
//this.receiver.get_Expr().getType()
|
||||
|
||||
}
|
||||
|
||||
|
@ -138,10 +138,7 @@ public class Return extends Statement
|
||||
|
||||
InstructionFactory _factory = new InstructionFactory(cg, cg.getConstantPool());
|
||||
|
||||
//Stimmt das VOID hier eigentlich? --> Wie wäre es mit getReturnType o.ä.? + evtl. von Type zu bcelType casten?
|
||||
il.append(_factory.createReturn(org.apache.bcel.generic.Type.VOID));
|
||||
|
||||
|
||||
il.append(_factory.createReturn(retexpr.getType().getBytecodeType()));
|
||||
|
||||
return il;
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
class Assign{
|
||||
|
||||
void method() {a; a = 20;b; b=59;}
|
||||
|
||||
void method() {
|
||||
a;
|
||||
a = 20;
|
||||
b;
|
||||
b=59;
|
||||
}
|
||||
|
||||
}
|
@ -20,7 +20,7 @@ import de.dhbwstuttgart.typeinference.Menge;
|
||||
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
|
||||
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
|
||||
|
||||
public class Assign {
|
||||
public class AssignTest {
|
||||
|
||||
public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
|
||||
public final static String testFile = "Assign.jav";
|
||||
@ -28,18 +28,7 @@ public class Assign {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
|
||||
MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
|
||||
try {
|
||||
compiler.parse(new File(rootDirectory + testFile));
|
||||
compiler.typeReconstruction();
|
||||
ByteCodeResult bytecode = compiler.generateBytecode();
|
||||
System.out.println(bytecode);
|
||||
bytecode.getByteCode().getJavaClass().dump(new File(rootDirectory + outputFile));
|
||||
} catch (IOException | yyException e) {
|
||||
e.printStackTrace();
|
||||
TestCase.fail();
|
||||
}
|
||||
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
|
||||
}
|
||||
|
||||
}
|
@ -28,18 +28,7 @@ public class BoolLitTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
|
||||
MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
|
||||
try {
|
||||
compiler.parse(new File(rootDirectory + testFile));
|
||||
compiler.typeReconstruction();
|
||||
ByteCodeResult bytecode = compiler.generateBytecode();
|
||||
System.out.println(bytecode);
|
||||
bytecode.getByteCode().getJavaClass().dump(new File(rootDirectory + outputFile));
|
||||
} catch (IOException | yyException e) {
|
||||
e.printStackTrace();
|
||||
TestCase.fail();
|
||||
}
|
||||
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,18 +28,7 @@ public class CharLitTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
|
||||
MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
|
||||
try {
|
||||
compiler.parse(new File(rootDirectory + testFile));
|
||||
compiler.typeReconstruction();
|
||||
ByteCodeResult bytecode = compiler.generateBytecode();
|
||||
System.out.println(bytecode);
|
||||
bytecode.getByteCode().getJavaClass().dump(new File(rootDirectory + outputFile));
|
||||
} catch (IOException | yyException e) {
|
||||
e.printStackTrace();
|
||||
TestCase.fail();
|
||||
}
|
||||
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,18 +28,7 @@ public class EmptyClassTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
|
||||
MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
|
||||
try {
|
||||
compiler.parse(new File(rootDirectory + testFile));
|
||||
compiler.typeReconstruction();
|
||||
ByteCodeResult bytecode = compiler.generateBytecode();
|
||||
System.out.println(bytecode);
|
||||
bytecode.getByteCode().getJavaClass().dump(new File(rootDirectory + outputFile));
|
||||
} catch (IOException | yyException e) {
|
||||
e.printStackTrace();
|
||||
TestCase.fail();
|
||||
}
|
||||
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
9
test/bytecode/MethodCall.jav
Normal file
9
test/bytecode/MethodCall.jav
Normal file
@ -0,0 +1,9 @@
|
||||
class Assign{
|
||||
|
||||
void method() {
|
||||
method();
|
||||
}
|
||||
|
||||
void method2(){}
|
||||
|
||||
}
|
@ -20,26 +20,15 @@ import de.dhbwstuttgart.typeinference.Menge;
|
||||
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
|
||||
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet;
|
||||
|
||||
public class Return {
|
||||
public class MethodCallTest {
|
||||
|
||||
public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
|
||||
public final static String testFile = "Assign.jav";
|
||||
public final static String outputFile = "Assign.class";
|
||||
public final static String testFile = "MethodCall.jav";
|
||||
public final static String outputFile = "MethodCall.class";
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
|
||||
MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
|
||||
try {
|
||||
compiler.parse(new File(rootDirectory + testFile));
|
||||
compiler.typeReconstruction();
|
||||
ByteCodeResult bytecode = compiler.generateBytecode();
|
||||
System.out.println(bytecode);
|
||||
bytecode.getByteCode().getJavaClass().dump(new File(rootDirectory + outputFile));
|
||||
} catch (IOException | yyException e) {
|
||||
e.printStackTrace();
|
||||
TestCase.fail();
|
||||
}
|
||||
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
class Assign{
|
||||
class Return{
|
||||
|
||||
method() {a;
|
||||
a = 20;
|
||||
b;
|
||||
b=59;
|
||||
return a + b;
|
||||
Integer method() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
|
34
test/bytecode/ReturnTest.java
Normal file
34
test/bytecode/ReturnTest.java
Normal file
@ -0,0 +1,34 @@
|
||||
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 ReturnTest {
|
||||
|
||||
public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
|
||||
public final static String testFile = "Return.jav";
|
||||
public final static String outputFile = "Return.class";
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile);
|
||||
}
|
||||
|
||||
}
|
32
test/bytecode/SingleClassTester.java
Normal file
32
test/bytecode/SingleClassTester.java
Normal file
@ -0,0 +1,32 @@
|
||||
package bytecode;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
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;
|
||||
|
||||
public class SingleClassTester {
|
||||
|
||||
public static void compileToBytecode(String inputFile, String outputFile){
|
||||
LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out);
|
||||
MyCompilerAPI compiler = MyCompiler.getAPI(logConfig);
|
||||
try {
|
||||
compiler.parse(new File(inputFile));
|
||||
compiler.typeReconstruction();
|
||||
Menge<ByteCodeResult> bytecode = compiler.generateBytecode();
|
||||
System.out.println(bytecode);
|
||||
bytecode.firstElement().getByteCode().getJavaClass().dump(new File(outputFile));
|
||||
} catch (IOException | yyException e) {
|
||||
e.printStackTrace();
|
||||
TestCase.fail();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,5 +4,7 @@
|
||||
class Test{
|
||||
public static void main(String[] args){
|
||||
new EmptyClass();
|
||||
new Assign();
|
||||
System.out.println(new Return().method());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user