mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-03 05:44:10 -08:00
Adds representative attribute to variables in SSA form. Adds program
bytecode logging
This commit is contained in:
parent
c704956ca1
commit
d704e503ee
|
@ -19,11 +19,13 @@ import java.io.*;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import org.teavm.codegen.*;
|
import org.teavm.codegen.*;
|
||||||
import org.teavm.dependency.DependencyChecker;
|
import org.teavm.dependency.DependencyChecker;
|
||||||
import org.teavm.javascript.ast.ClassNode;
|
import org.teavm.javascript.ast.ClassNode;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.resource.ClasspathClassHolderSource;
|
import org.teavm.model.resource.ClasspathClassHolderSource;
|
||||||
|
import org.teavm.model.util.ListingBuilder;
|
||||||
import org.teavm.optimization.ClassSetOptimizer;
|
import org.teavm.optimization.ClassSetOptimizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +37,8 @@ public class JavascriptBuilder {
|
||||||
private DependencyChecker dependencyChecker;
|
private DependencyChecker dependencyChecker;
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
|
private boolean bytecodeLogging;
|
||||||
|
private OutputStream logStream = System.out;
|
||||||
private Map<String, JavascriptEntryPoint> entryPoints = new HashMap<>();
|
private Map<String, JavascriptEntryPoint> entryPoints = new HashMap<>();
|
||||||
private Map<String, String> exportedClasses = new HashMap<>();
|
private Map<String, String> exportedClasses = new HashMap<>();
|
||||||
|
|
||||||
|
@ -60,6 +64,14 @@ public class JavascriptBuilder {
|
||||||
this.minifying = minifying;
|
this.minifying = minifying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBytecodeLogging() {
|
||||||
|
return bytecodeLogging;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBytecodeLogging(boolean bytecodeLogging) {
|
||||||
|
this.bytecodeLogging = bytecodeLogging;
|
||||||
|
}
|
||||||
|
|
||||||
public JavascriptEntryPoint entryPoint(String name, MethodReference ref) {
|
public JavascriptEntryPoint entryPoint(String name, MethodReference ref) {
|
||||||
if (entryPoints.containsKey(name)) {
|
if (entryPoints.containsKey(name)) {
|
||||||
throw new IllegalArgumentException("Entry point with public name `" + name + "' already defined " +
|
throw new IllegalArgumentException("Entry point with public name `" + name + "' already defined " +
|
||||||
|
@ -97,6 +109,13 @@ public class JavascriptBuilder {
|
||||||
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)));
|
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)));
|
||||||
dependencyChecker.checkDependencies();
|
dependencyChecker.checkDependencies();
|
||||||
ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses();
|
ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses();
|
||||||
|
if (bytecodeLogging) {
|
||||||
|
try {
|
||||||
|
logBytecode(new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")), classSet);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Just don't do anything
|
||||||
|
}
|
||||||
|
}
|
||||||
Decompiler decompiler = new Decompiler(classSet, classLoader);
|
Decompiler decompiler = new Decompiler(classSet, classLoader);
|
||||||
ClassSetOptimizer optimizer = new ClassSetOptimizer();
|
ClassSetOptimizer optimizer = new ClassSetOptimizer();
|
||||||
optimizer.optimizeAll(classSet);
|
optimizer.optimizeAll(classSet);
|
||||||
|
@ -119,6 +138,102 @@ public class JavascriptBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void logBytecode(PrintWriter writer, ListableClassHolderSource classes) {
|
||||||
|
for (String className : classes.getClassNames()) {
|
||||||
|
ClassHolder classHolder = classes.getClassHolder(className);
|
||||||
|
printModifiers(writer, classHolder);
|
||||||
|
writer.println("class " + className);
|
||||||
|
for (MethodHolder method : classHolder.getMethods()) {
|
||||||
|
logMethodBytecode(writer, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logMethodBytecode(PrintWriter writer, MethodHolder method) {
|
||||||
|
writer.print(" ");
|
||||||
|
printModifiers(writer, method);
|
||||||
|
writer.print(method.getName() + "(");
|
||||||
|
ValueType[] parameterTypes = method.getParameterTypes();
|
||||||
|
for (int i = 0; i < parameterTypes.length; ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
writer.print(", ");
|
||||||
|
}
|
||||||
|
printType(writer, parameterTypes[i]);
|
||||||
|
}
|
||||||
|
writer.println(")");
|
||||||
|
if (method.getProgram() != null) {
|
||||||
|
ListingBuilder builder = new ListingBuilder();
|
||||||
|
writer.println(builder.buildListing(method.getProgram(), " "));
|
||||||
|
} else {
|
||||||
|
writer.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printType(PrintWriter writer, ValueType type) {
|
||||||
|
if (type instanceof ValueType.Object) {
|
||||||
|
writer.print(((ValueType.Object)type).getClassName());
|
||||||
|
} else if (type instanceof ValueType.Array) {
|
||||||
|
printType(writer, ((ValueType.Array)type).getItemType());
|
||||||
|
writer.print("[]");
|
||||||
|
} else if (type instanceof ValueType.Primitive) {
|
||||||
|
switch (((ValueType.Primitive)type).getKind()) {
|
||||||
|
case BOOLEAN:
|
||||||
|
writer.print("boolean");
|
||||||
|
break;
|
||||||
|
case SHORT:
|
||||||
|
writer.print("short");
|
||||||
|
break;
|
||||||
|
case BYTE:
|
||||||
|
writer.print("byte");
|
||||||
|
break;
|
||||||
|
case CHARACTER:
|
||||||
|
writer.print("character");
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
writer.print("double");
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
writer.print("float");
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
writer.print("int");
|
||||||
|
break;
|
||||||
|
case LONG:
|
||||||
|
writer.print("long");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printModifiers(PrintWriter writer, ElementHolder element) {
|
||||||
|
switch (element.getLevel()) {
|
||||||
|
case PRIVATE:
|
||||||
|
writer.print("private ");
|
||||||
|
break;
|
||||||
|
case PUBLIC:
|
||||||
|
writer.print("public ");
|
||||||
|
break;
|
||||||
|
case PROTECTED:
|
||||||
|
writer.print("protected ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Set<ElementModifier> modifiers = element.getModifiers();
|
||||||
|
if (modifiers.contains(ElementModifier.ABSTRACT)) {
|
||||||
|
writer.print("abstract ");
|
||||||
|
}
|
||||||
|
if (modifiers.contains(ElementModifier.FINAL)) {
|
||||||
|
writer.print("final ");
|
||||||
|
}
|
||||||
|
if (modifiers.contains(ElementModifier.STATIC)) {
|
||||||
|
writer.print("static ");
|
||||||
|
}
|
||||||
|
if (modifiers.contains(ElementModifier.NATIVE)) {
|
||||||
|
writer.print("native ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void build(File file) throws RenderingException {
|
public void build(File file) throws RenderingException {
|
||||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||||
build(writer);
|
build(writer);
|
||||||
|
|
|
@ -37,6 +37,7 @@ public class Program {
|
||||||
public Variable createVariable() {
|
public Variable createVariable() {
|
||||||
Variable variable = new Variable(this);
|
Variable variable = new Variable(this);
|
||||||
variable.setIndex(variables.size());
|
variable.setIndex(variables.size());
|
||||||
|
variable.setRepresentative(variable.getIndex());
|
||||||
variables.add(variable);
|
variables.add(variable);
|
||||||
return variable;
|
return variable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.teavm.model;
|
||||||
public class Variable {
|
public class Variable {
|
||||||
private Program program;
|
private Program program;
|
||||||
private int index;
|
private int index;
|
||||||
|
private int representative;
|
||||||
|
|
||||||
Variable(Program program) {
|
Variable(Program program) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
|
@ -42,4 +43,12 @@ public class Variable {
|
||||||
void setProgram(Program program) {
|
void setProgram(Program program) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRepresentative() {
|
||||||
|
return representative;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepresentative(int representative) {
|
||||||
|
this.representative = representative;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
this.sb = sb;
|
this.sb = sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StringBuilder appendVar(Variable var) {
|
||||||
|
return sb.append('@').append(var.getIndex()).append(":").append(var.getRepresentative());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(EmptyInstruction insn) {
|
public void visit(EmptyInstruction insn) {
|
||||||
sb.append("nop");
|
sb.append("nop");
|
||||||
|
@ -37,49 +41,43 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ClassConstantInstruction insn) {
|
public void visit(ClassConstantInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := classOf ")
|
appendVar(insn.getReceiver()).append(" := classOf ").append(insn.getConstant());
|
||||||
.append(insn.getConstant());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NullConstantInstruction insn) {
|
public void visit(NullConstantInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := null");
|
appendVar(insn.getReceiver()).append(" := null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IntegerConstantInstruction insn) {
|
public void visit(IntegerConstantInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := ")
|
appendVar(insn.getReceiver()).append(" := ").append(insn.getConstant());
|
||||||
.append(insn.getConstant());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LongConstantInstruction insn) {
|
public void visit(LongConstantInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := ")
|
appendVar(insn.getReceiver()).append(" := ").append(insn.getConstant());
|
||||||
.append(insn.getConstant());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FloatConstantInstruction insn) {
|
public void visit(FloatConstantInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := ")
|
appendVar(insn.getReceiver()).append(" := ").append(insn.getConstant());
|
||||||
.append(insn.getConstant());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoubleConstantInstruction insn) {
|
public void visit(DoubleConstantInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := ")
|
appendVar(insn.getReceiver()).append(" := ").append(insn.getConstant());
|
||||||
.append(insn.getConstant());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StringConstantInstruction insn) {
|
public void visit(StringConstantInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := '")
|
appendVar(insn.getReceiver()).append(" := '").append(insn.getConstant()).append("'");
|
||||||
.append(insn.getConstant()).append("'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryInstruction insn) {
|
public void visit(BinaryInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := @")
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
.append(insn.getFirstOperand().getIndex()).append(" ");
|
appendVar(insn.getFirstOperand()).append(" ");
|
||||||
switch (insn.getOperation()) {
|
switch (insn.getOperation()) {
|
||||||
case ADD:
|
case ADD:
|
||||||
sb.append("+");
|
sb.append("+");
|
||||||
|
@ -118,24 +116,26 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
sb.append("^");
|
sb.append("^");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sb.append(" @").append(insn.getSecondOperand().getIndex());
|
sb.append(' ');
|
||||||
|
appendVar(insn.getSecondOperand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NegateInstruction insn) {
|
public void visit(NegateInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := -")
|
appendVar(insn.getReceiver()).append(" := -");
|
||||||
.append(" @").append(insn.getOperand().getIndex());
|
appendVar(insn.getOperand());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignInstruction insn) {
|
public void visit(AssignInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := @")
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
.append(insn.getAssignee().getIndex());
|
appendVar(insn.getAssignee());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BranchingInstruction insn) {
|
public void visit(BranchingInstruction insn) {
|
||||||
sb.append("if @").append(insn.getOperand().getIndex()).append(" ");
|
sb.append("if ");
|
||||||
|
appendVar(insn.getOperand()).append(" ");
|
||||||
switch (insn.getCondition()) {
|
switch (insn.getCondition()) {
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
sb.append("== 0");
|
sb.append("== 0");
|
||||||
|
@ -168,7 +168,8 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryBranchingInstruction insn) {
|
public void visit(BinaryBranchingInstruction insn) {
|
||||||
sb.append("if @").append(insn.getFirstOperand().getIndex()).append(" ");
|
sb.append("if ");
|
||||||
|
appendVar(insn.getFirstOperand()).append(" ");
|
||||||
switch (insn.getCondition()) {
|
switch (insn.getCondition()) {
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
case REFERENCE_EQUAL:
|
case REFERENCE_EQUAL:
|
||||||
|
@ -179,8 +180,7 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
sb.append("!=");
|
sb.append("!=");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sb.append("@").append(insn.getSecondOperand().getIndex())
|
appendVar(insn.getSecondOperand()).append(" then goto $").append(insn.getConsequent().getIndex())
|
||||||
.append(" then goto $").append(insn.getConsequent().getIndex())
|
|
||||||
.append(" else goto $").append(insn.getAlternative().getIndex());
|
.append(" else goto $").append(insn.getAlternative().getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,15 +191,15 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SwitchInstruction insn) {
|
public void visit(SwitchInstruction insn) {
|
||||||
sb.append("switch @").append(insn.getCondition().getIndex()).append(" ");
|
sb.append("switch ");
|
||||||
|
appendVar(insn.getCondition()).append(" ");
|
||||||
List<SwitchTableEntry> entries = insn.getEntries();
|
List<SwitchTableEntry> entries = insn.getEntries();
|
||||||
for (int i = 0; i < entries.size(); ++i) {
|
for (int i = 0; i < entries.size(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
sb.append("; ");
|
sb.append("; ");
|
||||||
}
|
}
|
||||||
SwitchTableEntry entry = entries.get(i);
|
SwitchTableEntry entry = entries.get(i);
|
||||||
sb.append("case ").append(entry.getCondition()).append(": goto $")
|
sb.append("case ").append(entry.getCondition()).append(": goto $").append(entry.getTarget());
|
||||||
.append(entry.getTarget());
|
|
||||||
}
|
}
|
||||||
sb.append(", default: goto $").append(insn.getDefaultTarget());
|
sb.append(", default: goto $").append(insn.getDefaultTarget());
|
||||||
}
|
}
|
||||||
|
@ -208,48 +208,46 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
public void visit(ExitInstruction insn) {
|
public void visit(ExitInstruction insn) {
|
||||||
sb.append("return");
|
sb.append("return");
|
||||||
if (insn.getValueToReturn() != null) {
|
if (insn.getValueToReturn() != null) {
|
||||||
sb.append(" @").append(insn.getValueToReturn().getIndex());
|
sb.append(" ");
|
||||||
|
appendVar(insn.getValueToReturn());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RaiseInstruction insn) {
|
public void visit(RaiseInstruction insn) {
|
||||||
sb.append("throw @").append(insn.getException().getIndex());
|
sb.append("throw ");
|
||||||
|
appendVar(insn.getException());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ConstructArrayInstruction insn) {
|
public void visit(ConstructArrayInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" = new ")
|
appendVar(insn.getReceiver()).append(" = new ").append(insn.getItemType()).append("[");
|
||||||
.append(insn.getItemType()).append("[@").append(insn.getSize().getIndex())
|
appendVar(insn.getSize()).append(']');
|
||||||
.append(']');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ConstructInstruction insn) {
|
public void visit(ConstructInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" = new ")
|
appendVar(insn.getReceiver()).append(" = new ").append(insn.getType()).append("()");
|
||||||
.append(insn.getType()).append("()");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ConstructMultiArrayInstruction insn) {
|
public void visit(ConstructMultiArrayInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" = new ")
|
appendVar(insn.getReceiver()).append(" = new ").append(insn.getItemType()).append("[");
|
||||||
.append(insn.getItemType()).append("[");
|
|
||||||
List<Variable> dimensions = insn.getDimensions();
|
List<Variable> dimensions = insn.getDimensions();
|
||||||
for (int i = 0; i < dimensions.size(); ++i) {
|
for (int i = 0; i < dimensions.size(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
Variable dimension = dimensions.get(i);
|
appendVar(dimensions.get(i));
|
||||||
sb.append("@").append(dimension.getIndex());
|
|
||||||
}
|
}
|
||||||
sb.append("]");
|
sb.append("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GetFieldInstruction insn) {
|
public void visit(GetFieldInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := ");
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
if (insn.getInstance() != null) {
|
if (insn.getInstance() != null) {
|
||||||
sb.append("@").append(insn.getInstance().getIndex());
|
appendVar(insn.getInstance());
|
||||||
} else {
|
} else {
|
||||||
sb.append(insn.getField().getClassName());
|
sb.append(insn.getField().getClassName());
|
||||||
}
|
}
|
||||||
|
@ -259,34 +257,35 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
@Override
|
@Override
|
||||||
public void visit(PutFieldInstruction insn) {
|
public void visit(PutFieldInstruction insn) {
|
||||||
if (insn.getInstance() != null) {
|
if (insn.getInstance() != null) {
|
||||||
sb.append("@").append(insn.getInstance().getIndex());
|
appendVar(insn.getInstance());
|
||||||
} else {
|
} else {
|
||||||
sb.append(insn.getField().getClassName());
|
sb.append(insn.getField().getClassName());
|
||||||
}
|
}
|
||||||
sb.append(".").append(insn.getField()).append(" := @").append(insn.getValue().getIndex());
|
sb.append(".").append(insn.getField()).append(" := ");
|
||||||
|
appendVar(insn.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GetElementInstruction insn) {
|
public void visit(GetElementInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := @")
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
.append(insn.getArray().getIndex()).append("[@")
|
appendVar(insn.getArray()).append("[");
|
||||||
.append(insn.getIndex().getIndex()).append("]");
|
appendVar(insn.getIndex()).append("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(PutElementInstruction insn) {
|
public void visit(PutElementInstruction insn) {
|
||||||
sb.append("@").append(insn.getArray().getIndex()).append("[@")
|
appendVar(insn.getArray()).append("[");
|
||||||
.append(insn.getIndex().getIndex()).append("] := @")
|
appendVar(insn.getIndex()).append("] := ");
|
||||||
.append(insn.getValue().getIndex());
|
appendVar(insn.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InvokeInstruction insn) {
|
public void visit(InvokeInstruction insn) {
|
||||||
if (insn.getReceiver() != null) {
|
if (insn.getReceiver() != null) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := ");
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
}
|
}
|
||||||
if (insn.getInstance() != null) {
|
if (insn.getInstance() != null) {
|
||||||
sb.append("@").append(insn.getInstance().getIndex());
|
appendVar(insn.getInstance());
|
||||||
} else {
|
} else {
|
||||||
sb.append(insn.getMethod().getClassName());
|
sb.append(insn.getMethod().getClassName());
|
||||||
}
|
}
|
||||||
|
@ -296,55 +295,52 @@ public class InstructionStringifier implements InstructionVisitor {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
sb.append("@").append(arguments.get(i).getIndex());
|
appendVar(arguments.get(i));
|
||||||
}
|
}
|
||||||
sb.append(")");
|
sb.append(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IsInstanceInstruction insn) {
|
public void visit(IsInstanceInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := @")
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
.append(insn.getValue().getIndex()).append(" instanceof ").append(insn.getType());
|
appendVar(insn.getValue()).append(" instanceof ").append(insn.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastInstruction insn) {
|
public void visit(CastInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := cast @")
|
appendVar(insn.getReceiver()).append(" := cast ");
|
||||||
.append(insn.getValue().getIndex()).append(" to ")
|
appendVar(insn.getValue()).append(" to ").append(insn.getTargetType());
|
||||||
.append(insn.getTargetType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastNumberInstruction insn) {
|
public void visit(CastNumberInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := cast @")
|
appendVar(insn.getReceiver()).append(" := cast ");
|
||||||
.append(insn.getValue().getIndex())
|
appendVar(insn.getValue()).append(" from ").append(insn.getSourceType())
|
||||||
.append(" from ").append(insn.getSourceType())
|
|
||||||
.append(" to ").append(insn.getTargetType());
|
.append(" to ").append(insn.getTargetType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastIntegerInstruction insn) {
|
public void visit(CastIntegerInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := cast @")
|
appendVar(insn.getReceiver()).append(" := cast ");
|
||||||
.append(insn.getValue().getIndex())
|
appendVar(insn.getValue()).append(" from INT to ").append(insn.getTargetType());
|
||||||
.append(" from INT to ").append(insn.getTargetType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(UnwrapArrayInstruction insn) {
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append("@").append(" := @")
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
.append(insn.getArray()).append(".data");
|
appendVar(insn.getArray()).append(".data");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArrayLengthInstruction insn) {
|
public void visit(ArrayLengthInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := @")
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
.append(insn.getArray().getIndex()).append(".length");
|
appendVar(insn.getArray()).append(".length");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CloneArrayInstruction insn) {
|
public void visit(CloneArrayInstruction insn) {
|
||||||
sb.append("@").append(insn.getReceiver().getIndex()).append("@")
|
appendVar(insn.getReceiver()).append(" := ");
|
||||||
.append(insn.getArray().getIndex()).append(".clone()");
|
appendVar(insn.getArray()).append(".clone()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,14 +31,16 @@ public class ListingBuilder {
|
||||||
sb.append(prefix).append("$").append(i).append(":\n");
|
sb.append(prefix).append("$").append(i).append(":\n");
|
||||||
for (Phi phi : block.getPhis()) {
|
for (Phi phi : block.getPhis()) {
|
||||||
sb.append(prefix).append(" ");
|
sb.append(prefix).append(" ");
|
||||||
sb.append("@").append(phi.getReceiver().getIndex()).append(" := ");
|
sb.append("@").append(phi.getReceiver().getIndex()).append(":")
|
||||||
|
.append(phi.getReceiver().getRepresentative()).append(" := ");
|
||||||
List<Incoming> incomings = phi.getIncomings();
|
List<Incoming> incomings = phi.getIncomings();
|
||||||
for (int j = 0; j < incomings.size(); ++j) {
|
for (int j = 0; j < incomings.size(); ++j) {
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
Incoming incoming = incomings.get(j);
|
Incoming incoming = incomings.get(j);
|
||||||
sb.append("@").append(incoming.getValue().getIndex()).append(" from ")
|
sb.append("@").append(incoming.getValue().getIndex()).append(":")
|
||||||
|
.append(incoming.getValue().getRepresentative()).append(" from ")
|
||||||
.append("$").append(incoming.getSource().getIndex());
|
.append("$").append(incoming.getSource().getIndex());
|
||||||
}
|
}
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class PhiEliminator {
|
||||||
|
|
||||||
|
}
|
|
@ -77,6 +77,9 @@ public class SSATransformer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i <= arguments.length; ++i) {
|
||||||
|
program.variableAt(i).setRepresentative(i);
|
||||||
|
}
|
||||||
arguments = null;
|
arguments = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +126,7 @@ public class SSATransformer {
|
||||||
for (Phi phi : currentBlock.getPhis()) {
|
for (Phi phi : currentBlock.getPhis()) {
|
||||||
Variable var = program.createVariable();
|
Variable var = program.createVariable();
|
||||||
variableMap[phi.getReceiver().getIndex()] = var;
|
variableMap[phi.getReceiver().getIndex()] = var;
|
||||||
|
var.setRepresentative(phi.getReceiver().getIndex());
|
||||||
phi.setReceiver(var);
|
phi.setReceiver(var);
|
||||||
}
|
}
|
||||||
for (Instruction insn : currentBlock.getInstructions()) {
|
for (Instruction insn : currentBlock.getInstructions()) {
|
||||||
|
@ -181,6 +185,7 @@ public class SSATransformer {
|
||||||
|
|
||||||
private Variable define(Variable var) {
|
private Variable define(Variable var) {
|
||||||
Variable result = program.createVariable();
|
Variable result = program.createVariable();
|
||||||
|
result.setRepresentative(var.getIndex());
|
||||||
variableMap[var.getIndex()] = result;
|
variableMap[var.getIndex()] = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,9 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean mainPageIncluded;
|
private boolean mainPageIncluded;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private boolean bytecodeLogging;
|
||||||
|
|
||||||
public void setProject(MavenProject project) {
|
public void setProject(MavenProject project) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +87,10 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
this.minifying = minifying;
|
this.minifying = minifying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBytecodeLogging(boolean bytecodeLogging) {
|
||||||
|
this.bytecodeLogging = bytecodeLogging;
|
||||||
|
}
|
||||||
|
|
||||||
public void setRuntimeSuppressed(boolean runtimeSuppressed) {
|
public void setRuntimeSuppressed(boolean runtimeSuppressed) {
|
||||||
this.runtimeSuppressed = runtimeSuppressed;
|
this.runtimeSuppressed = runtimeSuppressed;
|
||||||
}
|
}
|
||||||
|
@ -100,6 +107,7 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
log.info("Building JavaScript file");
|
log.info("Building JavaScript file");
|
||||||
JavascriptBuilder builder = new JavascriptBuilder(classLoader);
|
JavascriptBuilder builder = new JavascriptBuilder(classLoader);
|
||||||
builder.setMinifying(minifying);
|
builder.setMinifying(minifying);
|
||||||
|
builder.setBytecodeLogging(bytecodeLogging);
|
||||||
MethodDescriptor mainMethodDesc = new MethodDescriptor("main", ValueType.arrayOf(
|
MethodDescriptor mainMethodDesc = new MethodDescriptor("main", ValueType.arrayOf(
|
||||||
ValueType.object("java.lang.String")), ValueType.VOID);
|
ValueType.object("java.lang.String")), ValueType.VOID);
|
||||||
builder.entryPoint("main", new MethodReference(mainClass, mainMethodDesc))
|
builder.entryPoint("main", new MethodReference(mainClass, mainMethodDesc))
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<mainClass>org.teavm.samples.HelloWorld</mainClass>
|
<mainClass>org.teavm.samples.HelloWorld</mainClass>
|
||||||
<mainPageIncluded>true</mainPageIncluded>
|
<mainPageIncluded>true</mainPageIncluded>
|
||||||
|
<bytecodeLogging>true</bytecodeLogging>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user