From 8a012178ed1ccc43fe143b3f0516b4e525d66ff3 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 26 Sep 2016 23:53:43 +0300 Subject: [PATCH] WASM: add support of offset field in memory operations --- .../wasm/generate/WasmGenerationVisitor.java | 87 ++++++++++++------- .../model/expression/WasmLoadFloat32.java | 11 +++ .../model/expression/WasmLoadFloat64.java | 11 +++ .../wasm/model/expression/WasmLoadInt32.java | 11 +++ .../wasm/model/expression/WasmLoadInt64.java | 11 +++ .../model/expression/WasmMemoryAccess.java | 4 + .../model/expression/WasmStoreFloat32.java | 11 +++ .../model/expression/WasmStoreFloat64.java | 11 +++ .../wasm/model/expression/WasmStoreInt32.java | 11 +++ .../wasm/model/expression/WasmStoreInt64.java | 11 +++ .../render/WasmBinaryRenderingVisitor.java | 16 ++-- .../wasm/render/WasmCRenderingVisitor.java | 64 +++++++------- .../wasm/render/WasmRenderingVisitor.java | 24 +++++ 13 files changed, 213 insertions(+), 70 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 15f871862..cc409d86d 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 @@ -96,6 +96,7 @@ import org.teavm.backend.wasm.model.expression.WasmLoadFloat32; import org.teavm.backend.wasm.model.expression.WasmLoadFloat64; import org.teavm.backend.wasm.model.expression.WasmLoadInt32; import org.teavm.backend.wasm.model.expression.WasmLoadInt64; +import org.teavm.backend.wasm.model.expression.WasmMemoryAccess; import org.teavm.backend.wasm.model.expression.WasmReturn; import org.teavm.backend.wasm.model.expression.WasmSetLocal; import org.teavm.backend.wasm.model.expression.WasmStoreFloat32; @@ -472,34 +473,41 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { WasmExpression address = getAddress(qualified, field, location); ValueType type = context.getFieldType(field); accept(value); + + WasmMemoryAccess resultExpr; if (type instanceof ValueType.Primitive) { switch (((ValueType.Primitive) type).getKind()) { case BOOLEAN: case BYTE: - result = new WasmStoreInt32(1, address, result, WasmInt32Subtype.INT8); + resultExpr = new WasmStoreInt32(1, address, result, WasmInt32Subtype.INT8); break; case SHORT: - result = new WasmStoreInt32(2, address, result, WasmInt32Subtype.INT16); + resultExpr = new WasmStoreInt32(2, address, result, WasmInt32Subtype.INT16); break; case CHARACTER: - result = new WasmStoreInt32(2, address, result, WasmInt32Subtype.UINT16); + resultExpr = new WasmStoreInt32(2, address, result, WasmInt32Subtype.UINT16); break; case INTEGER: - result = new WasmStoreInt32(4, address, result, WasmInt32Subtype.INT32); + resultExpr = new WasmStoreInt32(4, address, result, WasmInt32Subtype.INT32); break; case LONG: - result = new WasmStoreInt64(8, address, result, WasmInt64Subtype.INT64); + resultExpr = new WasmStoreInt64(8, address, result, WasmInt64Subtype.INT64); break; case FLOAT: - result = new WasmStoreFloat32(4, address, result); + resultExpr = new WasmStoreFloat32(4, address, result); break; case DOUBLE: - result = new WasmStoreFloat64(8, address, result); + resultExpr = new WasmStoreFloat64(8, address, result); break; + default: + throw new AssertionError(type.toString()); } } else { - result = new WasmStoreInt32(4, address, result, WasmInt32Subtype.INT32); + resultExpr = new WasmStoreInt32(4, address, result, WasmInt32Subtype.INT32); } + + resultExpr.setOffset(getOffset(qualified, field)); + result = (WasmExpression) resultExpr; result.setLocation(location); } @@ -948,12 +956,18 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { slotExpr.acceptVisitor(this); WasmExpression slotOffset = getSlotOffset(result); WasmExpression address = new WasmGetLocal(stackVariable); - address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slotOffset); + if (!(slotOffset instanceof WasmInt32Constant)) { + address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slotOffset); + } gcRootExpr.acceptVisitor(this); WasmExpression gcRoot = result; - result = new WasmStoreInt32(4, address, gcRoot, WasmInt32Subtype.INT32); + WasmStoreInt32 store = new WasmStoreInt32(4, address, gcRoot, WasmInt32Subtype.INT32); + if (slotOffset instanceof WasmInt32Constant) { + store.setOffset(((WasmInt32Constant) slotOffset).getValue()); + } + result = store; } private void generateRemoveGcRoot(Expr slotExpr) { @@ -965,9 +979,15 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { slotExpr.acceptVisitor(this); WasmExpression slotOffset = getSlotOffset(result); WasmExpression address = new WasmGetLocal(stackVariable); - address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slotOffset); + if (!(slotOffset instanceof WasmInt32Constant)) { + address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, address, slotOffset); + } - result = new WasmStoreInt32(4, address, new WasmInt32Constant(0), WasmInt32Subtype.INT32); + WasmStoreInt32 store = new WasmStoreInt32(4, address, new WasmInt32Constant(0), WasmInt32Subtype.INT32); + if (slotOffset instanceof WasmInt32Constant) { + store.setOffset(((WasmInt32Constant) slotOffset).getValue()); + } + result = store; } private WasmExpression getSlotOffset(WasmExpression slot) { @@ -1008,58 +1028,61 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor { WasmExpression address = getAddress(expr.getQualified(), expr.getField(), expr.getLocation()); ValueType type = context.getFieldType(expr.getField()); + WasmMemoryAccess resultExpr; if (type instanceof ValueType.Primitive) { switch (((ValueType.Primitive) type).getKind()) { case BOOLEAN: case BYTE: - result = new WasmLoadInt32(1, address, WasmInt32Subtype.INT8); + resultExpr = new WasmLoadInt32(1, address, WasmInt32Subtype.INT8); break; case SHORT: - result = new WasmLoadInt32(2, address, WasmInt32Subtype.INT16); + resultExpr = new WasmLoadInt32(2, address, WasmInt32Subtype.INT16); break; case CHARACTER: - result = new WasmLoadInt32(2, address, WasmInt32Subtype.UINT16); + resultExpr = new WasmLoadInt32(2, address, WasmInt32Subtype.UINT16); break; case INTEGER: - result = new WasmLoadInt32(4, address, WasmInt32Subtype.INT32); + resultExpr = new WasmLoadInt32(4, address, WasmInt32Subtype.INT32); break; case LONG: - result = new WasmLoadInt64(8, address, WasmInt64Subtype.INT64); + resultExpr = new WasmLoadInt64(8, address, WasmInt64Subtype.INT64); break; case FLOAT: - result = new WasmLoadFloat32(4, address); + resultExpr = new WasmLoadFloat32(4, address); break; case DOUBLE: - result = new WasmLoadFloat64(8, address); + resultExpr = new WasmLoadFloat64(8, address); break; + default: + throw new AssertionError(type.toString()); } } else { - result = new WasmLoadInt32(4, address, WasmInt32Subtype.INT32); + resultExpr = new WasmLoadInt32(4, address, WasmInt32Subtype.INT32); } + + resultExpr.setOffset(getOffset(expr.getQualified(), expr.getField())); + result = (WasmExpression) resultExpr; } private WasmExpression getAddress(Expr qualified, FieldReference field, TextLocation location) { - int offset = classGenerator.getFieldOffset(field); if (qualified == null) { + int offset = classGenerator.getFieldOffset(field); WasmExpression result = new WasmInt32Constant(offset); result.setLocation(location); return result; } else { accept(qualified); - if (offset != 0) { - WasmExpression offsetExpr = new WasmInt32Constant(offset); - offsetExpr.setLocation(qualified.getLocation()); - - WasmExpression address = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.ADD, - result, offsetExpr); - address.setLocation(location); - return address; - } else { - return result; - } + return result; } } + private int getOffset(Expr qualified, FieldReference field) { + if (qualified == null) { + return 0; + } + return classGenerator.getFieldOffset(field); + } + @Override public void visit(BreakStatement statement) { IdentifiedStatement target = statement.getTarget(); diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat32.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat32.java index 93097a25d..42e533cfc 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat32.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat32.java @@ -20,6 +20,7 @@ import java.util.Objects; public class WasmLoadFloat32 extends WasmExpression implements WasmMemoryAccess { private int alignment; private WasmExpression index; + private int offset; public WasmLoadFloat32(int alignment, WasmExpression index) { Objects.requireNonNull(index); @@ -35,6 +36,16 @@ public class WasmLoadFloat32 extends WasmExpression implements WasmMemoryAccess this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat64.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat64.java index 7e72cd342..29ce11d98 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat64.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadFloat64.java @@ -20,6 +20,7 @@ import java.util.Objects; public class WasmLoadFloat64 extends WasmExpression implements WasmMemoryAccess { private int alignment; private WasmExpression index; + private int offset; public WasmLoadFloat64(int alignment, WasmExpression index) { Objects.requireNonNull(index); @@ -35,6 +36,16 @@ public class WasmLoadFloat64 extends WasmExpression implements WasmMemoryAccess this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt32.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt32.java index 6648a25a5..ed2c84a00 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt32.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt32.java @@ -21,6 +21,7 @@ public class WasmLoadInt32 extends WasmExpression implements WasmMemoryAccess { private int alignment; private WasmExpression index; private WasmInt32Subtype convertFrom; + private int offset; public WasmLoadInt32(int alignment, WasmExpression index, WasmInt32Subtype convertFrom) { Objects.requireNonNull(index); @@ -38,6 +39,16 @@ public class WasmLoadInt32 extends WasmExpression implements WasmMemoryAccess { this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt64.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt64.java index addcae63a..3b998ab0f 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt64.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmLoadInt64.java @@ -21,6 +21,7 @@ public class WasmLoadInt64 extends WasmExpression implements WasmMemoryAccess { private int alignment; private WasmExpression index; private WasmInt64Subtype convertFrom; + private int offset; public WasmLoadInt64(int alignment, WasmExpression index, WasmInt64Subtype convertFrom) { Objects.requireNonNull(index); @@ -38,6 +39,16 @@ public class WasmLoadInt64 extends WasmExpression implements WasmMemoryAccess { this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmMemoryAccess.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmMemoryAccess.java index 3b7a8b97e..bf71e46d4 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmMemoryAccess.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmMemoryAccess.java @@ -19,4 +19,8 @@ public interface WasmMemoryAccess { WasmExpression getIndex(); void setIndex(WasmExpression index); + + int getOffset(); + + void setOffset(int offset); } diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat32.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat32.java index d6356813d..6de915c73 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat32.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat32.java @@ -21,6 +21,7 @@ public class WasmStoreFloat32 extends WasmExpression implements WasmMemoryAccess private int alignment; private WasmExpression index; private WasmExpression value; + private int offset; public WasmStoreFloat32(int alignment, WasmExpression index, WasmExpression value) { Objects.requireNonNull(index); @@ -38,6 +39,16 @@ public class WasmStoreFloat32 extends WasmExpression implements WasmMemoryAccess this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat64.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat64.java index 758439b93..b5d81d29b 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat64.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreFloat64.java @@ -21,6 +21,7 @@ public class WasmStoreFloat64 extends WasmExpression implements WasmMemoryAccess private int alignment; private WasmExpression index; private WasmExpression value; + private int offset; public WasmStoreFloat64(int alignment, WasmExpression index, WasmExpression value) { Objects.requireNonNull(index); @@ -38,6 +39,16 @@ public class WasmStoreFloat64 extends WasmExpression implements WasmMemoryAccess this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt32.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt32.java index 998f3272a..492c98b45 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt32.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt32.java @@ -22,6 +22,7 @@ public class WasmStoreInt32 extends WasmExpression implements WasmMemoryAccess { private WasmExpression index; private WasmExpression value; private WasmInt32Subtype convertTo; + private int offset; public WasmStoreInt32(int alignment, WasmExpression index, WasmExpression value, WasmInt32Subtype convertTo) { @@ -42,6 +43,16 @@ public class WasmStoreInt32 extends WasmExpression implements WasmMemoryAccess { this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt64.java b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt64.java index 4156c0c09..03c1dd199 100644 --- a/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt64.java +++ b/core/src/main/java/org/teavm/backend/wasm/model/expression/WasmStoreInt64.java @@ -22,6 +22,7 @@ public class WasmStoreInt64 extends WasmExpression implements WasmMemoryAccess { private WasmExpression index; private WasmExpression value; private WasmInt64Subtype convertTo; + private int offset; public WasmStoreInt64(int alignment, WasmExpression index, WasmExpression value, WasmInt64Subtype convertTo) { @@ -42,6 +43,16 @@ public class WasmStoreInt64 extends WasmExpression implements WasmMemoryAccess { this.alignment = alignment; } + @Override + public int getOffset() { + return offset; + } + + @Override + public void setOffset(int offset) { + this.offset = offset; + } + @Override public WasmExpression getIndex() { return index; diff --git a/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderingVisitor.java b/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderingVisitor.java index ddc719ef5..3a20b4130 100644 --- a/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderingVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderingVisitor.java @@ -669,7 +669,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { break; } writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } @Override @@ -699,7 +699,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { break; } writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } @Override @@ -707,7 +707,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { expression.getIndex().acceptVisitor(this); writer.writeByte(0x2C); writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } @Override @@ -715,7 +715,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { expression.getIndex().acceptVisitor(this); writer.writeByte(0x2D); writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } @Override @@ -736,7 +736,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { break; } writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } @Override @@ -761,7 +761,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { break; } writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } @Override @@ -770,7 +770,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { expression.getValue().acceptVisitor(this); writer.writeByte(0x35); writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } @Override @@ -779,7 +779,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { expression.getValue().acceptVisitor(this); writer.writeByte(0x36); writer.writeByte(alignment(expression.getAlignment())); - writer.writeByte(0); + writer.writeLEB(expression.getOffset()); } private int alignment(int value) { diff --git a/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java b/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java index 12e2a0a90..52e01a0e1 100644 --- a/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java @@ -777,21 +777,22 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { } result.getLines().addAll(index.getLines()); + String base = "&wasm_heap[" + index.getText() + " + " + expression.getOffset() + "]"; switch (expression.getConvertFrom()) { case INT8: - result.setText("(int32_t) (int8_t) wasm_heap[" + index.getText() + "]"); + result.setText("(int32_t) (int8_t) " + base.substring(1)); break; case UINT8: - result.setText("(int32_t) (uint8_t) wasm_heap[" + index.getText() + "]"); + result.setText("(int32_t) (uint8_t) " + base.substring(1)); break; case INT16: - result.setText("(int32_t) *((int16_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("(int32_t) *((int16_t *) " + base + ")"); break; case UINT16: - result.setText("(int32_t) *((uint16_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("(int32_t) *((uint16_t *) " + base + ")"); break; case INT32: - result.setText("*((int32_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("*((int32_t *) " + base + ")"); break; } @@ -812,27 +813,28 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { } result.getLines().addAll(index.getLines()); + String base = "&wasm_heap[" + index.getText() + " + " + expression.getOffset() + "]"; switch (expression.getConvertFrom()) { case INT8: - result.setText("(int64_t) (int8_t) wasm_heap[" + index.getText() + "]"); + result.setText("(int64_t) (int8_t) " + base.substring(1)); break; case UINT8: - result.setText("(int64_t) (uint8_t) wasm_heap[" + index.getText() + "]"); + result.setText("(int64_t) (uint8_t) " + base.substring(1)); break; case INT16: - result.setText("(int64_t) *((int16_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("(int64_t) *((int16_t *) " + base + ")"); break; case UINT16: - result.setText("(int64_t) *((uint16_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("(int64_t) *((uint16_t *) " + base + ")"); break; case INT32: - result.setText("(int64_t) *((int32_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("(int64_t) *((int32_t *) " + base + ")"); break; case UINT32: - result.setText("(int64_t) *((uint32_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("(int64_t) *((uint32_t *) " + base + ")"); break; case INT64: - result.setText("*((int64_t *) &wasm_heap[" + index.getText() + "])"); + result.setText("*((int64_t *) " + base + ")"); break; } @@ -853,7 +855,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { } result.getLines().addAll(index.getLines()); - result.setText("*((float *) &wasm_heap[" + index.getText() + "])"); + result.setText("*((float *) &wasm_heap[" + index.getText() + " + " + expression.getOffset() + "])"); value = result; } @@ -872,7 +874,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { } result.getLines().addAll(index.getLines()); - result.setText("*((double *) &wasm_heap[" + index.getText() + "])"); + result.setText("*((double *) &wasm_heap[" + index.getText() + " + " + expression.getOffset() + "])"); value = result; } @@ -893,21 +895,22 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { result.getLines().addAll(valueToStore.getLines()); String line; + String base = "&wasm_heap[" + index.getText() + " + " + expression.getOffset() + "]"; switch (expression.getConvertTo()) { case INT8: - line = "wasm_heap[" + index.getText() + "] = " + valueToStore.getText() + ";"; + line = base.substring(1) + " = " + valueToStore.getText() + ";"; break; case UINT8: - line = "*((uint8_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((uint8_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case INT16: - line = "*((int16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((int16_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case UINT16: - line = "*((uint16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((uint16_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case INT32: - line = "*((int32_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((int32_t *) " + base + ") = " + valueToStore.getText() + ";"; break; default: throw new AssertionError(expression.getConvertTo().toString()); @@ -933,27 +936,28 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { result.getLines().addAll(valueToStore.getLines()); String line; + String base = "&wasm_heap[" + index.getText() + " + " + expression.getOffset() + "]"; switch (expression.getConvertTo()) { case INT8: - line = "wasm_heap[" + index.getText() + "] = " + valueToStore.getText(); + line = base.substring(1) + " = " + valueToStore.getText(); break; case UINT8: - line = "*((uint8_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((uint8_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case INT16: - line = "*((int16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((int16_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case UINT16: - line = "*((uint16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((uint16_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case INT32: - line = "*((int32_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((int32_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case UINT32: - line = "*((uint32_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((uint32_t *) " + base + ") = " + valueToStore.getText() + ";"; break; case INT64: - line = "*((int64_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";"; + line = "*((int64_t *) " + base + ") = " + valueToStore.getText() + ";"; break; default: throw new AssertionError(); @@ -979,8 +983,8 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { result.getLines().addAll(index.getLines()); result.getLines().addAll(valueToStore.getLines()); - result.addLine("*((float *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";", - expression.getLocation()); + result.addLine("*((float *) &wasm_heap[" + index.getText() + " + " + expression.getOffset() + "]) = " + + valueToStore.getText() + ";", expression.getLocation()); value = result; } @@ -1000,8 +1004,8 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { result.getLines().addAll(index.getLines()); result.getLines().addAll(valueToStore.getLines()); - result.addLine("*((double *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";", - expression.getLocation()); + result.addLine("*((double *) &wasm_heap[" + index.getText() + " + " + expression.getOffset() + "]) = " + + valueToStore.getText() + ";", expression.getLocation()); value = result; } diff --git a/core/src/main/java/org/teavm/backend/wasm/render/WasmRenderingVisitor.java b/core/src/main/java/org/teavm/backend/wasm/render/WasmRenderingVisitor.java index e70e3ac79..04bc47d3d 100644 --- a/core/src/main/java/org/teavm/backend/wasm/render/WasmRenderingVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/render/WasmRenderingVisitor.java @@ -399,6 +399,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { break; } append(" align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); close(); } @@ -430,6 +433,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { break; } append(" align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); close(); } @@ -437,6 +443,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { @Override public void visit(WasmLoadFloat32 expression) { open().append("f32.load align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); close(); } @@ -444,6 +453,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { @Override public void visit(WasmLoadFloat64 expression) { open().append("f64.load align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); close(); } @@ -465,6 +477,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { break; } append(" align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); line(expression.getValue()); close(); @@ -491,6 +506,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { break; } append(" align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); line(expression.getValue()); close(); @@ -499,6 +517,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { @Override public void visit(WasmStoreFloat32 expression) { open().append("f32.store align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); line(expression.getValue()); close(); @@ -507,6 +528,9 @@ class WasmRenderingVisitor implements WasmExpressionVisitor { @Override public void visit(WasmStoreFloat64 expression) { open().append("f64.store align=" + expression.getAlignment()); + if (expression.getOffset() > 0) { + append(" offset=" + expression.getOffset()); + } line(expression.getIndex()); line(expression.getValue()); close();