首页 > 代码库 > Lua2.4 函数相关 func.c

Lua2.4 函数相关 func.c

看一下和函数相关的数据结构和方法。

数据结构

typedef struct LocVar
{
  TaggedString *varname;           /* NULL signals end of scope */
  int       line;
} LocVar;

局部变量描述信息,这个主要是调试时有用,也就是编译时打开了调试选项。
varname 局部变量的名字,如果为空,表示函数的局部变量结束。
line 局部变量开始定义的地方。

/*
** Function Headers*/
typedef struct TFunc
{
  struct TFunc    *next;
  int        marked;
  int        size;
  Byte        *code;
  int        lineDefined;
  char        *fileName;
  LocVar        *locvars;
} TFunc;

函数描述信息。
next   : 下一个函数,所有有函数连成链表,以便垃圾回收。
marked : 垃圾回收标签。
size   : 函数的大小。
code   : 函数的字节码。
lineDefined : 定义函数行号。
fileName    : 定义函数的文件名。
locvars     : 函数的所有局部变量。

func.h 头文件中定义的几个对外接口,前四个函数简单的看一下。后面的四个都是和调试相关的,先放一放,留待以后再分析。

/*
** Initialize TFunc struct
*/
void luaI_initTFunc (TFunc *f)
{
  f->next = NULL;
  f->marked = 0;
  f->size = 0;
  f->code = NULL;
  f->lineDefined = 0;
  f->fileName = NULL;
  f->locvars = NULL;
}

初始化函数的数据结构。

/*
** Insert function in list for GC
*/
void luaI_insertfunction (TFunc *f)
{
  lua_pack();
  f->next = function_root;
  function_root = f;
  f->marked = 0;
}

函数插入函数链表,以便进行垃圾回收。

/*
** Free function
*/
void luaI_freefunc (TFunc *f)
{
  luaI_free (f->code);
  luaI_free (f->locvars);
  luaI_free (f);
}

释放函数内存空间。

/*
** Garbage collection function.
** This function traverse the function list freeing unindexed functions
*/
Long luaI_funccollector (void)
{
  TFunc *curr = function_root;
  TFunc *prev = NULL;
  Long counter = 0;
  while (curr)
  {
    TFunc *next = curr->next;
    if (!curr->marked)
    {
      if (prev == NULL)
        function_root = next;
      else
        prev->next = next;
      luaI_freefunc (curr);
      ++counter;
    }
    else
    {
      curr->marked = 0;
      prev = curr;
    }
    curr = next;
  }
  return counter;
}

垃圾回收。
遍历函数链表,释放没有 marked 的函数,同时调整链表指针。

这几个看到的代码都比较直接,后面的几个调试相关的代码相对来说复杂一点。

调试相关代码有一个比较好辨识的地方是,他们基本上都接在一个以 lua_debug 为条件的 if 判断里。
比如:

if (lua_debug)
   luaI_registerlocalvar(name, lua_linenumber

还有我们之前看到的 luaI_codedebugline,记录下脚本代码的行号的。
可以看到,他在 lex.c 中的调用就也是这样:

if (lua_debug)
  luaI_codedebugline(linelasttoken);

调试相关的信息还有的在执行时可以加回调的地方。
具体的描述可以参考下手册里的描述。
调试相关信息和程序的具体功能关系不大,暂时忽略它对程序具体功能分析并无影响。

----------------------------------------
到目前为止的问题:
> lua_parser 是什么? do_dump 方法里调的那几个方法又分别是干什么的?
----------------------------------------

Lua2.4 函数相关 func.c