From 3ad6a4fa0769d254e7cd6aa2c4e11a0629e6db64 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 26 Nov 2023 11:22:04 +0000 Subject: Support try without throw --- .../llvm/LlvmCodeGenLocalVariableSpace.java | 3 ++ .../compiler/backends/llvm/LlvmPatioCodeGen.java | 38 ++++++++++++++++++++-- .../compiler/backends/wasm/WasmPatioCodeGen.java | 34 ++++++++++++++----- 3 files changed, 63 insertions(+), 12 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenLocalVariableSpace.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenLocalVariableSpace.java index fb65ffb8..a6bd4ba4 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenLocalVariableSpace.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenLocalVariableSpace.java @@ -30,6 +30,9 @@ public enum LlvmCodeGenLocalVariableSpace { SWITCH_DEFAULT_START("switchDefaultStart"), SWITCH_DEFAULT_END("switchDefaultEnd"), SWITCH_END("switchEnd"), + TRY_BODY_START("tryBodyStart"), + TRY_BODY_END("tryBodyEnd"), + TRY_END("tryEnd"), TEMPORARY("tmp"); private final String name; diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java index 651f7aff..6a90e4b1 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGen.java @@ -74,7 +74,7 @@ public class LlvmPatioCodeGen { generateDataElementMutable(patioDataElementMutable, context); case PatioExceptionTypeDefinition patioExceptionTypeDefinition -> - throw new UnsupportedOperationException("TODO"); + context; case PatioFunctionDeclaration patioFunctionDeclaration -> generateFunctionDeclaration(patioFunctionDeclaration, context); @@ -569,8 +569,40 @@ public class LlvmPatioCodeGen { case PatioThrow throw_ -> throw new UnsupportedOperationException("TODO"); - case PatioTry try_ -> - throw new UnsupportedOperationException("TODO"); + case PatioTry try_ -> { + var tryBodyStartLabelResult = context.allocateLocalName( + LlvmCodeGenLocalVariableSpace.TRY_BODY_START + ); + var tryBodyStartLabel = tryBodyStartLabelResult.value(); + context = tryBodyStartLabelResult.context(); + + var tryBodyEndLabelResult = context.allocateLocalName( + LlvmCodeGenLocalVariableSpace.TRY_BODY_END + ); + var tryBodyEndLabel = tryBodyEndLabelResult.value(); + context = tryBodyEndLabelResult.context(); + + var tryEndLabelResult = context.allocateLocalName( + LlvmCodeGenLocalVariableSpace.TRY_END + ); + var tryEndLabel = tryEndLabelResult.value(); + context = tryEndLabelResult.context(); + + context = generateBranches( + try_.targets(), + List.of( + new Branch( + tryBodyStartLabel, + tryBodyEndLabel, + try_.body() + ) + ), + tryEndLabel, + context + ); + + yield context; + } case PatioUnreachable patioUnreachable -> context.addTerminatorInstruction(new LlvmUnreachable()); diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java index 8beac54d..063e9d8b 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java @@ -70,7 +70,11 @@ public class WasmPatioCodeGen { )); } case PatioExceptionTypeDefinition patioExceptionTypeDefinition -> { - throw new UnsupportedOperationException("TODO"); + module = module.addTag( + WasmTagType.EXCEPTION, + patioExceptionTypeDefinition.name(), + List.of(WasmValueType.I32) + ); } case PatioFunctionDefinition patioFunctionDefinition -> { var name = patioFunctionDefinition.name(); @@ -217,9 +221,7 @@ public class WasmPatioCodeGen { context = context.exitIfInstruction(); - for (var patioTarget : patioIf.targets().reversed()) { - context = popIntoPatioLocal(patioTarget, context); - } + context = popIntoPatioLocals(patioIf.targets(), context); yield context; } @@ -330,9 +332,7 @@ public class WasmPatioCodeGen { context = context.exitIfInstruction(); } - for (var patioTarget : patioSwitch.targets().reversed()) { - context = popIntoPatioLocal(patioTarget, context); - } + context = popIntoPatioLocals(patioSwitch.targets(), context); yield context; } @@ -340,8 +340,14 @@ public class WasmPatioCodeGen { case PatioThrow throw_ -> throw new UnsupportedOperationException("TODO"); - case PatioTry try_ -> - throw new UnsupportedOperationException("TODO"); + case PatioTry try_ -> { + context = generateBlockBody(try_.body(), context); + + context = popIntoPatioLocals(try_.targets(), context); + + yield context; + } + case PatioUnreachable patioUnreachable -> context.addInstruction(new WasmUnreachable()); @@ -418,6 +424,16 @@ public class WasmPatioCodeGen { return context.addInstruction(new WasmLocalSet(targetWasmLocalIndex)); } + private static Context popIntoPatioLocals( + List targets, + Context context + ) { + for (var patioTarget : targets.reversed()) { + context = popIntoPatioLocal(patioTarget, context); + } + return context; + } + private static Context generateOperand( PatioOperand patioOperand, Context context -- cgit v1.2.3