From f2668b867d029273ab9e7c0decf681d0a64fae74 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 14 Sep 2016 23:23:27 +0300 Subject: [PATCH] wasm: fix bugs in GC and runtime --- .../wasm/generate/WasmGenerationVisitor.java | 17 +++++++++++++---- .../wasm/intrinsics/AddressIntrinsic.java | 2 +- .../lowlevel/GcRootMaintainingTransformer.java | 2 -- core/src/main/java/org/teavm/runtime/GC.java | 1 + 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java b/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java index 4de48bf91..02fb4301b 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/WasmGenerationVisitor.java @@ -919,9 +919,9 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { } slotExpr.acceptVisitor(this); - WasmExpression slot = result; + WasmExpression slotOffset = getSlotOffset(result); WasmExpression address = new WasmGetLocal(stackVariable); - address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slot); + address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slotOffset); gcRootExpr.acceptVisitor(this); WasmExpression gcRoot = result; @@ -936,13 +936,22 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { } slotExpr.acceptVisitor(this); - WasmExpression slot = result; + WasmExpression slotOffset = getSlotOffset(result); WasmExpression address = new WasmGetLocal(stackVariable); - address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slot); + address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slotOffset); result = new WasmStoreInt32(4, address, new WasmInt32Constant(0), WasmInt32Subtype.INT32); } + private WasmExpression getSlotOffset(WasmExpression slot) { + if (slot instanceof WasmInt32Constant) { + int slotConstant = ((WasmInt32Constant) slot).getValue(); + return new WasmInt32Constant(slotConstant << 2); + } else { + return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SHL, slot, new WasmInt32Constant(2)); + } + } + @Override public void visit(BlockStatement statement) { WasmBlock block = new WasmBlock(false); diff --git a/core/src/main/java/org/teavm/backend/wasm/intrinsics/AddressIntrinsic.java b/core/src/main/java/org/teavm/backend/wasm/intrinsics/AddressIntrinsic.java index 8a504d946..30d7c258f 100644 --- a/core/src/main/java/org/teavm/backend/wasm/intrinsics/AddressIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/wasm/intrinsics/AddressIntrinsic.java @@ -157,7 +157,7 @@ public class AddressIntrinsic implements WasmIntrinsic { WasmCall call = new WasmCall(WasmMangling.mangleMethod(delegate)); call.getArguments().addAll(invocation.getArguments().stream() .map(arg -> manager.generate(arg)) - .collect(Collectors.toSet())); + .collect(Collectors.toList())); return call; } case "isLessThan": { diff --git a/core/src/main/java/org/teavm/model/lowlevel/GcRootMaintainingTransformer.java b/core/src/main/java/org/teavm/model/lowlevel/GcRootMaintainingTransformer.java index 44c51ff1e..96aa88ebd 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/GcRootMaintainingTransformer.java +++ b/core/src/main/java/org/teavm/model/lowlevel/GcRootMaintainingTransformer.java @@ -169,8 +169,6 @@ public class GcRootMaintainingTransformer { registerInvocation.getArguments().add(slotVar); registerInvocation.getArguments().add(program.variableAt(liveVar)); instructionsToAdd.add(registerInvocation); - - ++slot; } while (slot < maxDepth) { diff --git a/core/src/main/java/org/teavm/runtime/GC.java b/core/src/main/java/org/teavm/runtime/GC.java index 85ca446e4..6d7d08a70 100644 --- a/core/src/main/java/org/teavm/runtime/GC.java +++ b/core/src/main/java/org/teavm/runtime/GC.java @@ -317,6 +317,7 @@ public final class GC { Address address = Address.fromInt(Structure.sizeOf(RuntimeArray.class)); address = Address.align(address, itemSize); address = address.add(itemSize * array.size); + address = Address.align(address, 4); return address.toInt(); } }