Minimal WASM example works

This commit is contained in:
Alexey Andreev 2016-08-06 16:50:33 +03:00
parent 4fa0669e9a
commit 964d2cdf5b
7 changed files with 34 additions and 7 deletions

View File

@ -63,6 +63,7 @@ public abstract class Expr implements Cloneable {
UnaryExpr expr = new UnaryExpr(); UnaryExpr expr = new UnaryExpr();
expr.setOperand(arg); expr.setOperand(arg);
expr.setOperation(op); expr.setOperation(op);
expr.setType(type);
return expr; return expr;
} }

View File

@ -28,6 +28,16 @@ class GraphColorer {
public void colorize(List<MutableGraphNode> graph, int[] colors, int[] categories) { public void colorize(List<MutableGraphNode> graph, int[] colors, int[] categories) {
IntegerArray colorCategories = new IntegerArray(graph.size()); IntegerArray colorCategories = new IntegerArray(graph.size());
for (int i = 0; i < colors.length; ++i) {
int color = colors[i];
if (colors[i] < 0) {
continue;
}
while (colorCategories.size() <= color) {
colorCategories.add(-1);
}
colorCategories.set(color, categories[i]);
}
BitSet usedColors = new BitSet(); BitSet usedColors = new BitSet();
for (int v : getOrdering(graph)) { for (int v : getOrdering(graph)) {
if (colors[v] >= 0) { if (colors[v] >= 0) {

View File

@ -24,11 +24,11 @@ public final class Example {
public static void main(String[] args) { public static void main(String[] args) {
int a = 0; int a = 0;
int b = 1; int b = 1;
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 30; ++i) {
int c = a + b; int c = a + b;
a = b; a = b;
b = c; b = c;
}
WasmRuntime.print(a); WasmRuntime.print(a);
} }
}
} }

View File

@ -473,7 +473,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
if (statement.getCondition() != null) { if (statement.getCondition() != null) {
statement.getCondition().acceptVisitor(this); statement.getCondition().acceptVisitor(this);
loop.getBody().add(new WasmBranch(result, wrapper)); loop.getBody().add(new WasmBranch(negate(result), wrapper));
usedBlocks.add(wrapper); usedBlocks.add(wrapper);
} }
@ -481,6 +481,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
part.acceptVisitor(this); part.acceptVisitor(this);
loop.getBody().add(result); loop.getBody().add(result);
} }
loop.getBody().add(new WasmBreak(loop));
currentBreakTarget = oldBreakTarget; currentBreakTarget = oldBreakTarget;
currentContinueTarget = oldContinueTarget; currentContinueTarget = oldContinueTarget;

View File

@ -17,6 +17,7 @@ package org.teavm.wasm.generate;
import org.teavm.ast.RegularMethodNode; import org.teavm.ast.RegularMethodNode;
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;
@ -24,6 +25,7 @@ import org.teavm.model.MethodHolder;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.Program; 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.TypeInferer;
import org.teavm.model.util.VariableType; import org.teavm.model.util.VariableType;
import org.teavm.wasm.model.WasmFunction; import org.teavm.wasm.model.WasmFunction;
@ -49,11 +51,24 @@ public class WasmGenerator {
TypeInferer inferer = new TypeInferer(); TypeInferer inferer = new TypeInferer();
inferer.inferTypes(program, methodReference); 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) {
int varIndex = methodAst.getVariables().get(i); VariableType type = inferer.typeOf(variableRepresentatives.get(i));
VariableType type = inferer.typeOf(varIndex);
function.add(new WasmLocal(WasmGeneratorUtil.mapType(type))); function.add(new WasmLocal(WasmGeneratorUtil.mapType(type)));
} }

View File

@ -74,7 +74,7 @@ public class WasmRenderer {
importModule = ""; importModule = "";
} }
visitor.open().append("import $" + function.getName() + " \"" + importModule + "\" " visitor.open().append("import $" + function.getName() + " \"" + importModule + "\" "
+ "\"" + function.getName() + "\""); + "\"" + function.getImportName() + "\"");
renderSignature(function); renderSignature(function);
visitor.close(); visitor.close();
} }

View File

@ -45,6 +45,6 @@ public final class WasmRuntime {
return a - (double) (long) (a / b) * b; return a - (double) (long) (a / b) * b;
} }
@Import(name = "print.i32") @Import(name = "print", module = "spectest")
public static native void print(int a); public static native void print(int a);
} }