From 36540510fff921b46642c6a01b0e566d540b4076 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 20 Jul 2023 14:13:50 +0100 Subject: Allocate memory for closure --- .../compiler/patio/PatioCodeGenClosures.java | 24 ++++++++++++++++++++-- .../compiler/patio/PatioCodeGenLocalSpace.java | 1 + .../compiler/patio/ast/types/PatioTypes.java | 6 +++++- .../java/org/shedlang/compiler/util/Lists.java | 9 ++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) (limited to 'src/main/java') 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 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 elements) { + public static PatioDataLayout structFlat(List elements) { return new PatioStruct( elements.stream() .map(element -> scalar(element)) .toList() ); } + + public static PatioDataLayout struct(List 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 List repeat(T element, int count) { + var result = new ArrayList(count); + for (var i = 0; i < count; i++) { + result.add(element); + } + return result; + } + private static class ReverseIterator implements Iterator { private int index; private final List list; -- cgit v1.2.3