aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-26 21:46:39 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-26 21:46:39 +0100
commit17bcdbfef0e40bedd8e8c16e3b6eb6d134635d49 (patch)
tree81cee6ab44660381e76d3fcc47cdada7beffe5a8 /src/main/java
parenta5b889d21b9fcfac32f6f691fa08146139065fd3 (diff)
Add WASM code gen for call instructions with args
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java6
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenClosures.java17
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java42
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenClosures.java16
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenLocalSpace.java2
-rw-r--r--src/main/java/org/shedlang/compiler/util/Iterables.java12
6 files changed, 79 insertions, 16 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
index 7c4427b4..5eb418a9 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGen.java
@@ -36,7 +36,7 @@ public class LlvmCodeGen {
var field = fieldResult.value();
mainContext = fieldResult.context();
- mainContext = LlvmCodeGenClosures.call(field, List.of(), Map.of(), mainContext);
+ mainContext = LlvmCodeGenClosures.call(field, List.of(), List.of(), mainContext);
mainContext = mainContext.addTerminatorInstruction(
new LlvmReturn(LlvmTypes.INT_32, new LlvmOperandInt(0))
@@ -97,12 +97,12 @@ public class LlvmCodeGen {
public static LlvmCodeGenContext generateInstruction(Instruction instruction, LlvmCodeGenContext context) {
return switch (instruction) {
case CallInstruction call -> {
- var namedArgsByName = new HashMap<String, LlvmOperand>();
+ var namedArgsByName = new ArrayList<Map.Entry<String, LlvmOperand>>();
for (var argName : reversed(call.namedArgNames())) {
var argResult = context.pop();
var arg = argResult.value();
context = argResult.context();
- namedArgsByName.put(argName, arg);
+ namedArgsByName.add(Map.entry(argName, arg));
}
var positionalArgs = new ArrayList<LlvmOperand>();
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenClosures.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenClosures.java
index 098acbdd..62212a34 100644
--- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenClosures.java
+++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCodeGenClosures.java
@@ -11,12 +11,11 @@ import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableGlobal;
import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableLocal;
import org.shedlang.compiler.backends.llvm.ir.ast.types.*;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
import java.util.function.Function;
+import static org.shedlang.compiler.util.Iterables.sortedBy;
+
public class LlvmCodeGenClosures {
private LlvmCodeGenClosures() {
}
@@ -157,7 +156,7 @@ public class LlvmCodeGenClosures {
public static LlvmCodeGenContext call(
LlvmOperand closure,
List<LlvmOperand> positionalArgs,
- Map<String, LlvmOperand> namedArgsByName,
+ List<Map.Entry<String, LlvmOperand>> namedArgsByName,
LlvmCodeGenContext context
) {
var closurePointerResult = castValueToClosurePointer(closure, context);
@@ -176,14 +175,14 @@ public class LlvmCodeGenClosures {
var fullArgs = new ArrayList<LlvmTypedOperand>();
fullArgs.add(new LlvmTypedOperand(CALLABLE_TYPES.closurePointer(), closurePointer));
+
for (var arg : positionalArgs) {
fullArgs.add(new LlvmTypedOperand(LlvmCodeGenTypes.VALUE_TYPE, arg));
}
- namedArgsByName.entrySet()
- .stream().sorted(Map.Entry.comparingByKey())
- .map(x -> x.getValue())
- .forEachOrdered(x -> fullArgs.add(new LlvmTypedOperand(LlvmCodeGenTypes.VALUE_TYPE, x)));
+ for (var arg : sortedBy(namedArgsByName, x -> x.getKey())) {
+ fullArgs.add(new LlvmTypedOperand(LlvmCodeGenTypes.VALUE_TYPE, arg.getValue()));
+ }
return context.addInstruction(new LlvmCall(
callTarget,
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 3d466648..5926af9c 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGen.java
@@ -1,11 +1,15 @@
package org.shedlang.compiler.backends.wasm;
import org.shedlang.compiler.backends.wasm.structure.ast.instructions.*;
+import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmLocalIndex;
import org.shedlang.compiler.stackir.instructions.*;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Map;
+import static org.shedlang.compiler.util.Lists.reversed;
+
public class WasmCodeGen {
private WasmCodeGen() {
}
@@ -13,13 +17,47 @@ public class WasmCodeGen {
public static WasmCodeGenContext generateInstruction(Instruction instruction, WasmCodeGenContext context) {
return switch (instruction) {
case CallInstruction call -> {
+ var namedArgsByName = new ArrayList<Map.Entry<String, WasmLocalIndex>>();
+ for (var argName : reversed(call.namedArgNames())) {
+ var argResult = context.generateLocal(
+ WasmCodeGenLocalSpace.CALL_ARG_NAMED,
+ argName
+ );
+ var arg = argResult.value();
+ context = argResult.context();
+
+ context = context.addInstruction(new WasmLocalSet(arg));
+
+ namedArgsByName.add(Map.entry(argName, arg));
+ }
+
+ var positionalArgs = new ArrayList<WasmLocalIndex>();
+ for (var i = 0; i < call.positionalArgCount(); i++) {
+ var argResult = context.generateLocal(
+ WasmCodeGenLocalSpace.CALL_ARG_POSITIONAL,
+ Integer.toString(call.positionalArgCount() - i - 1)
+ );
+ var arg = argResult.value();
+ context = argResult.context();
+
+ context = context.addInstruction(new WasmLocalSet(arg));
+
+ positionalArgs.add(arg);
+ }
+ Collections.reverse(positionalArgs);
+
var receiverResult = context.generateLocal(WasmCodeGenLocalSpace.RECEIVER);
var receiver = receiverResult.value();
context = receiverResult.context();
context = context.addInstruction(new WasmLocalSet(receiver));
- yield WasmCodeGenClosures.call(receiver, List.of(), Map.of(), context);
+ yield WasmCodeGenClosures.call(
+ receiver,
+ positionalArgs,
+ namedArgsByName,
+ context
+ );
}
case DefineFunctionInstruction defineFunctionInstruction -> {
throw new UnsupportedOperationException("TODO");
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenClosures.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenClosures.java
index 86ae472d..a2d34df7 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenClosures.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenClosures.java
@@ -12,6 +12,8 @@ import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmValueType;
import java.util.List;
import java.util.Map;
+import static org.shedlang.compiler.util.Iterables.sortedBy;
+
public class WasmCodeGenClosures {
private WasmCodeGenClosures() {
}
@@ -21,14 +23,24 @@ public class WasmCodeGenClosures {
public static WasmCodeGenContext call(
WasmLocalIndex closure,
List<WasmLocalIndex> positionalArgs,
- Map<String, WasmLocalIndex> namedArgsByName,
+ List<Map.Entry<String, WasmLocalIndex>> namedArgsByName,
WasmCodeGenContext context
) {
+ context = context.addInstruction(new WasmLocalGet(closure));
+
+ for (var positionalArg : positionalArgs) {
+ context = context.addInstruction(new WasmLocalGet(positionalArg));
+ }
+
+ for (var namedArg : sortedBy(namedArgsByName, x -> x.getKey())) {
+ context = context.addInstruction(new WasmLocalGet(namedArg.getValue()));
+ }
+
context = loadClosureFunctionTableIndex(closure, context);
var funcType = new WasmFuncType(List.of(CLOSURE_TYPE), List.of(WasmCodeGenTypes.VALUE_TYPE));
+
return context
- .addInstruction(new WasmLocalGet(closure))
.addType(funcType)
.addInstruction(new WasmCallIndirect(context.indirectFunctionTableIndex(), funcType));
}
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenLocalSpace.java b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenLocalSpace.java
index 80e89155..eeda312a 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenLocalSpace.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/WasmCodeGenLocalSpace.java
@@ -1,6 +1,8 @@
package org.shedlang.compiler.backends.wasm;
public enum WasmCodeGenLocalSpace {
+ CALL_ARG_POSITIONAL("callArgPositional"),
+ CALL_ARG_NAMED("callArgNamed"),
LOCAL("local"),
RECEIVER("receiver");
diff --git a/src/main/java/org/shedlang/compiler/util/Iterables.java b/src/main/java/org/shedlang/compiler/util/Iterables.java
index ff043c13..38730594 100644
--- a/src/main/java/org/shedlang/compiler/util/Iterables.java
+++ b/src/main/java/org/shedlang/compiler/util/Iterables.java
@@ -1,5 +1,10 @@
package org.shedlang.compiler.util;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Function;
+
public class Iterables {
private Iterables() {
}
@@ -26,4 +31,11 @@ public class Iterables {
first = false;
}
}
+
+ public static <T, K extends Comparable<? super K>> List<T> sortedBy(
+ Collection<T> collection,
+ Function<? super T, ? extends K> key
+ ) {
+ return collection.stream().sorted(Comparator.comparing(key)).toList();
+ }
}