mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Propagating variable name via compiler's pipeline
This commit is contained in:
parent
c5c453d95b
commit
1c1b0c69fa
|
@ -49,7 +49,7 @@ public final class TArray extends TObject {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static RuntimeObject newInstanceLowLevel(RuntimeClass cls, int length) {
|
private static RuntimeObject newInstanceLowLevel(RuntimeClass cls, int length) {
|
||||||
return Allocator.allocateArray(cls, length).toStructure();
|
return Allocator.allocateArray(cls.arrayType, length).toStructure();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TObject get(TObject array, int index) throws TIllegalArgumentException,
|
public static TObject get(TObject array, int index) throws TIllegalArgumentException,
|
||||||
|
|
|
@ -15,15 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.ast;
|
package org.teavm.ast;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.teavm.model.TextLocation;
|
import org.teavm.model.TextLocation;
|
||||||
|
|
||||||
public class AssignmentStatement extends Statement {
|
public class AssignmentStatement extends Statement {
|
||||||
private Expr leftValue;
|
private Expr leftValue;
|
||||||
private Expr rightValue;
|
private Expr rightValue;
|
||||||
private TextLocation location;
|
private TextLocation location;
|
||||||
private Set<String> debugNames = new HashSet<>();
|
|
||||||
private boolean async;
|
private boolean async;
|
||||||
|
|
||||||
public Expr getLeftValue() {
|
public Expr getLeftValue() {
|
||||||
|
@ -50,10 +47,6 @@ public class AssignmentStatement extends Statement {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getDebugNames() {
|
|
||||||
return debugNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAsync() {
|
public boolean isAsync() {
|
||||||
return async;
|
return async;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ package org.teavm.ast;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
public class AsyncMethodNode extends MethodNode {
|
public class AsyncMethodNode extends MethodNode {
|
||||||
|
@ -33,19 +31,11 @@ public class AsyncMethodNode extends MethodNode {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<VariableNode> getVariables() {
|
public List<VariableNode> getVariables() {
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Set<String>> getParameterDebugNames() {
|
|
||||||
return variables.subList(0, getReference().parameterCount())
|
|
||||||
.stream()
|
|
||||||
.map(VariableNode::getDebugNames)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptVisitor(MethodNodeVisitor visitor) {
|
public void acceptVisitor(MethodNodeVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
|
|
|
@ -42,5 +42,5 @@ public abstract class MethodNode {
|
||||||
|
|
||||||
public abstract boolean isAsync();
|
public abstract boolean isAsync();
|
||||||
|
|
||||||
public abstract List<Set<String>> getParameterDebugNames();
|
public abstract List<VariableNode> getVariables();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package org.teavm.ast;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import org.teavm.backend.javascript.spi.Generator;
|
import org.teavm.backend.javascript.spi.Generator;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ public class NativeMethodNode extends MethodNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Set<String>> getParameterDebugNames() {
|
public List<VariableNode> getVariables() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ package org.teavm.ast;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
public class RegularMethodNode extends MethodNode {
|
public class RegularMethodNode extends MethodNode {
|
||||||
|
@ -37,18 +35,11 @@ public class RegularMethodNode extends MethodNode {
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<VariableNode> getVariables() {
|
public List<VariableNode> getVariables() {
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Set<String>> getParameterDebugNames() {
|
|
||||||
return variables.subList(0, getReference().parameterCount())
|
|
||||||
.stream()
|
|
||||||
.map(VariableNode::getDebugNames)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptVisitor(MethodNodeVisitor visitor) {
|
public void acceptVisitor(MethodNodeVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
|
|
|
@ -15,14 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.ast;
|
package org.teavm.ast;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.teavm.model.util.VariableType;
|
import org.teavm.model.util.VariableType;
|
||||||
|
|
||||||
public class VariableNode {
|
public class VariableNode {
|
||||||
private int index;
|
private int index;
|
||||||
private VariableType type;
|
private VariableType type;
|
||||||
private Set<String> debugNames = new HashSet<>();
|
private String name;
|
||||||
|
|
||||||
public VariableNode(int index, VariableType type) {
|
public VariableNode(int index, VariableType type) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
@ -45,7 +43,11 @@ public class VariableNode {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getDebugNames() {
|
public String getName() {
|
||||||
return debugNames;
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,6 @@ import org.teavm.model.Program;
|
||||||
import org.teavm.model.TextLocation;
|
import org.teavm.model.TextLocation;
|
||||||
import org.teavm.model.TryCatchBlock;
|
import org.teavm.model.TryCatchBlock;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.model.Variable;
|
|
||||||
import org.teavm.model.util.AsyncProgramSplitter;
|
import org.teavm.model.util.AsyncProgramSplitter;
|
||||||
import org.teavm.model.util.ListingBuilder;
|
import org.teavm.model.util.ListingBuilder;
|
||||||
import org.teavm.model.util.ProgramUtils;
|
import org.teavm.model.util.ProgramUtils;
|
||||||
|
@ -271,17 +270,14 @@ public class Decompiler {
|
||||||
typeInferer.inferTypes(program, method.getReference());
|
typeInferer.inferTypes(program, method.getReference());
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i));
|
VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i));
|
||||||
|
variable.setName(program.variableAt(i).getDebugName());
|
||||||
methodNode.getVariables().add(variable);
|
methodNode.getVariables().add(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optimizer optimizer = new Optimizer();
|
Optimizer optimizer = new Optimizer();
|
||||||
optimizer.optimize(methodNode, method.getProgram());
|
optimizer.optimize(methodNode, method.getProgram());
|
||||||
methodNode.getModifiers().addAll(method.getModifiers());
|
methodNode.getModifiers().addAll(method.getModifiers());
|
||||||
int paramCount = Math.min(method.getSignature().length, program.variableCount());
|
|
||||||
for (int i = 0; i < paramCount; ++i) {
|
|
||||||
Variable var = program.variableAt(i);
|
|
||||||
methodNode.getParameterDebugNames().add(new HashSet<>(var.getDebugNames()));
|
|
||||||
}
|
|
||||||
return methodNode;
|
return methodNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,17 +334,14 @@ public class Decompiler {
|
||||||
typeInferer.inferTypes(program, method.getReference());
|
typeInferer.inferTypes(program, method.getReference());
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i));
|
VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i));
|
||||||
|
variable.setName(program.variableAt(i).getDebugName());
|
||||||
node.getVariables().add(variable);
|
node.getVariables().add(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optimizer optimizer = new Optimizer();
|
Optimizer optimizer = new Optimizer();
|
||||||
optimizer.optimize(node, splitter);
|
optimizer.optimize(node, splitter);
|
||||||
node.getModifiers().addAll(method.getModifiers());
|
node.getModifiers().addAll(method.getModifiers());
|
||||||
int paramCount = Math.min(method.getSignature().length, program.variableCount());
|
|
||||||
for (int i = 0; i < paramCount; ++i) {
|
|
||||||
Variable var = program.variableAt(i);
|
|
||||||
node.getParameterDebugNames().add(new HashSet<>(var.getDebugNames()));
|
|
||||||
}
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,6 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
public void visit(AssignInstruction insn) {
|
public void visit(AssignInstruction insn) {
|
||||||
AssignmentStatement stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()),
|
AssignmentStatement stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()),
|
||||||
Expr.var(insn.getAssignee().getIndex()));
|
Expr.var(insn.getAssignee().getIndex()));
|
||||||
stmt.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
|
||||||
stmt.setLocation(currentLocation);
|
stmt.setLocation(currentLocation);
|
||||||
statements.add(stmt);
|
statements.add(stmt);
|
||||||
}
|
}
|
||||||
|
@ -500,7 +499,6 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
AssignmentStatement stmt;
|
AssignmentStatement stmt;
|
||||||
if (insn.getReceiver() != null) {
|
if (insn.getReceiver() != null) {
|
||||||
stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), invocationExpr);
|
stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), invocationExpr);
|
||||||
stmt.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
|
||||||
} else {
|
} else {
|
||||||
stmt = Statement.assign(null, invocationExpr);
|
stmt = Statement.assign(null, invocationExpr);
|
||||||
}
|
}
|
||||||
|
@ -523,7 +521,6 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
private void assign(Expr source, Variable target) {
|
private void assign(Expr source, Variable target) {
|
||||||
AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source);
|
AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source);
|
||||||
stmt.setLocation(currentLocation);
|
stmt.setLocation(currentLocation);
|
||||||
stmt.getDebugNames().addAll(target.getDebugNames());
|
|
||||||
statements.add(stmt);
|
statements.add(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,8 +126,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
private boolean async;
|
private boolean async;
|
||||||
private Precedence precedence;
|
private Precedence precedence;
|
||||||
private final Map<String, String> blockIdMap = new HashMap<>();
|
private final Map<String, String> blockIdMap = new HashMap<>();
|
||||||
private final List<Set<String>> debugNames = new ArrayList<>();
|
|
||||||
private final List<String> cachedVariableNames = new ArrayList<>();
|
private final List<String> cachedVariableNames = new ArrayList<>();
|
||||||
|
private MethodNode currentMethod;
|
||||||
private boolean end;
|
private boolean end;
|
||||||
private int currentPart;
|
private int currentPart;
|
||||||
private List<PostponedFieldInitializer> postponedFieldInitializers = new ArrayList<>();
|
private List<PostponedFieldInitializer> postponedFieldInitializers = new ArrayList<>();
|
||||||
|
@ -652,9 +652,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderBody(MethodNode method, boolean inner) throws IOException {
|
private void renderBody(MethodNode method, boolean inner) throws IOException {
|
||||||
debugNames.clear();
|
currentMethod = method;
|
||||||
cachedVariableNames.clear();
|
cachedVariableNames.clear();
|
||||||
debugNames.addAll(method.getParameterDebugNames());
|
|
||||||
blockIdMap.clear();
|
blockIdMap.clear();
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
debugEmitter.emitMethod(ref.getDescriptor());
|
debugEmitter.emitMethod(ref.getDescriptor());
|
||||||
|
@ -704,8 +703,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
Renderer.this.async = false;
|
Renderer.this.async = false;
|
||||||
this.async = false;
|
this.async = false;
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
for (int i = 0; i < method.getParameterDebugNames().size(); ++i) {
|
for (int i = 0; i < method.getVariables().size(); ++i) {
|
||||||
debugEmitter.emitVariable(method.getParameterDebugNames().get(i).toArray(new String[0]),
|
debugEmitter.emitVariable(new String[] { method.getVariables().get(i).getName() },
|
||||||
variableName(i));
|
variableName(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,8 +747,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
Renderer.this.async = true;
|
Renderer.this.async = true;
|
||||||
this.async = true;
|
this.async = true;
|
||||||
MethodReference ref = methodNode.getReference();
|
MethodReference ref = methodNode.getReference();
|
||||||
for (int i = 0; i < methodNode.getParameterDebugNames().size(); ++i) {
|
for (int i = 0; i < methodNode.getVariables().size(); ++i) {
|
||||||
debugEmitter.emitVariable(methodNode.getParameterDebugNames().get(i).toArray(new String[0]),
|
debugEmitter.emitVariable(new String[] { methodNode.getVariables().get(i).getName() },
|
||||||
variableName(i));
|
variableName(i));
|
||||||
}
|
}
|
||||||
int variableCount = 0;
|
int variableCount = 0;
|
||||||
|
@ -967,11 +966,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
if (statement.getLocation() != null) {
|
if (statement.getLocation() != null) {
|
||||||
popLocation();
|
popLocation();
|
||||||
}
|
}
|
||||||
if (statement.getLeftValue() instanceof VariableExpr) {
|
|
||||||
VariableExpr receiver = (VariableExpr) statement.getLeftValue();
|
|
||||||
debugEmitter.emitVariable(statement.getDebugNames().toArray(new String[0]),
|
|
||||||
variableName(receiver.getIndex()));
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RenderingException("IO error occurred", e);
|
throw new RenderingException("IO error occurred", e);
|
||||||
}
|
}
|
||||||
|
@ -1258,7 +1252,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
return minifying ? "$t" : "$this";
|
return minifying ? "$t" : "$this";
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> names = index < debugNames.size() ? debugNames.get(index) : null;
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
--index;
|
--index;
|
||||||
if (index < variableNames.length()) {
|
if (index < variableNames.length()) {
|
||||||
|
@ -1267,11 +1260,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
sb.append(Character.toString(variableNames.charAt(index % variableNames.length()))
|
sb.append(Character.toString(variableNames.charAt(index % variableNames.length()))
|
||||||
+ index / variableNames.length());
|
+ index / variableNames.length());
|
||||||
}
|
}
|
||||||
if (!minifying && names != null && !names.isEmpty()) {
|
if (!minifying) {
|
||||||
List<String> nameList = new ArrayList<>(names);
|
VariableNode variable = index < currentMethod.getVariables().size()
|
||||||
Collections.sort(nameList);
|
? currentMethod.getVariables().get(index)
|
||||||
for (String name : nameList) {
|
: null;
|
||||||
sb.append('_').append(escapeName(name));
|
if (variable != null && variable.getName() != null) {
|
||||||
|
sb.setLength(0);
|
||||||
|
sb.append(escapeName(variable.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class WasmGenerator {
|
||||||
WasmType type = variable.getType() != null
|
WasmType type = variable.getType() != null
|
||||||
? WasmGeneratorUtil.mapType(variable.getType())
|
? WasmGeneratorUtil.mapType(variable.getType())
|
||||||
: WasmType.INT32;
|
: WasmType.INT32;
|
||||||
function.add(new WasmLocal(type));
|
function.add(new WasmLocal(type, variable.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = firstVariable; i <= methodReference.parameterCount(); ++i) {
|
for (int i = firstVariable; i <= methodReference.parameterCount(); ++i) {
|
||||||
|
|
|
@ -182,12 +182,16 @@ public class WasmCRenderer {
|
||||||
}
|
}
|
||||||
sb.append(WasmCRenderingVisitor.mapType(function.getResult())).append(' ');
|
sb.append(WasmCRenderingVisitor.mapType(function.getResult())).append(' ');
|
||||||
sb.append(function.getName()).append("(");
|
sb.append(function.getName()).append("(");
|
||||||
|
WasmCRenderingVisitor visitor = new WasmCRenderingVisitor(function.getResult(), function.getModule());
|
||||||
for (int i = 0; i < function.getParameters().size(); ++i) {
|
for (int i = 0; i < function.getParameters().size(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
sb.append(WasmCRenderingVisitor.mapType(function.getParameters().get(i)));
|
sb.append(WasmCRenderingVisitor.mapType(function.getParameters().get(i)));
|
||||||
sb.append(" var_" + i);
|
WasmLocal local = i < function.getLocalVariables().size()
|
||||||
|
? function.getLocalVariables().get(i)
|
||||||
|
: null;
|
||||||
|
sb.append(" ").append(local != null ? visitor.getVariableName(local) : "var_" + i);
|
||||||
}
|
}
|
||||||
sb.append(")");
|
sb.append(")");
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
import org.teavm.backend.wasm.model.WasmModule;
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
||||||
|
@ -303,7 +304,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WasmGetLocal expression) {
|
public void visit(WasmGetLocal expression) {
|
||||||
value = new CExpression("var_" + expression.getLocal().getIndex());
|
value = new CExpression(getVariableName(expression.getLocal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -313,7 +314,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
||||||
expression.getValue().acceptVisitor(this);
|
expression.getValue().acceptVisitor(this);
|
||||||
result.getLines().addAll(value.getLines());
|
result.getLines().addAll(value.getLines());
|
||||||
|
|
||||||
result.addLine("var_" + expression.getLocal().getIndex() + " = " + value.getText() + ";",
|
result.addLine(getVariableName(expression.getLocal()) + " = " + value.getText() + ";",
|
||||||
expression.getLocation());
|
expression.getLocation());
|
||||||
|
|
||||||
value = result;
|
value = result;
|
||||||
|
@ -1033,4 +1034,11 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
||||||
String temporaryVariable;
|
String temporaryVariable;
|
||||||
WasmType type;
|
WasmType type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getVariableName(WasmLocal local) {
|
||||||
|
if (local.getName() != null) {
|
||||||
|
return local.getName();
|
||||||
|
}
|
||||||
|
return "var_" + local.getIndex();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
51
core/src/main/java/org/teavm/cache/AstIO.java
vendored
51
core/src/main/java/org/teavm/cache/AstIO.java
vendored
|
@ -20,7 +20,6 @@ import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -45,7 +44,6 @@ import org.teavm.ast.InitClassStatement;
|
||||||
import org.teavm.ast.InstanceOfExpr;
|
import org.teavm.ast.InstanceOfExpr;
|
||||||
import org.teavm.ast.InvocationExpr;
|
import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.ast.InvocationType;
|
import org.teavm.ast.InvocationType;
|
||||||
import org.teavm.ast.MethodNode;
|
|
||||||
import org.teavm.ast.MonitorEnterStatement;
|
import org.teavm.ast.MonitorEnterStatement;
|
||||||
import org.teavm.ast.MonitorExitStatement;
|
import org.teavm.ast.MonitorExitStatement;
|
||||||
import org.teavm.ast.NewArrayExpr;
|
import org.teavm.ast.NewArrayExpr;
|
||||||
|
@ -99,7 +97,6 @@ public class AstIO {
|
||||||
for (VariableNode var : method.getVariables()) {
|
for (VariableNode var : method.getVariables()) {
|
||||||
write(output, var);
|
write(output, var);
|
||||||
}
|
}
|
||||||
output.writeShort(method.getParameterDebugNames().size());
|
|
||||||
try {
|
try {
|
||||||
method.getBody().acceptVisitor(new NodeWriter(output));
|
method.getBody().acceptVisitor(new NodeWriter(output));
|
||||||
} catch (IOExceptionWrapper e) {
|
} catch (IOExceptionWrapper e) {
|
||||||
|
@ -110,10 +107,7 @@ public class AstIO {
|
||||||
private void write(DataOutput output, VariableNode variable) throws IOException {
|
private void write(DataOutput output, VariableNode variable) throws IOException {
|
||||||
output.writeShort(variable.getIndex());
|
output.writeShort(variable.getIndex());
|
||||||
output.writeByte(variable.getType().ordinal());
|
output.writeByte(variable.getType().ordinal());
|
||||||
output.writeByte(variable.getDebugNames().size());
|
output.writeUTF(variable.getName() != null ? variable.getName() : "");
|
||||||
for (String debugName : variable.getDebugNames()) {
|
|
||||||
output.writeUTF(debugName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegularMethodNode read(DataInput input, MethodReference method) throws IOException {
|
public RegularMethodNode read(DataInput input, MethodReference method) throws IOException {
|
||||||
|
@ -133,7 +127,10 @@ public class AstIO {
|
||||||
VariableNode variable = new VariableNode(index, type);
|
VariableNode variable = new VariableNode(index, type);
|
||||||
int nameCount = input.readByte();
|
int nameCount = input.readByte();
|
||||||
for (int i = 0; i < nameCount; ++i) {
|
for (int i = 0; i < nameCount; ++i) {
|
||||||
variable.getDebugNames().add(input.readUTF());
|
variable.setName(input.readUTF());
|
||||||
|
if (variable.getName().isEmpty()) {
|
||||||
|
variable.setName(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return variable;
|
return variable;
|
||||||
}
|
}
|
||||||
|
@ -144,8 +141,6 @@ public class AstIO {
|
||||||
for (VariableNode var : method.getVariables()) {
|
for (VariableNode var : method.getVariables()) {
|
||||||
write(output, var);
|
write(output, var);
|
||||||
}
|
}
|
||||||
output.writeShort(method.getParameterDebugNames().size());
|
|
||||||
writeParameters(output, method);
|
|
||||||
try {
|
try {
|
||||||
output.writeShort(method.getBody().size());
|
output.writeShort(method.getBody().size());
|
||||||
for (int i = 0; i < method.getBody().size(); ++i) {
|
for (int i = 0; i < method.getBody().size(); ++i) {
|
||||||
|
@ -156,17 +151,6 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeParameters(DataOutput output, MethodNode method) throws IOException {
|
|
||||||
for (Set<String> debugNames : method.getParameterDebugNames()) {
|
|
||||||
output.writeShort(debugNames != null ? debugNames.size() : 0);
|
|
||||||
if (debugNames != null) {
|
|
||||||
for (String debugName : debugNames) {
|
|
||||||
output.writeUTF(debugName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncMethodNode readAsync(DataInput input, MethodReference method) throws IOException {
|
public AsyncMethodNode readAsync(DataInput input, MethodReference method) throws IOException {
|
||||||
AsyncMethodNode node = new AsyncMethodNode(method);
|
AsyncMethodNode node = new AsyncMethodNode(method);
|
||||||
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
||||||
|
@ -174,7 +158,6 @@ public class AstIO {
|
||||||
for (int i = 0; i < varCount; ++i) {
|
for (int i = 0; i < varCount; ++i) {
|
||||||
node.getVariables().add(readVariable(input));
|
node.getVariables().add(readVariable(input));
|
||||||
}
|
}
|
||||||
readParameters(input, node);
|
|
||||||
int partCount = input.readShort();
|
int partCount = input.readShort();
|
||||||
for (int i = 0; i < partCount; ++i) {
|
for (int i = 0; i < partCount; ++i) {
|
||||||
AsyncMethodPart part = new AsyncMethodPart();
|
AsyncMethodPart part = new AsyncMethodPart();
|
||||||
|
@ -184,18 +167,6 @@ public class AstIO {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readParameters(DataInput input, MethodNode node) throws IOException {
|
|
||||||
int paramDebugNameCount = input.readShort();
|
|
||||||
for (int i = 0; i < paramDebugNameCount; ++i) {
|
|
||||||
int debugNameCount = input.readShort();
|
|
||||||
Set<String> debugNames = new HashSet<>();
|
|
||||||
for (int j = 0; j < debugNameCount; ++j) {
|
|
||||||
debugNames.add(input.readUTF());
|
|
||||||
}
|
|
||||||
node.getParameterDebugNames().add(debugNames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int packModifiers(Set<ElementModifier> modifiers) {
|
private int packModifiers(Set<ElementModifier> modifiers) {
|
||||||
int packed = 0;
|
int packed = 0;
|
||||||
for (ElementModifier modifier : modifiers) {
|
for (ElementModifier modifier : modifiers) {
|
||||||
|
@ -257,10 +228,6 @@ public class AstIO {
|
||||||
try {
|
try {
|
||||||
output.writeByte(statement.getLeftValue() != null ? 0 : 1);
|
output.writeByte(statement.getLeftValue() != null ? 0 : 1);
|
||||||
writeLocation(statement.getLocation());
|
writeLocation(statement.getLocation());
|
||||||
output.writeShort(statement.getDebugNames().size());
|
|
||||||
for (String name : statement.getDebugNames()) {
|
|
||||||
output.writeUTF(name);
|
|
||||||
}
|
|
||||||
if (statement.getLeftValue() != null) {
|
if (statement.getLeftValue() != null) {
|
||||||
writeExpr(statement.getLeftValue());
|
writeExpr(statement.getLeftValue());
|
||||||
}
|
}
|
||||||
|
@ -674,10 +641,6 @@ public class AstIO {
|
||||||
case 0: {
|
case 0: {
|
||||||
AssignmentStatement stmt = new AssignmentStatement();
|
AssignmentStatement stmt = new AssignmentStatement();
|
||||||
stmt.setLocation(readLocation(input));
|
stmt.setLocation(readLocation(input));
|
||||||
int debugNameCount = input.readShort();
|
|
||||||
for (int i = 0; i < debugNameCount; ++i) {
|
|
||||||
stmt.getDebugNames().add(input.readUTF());
|
|
||||||
}
|
|
||||||
stmt.setLeftValue(readExpr(input));
|
stmt.setLeftValue(readExpr(input));
|
||||||
stmt.setRightValue(readExpr(input));
|
stmt.setRightValue(readExpr(input));
|
||||||
stmt.setAsync(input.readBoolean());
|
stmt.setAsync(input.readBoolean());
|
||||||
|
@ -686,10 +649,6 @@ public class AstIO {
|
||||||
case 1: {
|
case 1: {
|
||||||
AssignmentStatement stmt = new AssignmentStatement();
|
AssignmentStatement stmt = new AssignmentStatement();
|
||||||
stmt.setLocation(readLocation(input));
|
stmt.setLocation(readLocation(input));
|
||||||
int debugNameCount = input.readShort();
|
|
||||||
for (int i = 0; i < debugNameCount; ++i) {
|
|
||||||
stmt.getDebugNames().add(input.readUTF());
|
|
||||||
}
|
|
||||||
stmt.setRightValue(readExpr(input));
|
stmt.setRightValue(readExpr(input));
|
||||||
stmt.setAsync(input.readBoolean());
|
stmt.setAsync(input.readBoolean());
|
||||||
return stmt;
|
return stmt;
|
||||||
|
|
|
@ -43,10 +43,7 @@ public class ProgramIO {
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
Variable var = program.variableAt(i);
|
Variable var = program.variableAt(i);
|
||||||
data.writeShort(var.getRegister());
|
data.writeShort(var.getRegister());
|
||||||
data.writeShort(var.getDebugNames().size());
|
data.writeUTF(var.getDebugName() != null ? var.getDebugName() : "");
|
||||||
for (String debugString : var.getDebugNames()) {
|
|
||||||
data.writeUTF(debugString);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock basicBlock = program.basicBlockAt(i);
|
BasicBlock basicBlock = program.basicBlockAt(i);
|
||||||
|
@ -106,9 +103,9 @@ public class ProgramIO {
|
||||||
for (int i = 0; i < varCount; ++i) {
|
for (int i = 0; i < varCount; ++i) {
|
||||||
Variable var = program.createVariable();
|
Variable var = program.createVariable();
|
||||||
var.setRegister(data.readShort());
|
var.setRegister(data.readShort());
|
||||||
int debugNameCount = data.readShort();
|
var.setDebugName(data.readUTF());
|
||||||
for (int j = 0; j < debugNameCount; ++j) {
|
if (var.getDebugName().isEmpty()) {
|
||||||
var.getDebugNames().add(data.readUTF());
|
var.setDebugName(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < basicBlockCount; ++i) {
|
for (int i = 0; i < basicBlockCount; ++i) {
|
||||||
|
|
|
@ -15,19 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model;
|
package org.teavm.model;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class Variable implements VariableReader {
|
public class Variable implements VariableReader {
|
||||||
private Program program;
|
private Program program;
|
||||||
private int index;
|
private int index;
|
||||||
private int register;
|
private int register;
|
||||||
private Set<String> debugNames;
|
private String debugName;
|
||||||
|
|
||||||
Variable(Program program) {
|
Variable(Program program) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
this.debugNames = new HashSet<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,12 +52,12 @@ public class Variable implements VariableReader {
|
||||||
this.register = register;
|
this.register = register;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getDebugNames() {
|
@Override
|
||||||
return debugNames;
|
public String getDebugName() {
|
||||||
|
return debugName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setDebugName(String debugName) {
|
||||||
public Set<String> readDebugNames() {
|
this.debugName = debugName;
|
||||||
return Collections.unmodifiableSet(debugNames);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,18 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model;
|
package org.teavm.model;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public interface VariableReader {
|
public interface VariableReader {
|
||||||
int getIndex();
|
int getIndex();
|
||||||
|
|
||||||
ProgramReader getProgram();
|
ProgramReader getProgram();
|
||||||
|
|
||||||
Set<String> readDebugNames();
|
String getDebugName();
|
||||||
|
|
||||||
int getRegister();
|
int getRegister();
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
if (map[i] != i) {
|
if (map[i] != i) {
|
||||||
Variable var = program.variableAt(i);
|
Variable var = program.variableAt(i);
|
||||||
Variable mapVar = program.variableAt(map[i]);
|
Variable mapVar = program.variableAt(map[i]);
|
||||||
mapVar.getDebugNames().addAll(var.getDebugNames());
|
mapVar.setDebugName(var.getDebugName());
|
||||||
program.deleteVariable(i);
|
program.deleteVariable(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,12 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bind(int var, String value) {
|
private void bind(int var, String value) {
|
||||||
KnownValue known = knownValues.get(value);
|
String name = program.variableAt(var).getDebugName();
|
||||||
|
if (name == null) {
|
||||||
|
name = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
KnownValue known = knownValues.get(name + ":" + value);
|
||||||
if (known != null && domTree.dominates(known.location, currentBlockIndex) && known.value != var) {
|
if (known != null && domTree.dominates(known.location, currentBlockIndex) && known.value != var) {
|
||||||
eliminate = true;
|
eliminate = true;
|
||||||
map[var] = known.value;
|
map[var] = known.value;
|
||||||
|
@ -173,7 +178,7 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
known = new KnownValue();
|
known = new KnownValue();
|
||||||
known.location = currentBlockIndex;
|
known.location = currentBlockIndex;
|
||||||
known.value = var;
|
known.value = var;
|
||||||
knownValues.put(value, known);
|
knownValues.put(name + ":" + value, known);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void visit(ClassConstantInstruction insn) {
|
public void visit(ClassConstantInstruction insn) {
|
||||||
var = program.createVariable();
|
var = program.createVariable();
|
||||||
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
var.setDebugName(insn.getReceiver().getDebugName());
|
||||||
ClassConstantInstruction copy = new ClassConstantInstruction();
|
ClassConstantInstruction copy = new ClassConstantInstruction();
|
||||||
copy.setConstant(insn.getConstant());
|
copy.setConstant(insn.getConstant());
|
||||||
copy.setReceiver(var);
|
copy.setReceiver(var);
|
||||||
|
@ -235,7 +235,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void visit(NullConstantInstruction insn) {
|
public void visit(NullConstantInstruction insn) {
|
||||||
var = program.createVariable();
|
var = program.createVariable();
|
||||||
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
var.setDebugName(insn.getReceiver().getDebugName());
|
||||||
NullConstantInstruction copy = new NullConstantInstruction();
|
NullConstantInstruction copy = new NullConstantInstruction();
|
||||||
copy.setReceiver(var);
|
copy.setReceiver(var);
|
||||||
this.copy = copy;
|
this.copy = copy;
|
||||||
|
@ -244,7 +244,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void visit(IntegerConstantInstruction insn) {
|
public void visit(IntegerConstantInstruction insn) {
|
||||||
var = program.createVariable();
|
var = program.createVariable();
|
||||||
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
var.setDebugName(insn.getReceiver().getDebugName());
|
||||||
IntegerConstantInstruction copy = new IntegerConstantInstruction();
|
IntegerConstantInstruction copy = new IntegerConstantInstruction();
|
||||||
copy.setConstant(insn.getConstant());
|
copy.setConstant(insn.getConstant());
|
||||||
copy.setReceiver(var);
|
copy.setReceiver(var);
|
||||||
|
@ -254,7 +254,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void visit(LongConstantInstruction insn) {
|
public void visit(LongConstantInstruction insn) {
|
||||||
var = program.createVariable();
|
var = program.createVariable();
|
||||||
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
var.setDebugName(insn.getReceiver().getDebugName());
|
||||||
LongConstantInstruction copy = new LongConstantInstruction();
|
LongConstantInstruction copy = new LongConstantInstruction();
|
||||||
copy.setConstant(insn.getConstant());
|
copy.setConstant(insn.getConstant());
|
||||||
copy.setReceiver(var);
|
copy.setReceiver(var);
|
||||||
|
@ -264,7 +264,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void visit(FloatConstantInstruction insn) {
|
public void visit(FloatConstantInstruction insn) {
|
||||||
var = program.createVariable();
|
var = program.createVariable();
|
||||||
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
var.setDebugName(insn.getReceiver().getDebugName());
|
||||||
FloatConstantInstruction copy = new FloatConstantInstruction();
|
FloatConstantInstruction copy = new FloatConstantInstruction();
|
||||||
copy.setConstant(insn.getConstant());
|
copy.setConstant(insn.getConstant());
|
||||||
copy.setReceiver(var);
|
copy.setReceiver(var);
|
||||||
|
@ -274,7 +274,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoubleConstantInstruction insn) {
|
public void visit(DoubleConstantInstruction insn) {
|
||||||
var = program.createVariable();
|
var = program.createVariable();
|
||||||
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
var.setDebugName(insn.getReceiver().getDebugName());
|
||||||
DoubleConstantInstruction copy = new DoubleConstantInstruction();
|
DoubleConstantInstruction copy = new DoubleConstantInstruction();
|
||||||
copy.setConstant(insn.getConstant());
|
copy.setConstant(insn.getConstant());
|
||||||
copy.setReceiver(var);
|
copy.setReceiver(var);
|
||||||
|
@ -284,7 +284,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void visit(StringConstantInstruction insn) {
|
public void visit(StringConstantInstruction insn) {
|
||||||
var = program.createVariable();
|
var = program.createVariable();
|
||||||
var.getDebugNames().addAll(insn.getReceiver().getDebugNames());
|
var.setDebugName(insn.getReceiver().getDebugName());
|
||||||
StringConstantInstruction copy = new StringConstantInstruction();
|
StringConstantInstruction copy = new StringConstantInstruction();
|
||||||
copy.setConstant(insn.getConstant());
|
copy.setConstant(insn.getConstant());
|
||||||
copy.setReceiver(var);
|
copy.setReceiver(var);
|
||||||
|
|
|
@ -193,7 +193,7 @@ public class AsyncProgramSplitter {
|
||||||
copy.createVariable();
|
copy.createVariable();
|
||||||
Variable varCopy = copy.variableAt(i);
|
Variable varCopy = copy.variableAt(i);
|
||||||
varCopy.setRegister(var.getRegister());
|
varCopy.setRegister(var.getRegister());
|
||||||
varCopy.getDebugNames().addAll(var.getDebugNames());
|
varCopy.setDebugName(var.getDebugName());
|
||||||
}
|
}
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,16 +28,8 @@ public class ListingBuilder {
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
sb.append(prefix).append("var @").append(i);
|
sb.append(prefix).append("var @").append(i);
|
||||||
VariableReader var = program.variableAt(i);
|
VariableReader var = program.variableAt(i);
|
||||||
if (var != null && !var.readDebugNames().isEmpty()) {
|
if (var != null && var.getDebugName() != null) {
|
||||||
sb.append(" as ");
|
sb.append(" as ").append(var.getDebugName());
|
||||||
boolean first = true;
|
|
||||||
for (String debugName : var.readDebugNames()) {
|
|
||||||
if (!first) {
|
|
||||||
sb.append(", ");
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
sb.append(debugName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,7 @@ public class PhiUpdater {
|
||||||
|
|
||||||
for (Phi phi : synthesizedPhis.get(index)) {
|
for (Phi phi : synthesizedPhis.get(index)) {
|
||||||
Variable var = program.createVariable();
|
Variable var = program.createVariable();
|
||||||
var.getDebugNames().addAll(phi.getReceiver().getDebugNames());
|
var.setDebugName(phi.getReceiver().getDebugName());
|
||||||
variableMap[phi.getReceiver().getIndex()] = var;
|
variableMap[phi.getReceiver().getIndex()] = var;
|
||||||
phi.setReceiver(var);
|
phi.setReceiver(var);
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ public class PhiUpdater {
|
||||||
incoming.setSource(currentBlock);
|
incoming.setSource(currentBlock);
|
||||||
incoming.setValue(var);
|
incoming.setValue(var);
|
||||||
phi.getIncomings().add(incoming);
|
phi.getIncomings().add(incoming);
|
||||||
phi.getReceiver().getDebugNames().addAll(var.getDebugNames());
|
phi.getReceiver().setDebugName(var.getDebugName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public final class ProgramUtils {
|
||||||
Program copy = new Program();
|
Program copy = new Program();
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
Variable var = copy.createVariable();
|
Variable var = copy.createVariable();
|
||||||
var.getDebugNames().addAll(program.variableAt(i).readDebugNames());
|
var.setDebugName(program.variableAt(i).getDebugName());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
copy.createBasicBlock();
|
copy.createBasicBlock();
|
||||||
|
|
|
@ -257,14 +257,13 @@ public class RegisterAllocator {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
mapper.apply(block);
|
mapper.apply(block);
|
||||||
}
|
}
|
||||||
String[][] originalNames = new String[program.variableCount()][];
|
String[] originalNames = new String[program.variableCount()];
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
Variable var = program.variableAt(i);
|
Variable var = program.variableAt(i);
|
||||||
originalNames[i] = var.getDebugNames().toArray(new String[0]);
|
originalNames[i] = var.getDebugName();
|
||||||
var.getDebugNames().clear();
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
program.variableAt(varMap[i]).getDebugNames().addAll(Arrays.asList(originalNames[i]));
|
program.variableAt(varMap[i]).setDebugName(originalNames[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -113,6 +114,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
private final Properties properties = new Properties();
|
private final Properties properties = new Properties();
|
||||||
private ProgramCache programCache;
|
private ProgramCache programCache;
|
||||||
private boolean incremental;
|
private boolean incremental;
|
||||||
|
private TeaVMOptimizationLevel optimizationLevel = TeaVMOptimizationLevel.SIMPLE;
|
||||||
private TeaVMProgressListener progressListener;
|
private TeaVMProgressListener progressListener;
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private ListableClassHolderSource writtenClasses;
|
private ListableClassHolderSource writtenClasses;
|
||||||
|
@ -202,6 +204,14 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
this.incremental = incremental;
|
this.incremental = incremental;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TeaVMOptimizationLevel getOptimizationLevel() {
|
||||||
|
return optimizationLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptimizationLevel(TeaVMOptimizationLevel optimizationLevel) {
|
||||||
|
this.optimizationLevel = optimizationLevel;
|
||||||
|
}
|
||||||
|
|
||||||
public TeaVMProgressListener getProgressListener() {
|
public TeaVMProgressListener getProgressListener() {
|
||||||
return progressListener;
|
return progressListener;
|
||||||
}
|
}
|
||||||
|
@ -359,12 +369,13 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//inline(classSet);
|
inline(classSet);
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeDebugNames(classSet);
|
||||||
optimize(classSet);
|
optimize(classSet);
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
|
@ -423,10 +434,13 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void inline(ListableClassHolderSource classes) {
|
private void inline(ListableClassHolderSource classes) {
|
||||||
|
if (optimizationLevel != TeaVMOptimizationLevel.FULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Inlining inlining = new Inlining();
|
Inlining inlining = new Inlining();
|
||||||
for (String className : classes.getClassNames()) {
|
for (String className : classes.getClassNames()) {
|
||||||
ClassHolder cls = classes.get(className);
|
ClassHolder cls = classes.get(className);
|
||||||
for (final MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
if (method.getProgram() != null) {
|
if (method.getProgram() != null) {
|
||||||
inlining.apply(method.getProgram(), classes);
|
inlining.apply(method.getProgram(), classes);
|
||||||
}
|
}
|
||||||
|
@ -437,6 +451,25 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeDebugNames(ListableClassHolderSource classes) {
|
||||||
|
if (optimizationLevel == TeaVMOptimizationLevel.SIMPLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String className : classes.getClassNames()) {
|
||||||
|
ClassHolder cls = classes.get(className);
|
||||||
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
|
if (method.getProgram() != null) {
|
||||||
|
for (int i = 0; i < method.getProgram().variableCount(); ++i) {
|
||||||
|
method.getProgram().variableAt(i).setDebugName(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wasCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void optimize(ListableClassHolderSource classSource) {
|
private void optimize(ListableClassHolderSource classSource) {
|
||||||
for (String className : classSource.getClassNames()) {
|
for (String className : classSource.getClassNames()) {
|
||||||
ClassHolder cls = classSource.get(className);
|
ClassHolder cls = classSource.get(className);
|
||||||
|
@ -481,17 +514,22 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MethodOptimization> getOptimizations() {
|
private List<MethodOptimization> getOptimizations() {
|
||||||
return Arrays.asList(
|
List<MethodOptimization> optimizations = new ArrayList<>();
|
||||||
new RedundantJumpElimination(),
|
optimizations.add(new RedundantJumpElimination());
|
||||||
new ArrayUnwrapMotion(),
|
optimizations.add(new ArrayUnwrapMotion());
|
||||||
new LoopInversion(),
|
if (optimizationLevel.ordinal() >= TeaVMOptimizationLevel.ADVANCED.ordinal()) {
|
||||||
new LoopInvariantMotion(),
|
optimizations.add(new LoopInversion());
|
||||||
new GlobalValueNumbering(),
|
optimizations.add(new LoopInvariantMotion());
|
||||||
new ConstantConditionElimination(),
|
}
|
||||||
new RedundantJumpElimination(),
|
optimizations.add(new GlobalValueNumbering());
|
||||||
new UnusedVariableElimination(),
|
if (optimizationLevel.ordinal() >= TeaVMOptimizationLevel.ADVANCED.ordinal()) {
|
||||||
new ClassInitElimination(),
|
optimizations.add(new ConstantConditionElimination());
|
||||||
new UnreachableBasicBlockElimination());
|
optimizations.add(new RedundantJumpElimination());
|
||||||
|
optimizations.add(new UnusedVariableElimination());
|
||||||
|
}
|
||||||
|
optimizations.add(new ClassInitElimination());
|
||||||
|
optimizations.add(new UnreachableBasicBlockElimination());
|
||||||
|
return optimizations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void build(File dir, String fileName) {
|
public void build(File dir, String fileName) {
|
||||||
|
|
22
core/src/main/java/org/teavm/vm/TeaVMOptimizationLevel.java
Normal file
22
core/src/main/java/org/teavm/vm/TeaVMOptimizationLevel.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.vm;
|
||||||
|
|
||||||
|
public enum TeaVMOptimizationLevel {
|
||||||
|
SIMPLE,
|
||||||
|
ADVANCED,
|
||||||
|
FULL
|
||||||
|
}
|
|
@ -170,8 +170,7 @@ class JSClassProcessor {
|
||||||
InstructionVariableMapper variableMapper = new InstructionVariableMapper(var ->
|
InstructionVariableMapper variableMapper = new InstructionVariableMapper(var ->
|
||||||
program.variableAt(var.getIndex() + 1));
|
program.variableAt(var.getIndex() + 1));
|
||||||
for (int i = program.variableCount() - 1; i > 0; --i) {
|
for (int i = program.variableCount() - 1; i > 0; --i) {
|
||||||
program.variableAt(i).getDebugNames().addAll(program.variableAt(i - 1).getDebugNames());
|
program.variableAt(i).setDebugName(program.variableAt(i - 1).getDebugName());
|
||||||
program.variableAt(i - 1).getDebugNames().clear();
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.teavm.tooling.RuntimeCopyOperation;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
import org.teavm.tooling.TeaVMTool;
|
import org.teavm.tooling.TeaVMTool;
|
||||||
import org.teavm.tooling.TeaVMToolException;
|
import org.teavm.tooling.TeaVMToolException;
|
||||||
|
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
import org.teavm.vm.TeaVMPhase;
|
import org.teavm.vm.TeaVMPhase;
|
||||||
import org.teavm.vm.TeaVMProgressFeedback;
|
import org.teavm.vm.TeaVMProgressFeedback;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
|
@ -61,6 +62,9 @@ public final class TeaVMRunner {
|
||||||
.withDescription("causes TeaVM to generate minimized JavaScript file")
|
.withDescription("causes TeaVM to generate minimized JavaScript file")
|
||||||
.withLongOpt("minify")
|
.withLongOpt("minify")
|
||||||
.create("m"));
|
.create("m"));
|
||||||
|
options.addOption(OptionBuilder
|
||||||
|
.withDescription("optimization level (1-3)")
|
||||||
|
.create("O"));
|
||||||
options.addOption(OptionBuilder
|
options.addOption(OptionBuilder
|
||||||
.withArgName("separate|merge|none")
|
.withArgName("separate|merge|none")
|
||||||
.hasArg()
|
.hasArg()
|
||||||
|
@ -160,6 +164,33 @@ public final class TeaVMRunner {
|
||||||
if (commandLine.hasOption('D')) {
|
if (commandLine.hasOption('D')) {
|
||||||
tool.setDebugInformationGenerated(true);
|
tool.setDebugInformationGenerated(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (commandLine.hasOption("O")) {
|
||||||
|
int level;
|
||||||
|
try {
|
||||||
|
level = Integer.parseInt(commandLine.getOptionValue("O"));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.err.print("Wrong optimization level");
|
||||||
|
printUsage(options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (level) {
|
||||||
|
case 1:
|
||||||
|
tool.setOptimizationLevel(TeaVMOptimizationLevel.SIMPLE);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
tool.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
tool.setOptimizationLevel(TeaVMOptimizationLevel.FULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.print("Wrong optimization level");
|
||||||
|
printUsage(options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (commandLine.hasOption('S')) {
|
if (commandLine.hasOption('S')) {
|
||||||
tool.setSourceMapsFileGenerated(true);
|
tool.setSourceMapsFileGenerated(true);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +205,7 @@ public final class TeaVMRunner {
|
||||||
if (commandLine.hasOption('p')) {
|
if (commandLine.hasOption('p')) {
|
||||||
classPath = commandLine.getOptionValues('p');
|
classPath = commandLine.getOptionValues('p');
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean interactive = commandLine.hasOption('w');
|
boolean interactive = commandLine.hasOption('w');
|
||||||
args = commandLine.getArgs();
|
args = commandLine.getArgs();
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
|
|
|
@ -62,6 +62,7 @@ import org.teavm.vm.DirectoryBuildTarget;
|
||||||
import org.teavm.vm.TeaVM;
|
import org.teavm.vm.TeaVM;
|
||||||
import org.teavm.vm.TeaVMBuilder;
|
import org.teavm.vm.TeaVMBuilder;
|
||||||
import org.teavm.vm.TeaVMEntryPoint;
|
import org.teavm.vm.TeaVMEntryPoint;
|
||||||
|
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
import org.teavm.vm.TeaVMTarget;
|
import org.teavm.vm.TeaVMTarget;
|
||||||
import org.teavm.vm.spi.AbstractRendererListener;
|
import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
|
@ -93,6 +94,7 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private TeaVMProgressListener progressListener;
|
private TeaVMProgressListener progressListener;
|
||||||
private TeaVM vm;
|
private TeaVM vm;
|
||||||
|
private TeaVMOptimizationLevel optimizationLevel = TeaVMOptimizationLevel.SIMPLE;
|
||||||
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
||||||
private DebugInformationBuilder debugEmitter;
|
private DebugInformationBuilder debugEmitter;
|
||||||
private JavaScriptTarget javaScriptTarget;
|
private JavaScriptTarget javaScriptTarget;
|
||||||
|
@ -227,6 +229,14 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
this.targetType = targetType;
|
this.targetType = targetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TeaVMOptimizationLevel getOptimizationLevel() {
|
||||||
|
return optimizationLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptimizationLevel(TeaVMOptimizationLevel optimizationLevel) {
|
||||||
|
this.optimizationLevel = optimizationLevel;
|
||||||
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
@ -361,6 +371,7 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
vm.setProperties(properties);
|
vm.setProperties(properties);
|
||||||
vm.setProgramCache(programCache);
|
vm.setProgramCache(programCache);
|
||||||
vm.setIncremental(incremental);
|
vm.setIncremental(incremental);
|
||||||
|
vm.setOptimizationLevel(optimizationLevel);
|
||||||
|
|
||||||
vm.installPlugins();
|
vm.installPlugins();
|
||||||
for (ClassHolderTransformer transformer : transformers) {
|
for (ClassHolderTransformer transformer : transformers) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user