Lua 数据结构--Closure
2017-03-28 20:48
148 查看
在 lua 中函数是作为第一类值存在的,即它和表、字符串、数值一样可以被变量引用。函数有三种类型 lua 函数 (LUA_TLCL)、轻量级 C 函数 (LUA_TLCF)、C 函数 (LUA_TCCL)。其中 LUA_TLCL 和 LUA_TCCL 属于 GCUnion–需要被回收的类型,被称为 Closure。当
LUA_TCCL 不包含 upvalue 时,直接用 C 函数指针即可,不必构造 Closure 对象, 也就是 LUA_TLCF。
lua 的闭包分成两类:CClosure 是 C 的函数闭包。LClosure 是 Lua 的函数闭包。
LClosure 由 Proto 和 UpVal 组成。Proto 描述了 lua 函数的函数原型,记录了函数原型的字节码、函数引用的常量表、调试信息、参数、栈大小等信息。UpVal 保存了对 upvalue 的引用。它直接用一个 TValue 指针引用一个 upvalue 值变量。当被引用的变量还在数据栈上时,这个指针直接指向栈上的 TValue,那么这个 upvalue 被称为开放的。由于 lua 的数据栈的大小可扩展,当数据栈内存延展时 (realloc),其内存地址会发生变化,这时需要将 upvalue
拷贝到 UpVal.u.value 中保存。
CClosure 由 lua_CFunction 和 TValue 组成。C 函数可以用闭包的方式嵌入 lua,与 LClosure 相比 CClosure 天生就是关闭的。因此,直接使用 TValue 来保存 upvalue。而 lua 与 C 交互的函数原型统一使用 lua_CFunction。当某个函数没有 upvalue 时,则不需要创建闭包直接使用 lua_CFunction。也称为 light C function。
LUA_TCCL 不包含 upvalue 时,直接用 C 函数指针即可,不必构造 Closure 对象, 也就是 LUA_TLCF。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* lua.h */ /* Type for C functions registered with Lua */ typedef int (*lua_CFunction) (lua_State *L); /* lobject.h */ /* Variant tags for functions */ #define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ #define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ #define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ /* Closures */ typedef struct CClosure { GCObject *next; lu_byte tt; lu_byte marked; lu_byte nupvalues; /* nums of upvalue */ GCObject *gclist; lua_CFunction f; TValue upvalue[1]; /* list of upvalues */ } CClosure; typedef struct LClosure { GCObject *next; lu_byte tt; lu_byte marked; lu_byte nupvalues; /* nums of upvalue */ GCObject *gclist; struct Proto *p; UpVal *upvals[1]; /* list of upvalues */ } LClosure; typedef union Closure { CClosure c; LClosure l; } Closure; |
LClosure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 3839 | /* lobject.h */ /* Function Prototypes */ typedef struct Proto { GCObject *next; lu_byte tt; lu_byte marked; lu_byte numparams; /* number of fixed parameters */ lu_byte is_vararg; /* 2: declared vararg; 1: uses vararg */ lu_byte maxstacksize; /* number of registers needed by this function */ int sizeupvalues; /* size of 'upvalues' */ int sizek; /* size of 'k' */ int sizecode; int sizelineinfo; int sizep; /* size of 'p' */ int sizelocvars; int linedefined; /* debug information */ int lastlinedefined; /* debug information */ TValue *k; /* constants used by the function */ Instruction *code; /* opcodes */ struct Proto **p; /* functions defined inside the function */ int *lineinfo; /* map from opcodes to source lines (debug information) */ LocVar *locvars; /* information about local variables (debug information) */ Upvaldesc *upvalues; /* upvalue information */ struct LClosure *cache; /* last-created closure with this prototype */ TString *source; /* used for debug information */ GCObject *gclist; } Proto; /* lfunc.h */ /* Upvalues for Lua closures */ struct UpVal { TValue *v; /* points to stack or to its own value */ lu_mem refcount; /* reference counter */ union { struct { /* (when open) */ UpVal *next; /* linked list */ int touched; /* mark to avoid cycles with dead threads */ } open; TValue value; /* (when closed) the value */ } u; }; |
拷贝到 UpVal.u.value 中保存。
CClosure
CClosure 由 lua_CFunction 和 TValue 组成。C 函数可以用闭包的方式嵌入 lua,与 LClosure 相比 CClosure 天生就是关闭的。因此,直接使用 TValue 来保存 upvalue。而 lua 与 C 交互的函数原型统一使用 lua_CFunction。当某个函数没有 upvalue 时,则不需要创建闭包直接使用 lua_CFunction。也称为 light C function。
相关文章推荐
- Lua的function、closure和upvalue
- Lua数据结构 — 闭包(四)
- lua数据结构-数组
- Lua中的closure(闭合函数)
- lua学习笔记之Lua的function、closure和upvalue
- 关于lua的闭包(Closure)和Upvalue
- Lua 的数据结构
- lua的closure创建和使用
- lua数据结构之table的内部实现
- lua2.1的基本数据结构(有不确定的地方,请勿被误导)
- Lua中使用table实现的其它5种数据结构
- Lua数据结构 — T
- Lua数据结构
- Lua学习笔记之函数、变长参数、closure(闭包)、select等
- lua解析脚本过程中的关键数据结构介绍
- lua的数据结构
- Lua的function、closure和upvalue
- Lua中的数据结构
- lua------Closure
- lua中的closure(闭合函数)