最開始想說的話
其實我是一個真實的Android應用開發(fā)程序猿,但是入職以后發(fā)現(xiàn)組里用的是C++,C#等語言,而且和Android的關系也不是很大,然后我就開始了轉(zhuǎn)型之路啦~
已經(jīng)實習了小半個月了,但是現(xiàn)在才想起寫周記,想在這里記錄一下自己學習到的東西,和大家一起分享。但是實習用到的東西對我來說基本上是全新的知識,所以有很多不足的地方,歡迎大家指正,么么噠
Lua源碼解析 - Proto
因為在做的項目涉及到lua語言,所以我去學習觀摩了一下大名鼎鼎的Lua的源碼(源碼核心大概是幾千行,和其他語言比起來著實不多),看看其實現(xiàn)原理。在lua中我覺得有一個很重要的struct就是Proto。
Proto是在語法分析,語義分析的產(chǎn)物,即分析階段的產(chǎn)物,執(zhí)行階段(LuaV_execute()) 就是使用的Proto來執(zhí)行虛擬機指令。在生成Proto的過程中也會涉及其他的很多結構,比如CallInfo,Lua_State, 就不贅述啦,其實是因為自己理解的也不到位,hhh。
Proto 簡述(其實是亂七八糟啥都說)
Proto定義在lobject這個文件中,lobject在Lua中負責對象管理,文件中的對外接口前綴為LuaO_,也就是說如果你在一個源碼文件中看到了一個方法是LuaO_XXXX()那么這個方法的定義和聲明一定是lobject文件中。每一段Lua代碼在經(jīng)過分析過程后將代碼的信息存進Proto, 每一個新的Proto生成和初始化時都在lfunc文件的LuaF_newproto(Lua_State *L)方法中。
Proto *luaF_newproto (lua_State *L) {
GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
Proto *f = gco2p(o);
f->k = NULL;
f->sizek = 0;
f->p = NULL;
f->sizep = 0;
f->code = NULL;
f->cache = NULL;
f->cachemiss = 0;
f->sizecode = 0;
f->lineinfo = NULL;
f->sizelineinfo = 0;
f->abslineinfo = NULL;
f->sizeabslineinfo = 0;
f->upvalues = NULL;
f->sizeupvalues = 0;
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
f->locvars = NULL;
f->sizelocvars = 0;
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
f->rettype = NULL;
f->args = NULL;
return f;
}
Proto存儲了:
- 函數(shù)的常量數(shù)組;
- 編譯生成的字節(jié)碼信息,存儲在Proto的code成員中
- 函數(shù)的局部變量信息
- 保存upvalue名字的數(shù)組
Proto最重要的一個點就是,每一段lua代碼經(jīng)過分析后在Proto中都是獨立的,也是不會重復的。比如,我想去分析lua執(zhí)行過程中調(diào)用了幾種不同的方法,只需要去比較每次調(diào)用的方法的Proto是否在之前已經(jīng)存在過(Proto地址比較即可, 因為源碼中Proto多是以指針形式存在)
總結
第一篇的試水就到這里啦就到,下次見~
最后放一張今日份開心,騰訊協(xié)會積分換的QQFamily的數(shù)據(jù)線(然鵝我并沒有iphone,??
