voidluaF_closeupval(lua_State*L,StkIdlevel){UpVal*uv;StkIdupl;/*stackindexpointedby'uv'*/while((uv=L->openupval)!=NULL&&(upl=uplevel(uv))>=level){TValue*slot=&uv->u.value;/*newpositionforvalue*/lua_assert(upleve
实际上,用来表示upvalue的有两个数据结构,一个是编译时期,存储upvalue信息的Upvaldesc(这个结构并不存储upvalue的实际值,只是用来标记upvalue的位置信息),还有一个是在运行期,实际存储upvalue值的UpVal结构。它们的结构定义如下所示: // luaobject.h typedef struct Upvaldesc { int in_stack; // 本函数的upvalu...
1)常量:TValue* k 为指针指向常量数组;int sizek 为函数内部定义的常量个数,也即常量数组 k 的元素个数。2)局部变量:LocVar* locvars 为指针指向局部变量数组;int sizelocvars 为函数定义的局部变量个数,也即局部变量数组 locvars 的元素个数。UpValue 的描述信息会存储在 Proto 结构体中的 Upvaldesc* upv...
这个函数将 value 赋给 栈上第 level 层函数的第 local 个局部变量。 如果没有那个变量,函数返回 nil 。 如果 level 越界,抛出一个错误。 12. setmetatable (value, table): 将value 的元表设为 table (可以是 nil)。 返回 value。 13. setupvalue (f, up, value): 这个函数将 value 设为函数 f...
小技巧: 需要注意的一点是我们注册元方法的时候会利用lua的up value机制将一些额外的参数带入对应的c++函数中, 这样在调用发生时, 就能够很简单的通过up value取到注册时附加上去的值了, 如上面代码中的MetaClass指针, class table本身, 我们都通过这种方式带入了对应的c++函数调用中, 这个是lua中间层比较常用的实...
upvalue是创建C闭包时压入的upvalue, 类型是TValue, 可以得知, upvalue可以是任意的lua类型 Lua闭包结构 struct LClosure{ ClosureHeader; strcut Proto* p; UpVal* upvals[1]; } Proto的结构比较复杂, 这里先不做分析 统一的闭包结构, 一个联合体, 说明一个闭包要么是C闭包, 要么是lua闭包, 这个是用isC表...
}value; } Lua其实是采用了这两个设计的结合,同时采用。 Lua在实现的时候 还添加了一个叫做Variant tags 来分别定义其子类型 比如说string定义了长串和短串,number里由float和int类型。 那我们现在来看一下 Lua中一些关键的数据结构 Value和TValue lua为了方便对所有的类型进行统一管理,把它们都抽象成了一个叫做...
setnilvalue(ra++); } while (b--); vmbreak; } ... //全局变量设置操作 vmcase(OP_SETUPVAL) { UpVal *uv = cl->upvals[GETARG_B(i)]; setobj(L, uv->v, ra); luaC_upvalbarrier(L, uv); vmbreak; } ... } } } } 1
case Up_value: //向上按键 User_MenuUpOneOption(); break; case Down_value: //向下按键 User_MenuDownOneOption(); break; case Enter_value: //确认按键 User_MenuEnterOption(); break; case Add_value: //+键 User_MenuAddOption();
好处是指令条数少,数据转移次数少。坏处是单挑指令长度较长。具体来看,lua 里的实际寄存器数组是用 TValue 结构的栈来模拟的,这个栈也是 lua 和 C 进行交互的虚拟栈。 lua 指令集 Lua 虚拟机的指令集为定长(Fixed-width)指令集,每条指令占 4 个字节(32bits),其中操作码(OpCode)占 6bits,操作数(Operand)使...