diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-07-14 23:04:25 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-07-14 23:05:18 +0100 |
| commit | 8b4e7af45f229fcce74cd380cc64399bc1d03384 (patch) | |
| tree | e03d6cf5cf9f3b3ba65894dbd3042530a8770056 /src/main/java | |
| parent | eeef2f1636e2fc96c0018532d1e6945ee97c43c6 (diff) | |
Support if instructions in WASM backend
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java | 35 | ||||
| -rw-r--r-- | src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenContext.java | 65 |
2 files changed, 84 insertions, 16 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java index cd5f3b24..ac8c8d62 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java @@ -155,9 +155,7 @@ public class WasmCodeGen { defineFunction.namedParams(), defineFunction.freeVariables(), functionContext -> { - for (var bodyInstruction : defineFunction.body()) { - functionContext = generateInstruction(bodyInstruction, functionContext); - } + functionContext = generateInstructions(defineFunction.body(), functionContext); return functionContext; }, context @@ -181,8 +179,25 @@ public class WasmCodeGen { ); } - case IfInstruction if_ -> - throw new UnsupportedOperationException("TODO"); + case IfInstruction if_ -> { + context = context.enterBlock(); + context = generateInstructions(if_.trueBody(), context); + var trueBodyResult = context.exitBlock(); + var trueBody = trueBodyResult.value(); + context = trueBodyResult.context(); + + context = context.enterBlock(); + context = generateInstructions(if_.falseBody(), context); + var falseBodyResult = context.exitBlock(); + var falseBody = falseBodyResult.value(); + context = falseBodyResult.context(); + + yield context.addInstruction(new WasmIf( + new WasmBlockType(List.of(WasmCodeGenTypes.VALUE_TYPE)), + trueBody, + falseBody + )); + } case IntAddInstruction intAdd -> context.addInstruction(new WasmI32Add()); @@ -251,4 +266,14 @@ public class WasmCodeGen { WasmCodeGenStrings.add(context); }; } + + private static WasmCodeGenContext generateInstructions( + List<Instruction> instructions, + WasmCodeGenContext context + ) { + for (var instruction : instructions) { + context = generateInstruction(instruction, context); + } + return context; + } } diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenContext.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenContext.java index 8e147ad6..1cb0e2e2 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenContext.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenContext.java @@ -11,6 +11,7 @@ import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmLimits; import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmReferenceType; import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmTableType; import org.shedlang.compiler.typechecker.TypeInfo; +import org.shedlang.compiler.util.P; import java.util.List; import java.util.Optional; @@ -168,25 +169,54 @@ public record WasmCodeGenContext( record FunctionContext( WasmFuncType funcType, PVector<WasmInstruction> instructions, + PStack<PVector<WasmInstruction>> blockStack, OrderedPMap<String, WasmLocal> locals, PMap<String, WasmLocalIndex> shedLocalNameToLocalIndex ) { - public static final FunctionContext EMPTY = new FunctionContext( - new WasmFuncType(List.of(), List.of()), - Empty.vector(), - OrderedPMap.empty(), - Empty.map() + public static final FunctionContext EMPTY = forFuncType( + new WasmFuncType(List.of(), List.of()) ); + public static FunctionContext forFuncType(WasmFuncType funcType) { + return new FunctionContext( + funcType, + Empty.vector(), + Empty.stack(), + OrderedPMap.empty(), + Empty.map() + ); + } + public FunctionContext addInstruction(WasmInstruction instruction) { return new FunctionContext( this.funcType, this.instructions.plus(instruction), + this.blockStack, this.locals, this.shedLocalNameToLocalIndex ); } + public FunctionContext enterBlock() { + return new FunctionContext( + this.funcType, + P.vector(), + this.blockStack.plus(this.instructions), + this.locals, + this.shedLocalNameToLocalIndex + ); + } + + public Result<PVector<WasmInstruction>> exitBlock() { + return new FunctionContext( + this.funcType, + this.blockStack.get(0), + this.blockStack.minus(0), + this.locals, + this.shedLocalNameToLocalIndex + ).toResult(this.instructions); + } + public Result<WasmLocalIndex> generateLocal(WasmCodeGenLocalSpace space, Optional<String> name) { var localIndex = new WasmLocalIndex(locals.size()); var localName = NameAllocator.generateName( @@ -197,6 +227,7 @@ public record WasmCodeGenContext( return new FunctionContext( this.funcType, this.instructions, + this.blockStack, this.locals.plus( localName, new WasmLocal(localName, WasmCodeGenTypes.VALUE_TYPE) @@ -213,6 +244,7 @@ public record WasmCodeGenContext( return new FunctionContext( context.funcType, context.instructions, + context.blockStack, context.locals, context.shedLocalNameToLocalIndex.plus(name, localIndex) ).toResult(localIndex); @@ -322,6 +354,22 @@ public record WasmCodeGenContext( ); } + public WasmCodeGenContext enterBlock() { + return new WasmCodeGenContext( + this.moduleContext, + this.functionContext.enterBlock() + ); + } + + public WasmCodeGenResult<List<WasmInstruction>> exitBlock() { + var exitResult = this.functionContext.exitBlock(); + + return new WasmCodeGenContext( + this.moduleContext, + exitResult.context + ).toResult(exitResult.value); + } + public WasmFunction toFunction(String name) { return this.functionContext.toFunction(name); } @@ -359,12 +407,7 @@ public record WasmCodeGenContext( ) { var bodyContext = new WasmCodeGenContext( this.moduleContext, - new FunctionContext( - funcType, - Empty.vector(), - OrderedPMap.empty(), - Empty.map() - ) + FunctionContext.forFuncType(funcType) ); bodyContext = create.apply(bodyContext); |
