mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-27 01:30:35 +08:00
Fix bugs in C emitter. Improve generation of temporary variables in WASM generation. Improve test class
This commit is contained in:
parent
0ac61919d5
commit
375506e875
@ -24,6 +24,17 @@ public final class Example {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
testFibonacci();
|
||||
testClasses();
|
||||
testVirtualCall();
|
||||
testInstanceOf();
|
||||
testPrimitiveArray();
|
||||
testLazyInitialization();
|
||||
testHashCode();
|
||||
testArrayList();
|
||||
}
|
||||
|
||||
private static void testFibonacci() {
|
||||
int a = 0;
|
||||
int b = 1;
|
||||
println("Fibonacci numbers:");
|
||||
@ -33,9 +44,13 @@ public final class Example {
|
||||
b = c;
|
||||
println(String.valueOf(a));
|
||||
}
|
||||
}
|
||||
|
||||
private static void testClasses() {
|
||||
println("A(2) + A(3) = " + (new A(2).getValue() + new A(3).getValue()));
|
||||
}
|
||||
|
||||
private static void testVirtualCall() {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
println("instance(" + i + ") = " + instance(i).foo());
|
||||
}
|
||||
@ -45,28 +60,38 @@ public final class Example {
|
||||
for (Base elem : array) {
|
||||
println("array[i] = " + elem.foo());
|
||||
}
|
||||
}
|
||||
|
||||
private static void testInstanceOf() {
|
||||
println("Derived2 instanceof Base = " + (new Derived2() instanceof Base));
|
||||
println("Derived3 instanceof Base = " + (new Derived3() instanceof Base));
|
||||
println("Derived2 instanceof Derived1 = " + ((Object) new Derived2() instanceof Derived1));
|
||||
println("Derived2 instanceof A = " + ((Object) new Derived2() instanceof A));
|
||||
println("A instanceof Base = " + (new A(23) instanceof Base));
|
||||
}
|
||||
|
||||
private static void testPrimitiveArray() {
|
||||
byte[] bytes = { 5, 6, 10, 15 };
|
||||
for (byte bt : bytes) {
|
||||
println("bytes[i] = " + bt);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testLazyInitialization() {
|
||||
Initialized.foo();
|
||||
Initialized.foo();
|
||||
Initialized.foo();
|
||||
}
|
||||
|
||||
private static void testHashCode() {
|
||||
Object o = new Object();
|
||||
println("hashCode1 = " + o.hashCode());
|
||||
println("hashCode1 = " + o.hashCode());
|
||||
println("hashCode2 = " + new Object().hashCode());
|
||||
println("hashCode3 = " + new Object().hashCode());
|
||||
}
|
||||
|
||||
private static void testArrayList() {
|
||||
List<Integer> list = new ArrayList<>(Arrays.asList(333, 444, 555));
|
||||
list.add(1234);
|
||||
list.remove((Integer) 444);
|
||||
|
@ -15,9 +15,12 @@
|
||||
*/
|
||||
package org.teavm.backend.wasm.generate;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -125,7 +128,8 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
private Map<IdentifiedStatement, WasmBlock> breakTargets = new HashMap<>();
|
||||
private Map<IdentifiedStatement, WasmBlock> continueTargets = new HashMap<>();
|
||||
private Set<WasmBlock> usedBlocks = new HashSet<>();
|
||||
private int temporaryInt32 = -1;
|
||||
private List<Deque<WasmLocal>> temporaryVariablesByType = new ArrayList<>();
|
||||
private List<WasmLocal> currentTemporaries = new ArrayList<>();
|
||||
WasmExpression result;
|
||||
|
||||
WasmGenerationVisitor(WasmGenerationContext context, WasmClassGenerator classGenerator,
|
||||
@ -135,6 +139,18 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
this.function = function;
|
||||
this.method = method;
|
||||
this.firstVariable = firstVariable;
|
||||
int typeCount = WasmType.values().length;
|
||||
for (int i = 0; i < typeCount; ++i) {
|
||||
temporaryVariablesByType.add(new ArrayDeque<>());
|
||||
}
|
||||
}
|
||||
|
||||
private void accept(Expr expr) {
|
||||
expr.acceptVisitor(this);
|
||||
}
|
||||
|
||||
private void accept(Statement statement) {
|
||||
statement.acceptVisitor(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -162,10 +178,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
Class<?> type = convertType(expr.getType());
|
||||
MethodReference method = new MethodReference(WasmRuntime.class, "remainder", type, type, type);
|
||||
WasmCall call = new WasmCall(WasmMangling.mangleMethod(method), false);
|
||||
expr.getFirstOperand().acceptVisitor(this);
|
||||
|
||||
accept(expr.getFirstOperand());
|
||||
call.getArguments().add(result);
|
||||
expr.getSecondOperand().acceptVisitor(this);
|
||||
|
||||
accept(expr.getSecondOperand());
|
||||
call.getArguments().add(result);
|
||||
|
||||
call.setLocation(expr.getLocation());
|
||||
result = call;
|
||||
break;
|
||||
@ -213,10 +232,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
Class<?> type = convertType(expr.getType());
|
||||
MethodReference method = new MethodReference(WasmRuntime.class, "compare", type, type, int.class);
|
||||
WasmCall call = new WasmCall(WasmMangling.mangleMethod(method), false);
|
||||
expr.getFirstOperand().acceptVisitor(this);
|
||||
|
||||
accept(expr.getFirstOperand());
|
||||
call.getArguments().add(result);
|
||||
expr.getSecondOperand().acceptVisitor(this);
|
||||
|
||||
accept(expr.getSecondOperand());
|
||||
call.getArguments().add(result);
|
||||
|
||||
call.setLocation(expr.getLocation());
|
||||
result = call;
|
||||
break;
|
||||
@ -231,9 +253,9 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
}
|
||||
|
||||
private void generateBinary(WasmIntBinaryOperation intOp, WasmFloatBinaryOperation floatOp, BinaryExpr expr) {
|
||||
expr.getFirstOperand().acceptVisitor(this);
|
||||
accept(expr.getFirstOperand());
|
||||
WasmExpression first = result;
|
||||
expr.getSecondOperand().acceptVisitor(this);
|
||||
accept(expr.getSecondOperand());
|
||||
WasmExpression second = result;
|
||||
|
||||
if (expr.getType() == null) {
|
||||
@ -258,9 +280,9 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
}
|
||||
|
||||
private void generateBinary(WasmIntBinaryOperation intOp, BinaryExpr expr) {
|
||||
expr.getFirstOperand().acceptVisitor(this);
|
||||
accept(expr.getFirstOperand());
|
||||
WasmExpression first = result;
|
||||
expr.getSecondOperand().acceptVisitor(this);
|
||||
accept(expr.getSecondOperand());
|
||||
WasmExpression second = result;
|
||||
|
||||
if (expr.getType() == OperationType.LONG) {
|
||||
@ -307,14 +329,14 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
private void generateAnd(BinaryExpr expr) {
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
|
||||
expr.getFirstOperand().acceptVisitor(this);
|
||||
accept(expr.getFirstOperand());
|
||||
WasmBranch branch = new WasmBranch(negate(result), block);
|
||||
branch.setResult(new WasmInt32Constant(0));
|
||||
branch.setLocation(expr.getLocation());
|
||||
branch.getResult().setLocation(expr.getLocation());
|
||||
block.getBody().add(branch);
|
||||
|
||||
expr.getSecondOperand().acceptVisitor(this);
|
||||
accept(expr.getSecondOperand());
|
||||
block.getBody().add(result);
|
||||
|
||||
block.setLocation(expr.getLocation());
|
||||
@ -325,14 +347,14 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
private void generateOr(BinaryExpr expr) {
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
|
||||
expr.getFirstOperand().acceptVisitor(this);
|
||||
accept(expr.getFirstOperand());
|
||||
WasmBranch branch = new WasmBranch(result, block);
|
||||
branch.setResult(new WasmInt32Constant(1));
|
||||
branch.setLocation(expr.getLocation());
|
||||
branch.getResult().setLocation(expr.getLocation());
|
||||
block.getBody().add(branch);
|
||||
|
||||
expr.getSecondOperand().acceptVisitor(this);
|
||||
accept(expr.getSecondOperand());
|
||||
block.getBody().add(result);
|
||||
|
||||
block.setLocation(expr.getLocation());
|
||||
@ -344,7 +366,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
public void visit(UnaryExpr expr) {
|
||||
switch (expr.getOperation()) {
|
||||
case INT_TO_BYTE:
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
accept(expr.getOperand());
|
||||
result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SHL,
|
||||
result, new WasmInt32Constant(24));
|
||||
result.setLocation(expr.getLocation());
|
||||
@ -353,7 +375,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
result.setLocation(expr.getLocation());
|
||||
break;
|
||||
case INT_TO_SHORT:
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
accept(expr.getOperand());
|
||||
result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SHL,
|
||||
result, new WasmInt32Constant(16));
|
||||
result.setLocation(expr.getLocation());
|
||||
@ -362,7 +384,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
result.setLocation(expr.getLocation());
|
||||
break;
|
||||
case INT_TO_CHAR:
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
accept(expr.getOperand());
|
||||
result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SHL,
|
||||
result, new WasmInt32Constant(16));
|
||||
result.setLocation(expr.getLocation());
|
||||
@ -371,15 +393,15 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
result.setLocation(expr.getLocation());
|
||||
break;
|
||||
case LENGTH:
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
accept(expr.getOperand());
|
||||
result = generateArrayLength(result);
|
||||
break;
|
||||
case NOT:
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
accept(expr.getOperand());
|
||||
result = negate(result);
|
||||
break;
|
||||
case NEGATE:
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
accept(expr.getOperand());
|
||||
switch (expr.getType()) {
|
||||
case INT:
|
||||
result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SUB,
|
||||
@ -404,7 +426,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
}
|
||||
break;
|
||||
case NULL_CHECK:
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
accept(expr.getOperand());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -425,13 +447,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
public void visit(AssignmentStatement statement) {
|
||||
Expr left = statement.getLeftValue();
|
||||
if (left == null) {
|
||||
statement.getRightValue().acceptVisitor(this);
|
||||
accept(statement.getRightValue());
|
||||
result = new WasmDrop(result);
|
||||
result.setLocation(statement.getLocation());
|
||||
} else if (left instanceof VariableExpr) {
|
||||
VariableExpr varExpr = (VariableExpr) left;
|
||||
WasmLocal local = function.getLocalVariables().get(varExpr.getIndex() - firstVariable);
|
||||
statement.getRightValue().acceptVisitor(this);
|
||||
accept(statement.getRightValue());
|
||||
result = new WasmSetLocal(local, result);
|
||||
result.setLocation(statement.getLocation());
|
||||
} else if (left instanceof QualificationExpr) {
|
||||
@ -448,7 +470,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
private void storeField(Expr qualified, FieldReference field, Expr value, TextLocation location) {
|
||||
WasmExpression address = getAddress(qualified, field, location);
|
||||
ValueType type = context.getFieldType(field);
|
||||
value.acceptVisitor(this);
|
||||
accept(value);
|
||||
if (type instanceof ValueType.Primitive) {
|
||||
switch (((ValueType.Primitive) type).getKind()) {
|
||||
case BOOLEAN:
|
||||
@ -482,7 +504,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
private void storeArrayItem(SubscriptExpr leftValue, Expr rightValue) {
|
||||
WasmExpression ptr = getArrayElementPointer(leftValue);
|
||||
rightValue.acceptVisitor(this);
|
||||
accept(rightValue);
|
||||
|
||||
switch (leftValue.getType()) {
|
||||
case BYTE:
|
||||
@ -512,12 +534,15 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ConditionalExpr expr) {
|
||||
expr.getCondition().acceptVisitor(this);
|
||||
accept(expr.getCondition());
|
||||
WasmConditional conditional = new WasmConditional(forCondition(result));
|
||||
expr.getConsequent().acceptVisitor(this);
|
||||
|
||||
accept(expr.getConsequent());
|
||||
conditional.getThenBlock().getBody().add(result);
|
||||
expr.getAlternative().acceptVisitor(this);
|
||||
|
||||
accept(expr.getAlternative());
|
||||
conditional.getElseBlock().getBody().add(result);
|
||||
|
||||
result = conditional;
|
||||
}
|
||||
|
||||
@ -525,7 +550,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
public void visit(SequentialStatement statement) {
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
for (Statement part : statement.getSequence()) {
|
||||
part.acceptVisitor(this);
|
||||
accept(part);
|
||||
if (result != null) {
|
||||
block.getBody().add(result);
|
||||
}
|
||||
@ -555,16 +580,17 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(ConditionalStatement statement) {
|
||||
statement.getCondition().acceptVisitor(this);
|
||||
accept(statement.getCondition());
|
||||
WasmConditional conditional = new WasmConditional(forCondition(result));
|
||||
|
||||
for (Statement part : statement.getConsequent()) {
|
||||
part.acceptVisitor(this);
|
||||
accept(part);
|
||||
if (result != null) {
|
||||
conditional.getThenBlock().getBody().add(result);
|
||||
}
|
||||
}
|
||||
for (Statement part : statement.getAlternative()) {
|
||||
part.acceptVisitor(this);
|
||||
accept(part);
|
||||
if (result != null) {
|
||||
conditional.getElseBlock().getBody().add(result);
|
||||
}
|
||||
@ -607,9 +633,10 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
}
|
||||
|
||||
private WasmExpression getArrayElementPointer(SubscriptExpr expr) {
|
||||
expr.getArray().acceptVisitor(this);
|
||||
accept(expr.getArray());
|
||||
WasmExpression array = result;
|
||||
expr.getIndex().acceptVisitor(this);
|
||||
|
||||
accept(expr.getIndex());
|
||||
WasmExpression index = result;
|
||||
|
||||
int size = -1;
|
||||
@ -658,7 +685,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
currentBreakTarget = statement;
|
||||
|
||||
WasmBlock wrapper = new WasmBlock(false);
|
||||
statement.getValue().acceptVisitor(this);
|
||||
accept(statement.getValue());
|
||||
if (min > 0) {
|
||||
result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SUB, result,
|
||||
new WasmInt32Constant(min));
|
||||
@ -677,7 +704,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
}
|
||||
|
||||
for (Statement part : clause.getBody()) {
|
||||
part.acceptVisitor(this);
|
||||
accept(part);
|
||||
if (result != null) {
|
||||
caseBlock.getBody().add(result);
|
||||
}
|
||||
@ -687,7 +714,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
defaultBlock.getBody().add(wrapper);
|
||||
for (Statement part : statement.getDefaultClause()) {
|
||||
part.acceptVisitor(this);
|
||||
accept(part);
|
||||
if (result != null) {
|
||||
defaultBlock.getBody().add(result);
|
||||
}
|
||||
@ -707,7 +734,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(UnwrapArrayExpr expr) {
|
||||
expr.getArray().acceptVisitor(this);
|
||||
accept(expr.getArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -723,13 +750,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
currentContinueTarget = statement;
|
||||
|
||||
if (statement.getCondition() != null) {
|
||||
statement.getCondition().acceptVisitor(this);
|
||||
accept(statement.getCondition());
|
||||
loop.getBody().add(new WasmBranch(negate(result), wrapper));
|
||||
usedBlocks.add(wrapper);
|
||||
}
|
||||
|
||||
for (Statement part : statement.getBody()) {
|
||||
part.acceptVisitor(this);
|
||||
accept(part);
|
||||
if (result != null) {
|
||||
loop.getBody().add(result);
|
||||
}
|
||||
@ -765,13 +792,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
call.setImported(true);
|
||||
}
|
||||
for (Expr argument : expr.getArguments()) {
|
||||
argument.acceptVisitor(this);
|
||||
accept(argument);
|
||||
call.getArguments().add(result);
|
||||
}
|
||||
result = call;
|
||||
} else if (expr.getType() == InvocationType.CONSTRUCTOR) {
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
WasmLocal tmp = function.getLocalVariables().get(getTemporaryInt32());
|
||||
WasmLocal tmp = getTemporary(WasmType.INT32);
|
||||
block.getBody().add(new WasmSetLocal(tmp, allocateObject(expr.getMethod().getClassName(),
|
||||
expr.getLocation())));
|
||||
|
||||
@ -779,19 +806,21 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
WasmCall call = new WasmCall(methodName);
|
||||
call.getArguments().add(new WasmGetLocal(tmp));
|
||||
for (Expr argument : expr.getArguments()) {
|
||||
argument.acceptVisitor(this);
|
||||
accept(argument);
|
||||
call.getArguments().add(result);
|
||||
}
|
||||
block.getBody().add(call);
|
||||
|
||||
block.getBody().add(new WasmGetLocal(tmp));
|
||||
releaseTemporary(tmp);
|
||||
|
||||
result = block;
|
||||
} else {
|
||||
expr.getArguments().get(0).acceptVisitor(this);
|
||||
accept(expr.getArguments().get(0));
|
||||
WasmExpression instance = result;
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
WasmLocal instanceVar = function.getLocalVariables().get(getTemporaryInt32());
|
||||
|
||||
WasmLocal instanceVar = getTemporary(WasmType.INT32);
|
||||
block.getBody().add(new WasmSetLocal(instanceVar, instance));
|
||||
instance = new WasmGetLocal(instanceVar);
|
||||
|
||||
@ -824,11 +853,12 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
call.getArguments().add(instance);
|
||||
for (int i = 1; i < expr.getArguments().size(); ++i) {
|
||||
expr.getArguments().get(i).acceptVisitor(this);
|
||||
accept(expr.getArguments().get(i));
|
||||
call.getArguments().add(result);
|
||||
}
|
||||
|
||||
block.getBody().add(call);
|
||||
releaseTemporary(instanceVar);
|
||||
result = block;
|
||||
}
|
||||
}
|
||||
@ -842,7 +872,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
}
|
||||
|
||||
for (Statement part : statement.getBody()) {
|
||||
part.acceptVisitor(this);
|
||||
accept(part);
|
||||
if (result != null) {
|
||||
block.getBody().add(result);
|
||||
}
|
||||
@ -897,7 +927,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
result.setLocation(location);
|
||||
return result;
|
||||
} else {
|
||||
qualified.acceptVisitor(this);
|
||||
accept(qualified);
|
||||
if (offset != 0) {
|
||||
WasmExpression offsetExpr = new WasmInt32Constant(offset);
|
||||
offsetExpr.setLocation(qualified.getLocation());
|
||||
@ -960,7 +990,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
RuntimeClass.class, int.class, Address.class));
|
||||
WasmCall call = new WasmCall(allocName);
|
||||
call.getArguments().add(new WasmInt32Constant(classPointer));
|
||||
expr.getLength().acceptVisitor(this);
|
||||
accept(expr.getLength());
|
||||
call.getArguments().add(result);
|
||||
call.setLocation(expr.getLocation());
|
||||
|
||||
@ -974,7 +1004,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
@Override
|
||||
public void visit(ReturnStatement statement) {
|
||||
if (statement.getResult() != null) {
|
||||
statement.getResult().acceptVisitor(this);
|
||||
accept(statement.getResult());
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
@ -984,7 +1014,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(InstanceOfExpr expr) {
|
||||
expr.getExpr().acceptVisitor(this);
|
||||
accept(expr.getExpr());
|
||||
|
||||
if (expr.getType() instanceof ValueType.Object) {
|
||||
ValueType.Object cls = (ValueType.Object) expr.getType();
|
||||
@ -993,7 +1023,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
block.setLocation(expr.getLocation());
|
||||
WasmLocal tagVar = function.getLocalVariables().get(getTemporaryInt32());
|
||||
WasmLocal tagVar = getTemporary(WasmType.INT32);
|
||||
int tagOffset = classGenerator.getFieldOffset(tagField);
|
||||
WasmExpression tagPtr = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD,
|
||||
getReferenceToClass(result), new WasmInt32Constant(tagOffset));
|
||||
@ -1028,6 +1058,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
}
|
||||
|
||||
block.getBody().add(new WasmInt32Constant(1));
|
||||
releaseTemporary(tagVar);
|
||||
|
||||
result = block;
|
||||
} else if (expr.getType() instanceof ValueType.Array) {
|
||||
@ -1041,7 +1072,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
public void visit(ThrowStatement statement) {
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
block.setLocation(statement.getLocation());
|
||||
statement.getException().acceptVisitor(this);
|
||||
accept(statement.getException());
|
||||
block.getBody().add(result);
|
||||
|
||||
block.getBody().add(new WasmUnreachable());
|
||||
@ -1051,7 +1082,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(CastExpr expr) {
|
||||
expr.getValue().acceptVisitor(this);
|
||||
accept(expr.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1066,7 +1097,7 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(PrimitiveCastExpr expr) {
|
||||
expr.getValue().acceptVisitor(this);
|
||||
accept(expr.getValue());
|
||||
result = new WasmConversion(WasmGeneratorUtil.mapType(expr.getSource()),
|
||||
WasmGeneratorUtil.mapType(expr.getTarget()), true, result);
|
||||
result.setLocation(expr.getLocation());
|
||||
@ -1232,17 +1263,25 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
private WasmIntrinsicManager intrinsicManager = new WasmIntrinsicManager() {
|
||||
@Override
|
||||
public WasmExpression generate(Expr expr) {
|
||||
expr.acceptVisitor(WasmGenerationVisitor.this);
|
||||
accept(expr);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
private int getTemporaryInt32() {
|
||||
if (temporaryInt32 < 0) {
|
||||
temporaryInt32 = function.getLocalVariables().size();
|
||||
function.add(new WasmLocal(WasmType.INT32));
|
||||
private WasmLocal getTemporary(WasmType type) {
|
||||
Deque<WasmLocal> stack = temporaryVariablesByType.get(type.ordinal());
|
||||
WasmLocal variable = stack.pollFirst();
|
||||
if (variable == null) {
|
||||
variable = new WasmLocal(type);
|
||||
function.add(variable);
|
||||
}
|
||||
return temporaryInt32;
|
||||
currentTemporaries.add(variable);
|
||||
return variable;
|
||||
}
|
||||
|
||||
private void releaseTemporary(WasmLocal variable) {
|
||||
Deque<WasmLocal> stack = temporaryVariablesByType.get(variable.getType().ordinal());
|
||||
stack.push(variable);
|
||||
}
|
||||
|
||||
private WasmExpression getReferenceToClass(WasmExpression instance) {
|
||||
|
@ -303,7 +303,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(WasmGetLocal expression) {
|
||||
value = CExpression.relocatable("var_" + expression.getLocal().getIndex());
|
||||
value = new CExpression("var_" + expression.getLocal().getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -713,7 +713,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
||||
requiredType = signature.get(i);
|
||||
wasmArguments.get(i).acceptVisitor(this);
|
||||
arguments.add(value);
|
||||
if (!result.getLines().isEmpty() && needsCachingUntil == 0) {
|
||||
if (!value.getLines().isEmpty() && needsCachingUntil == 0) {
|
||||
needsCachingUntil = i;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user