已完成当前这一轮。
这一轮把 TBC 从“只支持 nil/false 快速路径”继续往前推进,接上了真正可执行的第一版资源关闭链路。
这一轮主要参考这些官方文件:
references/lua-5.5.0/src/lfunc.creferences/lua-5.5.0/src/lvm.creferences/lua-5.5.0/src/ltm.creferences/lua-5.5.0/src/lapi.c- Lua 5.5 手册:https://www.lua.org/manual/5.5/
这一轮关注的核心点是:
OP_TBCOP_CLOSE__closesetmetatable
目标不是一次把完整资源释放语义做满,而是先把最小可跑通的真实路径接起来。
本轮先落这几件事:
- 为运行时补上最小 native closure 承载结构
- 在
_ENV中预置最小setmetatable - 为
LuaTable补上 metatable 挂载与__close查找 - 在
CallFrame中记录 to-be-closed 寄存器 - 在
CLOSE和函数退出时按逆序调用__close - 用真实 Lua 5.5 chunk 验证块关闭和函数退出两条路径
这一轮不打算先搭一整套“标准库框架”或者“通用元方法系统”,而是只补当前闭环真正依赖的最小能力:
- native closure
setmetatable- table metatable
__close
先把真实 chunk 跑起来,再继续往更一般的元方法调度扩展。
这一轮最重要的不是“找得到 __close”,而是关闭时机必须正确:
- 块结束时的
CLOSE - 函数返回前的剩余资源关闭
- 同一作用域里多个 to-be-closed 变量按逆序关闭
只有这三件事都对,后面往完整错误传播扩展才有意义。
Lua 的 __close 不只可能落在表上,但当前真实 fixture 走的是:
setmetatable(table, mt)mt.__close
所以这一轮先把表路径做扎实,其他对象类型后续再补。
这一轮新增支持:
LuaNativeClosureBody_ENV.setmetatableLuaTable.MetatableLuaTable.TryGetMetamethodTBC的真实登记路径CLOSE与函数退出时的 to-be-closed 关闭__close(self, nil)的最小调用路径
当前还没有进入这些内容:
__close的完整错误对象传播- 关闭过程中继续关闭后续资源的完整错误恢复策略
- userdata 的
__close - 更一般的元方法分发
这一轮新增 fixture:
test/fixtures/lua55/source/tbc_close_chunk.luatest/fixtures/lua55/chunks/tbc_close_chunk.luac
这份脚本同时覆盖了几条关键路径:
setmetatable返回的表被声明为<close>- 块作用域里的
<close>局部变量在CLOSE时触发__close - 函数作用域内剩余的
<close>局部变量在返回时触发__close - 多个 to-be-closed 变量按逆序执行关闭
最终期望结果是:
- 返回值仍然是
42 - 关闭日志是
xba
这说明:
- 块里的
x先关 - 函数退出时
b后于a注册,所以先关b - 最后再关
a
- 编写本轮文档
- 为运行时补上 native closure 承载
- 在
_ENV里注册最小setmetatable - 为
LuaTable补上 metatable - 为
CallFrame补上 to-be-closed 寄存器登记 - 在 VM 中支持
__close调用 - 新增真实
tbc_close_chunk.luac - 新增对应运行时测试与 VM 测试
本轮完成后,应满足:
<close>表值不再只停留在快速路径TBC会登记真正需要关闭的值CLOSE可以触发__close- 函数返回时会关闭剩余 to-be-closed 值
- 真实 Lua 5.5 fixture 可以验证关闭顺序
接下来继续往下补:
__close的错误传播与继续关闭已经拆到docs/014-step-05-close-errors.md- 剩余加载路径已经拆到
docs/015-step-04-load-opcodes.md - userdata 路径
- 更完整的元方法分发
- 更完整的调用协议