Lua检查函数的覆盖问题

Lua里面可以实现类面向对象,这个在后面会分析到。前几天项目里面遇到的一个问题,在不同模块中的同名函数,由于都是挂在某个类下面,会出现后面加载的模块函数覆盖了前面的函数。简单的例子就是这样的:

首先定义一个基类obj,里面有一个名为test的函数:

module("obj", package.seeall)

function test()
  print("in

Lua5.1.4代码分析(十七)-可变参数函数的实现

可变函数参数的实现相对简单。

首先来看看Lua中可变参数函数的使用方式。如果函数传入的参数是”…”,则表示这里的参数是可变参数,在使用时,它们最终会存储到一个名为arg的数组中。

如前面对函数的解析里面提到,在对一个函数的参数进行解析时,会走到parlist函数中,这里处理了变参参数的情况:

static void parlist (LexState *ls) {
  /* parlist -> [ param { `,' param } ] */
  FuncState *fs = ls->fs;
  Proto *f = fs->f;
 

Lua5.1.4代码分析(十六)-函数与Upvalue

Lua中的所谓upvalue是一类比较特殊的值,可以理解为在某函数内引用外部的数据。所以这里就涉及到垃圾回收相关的话题,比如函数A使用它的upvalue a,那么就需要保证a在函数A调用之前不会被Lua gc自动回收。里面还有一些其他细节。下面一一道来。

在前面提到的

如何在不同Lua虚拟机中传递函数

有一个需求,需要在同一个进程中不同的Lua虚拟机之间传递函数对象并且调用。

考虑了很久没啥进展。原来想干脆hack Lua的指针,因为是在同一个进程中的Lua虚拟机,所以看看能不能得到函数的内存。但是这次经历让我发现其实Lua封装的非常好,在gdb中根本看到Lua State这个结构体具体的内容,也只能按照它提供的API做它允许的操作,再次让我对Lua的实现敬仰程度增加了不少。

后来去Lua maillist发问,已经有老外实现了类似的项目

Lua5.1.4代码分析(十五)-Lua继承机制分析

Lua并不是一门以OO为卖点的脚本语言,但是这并不妨碍在Lua中使用Lua的一些特性来实现类面向对象的特性。

先简单看看Lua中实现继承的简单示例代码,再展开分析。如下定义了两个模块,base.lua和test.lua,其中后者继承自前者:
base.lua

module( "base", package.seeall )
function new( )
    local obj = {}
    setmetatable( obj, { __index = base } )
    return obj
end

test.lua

module( "test", package.seeall )
setmetatable( test,

Lua5.1.4代码分析(十四)-Lua外部模块加载机制

前面已经提到了Lua的内部模块加载机制,今天谈谈如何加载外部模块.与模块加载相关的库都在package库中提供,代码实现在loadlib.c中.

先来看Lua中与模块相关的几个函数.

1)module
在定义一个Lua模块时,第一句代码一般都是module(xxx).来看这一句背后的含义.module调用对应的c函数是loadlib.c中的函数ll_module:

static int ll_module (lua_State *L) {
  const char *modname = luaL_checkstring(L, 1);
  int loaded = lua_gettop(L) + 1;  /* index of _LOADED table */
 

Lua5.1.4代码分析(十二)-Lua内部模块的注册

今天讲解Lua内模块的注册机制.其实Lua自带的模块并不多,这是Lua被诟病比较多的地方,这样的坏处是很多东西需要自己造轮子没有标准的实现(虽然可以实现为库也不那么不方便使用),好处就是Lua足够的小,毕竟它的设计目标是定位成一个嵌入式的轻量级语言的.

这部分需要的知识点不多,但是可以顺带着理解Lua中的一些概念.

但是在讲解之前,还是先来看看另一个貌似并不那么相关的函数index2adr

static TValue *index2adr

Lua5.1.4代码分析(十一)-函数的调用

上一篇中,已经提到了函数的信息是如何在lua中保存的,本篇继续来讲解函数的调用机制.

首先谈谈函数的参数是如何处理的.
在分析函数的定义时,首先调用parlist处理函数的参数.简单起见,这里考虑函数的参数是确定的情况:

static void parlist (LexState *ls) {
  /* parlist -> [ param { `,' param } ] */
  FuncState *fs = ls->fs;
  Proto *f = fs->f;
  int nparams = 0;
  f->is_vararg = 0;
  if (ls->t.token != ')') {  /* is `parlist' not empty? */
    do {
      switch (ls->t.token)

十字链表的AOI算法

看了云风写的

Lua5.1.4代码分析(十)-函数的定义

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

Pages: Prev 1 2 3 4 5 6 7 8 9 Next