mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-23 23:04:50 -08:00
Add variables and variable types to AST. Use types to properly render variables in WASM
This commit is contained in:
parent
fc2c6b9e07
commit
ca874d178d
|
@ -18,16 +18,12 @@ 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.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class AsyncMethodNode extends MethodNode {
|
public class AsyncMethodNode extends MethodNode {
|
||||||
private List<AsyncMethodPart> body = new ArrayList<>();
|
private List<AsyncMethodPart> body = new ArrayList<>();
|
||||||
private List<Integer> variables = new ArrayList<>();
|
private List<VariableNode> variables = new ArrayList<>();
|
||||||
private List<Set<String>> parameterDebugNames = new ArrayList<>();
|
|
||||||
|
|
||||||
public AsyncMethodNode(MethodReference reference) {
|
public AsyncMethodNode(MethodReference reference) {
|
||||||
super(reference);
|
super(reference);
|
||||||
|
@ -37,15 +33,19 @@ public class AsyncMethodNode extends MethodNode {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getVariables() {
|
public List<VariableNode> getVariables() {
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Set<String>> getParameterDebugNames() {
|
public List<Set<String>> getParameterDebugNames() {
|
||||||
return parameterDebugNames;
|
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);
|
||||||
|
|
|
@ -21,10 +21,6 @@ import java.util.Set;
|
||||||
import org.teavm.javascript.spi.Generator;
|
import org.teavm.javascript.spi.Generator;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class NativeMethodNode extends MethodNode {
|
public class NativeMethodNode extends MethodNode {
|
||||||
private Generator generator;
|
private Generator generator;
|
||||||
private boolean async;
|
private boolean async;
|
||||||
|
|
|
@ -18,12 +18,12 @@ 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.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 {
|
||||||
private Statement body;
|
private Statement body;
|
||||||
private List<Integer> variables = new ArrayList<>();
|
private List<VariableNode> variables = new ArrayList<>();
|
||||||
private List<Set<String>> parameterDebugNames = new ArrayList<>();
|
|
||||||
|
|
||||||
public RegularMethodNode(MethodReference reference) {
|
public RegularMethodNode(MethodReference reference) {
|
||||||
super(reference);
|
super(reference);
|
||||||
|
@ -37,13 +37,16 @@ public class RegularMethodNode extends MethodNode {
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getVariables() {
|
public List<VariableNode> getVariables() {
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Set<String>> getParameterDebugNames() {
|
public List<Set<String>> getParameterDebugNames() {
|
||||||
return parameterDebugNames;
|
return variables.subList(0, getReference().parameterCount())
|
||||||
|
.stream()
|
||||||
|
.map(VariableNode::getDebugNames)
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
51
core/src/main/java/org/teavm/ast/VariableNode.java
Normal file
51
core/src/main/java/org/teavm/ast/VariableNode.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.ast;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.teavm.model.util.VariableType;
|
||||||
|
|
||||||
|
public class VariableNode {
|
||||||
|
private int index;
|
||||||
|
private VariableType type;
|
||||||
|
private Set<String> debugNames = new HashSet<>();
|
||||||
|
|
||||||
|
public VariableNode(int index, VariableType type) {
|
||||||
|
this.index = index;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VariableType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(VariableType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getDebugNames() {
|
||||||
|
return debugNames;
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,7 @@ import org.teavm.ast.RegularMethodNode;
|
||||||
import org.teavm.ast.SequentialStatement;
|
import org.teavm.ast.SequentialStatement;
|
||||||
import org.teavm.ast.Statement;
|
import org.teavm.ast.Statement;
|
||||||
import org.teavm.ast.TryCatchStatement;
|
import org.teavm.ast.TryCatchStatement;
|
||||||
|
import org.teavm.ast.VariableNode;
|
||||||
import org.teavm.ast.WhileStatement;
|
import org.teavm.ast.WhileStatement;
|
||||||
import org.teavm.ast.cache.MethodNodeCache;
|
import org.teavm.ast.cache.MethodNodeCache;
|
||||||
import org.teavm.ast.optimization.Optimizer;
|
import org.teavm.ast.optimization.Optimizer;
|
||||||
|
@ -71,6 +72,7 @@ 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;
|
||||||
|
import org.teavm.model.util.TypeInferer;
|
||||||
|
|
||||||
public class Decompiler {
|
public class Decompiler {
|
||||||
private ClassHolderSource classSource;
|
private ClassHolderSource classSource;
|
||||||
|
@ -267,9 +269,14 @@ public class Decompiler {
|
||||||
sb.append(new ListingBuilder().buildListing(program, " "));
|
sb.append(new ListingBuilder().buildListing(program, " "));
|
||||||
throw new DecompilationException(sb.toString(), e);
|
throw new DecompilationException(sb.toString(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeInferer typeInferer = new TypeInferer();
|
||||||
|
typeInferer.inferTypes(program, method.getReference());
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
methodNode.getVariables().add(program.variableAt(i).getRegister());
|
VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i));
|
||||||
|
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(mapModifiers(method.getModifiers()));
|
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
||||||
|
@ -328,10 +335,15 @@ public class Decompiler {
|
||||||
}
|
}
|
||||||
node.getBody().add(part);
|
node.getBody().add(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
Program program = method.getProgram();
|
Program program = method.getProgram();
|
||||||
|
TypeInferer typeInferer = new TypeInferer();
|
||||||
|
typeInferer.inferTypes(program, method.getReference());
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
node.getVariables().add(program.variableAt(i).getRegister());
|
VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i));
|
||||||
|
node.getVariables().add(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optimizer optimizer = new Optimizer();
|
Optimizer optimizer = new Optimizer();
|
||||||
optimizer.optimize(node, splitter);
|
optimizer.optimize(node, splitter);
|
||||||
node.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
node.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
||||||
|
|
|
@ -46,13 +46,17 @@ public class Optimizer {
|
||||||
method.getBody().acceptVisitor(optimizer);
|
method.getBody().acceptVisitor(optimizer);
|
||||||
method.setBody(optimizer.resultStmt);
|
method.setBody(optimizer.resultStmt);
|
||||||
int paramCount = method.getReference().parameterCount();
|
int paramCount = method.getReference().parameterCount();
|
||||||
|
|
||||||
UnusedVariableEliminator unusedEliminator = new UnusedVariableEliminator(paramCount, method.getVariables());
|
UnusedVariableEliminator unusedEliminator = new UnusedVariableEliminator(paramCount, method.getVariables());
|
||||||
method.getBody().acceptVisitor(unusedEliminator);
|
method.getBody().acceptVisitor(unusedEliminator);
|
||||||
method.getVariables().subList(unusedEliminator.lastIndex, method.getVariables().size()).clear();
|
method.getVariables().clear();
|
||||||
|
method.getVariables().addAll(unusedEliminator.getReorderedVariables());
|
||||||
|
|
||||||
RedundantLabelEliminator labelEliminator = new RedundantLabelEliminator();
|
RedundantLabelEliminator labelEliminator = new RedundantLabelEliminator();
|
||||||
method.getBody().acceptVisitor(labelEliminator);
|
method.getBody().acceptVisitor(labelEliminator);
|
||||||
|
|
||||||
for (int i = 0; i < method.getVariables().size(); ++i) {
|
for (int i = 0; i < method.getVariables().size(); ++i) {
|
||||||
method.getVariables().set(i, i);
|
method.getVariables().get(i).setIndex(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,18 +84,21 @@ public class Optimizer {
|
||||||
part.getStatement().acceptVisitor(optimizer);
|
part.getStatement().acceptVisitor(optimizer);
|
||||||
part.setStatement(optimizer.resultStmt);
|
part.setStatement(optimizer.resultStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int paramCount = method.getReference().parameterCount();
|
int paramCount = method.getReference().parameterCount();
|
||||||
UnusedVariableEliminator unusedEliminator = new UnusedVariableEliminator(paramCount, method.getVariables());
|
UnusedVariableEliminator unusedEliminator = new UnusedVariableEliminator(paramCount, method.getVariables());
|
||||||
for (AsyncMethodPart part : method.getBody()) {
|
for (AsyncMethodPart part : method.getBody()) {
|
||||||
part.getStatement().acceptVisitor(unusedEliminator);
|
part.getStatement().acceptVisitor(unusedEliminator);
|
||||||
}
|
}
|
||||||
method.getVariables().subList(unusedEliminator.lastIndex, method.getVariables().size()).clear();
|
method.getVariables().clear();
|
||||||
|
method.getVariables().addAll(unusedEliminator.getReorderedVariables());
|
||||||
|
|
||||||
RedundantLabelEliminator labelEliminator = new RedundantLabelEliminator();
|
RedundantLabelEliminator labelEliminator = new RedundantLabelEliminator();
|
||||||
for (AsyncMethodPart part : method.getBody()) {
|
for (AsyncMethodPart part : method.getBody()) {
|
||||||
part.getStatement().acceptVisitor(labelEliminator);
|
part.getStatement().acceptVisitor(labelEliminator);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < method.getVariables().size(); ++i) {
|
for (int i = 0; i < method.getVariables().size(); ++i) {
|
||||||
method.getVariables().set(i, i);
|
method.getVariables().get(i).setIndex(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.ast.optimization;
|
package org.teavm.ast.optimization;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.teavm.ast.AssignmentStatement;
|
import org.teavm.ast.AssignmentStatement;
|
||||||
|
@ -51,18 +52,23 @@ import org.teavm.ast.TryCatchStatement;
|
||||||
import org.teavm.ast.UnaryExpr;
|
import org.teavm.ast.UnaryExpr;
|
||||||
import org.teavm.ast.UnwrapArrayExpr;
|
import org.teavm.ast.UnwrapArrayExpr;
|
||||||
import org.teavm.ast.VariableExpr;
|
import org.teavm.ast.VariableExpr;
|
||||||
|
import org.teavm.ast.VariableNode;
|
||||||
import org.teavm.ast.WhileStatement;
|
import org.teavm.ast.WhileStatement;
|
||||||
|
|
||||||
class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
|
class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
|
||||||
|
private final VariableNode[] variableNodes;
|
||||||
private final int[] variables;
|
private final int[] variables;
|
||||||
private final int[] indexes;
|
private final int[] indexes;
|
||||||
|
private List<VariableNode> reorderedVariables = new ArrayList<>();
|
||||||
int lastIndex;
|
int lastIndex;
|
||||||
|
|
||||||
UnusedVariableEliminator(int parameterCount, List<Integer> variables) {
|
UnusedVariableEliminator(int parameterCount, List<VariableNode> variables) {
|
||||||
|
variableNodes = new VariableNode[variables.size()];
|
||||||
this.variables = new int[variables.size()];
|
this.variables = new int[variables.size()];
|
||||||
int variableCount = 0;
|
int variableCount = 0;
|
||||||
for (int i = 0; i < variables.size(); ++i) {
|
for (int i = 0; i < variables.size(); ++i) {
|
||||||
int var = variables.get(i);
|
variableNodes[i] = variables.get(i);
|
||||||
|
int var = variables.get(i).getIndex();
|
||||||
this.variables[i] = var;
|
this.variables[i] = var;
|
||||||
variableCount = Math.max(variableCount, var + 1);
|
variableCount = Math.max(variableCount, var + 1);
|
||||||
}
|
}
|
||||||
|
@ -71,9 +77,14 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
|
||||||
parameterCount = Math.min(parameterCount, indexes.length - 1);
|
parameterCount = Math.min(parameterCount, indexes.length - 1);
|
||||||
for (int i = 0; i <= parameterCount; ++i) {
|
for (int i = 0; i <= parameterCount; ++i) {
|
||||||
indexes[i] = lastIndex++;
|
indexes[i] = lastIndex++;
|
||||||
|
reorderedVariables.add(variableNodes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<VariableNode> getReorderedVariables() {
|
||||||
|
return reorderedVariables;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignmentStatement statement) {
|
public void visit(AssignmentStatement statement) {
|
||||||
if (statement.getLeftValue() != null) {
|
if (statement.getLeftValue() != null) {
|
||||||
|
@ -155,6 +166,7 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
index = lastIndex++;
|
index = lastIndex++;
|
||||||
indexes[variables[var]] = index;
|
indexes[variables[var]] = index;
|
||||||
|
reorderedVariables.add(variableNodes[var]);
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
36
core/src/main/java/org/teavm/cache/AstIO.java
vendored
36
core/src/main/java/org/teavm/cache/AstIO.java
vendored
|
@ -70,12 +70,14 @@ import org.teavm.ast.UnaryExpr;
|
||||||
import org.teavm.ast.UnaryOperation;
|
import org.teavm.ast.UnaryOperation;
|
||||||
import org.teavm.ast.UnwrapArrayExpr;
|
import org.teavm.ast.UnwrapArrayExpr;
|
||||||
import org.teavm.ast.VariableExpr;
|
import org.teavm.ast.VariableExpr;
|
||||||
|
import org.teavm.ast.VariableNode;
|
||||||
import org.teavm.ast.WhileStatement;
|
import org.teavm.ast.WhileStatement;
|
||||||
import org.teavm.model.FieldReference;
|
import org.teavm.model.FieldReference;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.model.instructions.ArrayElementType;
|
import org.teavm.model.instructions.ArrayElementType;
|
||||||
|
import org.teavm.model.util.VariableType;
|
||||||
|
|
||||||
public class AstIO {
|
public class AstIO {
|
||||||
private static final NodeModifier[] nodeModifiers = NodeModifier.values();
|
private static final NodeModifier[] nodeModifiers = NodeModifier.values();
|
||||||
|
@ -94,11 +96,10 @@ public class AstIO {
|
||||||
public void write(DataOutput output, RegularMethodNode method) throws IOException {
|
public void write(DataOutput output, RegularMethodNode method) throws IOException {
|
||||||
output.writeInt(packModifiers(method.getModifiers()));
|
output.writeInt(packModifiers(method.getModifiers()));
|
||||||
output.writeShort(method.getVariables().size());
|
output.writeShort(method.getVariables().size());
|
||||||
for (int var : method.getVariables()) {
|
for (VariableNode var : method.getVariables()) {
|
||||||
output.writeShort(var);
|
write(output, var);
|
||||||
}
|
}
|
||||||
output.writeShort(method.getParameterDebugNames().size());
|
output.writeShort(method.getParameterDebugNames().size());
|
||||||
writeParameters(output, method);
|
|
||||||
try {
|
try {
|
||||||
method.getBody().acceptVisitor(new NodeWriter(output));
|
method.getBody().acceptVisitor(new NodeWriter(output));
|
||||||
} catch (IOExceptionWrapper e) {
|
} catch (IOExceptionWrapper e) {
|
||||||
|
@ -106,23 +107,42 @@ public class AstIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void write(DataOutput output, VariableNode variable) throws IOException {
|
||||||
|
output.writeShort(variable.getIndex());
|
||||||
|
output.writeByte(variable.getType().ordinal());
|
||||||
|
output.writeByte(variable.getDebugNames().size());
|
||||||
|
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 {
|
||||||
RegularMethodNode node = new RegularMethodNode(method);
|
RegularMethodNode node = new RegularMethodNode(method);
|
||||||
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
||||||
int varCount = input.readShort();
|
int varCount = input.readShort();
|
||||||
for (int i = 0; i < varCount; ++i) {
|
for (int i = 0; i < varCount; ++i) {
|
||||||
node.getVariables().add((int) input.readShort());
|
node.getVariables().add(readVariable(input));
|
||||||
}
|
}
|
||||||
readParameters(input, node);
|
|
||||||
node.setBody(readStatement(input));
|
node.setBody(readStatement(input));
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private VariableNode readVariable(DataInput input) throws IOException {
|
||||||
|
int index = input.readShort();
|
||||||
|
VariableType type = VariableType.values()[input.readByte()];
|
||||||
|
VariableNode variable = new VariableNode(index, type);
|
||||||
|
int nameCount = input.readByte();
|
||||||
|
for (int i = 0; i < nameCount; ++i) {
|
||||||
|
variable.getDebugNames().add(input.readUTF());
|
||||||
|
}
|
||||||
|
return variable;
|
||||||
|
}
|
||||||
|
|
||||||
public void writeAsync(DataOutput output, AsyncMethodNode method) throws IOException {
|
public void writeAsync(DataOutput output, AsyncMethodNode method) throws IOException {
|
||||||
output.writeInt(packModifiers(method.getModifiers()));
|
output.writeInt(packModifiers(method.getModifiers()));
|
||||||
output.writeShort(method.getVariables().size());
|
output.writeShort(method.getVariables().size());
|
||||||
for (int var : method.getVariables()) {
|
for (VariableNode var : method.getVariables()) {
|
||||||
output.writeShort(var);
|
write(output, var);
|
||||||
}
|
}
|
||||||
output.writeShort(method.getParameterDebugNames().size());
|
output.writeShort(method.getParameterDebugNames().size());
|
||||||
writeParameters(output, method);
|
writeParameters(output, method);
|
||||||
|
@ -152,7 +172,7 @@ public class AstIO {
|
||||||
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
node.getModifiers().addAll(unpackModifiers(input.readInt()));
|
||||||
int varCount = input.readShort();
|
int varCount = input.readShort();
|
||||||
for (int i = 0; i < varCount; ++i) {
|
for (int i = 0; i < varCount; ++i) {
|
||||||
node.getVariables().add((int) input.readShort());
|
node.getVariables().add(readVariable(input));
|
||||||
}
|
}
|
||||||
readParameters(input, node);
|
readParameters(input, node);
|
||||||
int partCount = input.readShort();
|
int partCount = input.readShort();
|
||||||
|
|
|
@ -75,6 +75,7 @@ import org.teavm.ast.TryCatchStatement;
|
||||||
import org.teavm.ast.UnaryExpr;
|
import org.teavm.ast.UnaryExpr;
|
||||||
import org.teavm.ast.UnwrapArrayExpr;
|
import org.teavm.ast.UnwrapArrayExpr;
|
||||||
import org.teavm.ast.VariableExpr;
|
import org.teavm.ast.VariableExpr;
|
||||||
|
import org.teavm.ast.VariableNode;
|
||||||
import org.teavm.ast.WhileStatement;
|
import org.teavm.ast.WhileStatement;
|
||||||
import org.teavm.codegen.NamingException;
|
import org.teavm.codegen.NamingException;
|
||||||
import org.teavm.codegen.NamingOrderer;
|
import org.teavm.codegen.NamingOrderer;
|
||||||
|
@ -709,8 +710,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
int variableCount = 0;
|
int variableCount = 0;
|
||||||
for (int var : method.getVariables()) {
|
for (VariableNode var : method.getVariables()) {
|
||||||
variableCount = Math.max(variableCount, var + 1);
|
variableCount = Math.max(variableCount, var.getIndex() + 1);
|
||||||
}
|
}
|
||||||
TryCatchFinder tryCatchFinder = new TryCatchFinder();
|
TryCatchFinder tryCatchFinder = new TryCatchFinder();
|
||||||
method.getBody().acceptVisitor(tryCatchFinder);
|
method.getBody().acceptVisitor(tryCatchFinder);
|
||||||
|
@ -752,8 +753,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
variableName(i));
|
variableName(i));
|
||||||
}
|
}
|
||||||
int variableCount = 0;
|
int variableCount = 0;
|
||||||
for (int var : methodNode.getVariables()) {
|
for (VariableNode var : methodNode.getVariables()) {
|
||||||
variableCount = Math.max(variableCount, var + 1);
|
variableCount = Math.max(variableCount, var.getIndex() + 1);
|
||||||
}
|
}
|
||||||
List<String> variableNames = new ArrayList<>();
|
List<String> variableNames = new ArrayList<>();
|
||||||
for (int i = ref.parameterCount() + 1; i < variableCount; ++i) {
|
for (int i = ref.parameterCount() + 1; i < variableCount; ++i) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ElementModifier;
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.FieldReference;
|
||||||
import org.teavm.model.Instruction;
|
import org.teavm.model.Instruction;
|
||||||
import org.teavm.model.ListableClassHolderSource;
|
import org.teavm.model.ListableClassHolderSource;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
|
@ -122,6 +123,8 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
RuntimeClass.class, int.class, Address.class), null).use();
|
RuntimeClass.class, int.class, Address.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "<clinit>", void.class), null).use();
|
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "<clinit>", void.class), null).use();
|
||||||
|
|
||||||
|
dependencyChecker.linkField(new FieldReference("java.lang.Object", "monitor"), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,18 +16,14 @@
|
||||||
package org.teavm.wasm.generate;
|
package org.teavm.wasm.generate;
|
||||||
|
|
||||||
import org.teavm.ast.RegularMethodNode;
|
import org.teavm.ast.RegularMethodNode;
|
||||||
|
import org.teavm.ast.VariableNode;
|
||||||
import org.teavm.ast.decompilation.Decompiler;
|
import org.teavm.ast.decompilation.Decompiler;
|
||||||
import org.teavm.common.IntegerArray;
|
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ClassHolderSource;
|
import org.teavm.model.ClassHolderSource;
|
||||||
import org.teavm.model.ElementModifier;
|
import org.teavm.model.ElementModifier;
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodHolder;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.Program;
|
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.model.Variable;
|
|
||||||
import org.teavm.model.util.TypeInferer;
|
|
||||||
import org.teavm.model.util.VariableType;
|
|
||||||
import org.teavm.wasm.model.WasmFunction;
|
import org.teavm.wasm.model.WasmFunction;
|
||||||
import org.teavm.wasm.model.WasmLocal;
|
import org.teavm.wasm.model.WasmLocal;
|
||||||
|
|
||||||
|
@ -48,31 +44,13 @@ public class WasmGenerator {
|
||||||
public WasmFunction generate(MethodReference methodReference) {
|
public WasmFunction generate(MethodReference methodReference) {
|
||||||
ClassHolder cls = classSource.get(methodReference.getClassName());
|
ClassHolder cls = classSource.get(methodReference.getClassName());
|
||||||
MethodHolder method = cls.getMethod(methodReference.getDescriptor());
|
MethodHolder method = cls.getMethod(methodReference.getDescriptor());
|
||||||
Program program = method.getProgram();
|
|
||||||
|
|
||||||
RegularMethodNode methodAst = decompiler.decompileRegular(method);
|
RegularMethodNode methodAst = decompiler.decompileRegular(method);
|
||||||
TypeInferer inferer = new TypeInferer();
|
|
||||||
inferer.inferTypes(program, methodReference);
|
|
||||||
|
|
||||||
IntegerArray variableRepresentatives = new IntegerArray(methodAst.getVariables().size());
|
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
|
||||||
Variable var = program.variableAt(i);
|
|
||||||
if (var.getRegister() < 0 || inferer.typeOf(i) == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
while (variableRepresentatives.size() <= var.getRegister()) {
|
|
||||||
variableRepresentatives.add(-1);
|
|
||||||
}
|
|
||||||
if (variableRepresentatives.get(var.getRegister()) < 0) {
|
|
||||||
variableRepresentatives.set(var.getRegister(), i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
||||||
int firstVariable = method.hasModifier(ElementModifier.STATIC) ? 1 : 0;
|
int firstVariable = method.hasModifier(ElementModifier.STATIC) ? 1 : 0;
|
||||||
for (int i = firstVariable; i < methodAst.getVariables().size(); ++i) {
|
for (int i = firstVariable; i < methodAst.getVariables().size(); ++i) {
|
||||||
VariableType type = inferer.typeOf(variableRepresentatives.get(i));
|
VariableNode variable = methodAst.getVariables().get(i);
|
||||||
function.add(new WasmLocal(WasmGeneratorUtil.mapType(type)));
|
function.add(new WasmLocal(WasmGeneratorUtil.mapType(variable.getType())));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = firstVariable; i <= methodReference.parameterCount(); ++i) {
|
for (int i = firstVariable; i <= methodReference.parameterCount(); ++i) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user