最开始想说的话
其实我是一个真实的Android应用开发程序猿,但是入职以后发现组里用的是C++,C#等语言,而且和Android的关系也不是很大,然后我就开始了转型之路啦~
已经实习了小半个月了,但是现在才想起写周记,想在这里记录一下自己学习到的东西,和大家一起分享。但是实习用到的东西对我来说基本上是全新的知识,所以有很多不足的地方,欢迎大家指正,么么哒
Lua源码解析 - Proto
因为在做的项目涉及到lua语言,所以我去学习观摩了一下大名鼎鼎的Lua的源码(源码核心大概是几千行,和其他语言比起来着实不多),看看其实现原理。在lua中我觉得有一个很重要的struct就是Proto。
Proto是在语法分析,语义分析的产物,即分析阶段的产物,执行阶段(LuaV_execute()) 就是使用的Proto来执行虚拟机指令。在生成Proto的过程中也会涉及其他的很多结构,比如CallInfo,Lua_State, 就不赘述啦,其实是因为自己理解的也不到位,hhh。
Proto 简述(其实是乱七八糟啥都说)
Proto定义在lobject这个文件中,lobject在Lua中负责对象管理,文件中的对外接口前缀为LuaO_,也就是说如果你在一个源码文件中看到了一个方法是LuaO_XXXX()那么这个方法的定义和声明一定是lobject文件中。每一段Lua代码在经过分析过程后将代码的信息存进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存储了:
- 函数的常量数组;
- 编译生成的字节码信息,存储在Proto的code成员中
- 函数的局部变量信息
- 保存upvalue名字的数组
Proto最重要的一个点就是,每一段lua代码经过分析后在Proto中都是独立的,也是不会重复的。比如,我想去分析lua执行过程中调用了几种不同的方法,只需要去比较每次调用的方法的Proto是否在之前已经存在过(Proto地址比较即可, 因为源码中Proto多是以指针形式存在)
总结
第一篇的试水就到这里啦就到,下次见~
最后放一张今日份开心,腾讯协会积分换的QQFamily的数据线(然鹅我并没有iphone,😂