aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-11-26 16:45:51 +0000
committerMichael Williamson <mike@zwobble.org>2023-11-26 16:45:51 +0000
commitaa13c97dac536bd1c4bf2f4e5c6ee505a487c634 (patch)
tree61fe8650b0579aa5dc5b55fb50b41eff6c3470d6 /src
parentee02a8cd9af3b2ae723cbba9a910fc159fe75a7c (diff)
Support Patio exceptions in Patio Wasm backend
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java109
-rw-r--r--src/test/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGenTests.java8
-rw-r--r--src/test/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGenTests.java10
-rw-r--r--src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java7
4 files changed, 125 insertions, 9 deletions
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 1447ee14..585de4e6 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java
@@ -337,18 +337,36 @@ public class WasmPatioCodeGen {
yield context;
}
- case PatioThrow throw_ ->
- throw new UnsupportedOperationException("TODO");
+ case PatioThrow throw_ -> {
+ context = generateOperand(throw_.value(), context);
+
+ context = context.addInstruction(new WasmThrow(new WasmTagName(throw_.exceptionTypeName())));
+
+ yield context;
+ }
case PatioTry try_ -> {
+ context = context.enterTryInstruction(
+ new WasmBlockType(List.of(WasmValueType.I32))
+ );
+
context = generateBlockBody(try_.body(), context);
+ for (var catchClause : try_.catchClauses()) {
+ context = context.enterCatch(new WasmTagName(catchClause.exceptionTypeName()));
+
+ // TODO: pop into local for catch
+ context = context.addInstruction(new WasmDrop());
+ context = generateBlockBody(catchClause.body(), context);
+ }
+
+ context = context.exitTryInstruction();
+
context = popIntoPatioLocals(try_.targets(), context);
yield context;
}
-
case PatioUnreachable patioUnreachable ->
context.addInstruction(new WasmUnreachable());
@@ -732,6 +750,33 @@ public class WasmPatioCodeGen {
return exitStructuredInstruction();
}
+ public Context enterTryInstruction(WasmBlockType blockType) {
+ return new Context(
+ this.module,
+ P.vector(),
+ this.instructionsStack.plus(this.instructions),
+ this.patioLocalNameToWasmLocalIndex,
+ new WasmTryInstructionBuilder(blockType),
+ this.structuredInstructionBuilderStack.plus(this.structuredInstructionBuilder)
+ );
+ }
+
+ public Context enterCatch(WasmTagName tagName) {
+ return new Context(
+ this.module,
+ P.vector(),
+ this.instructionsStack,
+ this.patioLocalNameToWasmLocalIndex,
+ this.structuredInstructionBuilder.enterCatch(tagName, this.instructions),
+ this.structuredInstructionBuilderStack
+ );
+ }
+
+ public Context exitTryInstruction() {
+ // TODO: verify matching enter/exit?
+ return exitStructuredInstruction();
+ }
+
public Context exitStructuredInstruction() {
var context = new Context(
this.module,
@@ -775,6 +820,13 @@ public class WasmPatioCodeGen {
default WasmStructuredInstructionBuilder enterElse(PVector<WasmInstruction> instructions) {
throw new UnsupportedOperationException();
}
+
+ default WasmStructuredInstructionBuilder enterCatch(
+ WasmTagName tagName,
+ PVector<WasmInstruction> instructions
+ ) {
+ throw new UnsupportedOperationException();
+ }
}
private static class NullStructuredInstructionBuilder implements WasmStructuredInstructionBuilder {
@@ -821,4 +873,55 @@ public class WasmPatioCodeGen {
return new WasmIf(blockType, ifTrue, instructions);
}
}
+
+ private record WasmTryInstructionBuilder(
+ WasmBlockType blockType
+ ) implements WasmStructuredInstructionBuilder {
+ @Override
+ public WasmInstruction exit(PVector<WasmInstruction> instructions) {
+ return new WasmTry(blockType, List.of(), instructions);
+ }
+
+ @Override
+ public WasmStructuredInstructionBuilder enterCatch(
+ WasmTagName tagName,
+ PVector<WasmInstruction> instructions
+ ) {
+ return new WasmTryCatchInstructionBuilder(
+ blockType,
+ instructions,
+ tagName,
+ P.vector()
+ );
+ }
+ }
+
+ private record WasmTryCatchInstructionBuilder(
+ WasmBlockType blockType,
+ List<WasmInstruction> tryBodyInstructions,
+ WasmTagName tagName,
+ PVector<WasmCatchBlock> catchBlocks
+ ) implements WasmStructuredInstructionBuilder {
+ @Override
+ public WasmInstruction exit(PVector<WasmInstruction> instructions) {
+ return new WasmTry(
+ this.blockType,
+ this.catchBlocks.plus(new WasmCatchBlock(this.tagName, instructions)),
+ this.tryBodyInstructions
+ );
+ }
+
+ @Override
+ public WasmStructuredInstructionBuilder enterCatch(
+ WasmTagName tagName,
+ PVector<WasmInstruction> instructions
+ ) {
+ return new WasmTryCatchInstructionBuilder(
+ this.blockType,
+ this.tryBodyInstructions,
+ tagName,
+ this.catchBlocks.plus(new WasmCatchBlock(this.tagName, instructions))
+ );
+ }
+ }
}
diff --git a/src/test/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGenTests.java b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGenTests.java
index a4c823df..56262676 100644
--- a/src/test/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGenTests.java
+++ b/src/test/java/org/shedlang/compiler/backends/llvm/LlvmPatioCodeGenTests.java
@@ -1,5 +1,7 @@
package org.shedlang.compiler.backends.llvm;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
import org.shedlang.compiler.backends.llvm.ir.ast.LlvmBasicBlock;
import org.shedlang.compiler.backends.llvm.ir.ast.LlvmFunctionDefinition;
import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmCall;
@@ -64,4 +66,10 @@ public class LlvmPatioCodeGenTests extends PatioExampleTests {
return TestProcessRunner.runCaptureOutput(List.of(executablePath.toString()));
}
+
+ @Disabled("WIP")
+ @Test
+ public void whenExceptionIsThrownThenFirstMatchingExceptionHandlerIsUsed() {
+
+ }
}
diff --git a/src/test/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGenTests.java b/src/test/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGenTests.java
index b3c0960f..fe87bfc8 100644
--- a/src/test/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGenTests.java
+++ b/src/test/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGenTests.java
@@ -9,6 +9,7 @@ import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmImport;
import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmImportDescriptor;
import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmFuncType;
import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmValueType;
+import org.shedlang.compiler.filesystem.ShedCompilerFiles;
import org.shedlang.compiler.patio.PatioExampleTests;
import org.shedlang.compiler.patio.ast.PatioCompilationUnit;
import org.shedlang.compiler.testing.ExecutionResult;
@@ -61,6 +62,13 @@ public class WasmPatioCodeGenTests extends PatioExampleTests {
executablePath
);
- return TestProcessRunner.runCaptureOutput(List.of("wasmtime", executablePath.toString()));
+ return TestProcessRunner.runCaptureOutput(List.of(
+ "node",
+ "--experimental-wasi-unstable-preview1",
+ "--no-warnings=ExperimentalWarning",
+ "--experimental-wasm-eh",
+ ShedCompilerFiles.getRoot().resolve("run-wasm.js").toString(),
+ executablePath.toString()
+ ));
}
}
diff --git a/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java b/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java
index b0917393..d1314e5c 100644
--- a/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java
+++ b/src/test/java/org/shedlang/compiler/patio/PatioExampleTests.java
@@ -1,6 +1,5 @@
package org.shedlang.compiler.patio;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.shedlang.compiler.patio.ast.PatioCompilationUnit;
import org.shedlang.compiler.patio.ast.PatioFunctionDefinition;
@@ -223,7 +222,6 @@ public abstract class PatioExampleTests {
}
@Test
- @Disabled("WIP")
public void whenExceptionIsThrownThenFirstMatchingExceptionHandlerIsUsed() throws IOException, InterruptedException {
var patioFunction = PatioFunctionDefinition.builder()
.withName(FUNCTION_NAME)
@@ -266,7 +264,7 @@ public abstract class PatioExampleTests {
)
)
),
- List.of(Patio.int_(0))
+ List.of(Patio.localRef("r2"))
)
))
.addBodyInstruction(Patio.return_(
@@ -275,13 +273,12 @@ public abstract class PatioExampleTests {
.build();
var patio = Patio.compilationUnit(List.of(
Patio.exceptionTypeDefinition("Error", PatioTypes.INT),
- Patio.exceptionTypeDefinition("OtherError", PatioTypes.INT),
patioFunction
));
var result = run(patio);
- assertThat(result, isSilentExit(47));
+ assertThat(result, isSilentExit(2));
}
@Test