aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-04-06 14:06:15 +0100
committerMichael Williamson <mike@zwobble.org>2026-04-06 14:06:15 +0100
commitd11f5583d0f3b941dfe7b27e9e80d051a0a7231e (patch)
treef0d652daea9e5e96992105c3665c47f9c3806b7e /src
parent0b8637f445a6e3483dabe091742012f528457fe9 (diff)
Add full backend support for cranelift
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/cranelift/CraneliftBackend.java136
-rw-r--r--src/test/java/org/shedlang/compiler/backends/cranelift/CraneliftAmd64ExampleTests.java34
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);
+ }
+}