From ff3ff36d82e801a6b61ce230bb82da1ecd904dc5 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 26 Dec 2023 21:50:42 +0000 Subject: Use Wasm platform to determine value size --- .../compiler/backends/wasm/PatioToWasm.java | 66 ++++++++++++++-------- .../compiler/backends/wasm/WasmTarget.java | 8 +++ .../wasm/structure/ast/types/WasmValueType.java | 12 ++-- 3 files changed, 57 insertions(+), 29 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java index f62bd994..e212535a 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java @@ -59,14 +59,14 @@ public class PatioToWasm { case PatioDataElementImmutable patioDataElementImmutable -> { wasmMemoryBuilder = wasmMemoryBuilder.add( patioDataElementImmutable.name(), - patioDataValueToBytes(patioDataElementImmutable.value()), + patioDataValueToBytes(patioDataElementImmutable.value(), platformTarget), WasmAlignment.ALIGN_32_BIT ).memory(); } case PatioDataElementMutable patioDataElementMutable -> { wasmMemoryBuilder = wasmMemoryBuilder.add( patioDataElementMutable.name(), - patioDataValueToBytes(patioDataElementMutable.initialValue()), + patioDataValueToBytes(patioDataElementMutable.initialValue(), platformTarget), WasmAlignment.ALIGN_32_BIT ).memory(); } @@ -156,10 +156,14 @@ public class PatioToWasm { return switch (patioInstruction) { case PatioAllocHeap patioAllocHeap -> { context = context - .addInstruction(new WasmI32Const(sizeOf(patioAllocHeap.layout()))) + .addInstruction(new WasmI32Const(sizeOf( + patioAllocHeap.layout(), + platformTarget + ))) .addInstruction(new WasmI32Const(offsetOf( patioAllocHeap.layout(), - patioAllocHeap.gcChildrenOffset() + patioAllocHeap.gcChildrenOffset(), + platformTarget ))) .addInstruction(new WasmI32Const(patioAllocHeap.gcChildrenCount())) .addInstruction(new WasmCall(new WasmFuncName(ALLOC_NAME))) @@ -170,7 +174,7 @@ public class PatioToWasm { case PatioAllocStack patioAllocStack -> { context = context - .addInstruction(new WasmI32Const(sizeOf(patioAllocStack.layout()))) + .addInstruction(new WasmI32Const(sizeOf(patioAllocStack.layout(), platformTarget))) .addInstruction(new WasmCall(new WasmFuncName(STACK_ALLOC_NAME))) .addInstruction(new WasmLocalSet(context.wasmLocalIndex(patioAllocStack.target()))); @@ -312,7 +316,11 @@ public class PatioToWasm { context = generateOperand(patioMemoryLoad.pointer(), context); context = context.addInstruction(new WasmI32Load( - wasmMemoryArg(patioMemoryLoad.layout(), patioMemoryLoad.offset()) + wasmMemoryArg( + patioMemoryLoad.layout(), + patioMemoryLoad.offset(), + platformTarget + ) )); context = popIntoPatioLocal(patioMemoryLoad.target(), context); @@ -326,7 +334,11 @@ public class PatioToWasm { context = generateOperand(patioMemoryStore.value(), context); context = context.addInstruction(new WasmI32Store( - wasmMemoryArg(patioMemoryStore.layout(), patioMemoryStore.offset()) + wasmMemoryArg( + patioMemoryStore.layout(), + patioMemoryStore.offset(), + platformTarget + ) )); yield context; @@ -520,10 +532,10 @@ public class PatioToWasm { }; } - private static int sizeOf(PatioDataLayout layout) { + private static int sizeOf(PatioDataLayout layout, WasmTarget platformTarget) { return switch (layout) { case PatioDataLayoutArray patioDataLayoutArray -> - sizeOf(patioDataLayoutArray.element()) * patioDataLayoutArray.size(); + sizeOf(patioDataLayoutArray.element(), platformTarget) * patioDataLayoutArray.size(); case PatioDataLayoutBool patioDataLayoutBool -> 1; @@ -532,31 +544,33 @@ public class PatioToWasm { 1; case PatioDataLayoutDataPointer patioDataLayoutDataPointer -> - 4; + platformTarget.dataPointerType().sizeBytes(); case PatioDataLayoutFunctionPointer patioDataLayoutFunctionPointer -> - 4; + platformTarget.functionPointerType().sizeBytes(); case PatioDataLayoutInt patioDataLayoutInt -> - 4; + platformTarget.patioIntType().sizeBytes(); case PatioDataLayoutStruct patioDataLayoutStruct -> patioDataLayoutStruct.elements().stream() - .map(element -> sizeOf(element)) + .map(element -> sizeOf(element, platformTarget)) .reduce(0, Integer::sum); }; } private static int offsetOf( PatioDataLayout patioDataLayout, - List patioOffsets + List patioOffsets, + WasmTarget platformTarget ) { var wasmOffset = 0; for (var patioOffset : patioOffsets) { switch (patioDataLayout) { case PatioDataLayoutArray patioDataLayoutArray -> { - wasmOffset += sizeOf(patioDataLayoutArray.element()) * patioOffset; + var elementSize = sizeOf(patioDataLayoutArray.element(), platformTarget); + wasmOffset += elementSize * patioOffset; patioDataLayout = patioDataLayoutArray.element(); } case PatioDataLayoutBool patioDataLayoutBool -> { @@ -576,7 +590,8 @@ public class PatioToWasm { } case PatioDataLayoutStruct patioDataLayoutStruct -> { for (var i = 0; i < patioOffset; i++) { - wasmOffset += sizeOf(patioDataLayoutStruct.elements().get(i)); + var element = patioDataLayoutStruct.elements().get(i); + wasmOffset += sizeOf(element, platformTarget); } patioDataLayout = patioDataLayoutStruct.elements().get(patioOffset); } @@ -588,16 +603,17 @@ public class PatioToWasm { private static WasmMemoryArg wasmMemoryArg( PatioDataLayout patioDataLayout, - List patioOffsets + List patioOffsets, + WasmTarget platformTarget ) { - var wasmOffset = offsetOf(patioDataLayout, patioOffsets); + var wasmOffset = offsetOf(patioDataLayout, patioOffsets, platformTarget); // TODO: alignment return new WasmMemoryArg(wasmOffset, WasmAlignment.NONE); } - private static byte[] patioDataValueToBytes(PatioDataValue value) { - var bytes = ByteBuffer.allocate(sizeOf(value)); + private static byte[] patioDataValueToBytes(PatioDataValue value, WasmTarget platformTarget) { + var bytes = ByteBuffer.allocate(sizeOf(value, platformTarget)); bytes.order(ByteOrder.LITTLE_ENDIAN); patioDataValueToBytes(value, bytes); @@ -632,8 +648,8 @@ public class PatioToWasm { } } - private static int sizeOf(PatioDataValue value) { - return sizeOf(value.layout()); + private static int sizeOf(PatioDataValue value, WasmTarget platformTarget) { + return sizeOf(value.layout(), platformTarget); } private static WasmLocal patioLocalToWasmLocal( @@ -647,14 +663,16 @@ public class PatioToWasm { PatioOperand operand, WasmTarget platformTarget ) { - return platformTarget.sizeT(); + // TODO: handle 32-bit values on wasm64 + return platformTarget.patioIntType(); } private static WasmValueType patioTypeToWasmValueType( PatioType type, WasmTarget platformTarget ) { - return platformTarget.sizeT(); + // TODO: handle 32-bit values on wasm64 + return platformTarget.patioIntType(); } private static List patioTypeToWasmResultTypes(PatioType type) { diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmTarget.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmTarget.java index 31c32177..cee2e24b 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmTarget.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmTarget.java @@ -45,6 +45,14 @@ public enum WasmTarget { return sizeT; } + public WasmValueType functionPointerType() { + return sizeT; + } + + public WasmValueType patioIntType() { + return sizeT; + } + public List linkerFlags() { return linkerFlags; } diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/types/WasmValueType.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/types/WasmValueType.java index 99664f5c..aa323f64 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/types/WasmValueType.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/types/WasmValueType.java @@ -1,10 +1,12 @@ package org.shedlang.compiler.backends.wasm.structure.ast.types; public sealed interface WasmValueType { - WasmValueType I32 = new Number(WasmNumberType.I32); - WasmValueType I64 = new Number(WasmNumberType.I64); - WasmValueType F32 = new Number(WasmNumberType.F32); - WasmValueType F64 = new Number(WasmNumberType.F64); + WasmValueType I32 = new Number(WasmNumberType.I32, 4); + WasmValueType I64 = new Number(WasmNumberType.I64, 8); + WasmValueType F32 = new Number(WasmNumberType.F32, 4); + WasmValueType F64 = new Number(WasmNumberType.F64, 8); - record Number(WasmNumberType type) implements WasmValueType {} + int sizeBytes(); + + record Number(WasmNumberType type, int sizeBytes) implements WasmValueType {} } -- cgit v1.2.3