Merge branch 'bytecode' into refactoring

This commit is contained in:
JanUlrich 2015-08-27 13:37:45 +02:00
commit 133740d1f8
37 changed files with 573 additions and 112 deletions

Binary file not shown.

View File

@ -0,0 +1,7 @@
package bcelifier;
public class IntLiteral {
Integer methode(){
return 50000;
}
}

View 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"));
}
}

View 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();
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
package bcelifier;
public class Lambda1 {
Runnable methode(){
return ()->System.out.println(this);
}
}

View 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"));
}
}

Binary file not shown.

View File

@ -0,0 +1,12 @@
package bcelifier;
public class MethodCall {
void methode(){
}
void methode2(Runnable r){
methode();
r.run();
}
}

View 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

Binary file not shown.

8
BCEL/bcelifier/This.java Normal file
View File

@ -0,0 +1,8 @@
package bcelifier;
public class This {
This methode(){
return this;
}
}

View 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"));
}
}

View 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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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());
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()
}

View File

@ -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;
}

View File

@ -1,6 +1,10 @@
class Assign{
void method() {a; a = 20;b; b=59;}
void method() {
a;
a = 20;
b;
b=59;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,9 @@
class Assign{
void method() {
method();
}
void method2(){}
}

View File

@ -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);
}
}

View File

@ -1,10 +1,7 @@
class Assign{
class Return{
method() {a;
a = 20;
b;
b=59;
return a + b;
Integer method() {
return 5;
}

View 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);
}
}

View 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();
}
}
}

View File

@ -4,5 +4,7 @@
class Test{
public static void main(String[] args){
new EmptyClass();
new Assign();
System.out.println(new Return().method());
}
}