lua 源码阅读(五)

2018-01-15 11:17编辑本页

lua 源码系列文章:

lua源码欣赏的第五章的内容,是与 lua 闭包相关的内容

Contents

Lua 闭包概念

在 Lua 中,将一组数据绑定到特定函数上,即为闭包。被绑定的数据成为 upval,也可以成为非局部变量(区别于局部变量和全局变量)。

闭包的实现与分类

Lua 的函数区别于 C 中的函数,Lua 的函数可以在虚拟机运行时动态生成,可以在 Lua 的函数中生成函数。将 Lua 的函数原型与一组 upval 绑定,即 Proto 结构体与 UpVal 绑定在一起,就是 Lua 中闭包的实现方式。

Lua 中有两种闭包:Lua 闭包与 C 闭包。其中 Lua 闭包较为复杂。

  1. 虚拟机运行时生成闭包: 在函数退出之前,使用一个数据栈上的索引来映射局部变量,此时的 upval 称为开放的。当外层函数返回,使用数据栈空间收缩,通过调用 luaF_close 来关闭,并将之前的指针指向一个安全的地方来存放。
  2. 从外部加载源码(二进制或文本)来生成闭包: 不使用数据栈上的局部变量作为 upval,而是重新创建 upval。补充说明:Lua 在加载外部代码时,Lua 代码会被编译成为函数原型,而 lua 的外部调用是不返回函数原型的,而是把这个函数原型转化为闭包。

C 闭包相对与 Lua 闭包较为简单,由于C 闭包不会引用外部的 upval,upval都为关闭状态。将 upval 绑定在 Closure 结构体上即可。C 闭包还有一种无 upval 的特殊情况,这种情况称之为轻量函数(C light function)。轻量函数不需要使用 UpVal 结构体,也不需要 GC 来管理。

C 技巧

在 Lua 源码中,有用到 UNUSED() 宏,是为了避免编译器未使用的警告,源码如下:

1
#define UNUSED(x) ((void)(x))

https://github.com/xiaocang/lua-5.2.2_with_comments/releases/tag/lua_closure_06

除另有声明外 本博客文章均采用 知识共享(Creative Commons) 署名 4.0 国际许可协议 进行许可 转载请注明原作者与文章出处


标签: lua

点击加载Disqus评论
Creative Commons © 2013 — 2023 xiaocang | Theme based on fzheng.me & NexT | Hosted by Netlify