在这里,我说的 Lua 主函数主要指的是 lua.c
里面的 main
函数,我也不知道有没有专门的描述指向这个,就暂时这么理解吧。
- main(lua.c#L596)
- lua_State *L = luaL_newstate(lauxlib.c#L1026)(); 用于 create state
- lua_newstate(lstate.c#295) 官方的说法:The auxiliary library provides several convenient functions to interface C with Lua。在这里真正创建 state 的是 lstate.c 的 lua_newstate,而这个函数要求传进来的其中一个参数是
lua_Alloc f
,luaxlib 传进来的是 l_alloc(lauxlib.c#1008)(这个函数是 static 的,所以只能在 lauxlib.c 里面使用)
- 用传进来的
lua_Alloc f
方法指针来创建一个 LG) 结构体,用来记录 LX l 跟 global_state g。而 LX 里面会记录一个 lu_byte extra_[LUA_EXTRASPACE]
(这个是目测是用来提供给用户使用的,Lua 并不会用这部分的空姐)和一个 lua_State。而在 lua_State
里面记录了一个 CommonHeader(这个主要是用于 GC 通用的数据)。
- 设置一些 GC 的属性,L->next,L->tt,g->currentwhite,L->marked
- preinit_thread
- 设置 global 的属性
- 调用 luaD_rawrunprotected 来执行 f_luaopen,luaD_rawrunprotected 主要就是维护
errorJmp
,把它们串起来,我想大概就可以是为了抛出错误类似那样的功能。
- 记录
L->nCcalls
- 设置 lua_longjmp 结构的 lj 的
status
和 previous
,并把当前的 L->errorJmp
设置成 lj
- 用 LUAI_TRY 调用 f_luaopen,所以以下是 f_luaopen 的执行过程了
- stack_init(L, L)
- 调用 luaM_newvector(L, BASIC_STACK_SIZE, TValue) 创建 BASIC_STACK_SIZE TValue 的 vector
- 设置 L 中 stack 相关属性
L->stack
,L->stacksize
,L->top
,L->stack_last
- 初始化第一个 CallInfo
L1->ci
- init_registry(L, g)
- Table *registry = luaH_new(L)
- sethvalue(L, &g->l_registry, registry)
- luaH_resize(L, registry, LUA_RIDX_LAST, 0)
- 设置 registry[LUA_RIDX_MAINTHREAD] 记录 L
- 设置 registry[LUA_RIDX_GLOBALS] 记录一个 Table
- luaS_init(#luas_initlstringc113)(L) 初始化字符串 Table
- luaT_init(#luat_initltmc37)(L) 初始化 Tag Method 相关
- luaX_init(#luax_initllexc70)(L) 初始化 Lexical Tokens
- g->gcrunning = 1; /* allow gc */
- g->version = lua_version(#lua_versionlapic144)(NULL); 初始化 version
- luai_userstateopen(#luai_userstateopenllimitsh227)(L); 这里可以通过自己定义 luai_userstateopen 宏来覆盖
- 恢复
L->errorJmp
和 L->nCcalls
,返回 lj.status
- if (L) lua_atpanic(L, &panic);
- lua_pushcfunction(L, &pmain); /* to call ‘pmain’ in protected mode */
- lua_pushinteger(L, argc); /* 1st argument */
- lua_pushlightuserdata(L, argv); /* 2nd argument */
- status = lua_pcall(L, 2, 1, 0); /* do the call */
- lua_pcallk(L, (n), (r), (f), 0, NULL)
main(lua.c#L596)
luaL_newstate(lauxlib.c#L1026)
lua_newstate(lstate.c#295)
l_alloc(lauxlib.c#1008)
LG(lstate.c#63)
LX(lstate.c#54)
global_state(lstate.h#119)
lua_State(lstate.h#160)
preinit_thread(lstate.c#217)
luaD_rawrunprotected(ldo.c#136)
f_luaopen(lstate.c#198)
lua_longjmp(ldo.c#84)
LUAI_TRY(ldo.c#74)
stack_init(lstate.c#151)
luaM_newvector(lmem.h#47)
luaM_reallocv(lmem.h#17)
luaM_realloc_(lmem.c#74)
CallInfo(lstate.h#65)
init_registry(lstate.c#181)
luaH_new(ltable.c#402)
luaC_newobj(lgc.c#204)
luaM_newobject(lmem.h#50)
GCObject(lobject.h#82)
gco2t(lstate.h#214)
cast_u(lstate.h#204)
GCUnion(lstate.h#190)
Table(lobjec.h#497)
sethvalue(lobject.h#250)
luaH_resize(ltable.c#333)
luaS_init(lstring.c#113)
luaT_init(ltm.c#37)
luaX_init(llex.c#70)
lua_version(lapi.c#144)
luai_userstateopen(llimits.h#227)
lua_atpanic(lapi.c#134)
panic(lauxlib.c#1019)
lua_pushcfunction(lua.h#350)
lua_pushcclosure(lapi.c#532)
api_incr_top(lapi.h#14)
luaC_checkGC(lgc.h#114)
luaC_condGC(lgc.h#104)
luaC_step(lgc.c#1125)
lua_pushinteger(lapi.c#466)
lua_pushlightuserdata(lapi.c#564)
lua_pcall(lua.h#278)
lua_pcallk(lapi.c#947)
api_checknelems(lapi.h#20)
luaD_pcall(ldo.c#721)
pmain(lua.c#550)