windows 7平台 VS 2012 lua 5.3.3源码 debug模式下
上篇lua数据结构讲完了,这篇看lua执行过程中的数据变化
正好元旦放假,在家没什么事,可以坐下来安安静静看lua源码,开启VS,单步调试
extern "C"
{
#include "lauxlib.h"
#include "lualib.h"
#include "lua.h"
}
void main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_close(L);
return;
}
lua_State *L = luaL_newstate();看看这句代码到底发生了什么
LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
if (L) lua_atpanic(L, &panic);
return L;
}
`/*
** thread state + extra space
*/
typedef struct LX {
lu_byte extra_[LUA_EXTRASPACE];//这里默认为sizeof(void *)即为4
lua_State l;
} LX;
/*
** Main thread combines a thread state and the global state
*/
typedef struct LG {
LX l;
global_State g;
} LG;
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
int i;
lua_State *L;
global_State *g;
LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
if (l == NULL) return NULL;
L = &l->l.l;
g = &l->g;
...
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */
close_state(L);
L = NULL;
}
return L;
}
观察到lua_newstate 接受2个参数,一个类型是lua_Alloc,另一个是void *
其中lua_Alloc是什么类型,我们跟踪看看
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
定义了一个lua_Alloc的函数指针类型,其返回值为 void *
lua_newstate(l_alloc, NULL);
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
(void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
lua_newstate(l_alloc, NULL);中其实简单理解就是把l_alloc函数指针传递进去,方便在ua_newstaten内调用l_alloc函数
看看l_alloc这个函数干了啥,居然ud,osize 2个参数都没有使用,不知道为啥还留这么多参数,可能历史原因吧,这样安慰自己
nsize不为0时,就重新分配ptr指向的内存大小为nsize,为0就释放内存
继续看看 lua_newstate函数中luaD_rawrunprotected
/* type of protected functions, to be ran by 'runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud)
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */
close_state(L);
L = NULL;
}
luaD_rawrunprotected 中调用 f_luaopen 中调用 stack_init(L, L) 初始化L大小
这里不贴代码了,可以下载lua源码中查看
由于lua和C交互主要是栈,我们看和栈有关的地址L->top ,L->stack,L.stacksize
lua_newstate 内存分配,初始化lua_State ,global_State g
stack_init初始化栈大小,默认为2*LUA_MINSTACK,即 2* 20 = 40
L->top是指向栈实际使用的下一个地址的
L->stack地址为栈起始地址,并且小于L->top地址,平时我们看其它博文栈顶在上面,但是内存中其实是在高地址也就是下面.
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
堆栈大小 L.stacksize = (L->stack_last - L->stack) /sizeof(lua_TValue) + EXTRA_STACK
目前堆栈已使用 (L->top- L->stack) /sizeof(lua_TValue)
lua_newtable(L); luaC_checkGC(L); luaC_step (lua_State *L)会导致GC,所以lua_openlibs后面栈的大小改变,这里GC暂不深入
数据结构中每个变量的含义还未完全了解,得好好把lua源码中的注释看一遍
不必深入了解这些数据在内存中的表示,什么内存对齐啥的,会增加学习负担,重点看数据之间的转移,数据流向
希望大家有好的相关文章可以留言推荐给我.
结构体和联合体内存大小计算
http://blog.csdn.net/vincent_1011/article/details/4479965
函数指针用法
http://blog.csdn.net/qll125596718/article/details/6891881