lua函数定义
FuncState
proto结构数组保存函数原型信息;prev保存父函数体指针;actvar保存定义的局部变量;upvalues保存upvalue
Lua源码中,专门有一个结构体FuncState用来保存函数相关的信息.其实,即使没有创建任何函数,对于Lua而言也有一个最外层的FuncState数据.这个结构体的定义:
typedef struct FuncState {
Proto *f; /* current function header */
Table *h; /* table to find (and reuse) elements in */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
struct lua_State *L; /* copy of the Lua state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
int lasttarget; /* `pc' of last `jump target' */
int jpc; /* list of pending jumps to `pc' */
int freereg; /* first free register */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
short nlocvars; /* number of elements in `locvars' */
lu_byte nactvar; /* number of active local variables */
upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
} FuncState;
其中的Proto结构体数组用于保存函数原型信息,包括函数体代码(opcode),之所以使用数组,是因为在某个函数内,可能存在多个局部函数.而prev指针就是指向这个函数的”父函数体”的指针.
比如以下代码:
function fun()
function test()
end
end
那么,在保存test函数原型的Proto数据就存放在保存fun函数的FuncState结构体的p数组中,反之,保存test函数的FuncState.prev指针就指向保存func函数的FuncState指针.
接着看Funcstate结构体的成员,actvar数组用于保存局部变量,比如函数的参数就是保存在这里.另外还有一个存放upval值的upvalues数组.这里有两种不同的处理.如果这个upval是父函数内的局部变量,则生成的是MOVE指令用于赋值;如果对于父函数而言也是它的upval,则生成GET_UPVAL指令用于赋值.
当开始处理一个函数的定义时,首先调用open_func函数,创建一个新的Proto结构体用于保存函数原型信息,接着将该函数的FuncState的prev指针指向父函数.
最后当函数处理完毕时,调用pushclosure函数将这个新的函数的信息push到父函数的Proto数组中.
函数也是第一类值 可以存在变量里
最后,由于函数在Lua中是所谓的”first class type”,所以其实以下两段Lua代码是等价的:
local function test()
-- 可以test
end
--以上相当于 local test; test = function() ... end
local test = function ()
--不可以调用test 以为第一类之定义完成之后才可以使用
end
也就是说,其实是生成一段代码,用于保存函数test的相关信息,之后再将这些信息赋值给变量test,这里的test可以是local,也可以是global的,这一点跟一般的变量无异.
函数定义词法分析
所以在与函数定义相关的词法分析代码中:
static void funcstat (LexState *ls, int line) {
/* funcstat -> FUNCTION funcname body */
int needself;
expdesc v, b;
luaX_next(ls); /* skip FUNCTION */
needself = funcname(ls, &v);
body(ls, &b, needself, line);
luaK_storevar(ls->fs, &v, &b);
luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
}
上面的变量v首先在funcname函数中获得该函数的函数名,变量b在进入函数body之后可以得到函数体相关的内容.在这之后的luaK_storevar调用,就是把b的值赋值给v,也就是前面提到的函数体赋值给函数名.
lua函数定义的更多相关文章
- lua os.date函数定义和示例
os.date函数定义 原型:os.date ([format [, time]]) 解释:返回一个按format格式化日期.时间的字串或表. lua源码中os.date的注释如下: --- --- ...
- Lua学习---函数定义
1.函数定义的格式: Lua使用function定义函数,语法如下: function function_name (arc) --arc表示参数列表,函数的参数列表可以为空 --body end 上 ...
- Lua函数之二
Lua函数之二 Lua中函数的两个重要特性: 1.函数和其他类型(如number.string)一样,可以存放在变量中,也可以存放在table中,可以作为函数的参数,还可以作为函数的返回值. 2.嵌套 ...
- C语言调用Lua函数
记得上学时,初中英文课本中,上网叫做surfing the internet,中文叫网上冲浪. 那个时期,人们常常称互联网为赛博空间.现在工作了,大量的零碎时间用于上微博,知乎,QQ.这些碎片化的阅读 ...
- Lua函数以及闭合函数的理解
Lua函数以及闭合函数的理解 来源 http://blog.csdn.net/mydad353193052/article/details/48731467 词法域和第一类型 在C/C++,C#或者J ...
- lua函数随记
在大多数Lua语法分析中可以获得这些标准Lua函数. 无可争辩, 我们可以查阅Lua网站, 但是一些少了的函数被Blizzard进行了调整. 下面列出了所有Lua函数. WoW API中的Lua注意在 ...
- Lua函数[转]
在大多数Lua语法分析中可以获得这些标准Lua函数. 无可争辩, 我们可以查阅Lua网站, 但是一些少了的函数被Blizzard进行了调整. 下面列出了所有Lua函数. WoW API中的Lua注意在 ...
- cocos2d-x 3.0 在C++中调用lua函数(2)
个人觉得3.0里面, 在C++下面调用lua函数很不方便, 所以就扩展了一个类, 继承自LuaStack, 代码和使用方式如下: #ifndef __CC_LUA_STACKEX_H_ #define ...
- cocos2d-x 3.0 在C++中调用lua函数
代码用的是<cocos2d-x 3.0 在lua中调用自定义类>中的代码. 在上篇的基础上进行扩充. 写lua函数 local function process_packet(user_d ...
随机推荐
- Re:LieF ~親愛なるあなたへ~ 后感
遇到烦恼就能有个安逸的地方逃避.这个想法真好.遗憾现实并不能如此.若是觉得这款纯爱作有些许的感人之处,那定时因为受众玩家正在通过玩游戏来逃避现实.“虚拟世界的感情是真实的.” 这件事在旁人看来或许是笑 ...
- 9 tensorflow提示in different while loops的错误该如何解决
示例代码 ii=tf.constant(0,dtype=tf.int32) loop__cond=lambda a: tf.less(a,sentence_length) loop__vars=[ii ...
- 读书笔记week1——涂涵越
这次读书笔记主要是就<程序员修炼之道>这本书的前半部分做一些总结以及发表一些自己的看法. 本书前面的一部分主要是一些程序员应该在工作中时刻注意的事情,一些关键的信息如下: 1.处理问题的态 ...
- beautifulsoup之CSS选择器
BeautifulSoup支持大部分的CSS选择器,其语法为:向tag或soup对象的.select()方法中传入字符串参数,选择的结果以列表形式返回. tag.select("string ...
- 《SQL Server 2008从入门到精通》20180627
数据库范式理论 范式理论是为了建立冗余较小结构合理的数据库所遵循的规则.关系数据库中的关系必须满足不同的范式.目前关系数据库有六种范式:第一范式(1NF).第二范式(2NF).第三范式(3NF).BC ...
- spring配置datasource
1.使用org.springframework.jdbc.datasource.DriverManagerDataSource 说明:DriverManagerDataSource建立连接是只要有连 ...
- android 常用adb 及linux 命令
一.ADB相关 adb shell:进入连接的USB调试模式设备shell命令行下 adb tcpip 5555:将USB连接的调试及的连接方式改为网络远程模式进行调试 这里端口为5555(adb 默 ...
- iOS设计模式 - 模板
iOS设计模式 - 模板 原理图 说明 定义一个操作中的算法的骨架,而将步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤. 源码 https://github.c ...
- 一段滚动文字的js (jQuery)
function startmarqueeOneSMS() { var t; var to; var ishover = false; var waitone = 3000; var speed = ...
- 字典 & 列表表达式 结合
题: 思路: 要求的结果是小字典里面的两个值组成的列表,所以只要抓到小字典,这个题就可以用列表推导式直接表达了.所 以把小字典设为元素d,然后用d在列表里面遍历,列表呢,是大字典的一个值. 答案: