1 / 35
文档名称:

《lua源码剖析》.doc

格式:doc   大小:567KB   页数:35页
下载后只包含 1 个 DOC 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

《lua源码剖析》.doc

上传人:changdan5609 2019/3/18 文件大小:567 KB

下载得到文件列表

《lua源码剖析》.doc

相关文档

文档介绍

文档介绍:lua源码剖析先来看lua中值的表示方式。 Java代码  #define TValuefields Value value; int tt    typedef struct lua_TValue {    TValuefields;  } TValue;  其中tt表示类型,value也就是lua中对象的表示。 Java代码  typedef union {    GCObject *gc;    void *p;    lua_Number n;    int b;  } Value;  gc用于表示需要垃圾回收的一些值,比如string,table等等。 p用于表示lightuserdata它是不会被gc的。 n表示double b表示boolean ,,指针都是严格对齐(4或者8字节对齐).因此后面的2,3位就是0,因此我们可以将类型存储在这几位,从而极大地压缩了Value的大小. 更新:这里经的老朱同学的提醒,其实tvalue之所以不使用指针的后几位来存储类型,,我们就必须强制和lua交互的c模块也必须保持和我们一样的内存模型了. lua_state表示一个lua虚拟机,它是per-thread的,也就是一个协程(多个和lua交互的c程序,那自然也会有多个lua-state)一个lua_state,然后来看它的几个比较重要的域。 StkIdtop这个域表示在这个栈上的第一个空闲的slot。 StkIdbase这个域表示当前所在函数的base。这个base可以说就是栈底。只不过是当前函数的。 StkIdstack_last在栈上的最后一个空闲的slot StkIdstack 栈的base,这个是整个栈的栈底。 StkId是一个Tvalue类型的指针。 在lstrlib中,基本上所有的str函数都是首先调用luaL_checklstring来得到所需要处理的字符串然后再进行处理。如果是需要改变字符串的话,那么都会首先生成一个luaL_Buffer对象(主要原因是在lua中,都会做一个传递进来的字符串的副本的),然后最终将处理的结果通过调用luaL_pushXXX放到栈中。 luaL_checklstring函数,这个函数只是简单的对lua_tolstring进行了一层简单的封装。而luaL_tolstring也是对index2adr函数做了一层简单封装,然后判断所得到的值是否为字符串,是的话返回字符串,并修改len为字符串长度。 Java代码  LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {  ///通过luaL_tolstring得到字符串s    const char *s = lua_tolstring(L, narg, len);    if (!s) tag_error(L, narg, LUA_TSTRING);    return s;  }  因此我们详细来看index2adr这个函数,这个函数目的很简单,就是通过索引得到对应的值的指针。第一个参数lua_state,第二个参数为索引值。 我们首先要知道在lua中,索引值可以为负数也可以为正数,当为负数的话,top为-1,当为正数第一个压入栈的元素为1,依此类推. 而且有些类型的对象当转换时还需要一些特殊处理,比如闭包中的变量。 除去特殊的,一般的存取很简单,当index>0则我们只需要用base+i-1来取得这个指针,为什么要用base而不是top呢,我们上面已经说过了,当index为正数,所取得的是第一个值,因此也就是栈的最下面那个值,而base表示当前函数在栈里面的位置,因此我们加上i-1就可以了。当index<0则更简单,我们用top+index就可以了。 Java代码  static TValue *index2adr (lua_State *L, int idx) {    if (idx > 0) {  ///索引为正值时,通过base取得value      TValue *o = L->base + (idx - 1);      api_check(L, idx <= L->ci->top - L->base);  ///如果超过top,则返回nil,否则返回o。      if (o >= L->top) return cast(TValue *, luaO_nilobject);      else return o;    }    else if (idx