已完成当前这一轮。
这一轮继续沿着基础库主线往前补,但不再只盯着 metatable 和 raw*。
这次落地的是 Lua 里最常用、也最容易放大运行时能力的一组核心函数:
typeassertselectpcall
这一轮主要参考这些官方文件:
references/lua-5.5.0/src/lbaselib.creferences/lua-5.5.0/src/ldo.creferences/lua-5.5.0/src/lvm.c- Lua 5.5 手册:https://www.lua.org/manual/5.5/
这一轮关注的核心点是:
luaB_typeluaB_assertluaB_selectluaB_pcall
本轮先落这几件事:
- 在
_ENV中预置type - 在
_ENV中预置assert - 在
_ENV中预置select - 在
_ENV中预置pcall - 让
pcall复用 VM 当前已经存在的 callable 解析路径 - 用真实 Lua 5.5 chunk 验证这组函数的 Lua 层行为
这四个函数看起来不大,但都很适合拿来压运行时语义:
type能直接验证值类型分类assert能直接验证真假值和错误对象传递select能直接验证 vararg 下标和开放结果pcall能直接验证受保护调用和错误收敛
把这组函数补上之后,后面继续做 xpcall、迭代器和更多基础库时,地基会稳很多。
这一轮最关键的点,不是把 pcall 做成“能跑”,而是不要再单独复制一套调用逻辑。
现在 pcall 走的是 LuaState.InvokeCallable,而 LuaVirtualMachine 会把它接回当前统一的 callable 解析路径。
这样 pcall 处理的就不只是普通函数,还包括:
- Lua 闭包
- native closure
- table / userdata metatable 上的最小
__call
也就是说,这一轮没有新造第二套调用协议,而是把基础库函数接回了当前 VM 主线。
这两个函数都容易被写成“差不多”。
这一轮先把 Lua 层最容易看见的行为钉住:
assert(true, ...)原样返回所有参数assert(false, err)直接把第二个参数作为错误对象抛出assert(false)使用默认错误消息"assertion failed!"select("#", ...)返回 vararg 个数select(n, ...)支持正索引和负索引
这一轮新增支持:
_ENV.type_ENV.assert_ENV.select_ENV.pcalltype的 Lua 类型名映射assert的多返回值透传语义assert的默认错误消息与自定义错误对象select("#", ...)计数语义select(n, ...)的正负索引语义pcall的(true, ...)/(false, err)返回协议pcall复用当前统一 callable 解析路径
当前这一轮还没有展开的是:
xpcall(已拆到docs/028-step-07-xpcall.md)tonumber/tostring(已拆到docs/029-step-07-number-string-conversion.md)next/pairs/ipairs(已拆到docs/030-step-07-table-iteration-functions.md)- 更系统的
Lua.StandardLib模块拆分
这一轮新增 fixture:
test/fixtures/lua55/source/type_chunk.luatest/fixtures/lua55/chunks/type_chunk.luactest/fixtures/lua55/source/select_chunk.luatest/fixtures/lua55/chunks/select_chunk.luactest/fixtures/lua55/source/pcall_chunk.luatest/fixtures/lua55/chunks/pcall_chunk.luac
它们分别覆盖:
type(nil)、type(number)、type(string)、type(table)、type(function)、type(userdata)assert的多返回值透传select("#", ...)与正负索引pcall(function() ... end)的成功路径pcall(ud, ...)走 userdata__call的路径pcall(erroringFn)和pcall(assert, false, "...")的失败路径
- 编写本轮文档
- 在
_ENV中注册type - 在
_ENV中注册assert - 在
_ENV中注册select - 在
_ENV中注册pcall - 为
LuaState增加统一 callable 调用入口 - 让
LuaVirtualMachine把pcall接回当前 callable 解析路径 - 新增对应运行时测试
- 新增对应真实 fixture
- 新增对应 VM 测试
本轮完成后,应满足:
- Lua 层可以直接调用
type/assert/select/pcall - 这组函数能在真实 Lua 5.5 chunk 中跑通
pcall不需要单独维护第二套调用协议pcall对普通函数和最小__call路径都可用
接下来继续往下补:
xpcalltonumber/tostringnext/pairs/ipairs- 更完整的错误处理与标准库拆分