aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-20 14:13:50 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-20 14:17:03 +0100
commit36540510fff921b46642c6a01b0e566d540b4076 (patch)
tree6909806e14ff11740207272ed8d3527f20d579eb /src/main/java
parent557198d9f3718e2be26b793dc32e76912f2c5bcc (diff)
Allocate memory for closure
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java24
-rw-r--r--src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java1
-rw-r--r--src/main/java/org/shedlang/compiler/patio/ast/types/PatioTypes.java6
-rw-r--r--src/main/java/org/shedlang/compiler/util/Lists.java9
4 files changed, 37 insertions, 3 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java
index 16b9172b..b3cace14 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenClosures.java
@@ -1,6 +1,7 @@
package org.shedlang.compiler.patio;
import org.shedlang.compiler.ast.typed.FreeVariables;
+import org.shedlang.compiler.patio.ast.instructions.PatioAlloc;
import org.shedlang.compiler.patio.ast.instructions.PatioCallPointer;
import org.shedlang.compiler.patio.ast.PatioLocalRef;
import org.shedlang.compiler.patio.ast.instructions.PatioMemoryLoad;
@@ -10,6 +11,7 @@ import org.shedlang.compiler.patio.ast.types.PatioType;
import org.shedlang.compiler.patio.ast.types.PatioTypes;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction;
+import org.shedlang.compiler.util.Lists;
import java.util.ArrayList;
import java.util.List;
@@ -25,12 +27,19 @@ class PatioCodeGenClosures {
private static final int FUNCTION_POINTER_OFFSET = 0;
- private static PatioDataLayout closureDataLayout() {
+ private static PatioDataLayout closureDataLayoutForCall() {
return new PatioStruct(List.of(
PatioTypes.scalar(PatioTypes.FUNCTION_POINTER)
));
}
+ private static PatioDataLayout closureDataLayout(int freeVariableCount) {
+ return PatioTypes.struct(List.of(
+ PatioTypes.scalar(PatioTypes.FUNCTION_POINTER),
+ PatioTypes.structFlat(Lists.repeat(PatioCodeGenTypes.VALUE_TYPE, freeVariableCount))
+ ));
+ }
+
public static PatioCodeGenContext create(
String name,
List<DefineFunctionInstruction.Param> positionalParams,
@@ -40,6 +49,8 @@ class PatioCodeGenClosures {
Source source,
PatioCodeGenContext context
) {
+ var layout = closureDataLayout(freeVariables.size());
+
var fullNameResult = context.allocateCompilationUnitElementName(
PatioCodeGenCompilationUnitElementSpace.FUNCTION,
name
@@ -51,6 +62,15 @@ class PatioCodeGenClosures {
return bodyContext;
});
+ var closureResult = context.allocateLocal(
+ PatioCodeGenLocalSpace.CLOSURE,
+ PatioTypes.DATA_POINTER
+ );
+ var closure = closureResult.value();
+ context = closureResult.context();
+
+ context = context.addInstruction(new PatioAlloc(closure, layout, source));
+
return context;
}
@@ -72,7 +92,7 @@ class PatioCodeGenClosures {
context = context.addInstruction(new PatioMemoryLoad(
functionPointer,
closure,
- closureDataLayout(),
+ closureDataLayoutForCall(),
FUNCTION_POINTER_OFFSET,
source
));
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
index cad33bdd..89fd69c6 100644
--- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
+++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenLocalSpace.java
@@ -4,6 +4,7 @@ public enum PatioCodeGenLocalSpace {
CALL_ARG_POSITIONAL("callArgPositional"),
CALL_ARG_NAMED("callArgNamed"),
CALL_FUNCTION_POINTER("callFunctionPointer"),
+ CLOSURE("closure"),
LOCAL("local"),
RECEIVER("receiver"),
TEMPORARY("tmp");
diff --git a/src/main/java/org/shedlang/compiler/patio/ast/types/PatioTypes.java b/src/main/java/org/shedlang/compiler/patio/ast/types/PatioTypes.java
index dd31bde0..7059715d 100644
--- a/src/main/java/org/shedlang/compiler/patio/ast/types/PatioTypes.java
+++ b/src/main/java/org/shedlang/compiler/patio/ast/types/PatioTypes.java
@@ -14,11 +14,15 @@ public class PatioTypes {
return new PatioScalar(type);
}
- public static PatioDataLayout struct(List<PatioType> elements) {
+ public static PatioDataLayout structFlat(List<PatioType> elements) {
return new PatioStruct(
elements.stream()
.map(element -> scalar(element))
.toList()
);
}
+
+ public static PatioDataLayout struct(List<PatioDataLayout> elements) {
+ return new PatioStruct(elements);
+ }
}
diff --git a/src/main/java/org/shedlang/compiler/util/Lists.java b/src/main/java/org/shedlang/compiler/util/Lists.java
index f9d1a538..c89534fc 100644
--- a/src/main/java/org/shedlang/compiler/util/Lists.java
+++ b/src/main/java/org/shedlang/compiler/util/Lists.java
@@ -1,5 +1,6 @@
package org.shedlang.compiler.util;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
@@ -25,6 +26,14 @@ public class Lists {
};
}
+ public static <T> List<T> repeat(T element, int count) {
+ var result = new ArrayList<T>(count);
+ for (var i = 0; i < count; i++) {
+ result.add(element);
+ }
+ return result;
+ }
+
private static class ReverseIterator<T> implements Iterator<T> {
private int index;
private final List<T> list;