Skip to content

Commit 39a0d23

Browse files
committed
Preserve captured environments in nested AOT functions
1 parent eda5659 commit 39a0d23

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

pkg/runtime/codegen.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,12 @@ func (g *Generator) generateFnFunc(fn lang.FnFunc) string {
11591159
func (g *Generator) generateFn(fn *Fn) string {
11601160
// Save and restore current environment
11611161
prevEnv := g.currentFnEnv
1162-
g.currentFnEnv = fn.GetEnvironment() // Set the captured environment for this function
1162+
// Runtime function values carry their captured environment. Functions
1163+
// constructed directly from nested AST nodes do not; in that case they
1164+
// inherit the environment of the function currently being generated.
1165+
if env := fn.GetEnvironment(); env != nil {
1166+
g.currentFnEnv = env
1167+
}
11631168
defer func() { g.currentFnEnv = prevEnv }()
11641169

11651170
astNode := fn.ASTNode()

pkg/runtime/codegen_internal_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ func TestGenerateStandardFileHandles(t *testing.T) {
4141
}
4242
}
4343

44+
func TestGenerateNestedClosureCapturedAtLoadTime(t *testing.T) {
45+
ns := lang.FindOrCreateNamespace(lang.NewSymbol("codegen.nested-capture"))
46+
ns.ReferAllSnapshot(lang.NSCore, nil)
47+
lang.PushThreadBindings(lang.NewMap(lang.VarCurrentNS, ns))
48+
defer lang.PopThreadBindings()
49+
50+
ReadEval(`
51+
(defn make-closure [keep]
52+
(fn [_]
53+
(let [finish (fn [] keep)]
54+
(finish))))
55+
(def captured (make-closure true))`)
56+
57+
var output bytes.Buffer
58+
if err := NewGenerator(&output).Generate(ns); err != nil {
59+
t.Fatalf("generate nested captured closure: %v", err)
60+
}
61+
}
62+
4463
func TestGenerateResolvedHostReference(t *testing.T) {
4564
generator := NewGenerator(&bytes.Buffer{})
4665
node := ast.MakeNode(ast.OpConst, nil)

0 commit comments

Comments
 (0)