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