Activation Records
:material-circle-edit-outline: 约 465 个字 :material-clock-time-two-outline: 预计阅读时间 2 分钟
函数被调用是就会产生一个对应的 activation,活跃的 activation 对应一个 activation record (sometimes called a frame),位于 control stack
Stack Frames
栈由高地址向低地址增长
sp
寄存器存栈顶地址,fp
指向 caller 帧头
- 寄存器存:
- 部分函数参数
- 返回地址
- 函数返回值
- 部分本地变量
- 栈存:
- 额外的函数参数
- 体积过大的变量
- 通过引用传的变量,或者这个变量有被取地址
- 有些语言允许函数内定义函数,内部函数访问外部函数参数时得存栈上
- 数组
嵌套函数变量访问问题
对于嵌套函数,内部函数可能需要访问外部函数的变量,即访问外部函数的栈帧
有三个解决方案
Static Links
如果 f 是 g 内部的嵌套函数,那么调用 f 时需要把 g 最近一次的 activation record 的地址传递给 f 作为 Static Links,也就是说 Static Links 是一个指向外部函数栈帧的指针
如此内部函数就能通过 Static Links 访问外部函数栈帧
Display
给每一个函数标记静态嵌套深度,然后设置一个全局数组 Display,以嵌套深度为 index 存储该深度函数的最近一次调用的栈帧地址
Lambda Lifting
编译时直接看调用的函数会用到哪些外部变量,直接当参数传进去
Higher-Order Functions
我们之前讨论的都是基于栈帧的存储方法,使用栈帧有个要求是:函数退出后需要释放其内部的所有信息(包括内部函数的栈帧)
但是这样就不支持高阶函数了,高阶函数将函数作为返回值
调用 f(3)
后,传入的 3
不应该被销毁