`

LUA源码分析六:环境设置

    博客分类:
  • LUA
阅读更多

 

 

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工作方式就很明了了

1
2
分享到:
评论

相关推荐

    Lua源码分析

    Lua源码分析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的源码写的非常好,整个设计的结构非常巧妙,不管是对于学习lua本身还是c语言的数据结构都非常有帮助。

    云风-lua源码欣赏-lua-5.21

    第一章概览由甮由源文件划分 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮 甮

    lua 源码剖析

    里面有风云 大神写的对lua 的源码剖析。还有lua5.2源码。

    Lua 源码赏析.pdf

    Lua 源码赏析.pdf, 其中有着非常棒的lua源代码资源可供学习。下载文件为该书的百度云连接地址。

    《Lua 源码欣赏》

    最近有一点空闲,想续写我那本 Lua 源码欣赏。按我心里的计划,还有大约 6 章。虚拟机、字节码持久化、C API 、解释器、GC、库函数。 新添了一章关于虚拟机的,所以重新读了一遍相关源码。发现 Lua 5.2 比上一版...

    Lua CJSON 源码

    Lua CJSON 为 Lua 语言提供高性能的 JSON 解析器和编码器,其性能比纯 Lua 库要高 10 到 20 倍。Lua CJSON 完全支持 UTF-8 ,无需依赖其他非 Lua/LuaJIT 的相关包。

    lua源码导读---云风

    云风新作-----lua源码导读。目前网上最好的lua源代码阅读教程。帮助你快速理解lua实现原理。

    lua脚本加密工具:简单异或加密

    做了那么多 Lua 脚本破解,我们来尝试写一个不能被破解的加密。 所谓不能被破解,并不是真正不能被破解,只是在没有密码的情况下很难破解。

    云风《Lua源码欣赏》1积分

    云风写的Lua源码欣赏,基于lua5.2版本源代码解析,对于初初学习lua语言的有很不错的帮助

    lua-utf8.zip

    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位版本...

    集成lua源码的c++编译环境

    本环境使用makefile进行编译,集成了lua-5.3.0的源码和简单的使用方法,在mac和linux环境下使用make命令编译运行

    lua源码欣赏

    lua源码欣赏 lua源代码分析,来之云风!

    redis-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源码及中文文档

    Lua被设计成很容易和传统的C/C++整合的语言。这种语言的二元性带来了极大的好处。Lua是一个小巧而简单的语言,因为Lua不致力于做C语言已经做得很好的领域,比如:性能、底层操作以及与第三方软件的接口。Lua依赖于C...

    Lua源码欣赏中文版

    讲解lua语言的实现源代码,由于lua是基于C语言实现,所以需要有一定C语言基础。 请配合《the implementation of Lua5.0中文版》一起阅读。 http://download.csdn.net/detail/havesnag/5071833

    cjson.lua源码

    用sublime调试lua,lua中需要 require 'cjson',使用cjson.dll报错,可以将该cjson.lua直接放入同一目录下。

    lua-5.3.4源码

    lua5.3.4源码,导入VS2015可以直接编译,想学习分析Lua源码的可以下载,研究。

    打地鼠lua源码

    打地鼠的lua源码,是我学习脚本的时候用到的,希望对大家有所帮助,希望大家喜欢

Global site tag (gtag.js) - Google Analytics