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 ...
随机推荐
- Eclipse连接sqlserver体验过程
以前装的sqlserver 2008试用期到了,就按照网上的步骤,彻底删除了sqlserver,然后又重新装了下,再用eclipse连接的时候,发现提示TCP/IP被禁用,然后找到了sqlserver ...
- 关于removeChild
var a=document.body; document.body.parentNode.removeChild(a) console.log(a); a的内容还是body???whY
- leetcode 之 Same Tree
1.题目描述 Given two binary trees, write a function to check if they are the same or not. Two binary tre ...
- SQLSERVER2012里的扩展事件初尝试(上)
SQLSERVER2012里的扩展事件初尝试(上) SQLSERVER2012里的扩展事件初尝试(下) 周未看了这两篇文章: 扩展事件在Denali CTP3里的新UI(一) 扩展事件在Denali ...
- Nodejs和npm入门使用
目录 引子 何为node.js 和 npm 怎么使用node.js和npm 安装node.js & npm npm init 初始化项目(创建node.js模块) Package.json 属 ...
- 铁乐学python_day13_迭代器生成器
一.[可迭代对象Iterable] 粗略判断的话,我们可以说能被for循环进行遍历的对象就是可迭代对象,如str,list,tuple,dict(key),set,range. (open file ...
- 安全预警-防范新型勒索软件“BlackRouter”
近期,出现一种新型勒索软件“BlackRouter”,开发者将其与正常软件恶意捆绑在一起,借助正常软件的下载和安装实现病毒传播,并以此躲避安全软件的查杀.目前,已知的被利用软件有AnyDesk工具(一 ...
- Programming Assignment 5: Burrows–Wheeler Data Compression
编程作业五 作业链接:Burrows-Wheeler Data Compression & Checklist 我的代码:MoveToFront.java & CircularSuff ...
- 【转载】Spring最佳后台框架
https://www.quora.com/What-is-the-best-backend-arquitecture-using-spring-framework The most modern a ...
- 【原创】Apache ab结果参数详解
解释如下: Server Software 服务器软件软件名称. Server Hostname 被测服务器的主机名. Server Port 被测试的Web服务器的监听端口. SSL/TLS Pro ...