« 选择开源项目的几点原则 | 返回首页 | 构建工具从 Make 到 Ninja »

扩展 Lua 的常量类型

最近有点关于 Lua 不成熟的想法。

Lua 目前函数原型的常量表只支持了布尔、数字和字符串类型的常量。而 table function 这些是不会存在于常量表中的。

我想,如果常量如果不限于前三种类型,可能会更好一些。比如,一个惯用法是在代码前面写上

local pairs = pairs

这个惯用法是基于 local 变量比全局变量少一次 hash 表查询,性能可能会高一点。 但实际上,往往差距并不大。而这种写法还会给其它应用 pairs 的函数增加额外的 upvalue ,很有可能得不偿失。

但我们真正需要的是让 pairs 这个 light C function 是一个像 1,2,3 这样的常量。不必增加额外的 upvalue 的负担。

Lua 5.4 之后可以用 const 修饰 local 变量。

local pairs <const> = pairs

但 pairs 依旧不是常量。

我想,如果可以稍微修改一下这行代码的语义。当把一个全局变量赋值给 const 的 local 变量时,Lua 是在 load 的阶段就对全局变量求值,这样,pairs 就可以被放入常量表了。

而需要把代码编译成 bytecode 也没有关系,我们只需要把全局变量的名字记录在常量表中,等加载 bytecode 的时候再求值。

这样修改之后,相当于每个 lua chunk 就有了一张外部符号导入表。load 的阶段更接近静态语言的 link 阶段。如果以后需要给 Lua 加 JIT 或 AOT 编译器,也能做的更高效一些。

Comments

和风哥有过相同的想法,这样其实类似于DLL中的导入表,在load阶段就把需要的函数确定了并存入到常量表

对于现有的代码来说,可以替换掉在一开头就简单地调用require的写法,需要引入新的语法在编译期声明要导入的模块及函数,例如这样写`@import pairs, ipairs from _G` `@import dump as dumpjson from cjson`

假如能这样实现,有两个好处,一是简化了导入其他模块函数的写法,二是存入常量表不会给closure增加额外的upvalue

综合lua的编译过程和指令格式来看,给函数名标记为常量,牵涉的范围蛮广的。

综合lua的编译过程和指令格式来看,给函数名标记为常量,牵涉的范围蛮广的。

我有个大胆的想法,风哥可以给lua官方提pr

Post a comment

非这个主题相关的留言请到:留言本