From 8f3ae2a811d676214d99b6ebd315d86488a7544d Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 22 Jul 2023 17:27:00 +0100 Subject: Generate main function using Patio in wasm-patio backend --- .../compiler/backends/wasm/WasmBackend.java | 56 +++++++++++++++- .../org/shedlang/compiler/patio/PatioCodeGen.java | 78 ++++++++++++++++++++++ .../PatioCodeGenCompilationUnitElementSpace.java | 1 + .../compiler/patio/PatioCodeGenLocalSpace.java | 1 + 4 files changed, 134 insertions(+), 2 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java index 2ce1397c..10102a0a 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmBackend.java @@ -2,13 +2,17 @@ package org.shedlang.compiler.backends.wasm; import org.shedlang.compiler.backends.Backend; import org.shedlang.compiler.backends.wasm.structure.WasmBinaryFormat; -import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmModule; +import org.shedlang.compiler.backends.wasm.structure.ast.instructions.*; +import org.shedlang.compiler.backends.wasm.structure.ast.modules.*; +import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmValueType; import org.shedlang.compiler.config.ProjectConfig; import org.shedlang.compiler.filesystem.ShedCompilerFiles; import org.shedlang.compiler.patio.PatioCodeGen; import org.shedlang.compiler.patio.PatioCodeGenContext; +import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.stackir.StackIrNamespace; import org.shedlang.compiler.typechecker.TypeInfo; +import org.shedlang.compiler.types.NamespaceName; import java.io.FileOutputStream; import java.io.IOException; @@ -25,6 +29,11 @@ public class WasmBackend implements Backend { public WasmModule generateNamespace(StackIrNamespace stackIrNamespace, TypeInfo typeInfo) { return WasmCodeGen.generateNamespace(stackIrNamespace, typeInfo); } + + @Override + public WasmModule generateMain(NamespaceName main, TypeInfo typeInfo) { + return WasmCodeGen.generateMain(main, typeInfo); + } }); public static final WasmBackend PATIO = new WasmBackend("wasm-patio", new CodeGen() { @@ -37,6 +46,47 @@ public class WasmBackend implements Backend { return WasmPatioCodeGen.generateCompilationUnit(patioCompilationUnit); } + + @Override + public WasmModule generateMain(NamespaceName main, TypeInfo typeInfo) { + // TODO: set appropriate source + var source = Sources.NULL; + + var context = PatioCodeGenContext.forTypeInfo(typeInfo); + + var generateMainResult = PatioCodeGen.generateMain(main, source, context); + var mainFunctionName = generateMainResult.value(); + context = generateMainResult.context(); + + var patioCompilationUnit = context.toCompilationUnit(source); + + var wasmModule = WasmPatioCodeGen.generateCompilationUnit(patioCompilationUnit); + + // TODO: put these in separate module, remove duplication + wasmModule = wasmModule.addFunction(new WasmFunction( + "wasm_memory_grow", + List.of(new WasmLocal("pages", WasmValueType.I32)), + List.of(), + List.of(WasmValueType.I32), + new WasmExpression(List.of( + new WasmLocalGet(new WasmLocalIndex(0)), + new WasmMemoryGrow() + )) + )); + + wasmModule = wasmModule.addFunction(new WasmFunction( + "_start", + List.of(), + List.of(), + List.of(), + new WasmExpression(List.of( + new WasmCall(new WasmFuncName(mainFunctionName)), + new WasmDrop() + )) + )); + + return wasmModule; + } }); interface CodeGen { @@ -44,6 +94,8 @@ public class WasmBackend implements Backend { StackIrNamespace stackIrNamespace, TypeInfo typeInfo ); + + WasmModule generateMain(NamespaceName main, TypeInfo typeInfo); } private final String name; @@ -84,7 +136,7 @@ public class WasmBackend implements Backend { ldArgs.add(objectFilePath.toString()); } - var mainModule = WasmCodeGen.generateMain(config.main(), typeInfo); + var mainModule = this.codeGen.generateMain(config.main(), typeInfo); var mainObjectPath = writeObjectFile(mainModule, targetDir.resolve("bins"), bin.name()); ldArgs.add(mainObjectPath.toString()); diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java index e6a12214..f9bfd38b 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGen.java @@ -1,16 +1,19 @@ package org.shedlang.compiler.patio; import org.shedlang.compiler.patio.ast.PatioCompilationUnit; +import org.shedlang.compiler.patio.ast.PatioVisibility; import org.shedlang.compiler.patio.ast.instructions.PatioDataPtrToInt; import org.shedlang.compiler.patio.ast.instructions.PatioIntAdd; import org.shedlang.compiler.patio.ast.instructions.PatioLocalStore; import org.shedlang.compiler.patio.ast.instructions.PatioReturn; import org.shedlang.compiler.patio.ast.operands.PatioInt; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; +import org.shedlang.compiler.patio.ast.types.PatioTypes; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.stackir.StackIrNamespace; import org.shedlang.compiler.stackir.instructions.*; +import org.shedlang.compiler.types.NamespaceName; import java.util.ArrayList; import java.util.Collections; @@ -22,6 +25,81 @@ import static org.shedlang.compiler.util.Lists.reversed; public class PatioCodeGen { private PatioCodeGen() {} + public static PatioCodeGenResult generateMain( + NamespaceName main, + Source source, + PatioCodeGenContext context + ) { + var mainFunctionNameResult = context.allocateCompilationUnitElementName( + PatioCodeGenCompilationUnitElementSpace.MAIN + ); + var mainFunctionName = mainFunctionNameResult.value(); + context = mainFunctionNameResult.context(); + + context = context.createFunction( + mainFunctionName, + PatioVisibility.PRIVATE, + PatioTypes.INT, + source, + mainContext -> { + var namespaceValueResult = mainContext.allocateLocal( + PatioCodeGenLocalSpace.NAMESPACE_VALUE, + PatioCodeGenTypes.VALUE_TYPE + ); + var namespaceValue = namespaceValueResult.value(); + mainContext = namespaceValueResult.context(); + + mainContext = PatioCodeGenNamespaces.importValue( + namespaceValue, + main, + source, + mainContext + ); + + var mainFieldResult = mainContext.allocateLocal( + PatioCodeGenLocalSpace.MAIN, + PatioCodeGenTypes.VALUE_TYPE + ); + var mainField = mainFieldResult.value(); + mainContext = mainFieldResult.context(); + + mainContext = PatioCodeGenNamespaces.fieldLoad( + mainField, + namespaceValue, + main, + // TODO: check there is a main function + "main", + source, + mainContext + ); + + var exitCodeResult = mainContext.allocateLocal( + PatioCodeGenLocalSpace.MAIN, + PatioCodeGenTypes.VALUE_TYPE + ); + var exitCode = exitCodeResult.value(); + mainContext = exitCodeResult.context(); + + mainContext = PatioCodeGenClosures.call( + exitCode, + mainField, + List.of(), + List.of(), + source, + mainContext + ); + + mainContext = mainContext.addInstruction( + new PatioReturn(exitCode, source) + ); + + return mainContext; + } + ); + + return context.toResult(mainFunctionName); + } + public static PatioCompilationUnit generateNamespace( StackIrNamespace stackIrNamespace, PatioCodeGenContext context diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java index 4d18223e..d6bd46fa 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenCompilationUnitElementSpace.java @@ -2,6 +2,7 @@ package org.shedlang.compiler.patio; public enum PatioCodeGenCompilationUnitElementSpace { FUNCTION("function"), + MAIN("main"), STRING("string"); private final String name; diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java index 1735c2a0..fb46b165 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java @@ -7,6 +7,7 @@ public enum PatioCodeGenLocalSpace { CLOSURE("closure"), CLOSURE_POINTER("closurePointer"), CLOSURE_FUNCTION_POINTER("closureFunctionPointer"), + MAIN("main"), NAMESPACE_IS_INITED_POINTER("namespaceIsInitedPointer"), NAMESPACE_POINTER("namespacePointer"), NAMESPACE_VALUE("namespaceValue"), -- cgit v1.2.3