aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-10-08 20:48:18 +0100
committerMichael Williamson <mike@zwobble.org>2023-10-08 20:48:18 +0100
commitb8b4814b92c4d808da5a79d1d7311c27b325853f (patch)
treeb07cc48476a0bd0bc42c4fe7e76468dc510e9607 /src/main/java
parentebf5f513c8305ae37d03d990fb24e5b7a6623244 (diff)
Support Patio switch in WASM code gen
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java38
1 files changed, 32 insertions, 6 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 fe01d9c5..16d4b520 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmPatioCodeGen.java
@@ -198,11 +198,7 @@ public class WasmPatioCodeGen {
case PatioIf patioIf -> {
context = generateOperand(patioIf.condition(), context);
- var wasmBlockType = new WasmBlockType(
- patioIf.targets().stream()
- .map(patioTarget -> patioOperandToWasmValueType(patioTarget))
- .toList()
- );
+ var wasmBlockType = generateBlockType(patioIf.targets());
context = context.enterIfInstruction(wasmBlockType);
context = generateBlockBody(patioIf.trueBody(), context);
@@ -307,7 +303,29 @@ public class WasmPatioCodeGen {
}
case PatioSwitch patioSwitch -> {
- throw new UnsupportedOperationException("TODO");
+ // TODO: use br_table?
+ var wasmBlockType = generateBlockType(patioSwitch.targets());
+
+ for (var patioSwitchCase : patioSwitch.cases()) {
+ context = generateOperand(patioSwitch.value(), context);
+ context = context.addInstruction(new WasmI32Const(patioSwitchCase.value()));
+ context = context.addInstruction(new WasmI32Eq());
+ context = context.enterIfInstruction(wasmBlockType);
+ context = generateBlockBody(patioSwitchCase.body(), context);
+ context = context.enterElse();
+ }
+
+ context = generateBlockBody(patioSwitch.defaultBody(), context);
+
+ for (var patioSwitchCase : patioSwitch.cases()) {
+ context = context.exitIfInstruction();
+ }
+
+ for (var patioTarget : Lists.reversed(patioSwitch.targets())) {
+ context = popIntoPatioLocal(patioTarget, context);
+ }
+
+ yield context;
}
case PatioUnreachable patioUnreachable ->
@@ -331,6 +349,14 @@ public class WasmPatioCodeGen {
};
}
+ private static WasmBlockType generateBlockType(List<PatioLocalRef> targets) {
+ return new WasmBlockType(
+ targets.stream()
+ .map(patioTarget -> patioOperandToWasmValueType(patioTarget))
+ .toList()
+ );
+ }
+
private static Context generateBlockBody(
PatioBlock block,
Context context