From 36124bbfe721aedf17089b82fcc433592366ae4e Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 21 Jan 2024 19:10:39 +0000 Subject: Implement Patio byte-offset-of instruction --- .../backends/llvm/codegen/PatioToLlvm.java | 41 +++++++++++++++++----- .../compiler/backends/wasm/PatioToWasm.java | 19 ++++++++-- .../shedlang/compiler/patio/PatioExampleTests.java | 36 +++++++++++++++++++ 3 files changed, 85 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java index fbeaa039..9ce9ad36 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java @@ -370,8 +370,18 @@ public class PatioToLlvm { )); } - case PatioByteOffsetOf patioByteOffsetOf -> - throw new UnsupportedOperationException("TODO"); + case PatioByteOffsetOf patioByteOffsetOf -> { + var destinationResult = context.addPatioLocalToLlvmLocal(patioByteOffsetOf.destination()); + var destination = destinationResult.value(); + context = destinationResult.context(); + + yield offsetOf( + destination, + patioByteOffsetOf.layout(), + patioByteOffsetOf.offset(), + context + ); + } case PatioByteSizeOf patioByteSizeOf -> throw new UnsupportedOperationException("TODO"); @@ -1381,14 +1391,28 @@ public class PatioToLlvm { List patioOffset, PatioToLlvmFunctionContext context ) { - var offsetPtrResult = context.allocateLocalName(LlvmCodeGenLocalVariableSpace.OFFSET_PTR); - var offsetPtr = offsetPtrResult.value(); - context = offsetPtrResult.context(); - var offsetResult = context.allocateLocalName(LlvmCodeGenLocalVariableSpace.OFFSET); var offset = offsetResult.value(); context = offsetResult.context(); + return offsetOf( + offset, + patioDataLayout, + patioOffset, + context + ).toResult(offset); + } + + private static PatioToLlvmFunctionContext offsetOf( + LlvmVariable destination, + PatioDataLayout patioDataLayout, + List patioOffset, + PatioToLlvmFunctionContext context + ) { + var offsetPtrResult = context.allocateLocalName(LlvmCodeGenLocalVariableSpace.OFFSET_PTR); + var offsetPtr = offsetPtrResult.value(); + context = offsetPtrResult.context(); + return context .addInstruction( new LlvmGetElementPtr( @@ -1403,11 +1427,10 @@ public class PatioToLlvm { ) .addInstruction( new LlvmPtrToInt( - offset, + destination, offsetPtr, context.target().patioIntType() ) - ) - .toResult(offset); + ); } } 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 c140bf92..3bbbd41c 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java @@ -214,8 +214,23 @@ public class PatioToWasm { yield context; } - case PatioByteOffsetOf patioByteOffsetOf -> - throw new UnsupportedOperationException("TODO"); + case PatioByteOffsetOf patioByteOffsetOf -> { + context = context.addInstruction(wasmIntConst( + target.patioIntType(), + offsetOf( + patioByteOffsetOf.layout(), + patioByteOffsetOf.offset(), + target + ) + )); + + var destinationIndex = context.wasmLocalIndex(patioByteOffsetOf.destination()); + context = context.addInstruction(new WasmLocalSet(destinationIndex)); + + yield context; + } + + case PatioByteSizeOf patioByteSizeOf -> throw new UnsupportedOperationException("TODO"); diff --git a/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java b/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java index d485e9e5..8582cfd0 100644 --- a/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java +++ b/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java @@ -818,6 +818,42 @@ public abstract class PatioExampleTests { assertThat(result, isSilentExit(47)); } + @Test + public void canGetByteOffset() throws IOException, InterruptedException { + var patioFunction = PatioFunctionDefinition.builder() + .withName(FUNCTION_NAME) + .withReturnType(PatioTypes.INT) + .addLocal(Patio.val("x", PatioTypes.INT)) + .addBodyInstruction(Patio.byteOffsetOf( + Patio.localRef("x"), + PatioDataLayouts.struct(List.of( + PatioDataLayouts.struct(List.of( + PatioDataLayouts.BYTE, + PatioDataLayouts.BYTE + )), + PatioDataLayouts.struct(List.of( + PatioDataLayouts.BYTE, + PatioDataLayouts.BYTE, + PatioDataLayouts.BYTE, + PatioDataLayouts.BYTE + )), + PatioDataLayouts.BYTE + )), + List.of(1, 2) + )) + .addBodyInstruction(Patio.return_( + Patio.localRef("x") + )) + .build(); + var patio = Patio.compilationUnit(List.of( + patioFunction + )); + + var result = run(patio); + + assertThat(result, isSilentExit(4)); + } + private Matcher isSilentExit(int exitCode) { return allOf( has("stderr", x -> x.stderr(), equalTo("")), -- cgit v1.2.3