diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-04-06 14:06:15 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-04-06 14:06:15 +0100 |
| commit | d11f5583d0f3b941dfe7b27e9e80d051a0a7231e (patch) | |
| tree | f0d652daea9e5e96992105c3665c47f9c3806b7e /src | |
| parent | 0b8637f445a6e3483dabe091742012f528457fe9 (diff) | |
Add full backend support for cranelift
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackend.java | 136 | ||||
| -rw-r--r-- | src/test/java/org/shedlang/compiler/backends/cranelift/CraneliftAmd64ExampleTests.java | 34 |
2 files changed, 163 insertions, 7 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackend.java b/src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackend.java index 7a16cc44..584fd7d0 100644 --- a/src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackend.java @@ -1,23 +1,35 @@ package org.shedlang.compiler.backends.cranelift; import com.google.flatbuffers.FlatBufferBuilder; +import org.pcollections.PVector; +import org.shedlang.compiler.backends.Backend; +import org.shedlang.compiler.backends.PatioBackends; import org.shedlang.compiler.backends.llvm.LlvmBackend; import org.shedlang.compiler.backends.llvm.LlvmTarget; import org.shedlang.compiler.backends.paths.PartialTargetPath; +import org.shedlang.compiler.backends.paths.TargetDir; +import org.shedlang.compiler.config.ProfileConfig; +import org.shedlang.compiler.config.ProjectConfig; import org.shedlang.compiler.filesystem.ShedCompilerFiles; import org.shedlang.compiler.patio.PatioCompilationUnit; import org.shedlang.compiler.patio.serialization.PatioToFlatbuffers; import org.shedlang.compiler.runtime.ShedRuntime; +import org.shedlang.compiler.shid.ShidNamespace; +import org.shedlang.compiler.typechecker.TypeInfos; +import org.shedlang.compiler.types.NamespaceName; +import org.shedlang.compiler.util.P; import org.shedlang.compiler.util.processes.ProcessError; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; import static org.shedlang.compiler.util.processes.ProcessRunner.runInheritIo; -public class CraneliftBackend { +public class CraneliftBackend implements Backend { public static final CraneliftBackend AMD64 = forTarget(LlvmTarget.AMD64); public static CraneliftBackend forTarget(LlvmTarget target) { @@ -34,20 +46,47 @@ public class CraneliftBackend { PatioCompilationUnit patio, PartialTargetPath partialTargetPath ) throws IOException, InterruptedException { + return compileCompilationUnit(patio, Optional.empty(), partialTargetPath); + } + + private Path compileMain( + PatioCompilationUnit patio, + String mainFunctionName, + PartialTargetPath partialTargetPath + ) throws IOException, InterruptedException { + return compileCompilationUnit(patio, Optional.of(mainFunctionName), partialTargetPath); + } + + private Path compileCompilationUnit( + PatioCompilationUnit patio, + Optional<String> mainFunctionName, + PartialTargetPath partialTargetPath + ) throws IOException, InterruptedException { var fbsBuilder = new FlatBufferBuilder(); var compilationUnitOffset = PatioToFlatbuffers.serializeCompilationUnit(fbsBuilder, patio); fbsBuilder.finish(compilationUnitOffset); // TODO: avoid the copy var patioPath = partialTargetPath.withExtension(".patio"); + Files.createDirectories(patioPath.getParent()); Files.write(patioPath, fbsBuilder.sizedByteArray()); - runInheritIo(List.of( - ShedCompilerFiles.getRoot().resolve("patio-to-cranelift/target/debug/patio-to-cranelift").toString(), - patioPath.toString(), - "--target", - this.target.targetTriple() - )); + var patioToCraneliftArgs = new ArrayList<String>(); + patioToCraneliftArgs.add( + ShedCompilerFiles.getRoot() + .resolve("patio-to-cranelift/target/debug/patio-to-cranelift") + .toString() + ); + patioToCraneliftArgs.add(patioPath.toString()); + patioToCraneliftArgs.add("--target"); + patioToCraneliftArgs.add(this.target.targetTriple()); + + if (mainFunctionName.isPresent()) { + patioToCraneliftArgs.add("--main"); + patioToCraneliftArgs.add(mainFunctionName.get()); + } + + runInheritIo(patioToCraneliftArgs); var objectFilePath = partialTargetPath.withExtension(".o"); return objectFilePath; @@ -61,4 +100,87 @@ public class CraneliftBackend { // TODO: extract linking if it's not specific to LLVM. LlvmBackend.forTarget(this.target).link(inputs, outputPath, shedRuntime); } + + @Override + public String targetName() { + return "cranelift-" + target.targetName(); + } + + @Override + public void compile( + ProjectConfig config, + ProfileConfig profileConfig, + List<ShidNamespace> namespaces, + TypeInfos typeInfos, + TargetDir targetDir + ) throws IOException, InterruptedException { + PatioBackends.compile( + config, + profileConfig, + namespaces, + typeInfos, + new PatioToBinary( + targetDir, + P.vector() + ) + ); + } + + private class PatioToBinary implements PatioBackends.PatioToTarget { + private final TargetDir targetDir; + private final PVector<Path> objectFilePaths; + + public PatioToBinary( + TargetDir targetDir, + PVector<Path> objectFilePaths + ) { + this.targetDir = targetDir; + this.objectFilePaths = objectFilePaths; + } + + @Override + public PatioBackends.PatioToTarget namespace( + NamespaceName namespaceName, + PatioCompilationUnit patioCompilationUnit + ) throws IOException, InterruptedException { + var objectPath = compileCompilationUnit( + patioCompilationUnit, + this.targetDir.namespace(namespaceName) + ); + + return new PatioToBinary( + this.targetDir, + this.objectFilePaths.plus(objectPath) + ); + } + + @Override + public void bin( + String binName, + PatioCompilationUnit patioCompilationUnit, + String mainFunctionName, + ProfileConfig profileConfig + ) throws IOException, InterruptedException { + var linkInputs = new ArrayList<>(objectFilePaths); + + var mainObjectPath = compileMain( + patioCompilationUnit, + mainFunctionName, + this.targetDir.bin(binName) + ); + linkInputs.add(mainObjectPath); + + var shedRuntime = ShedRuntime.runtime( + target.targetName(), + profileConfig.gc(), + targetDir + ); + + link( + linkInputs, + targetDir.topLevel(binName), + shedRuntime + ); + } + } } diff --git a/src/test/java/org/shedlang/compiler/backends/cranelift/CraneliftAmd64ExampleTests.java b/src/test/java/org/shedlang/compiler/backends/cranelift/CraneliftAmd64ExampleTests.java new file mode 100644 index 00000000..bc78c435 --- /dev/null +++ b/src/test/java/org/shedlang/compiler/backends/cranelift/CraneliftAmd64ExampleTests.java @@ -0,0 +1,34 @@ +package org.shedlang.compiler.backends.cranelift; + +import org.junit.jupiter.api.Disabled; +import org.shedlang.compiler.backends.Backend; +import org.shedlang.compiler.backends.ExampleTests; + +import java.util.List; +import java.util.Set; + +@Disabled +public class CraneliftAmd64ExampleTests extends ExampleTests { + @Override + protected Backend backend() { + return CraneliftBackend.AMD64; + } + + @Override + protected List<String> binaryRunner() { + return List.of(); + } + + @Override + protected String executableExtension() { + return ""; + } + + private static final Set<String> DISABLED = Set.of( + ); + + @Override + protected boolean isDisabled(String testName) { + return DISABLED.contains(testName); + } +} |
