m := 1 n := 2
fun D {
d := 3 e := 4
fun A {
a := 5
fun C {
c := 6
log d
D()
}
C()
D()
}
fun B {
b := 7
ret A
}
B()()
}
考虑上面的代码,故意难以“手动”分析,在函数B中,函数A返回,并且在那一刻它必须捕获环境,即m
n
{ {1}} d
。但仔细观察后,我们发现只能捕获e
和c
。我甚至不确定这一点。假设我们有AST,如何确定编译器生成m
时ret A
的闭包环境中要包含的变量?
有了这个问题,我告诉我已经尝试过的事情。我试图将当前函数ret A
下面的所有内容都包括在内,即B
,但是在较大的程序中,这会在堆中留下大量无用的数据。我尝试从{m n d e}
构建所有可能的“spawnees”树(抱歉蹩脚的术语,不知道更好的词),然后合并它们所指的内容,但我发现它可能包含循环引用和甚至对A
和B
本身的父函数的引用,此时我感到头晕,经过几天的思考,我只需要帮助。那你如何建立这个清单呢?