LUA源码分析五:环境设置
版本日期 2011年4月22日
lua里的环境设置,可以看成是一个临时的域名空间。这个空间里有名字和变量等等。可以试着运行一下以下代码,输出全局的环境
local l_lindp=1
g_lindp=1
for n in pairs(_G) do print(n) end
输出:
string
xpcall
package
tostring
print
os
unpack
require
getfenv
setmetatable
next
assert
tonumber
io
rawequal
collectgarbage
getmetatable
module
rawset
Average
g_lindp //定义的全局
...
相对于整个开发环境讲,全局的表就是一个局部的表。那么同理,也可以为某个函数设置一个环境。在lua里的实现很巧妙,它并不是通过增加一个表系
统来做这事,而是把函数当成了一个对象,环境表只是里面的一个成员:
#define ClosureHeader \
CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
struct Table *env //存放在这
typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
TValue upvalue[1];
} CClosure;
整个设置的过程通过luaB_setfenv和lua_setfenv完成
static int luaB_setfenv (lua_State *L) {
luaL_checktype(L, 2, LUA_TTABLE);
//取得函数的环境
getfunc(L, 0);
lua_pushvalue(L, 2);
//判断setfenv的参数是否合法,也就是level.
if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
/* change environment of current thread */
lua_pushthread(L);
lua_insert(L, -2);
lua_setfenv(L, -2);
return 0;
}
else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
luaL_error(L,
LUA_QL("setfenv") " cannot change environment of given object");
return 1;
}
LUA_API int lua_setfenv (lua_State *L, int idx) {
StkId o;
int res = 1;
lua_lock(L);
api_checknelems(L, 1);
o = index2adr(L, idx);
api_checkvalidindex(L, o);
api_check(L, ttistable(L->top - 1));
switch (ttype(o)) {
case LUA_TFUNCTION:
//赋值
clvalue(o)->c.env = hvalue(L->top - 1);
break;
}
在getfunc(L, 0);里面有段代码的封装非常的简单巧妙:
luaL_optint(L, 1, 1)
((int)luaL_optinteger(L, (n), (d)))
LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
lua_Integer def) {
return luaL_opt(L, luaL_checkinteger, narg, def);
}
LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
lua_Integer d = lua_tointeger(L, narg);
if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
tag_error(L, narg, LUA_TNUMBER);
return d;
}
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
而luaL_optint是外部开放的API
luaL_optinteger负责组合luaL_checkinteger和luaL_opt
luaL_checkinteger 是具体的逻辑
luaL_opt是个最底层的调用函数
当编译器执行到对变量去值时,会先去获取当前宿主的环境表里,然后从里面取值
case OP_GETGLOBAL: {
TValue g;
TValue *rb = KBx(i);
sethvalue(L, &g, cl->env);
lua_assert(ttisstring(rb));
Protect(luaV_gettable(L, &g, rb, ra));
continue;
}
有了这几个关键点后,lua的env工作方式就很明了了
分享到:
相关推荐
Lua源码分析Lua源码分析Lua源码分析Lua源码分析Lua源码分析Lua源码分析Lua源码分析Lua源码分析
所有版本LUA源码 lua-5.3.5 lua-5.3.4 lua-5.3.3 lua-5.3.2 lua-5.3.1 lua-5.3.0 lua-5.2.4 lua-5.2.3 lua-5.2.2 lua-5.2.1 lua-5.2.0 lua-5.1.5 lua-5.1.4 lua-5.1.3 lua-5.1.2 lua-5.1.1 lua-5.1 lua-5.0.3 lua-...
这个是lua的源码分析,lua的源码写的非常好,整个设计的结构非常巧妙,不管是对于学习lua本身还是c语言的数据结构都非常有帮助。
第一章概览由甮由源文件划分 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮
里面有风云 大神写的对lua 的源码剖析。还有lua5.2源码。
Lua 源码赏析.pdf, 其中有着非常棒的lua源代码资源可供学习。下载文件为该书的百度云连接地址。
最近有一点空闲,想续写我那本 Lua 源码欣赏。按我心里的计划,还有大约 6 章。虚拟机、字节码持久化、C API 、解释器、GC、库函数。 新添了一章关于虚拟机的,所以重新读了一遍相关源码。发现 Lua 5.2 比上一版...
Lua CJSON 为 Lua 语言提供高性能的 JSON 解析器和编码器,其性能比纯 Lua 库要高 10 到 20 倍。Lua CJSON 完全支持 UTF-8 ,无需依赖其他非 Lua/LuaJIT 的相关包。
云风新作-----lua源码导读。目前网上最好的lua源代码阅读教程。帮助你快速理解lua实现原理。
做了那么多 Lua 脚本破解,我们来尝试写一个不能被破解的加密。 所谓不能被破解,并不是真正不能被破解,只是在没有密码的情况下很难破解。
云风写的Lua源码欣赏,基于lua5.2版本源代码解析,对于初初学习lua语言的有很不错的帮助
a utf-8 support module for Lua and LuaJIT 源码地址:https://github.com/starwing/luautf8 编译后可用的库: Linux版:lua-utf8.so Windows版:lua-utf8.dll(若是用在openresty中,openresty版本需使用32位版本...
本环境使用makefile进行编译,集成了lua-5.3.0的源码和简单的使用方法,在mac和linux环境下使用make命令编译运行
lua源码欣赏 lua源代码分析,来之云风!
redis-lua 是 Redis 的 Lua 语言的客户端开发包。 示例代码: require 'redis' local redis = Redis.connect('127.0.0.1', 6379) local response = redis:ping() -- true redis:set('usr:nrk', 10) redis:set('usr...
Lua被设计成很容易和传统的C/C++整合的语言。这种语言的二元性带来了极大的好处。Lua是一个小巧而简单的语言,因为Lua不致力于做C语言已经做得很好的领域,比如:性能、底层操作以及与第三方软件的接口。Lua依赖于C...
讲解lua语言的实现源代码,由于lua是基于C语言实现,所以需要有一定C语言基础。 请配合《the implementation of Lua5.0中文版》一起阅读。 http://download.csdn.net/detail/havesnag/5071833
用sublime调试lua,lua中需要 require 'cjson',使用cjson.dll报错,可以将该cjson.lua直接放入同一目录下。
lua5.3.4源码,导入VS2015可以直接编译,想学习分析Lua源码的可以下载,研究。
打地鼠的lua源码,是我学习脚本的时候用到的,希望对大家有所帮助,希望大家喜欢