Lua 解释器原理学习笔记 -- 基本数据类型、栈、函数调用

本文介绍了如何使用C++调用Lua函数以及Lua中调用C函数的示例,同时详细解析了lua_State、CallInfo数据结构,阐述了它们在函数调用和栈管理中的作用。还提到了lua全局状态机global_State在多线程环境中的共享情况。
摘要由CSDN通过智能技术生成

Lua使用示例

1. 使用C++调用

#include "lua.h"
#include "lauxlib.h"

#include <stdio.h>

int test_main01(lua_State* L) {
        lua_Integer a = lua_tointeger(L, -1);
        lua_Integer b = lua_tointeger(L, -2);
        lua_pushinteger(L, a+b);
        return 1;
}

// C调用lua,并在lua中调用C函数
void test01() {
        printf("=====test01=====\n");
        lua_State* L = luaL_newstate();
        lua_pushcfunction(L, &test_main01);
        lua_pushinteger(L, 10);
        lua_pushinteger(L, 2);
        lua_call(L, 2, 1);
        lua_Integer sum = lua_tointeger(L, -1);
        printf("sum result:%d\n", sum);
        lua_close(L);
        return;
}

// C调用lua,并调用lua中的函数
void test02() {
        printf("=====test02=====\n");
        lua_State* L = luaL_newstate();
        int ret = luaL_loadfile(L, "sum.lua");
        if (ret) {
                printf("load file error");
                return;
        }
        lua_pcall(L, 0, 0, 0);
        lua_getglobal(L, "sum");
        lua_pushinteger(L, 10);
        lua_pushinteger(L, 2);
        lua_call(L, 2, 1);
        lua_Integer sum = lua_tointeger(L, -1);
        printf("sum result:%d\n", sum);
        lua_close(L);
        return;

}

int main() {
        test01();
        test02();
        return 0;
}

其中的sum.lua文件如下

function sum(a, b)
        return a + b
end

if __runtime__ == nil then
        sum(1, 2)
end

2. 使用lua脚本

在lua脚本中调用lua函数,参考上面sum.lua脚本中的调用

暂不列出lua脚本中调用C函数的过程,后续有需求再补充这一部分。

基本数据类型

lua_State:lua主线程栈结构,记录了栈底、栈顶、栈最大值、函数调用等信息

数据结构:

/*
** 'per thread' state
** 仅保留了一些在本节中关注的字段
*/
struct lua_State {
  CommonHeader;
  ...
  StkIdRel top;  /* first free slot in the stack */
  global_State *l_G;
  CallInfo *ci;  /* call info for current function */
  StkIdRel stack_last;  /* end of stack (last element + 1) */
  StkIdRel stack;  /* stack base */
  struct lua_longjmp *errorJmp;  /* current error recover point */
  CallInfo base_ci;  /* CallInfo for first level (C calling Lua) */
  ptrdiff_t errfunc;  /* current error handling function (stack index) */
  ...
};

从结构中可以看出,每个lua_State都会保留一个指向global_State的指针。

对应的栈结构:

global_State:lua全局状态机,同一个lua_State创建的thread共享此global_State,主要是进行内存管理。

数据结构:

/*
** 'global state', shared by all threads of this state
*/
typedef struct global_State {
  lua_Alloc frealloc;  /* function to reallocate memory */
  void *ud;         /* auxiliary data to 'frealloc' */
  lua_CFunction panic;  /* to be called in unprotected errors */
  struct lua_State *mainthread;
} global_State;

这里可以看出,每个global_State会保存一个执行主线程的lua_State的指针。

CallInfo:记录一次调用的信息。

数据结构:

/*
** Information about a call.
** About union 'u':
** - field 'l' is used only for Lua functions;
** - field 'c' is used only for C functions.
** About union 'u2':
** - field 'funcidx' is used only by C functions while doing a
** protected call;
** - field 'nyield' is used only while a function is "doing" an
** yield (from the yield until the next resume);
** - field 'nres' is used only while closing tbc variables when
** returning from a function;
** - field 'transferinfo' is used only during call/returnhooks,
** before the function starts or after it ends.
*/
typedef struct CallInfo {
  StkIdRel func;  /* function index in the stack */
  StkIdRel	top;  /* top for this function */
  struct CallInfo *previous, *next;  /* dynamic call link */
  union {
    struct {  /* only for Lua functions */
      const Instruction *savedpc;
      volatile l_signalT trap;
      int nextraargs;  /* # of extra arguments in vararg functions */
    } l;
    struct {  /* only for C functions */
      lua_KFunction k;  /* continuation in case of yields */
      ptrdiff_t old_errfunc;
      lua_KContext ctx;  /* context info. in case of yields */
    } c;
  } u;
  union {
    int funcidx;  /* called-function index */
    int nyield;  /* number of values yielded */
    int nres;  /* number of values returned */
    struct {  /* info about transferred values (for call/return hooks) */
      unsigned short ftransfer;  /* offset of first value transferred */
      unsigned short ntransfer;  /* number of values transferred */
    } transferinfo;
  } u2;
  short nresults;  /* expected number of results from this function */
  unsigned short callstatus;
} CallInfo;

 lua_State与CallInfo的关系:

栈上进行函数调用(C or lua)

 未完待更新。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值