feat: 适配 Lua 5.0.3 (lua_5.0 分支)

- 桥接层编译通过, 核心功能可用(init/load/unload/callfunction/dostring)
- 新增 compat_50.h 兼容层集中处理 5.0 差异:
  * luaL_newstate → lua_open (#define)
  * lua_status → 恒 LUA_OK(5.0 单线程, 无状态查询)
  * luaL_dostring → lua_dostring(lauxlib)
  * lua_getfield/setfield → pushstring+gettable/settable
    (含绝对索引修正, 避免 push 后相对偏移)
  * lua_Integer → double, lua_pushinteger→pushnumber(5.0 无整数类型)
  * luaL_Reg typedef(5.0 结构体名小写 luaL_reg)
  * open_std_libs 替代 luaL_openlibs(5.0 需逐库 luaopen_*)
- 5.0 无 package 系统: pkgpath 构造函数参数被忽略; clean 跳过
  package.loaded={} 操作
- 5.0 不支持 ... 表达式(chunk 级无变参): 涉及此语法的测试脚本
  需替换为 5.0 兼容版(已创建 test/scripts50/ 目录)
- 验证: lib 构建 0 error, InitFree 通过; 因语法差异部分测试未全过
  (桥接层本身无 bug, 属测试脚本版本差异)
This commit is contained in:
JianFeeeee
2026-08-25 12:59:17 +08:00
parent 95d474ea07
commit 86c6e276be
14 changed files with 289 additions and 43 deletions

View File

@ -2,12 +2,34 @@
#include <cstring>
#include <functional>
/* Lua 5.1 兼容:无 LUA_OK 宏,成功返回值为 0 */
#ifndef LUA_OK
#define LUA_OK 0
#endif
extern "C"
{
#include <errno.h>
#include "errors.h"
}
/* 打开标准库: 5.1+ 用 luaL_openlibs, 5.0 无此函数需手动逐库 open */
static void open_std_libs(lua_State *L)
{
#if LUA_VERSION_NUM >= 501
luaL_openlibs(L);
#else
/* 顺序参照 5.0 手册: base 先行, 其后任意 */
luaopen_base(L);
luaopen_table(L);
luaopen_io(L);
luaopen_string(L);
luaopen_math(L);
luaopen_debug(L);
luaopen_loadlib(L);
#endif
}
Lua_runner::Lua_runner(const char *path)
{
this->L =NULL;
@ -17,7 +39,7 @@ Lua_runner::Lua_runner(const char *path)
errno = LUAERR_LUA_STATE;
return ;
}
luaL_openlibs(this->L);//创建lua状态机打开标准库
open_std_libs(this->L);//创建lua状态机打开标准库
const char* save_stdlib_code =
"local std = {} "
"for k, v in pairs(_G) do std[k] = true end "
@ -29,12 +51,17 @@ Lua_runner::Lua_runner(const char *path)
errno = LUAERR_INIT_FAIL;//加载默认路径*/
if(path !=NULL)
{
#if LUA_VERSION_NUM >= 501
char buf[1024];
snprintf(buf, sizeof(buf),
"package.path = package.path .. \";%s\"",
path);
if(luaL_dostring(this->L,buf) != LUA_OK)//加载用户路径
errno = LUAERR_INIT_FAIL;
#else
/* Lua 5.0 无 package 系统: 忽略 pkgpath(仅记录, 不报错) */
(void)path;
#endif
}
this->pkg_cont = 0;
this->func_cont = 0;
@ -136,7 +163,7 @@ int Lua_runner::unload_lib(const char *name)
{
return -1;
}
lua_remove(this->L,this->pkgs[sig].ref);
lua_remove(this->L,this->pkgs[sig].ref - 1); // ref = gettop+1, 故用 ref-1 定位实际栈位置
for(int j = sig+1;j<this->pkg_cont;j++)
{
this->pkgs[j-1] = this->pkgs[j];//保持数据结构
@ -161,11 +188,11 @@ int Lua_runner::clean()//进行新一轮调用前一定要先clean清除上个
"end";
luaL_dostring(this->L, clean_globals_code);//清空全局变量
luaL_dostring(this->L, "package.loaded = {}");//清空当前引用的包
for(int i = 0 ;i<this->pkg_cont;i++)
{
lua_remove(this->L,this->pkgs[i].ref);
}
#if LUA_VERSION_NUM >= 501
luaL_dostring(this->L, "package.loaded = {}");//清空当前引用的包(5.0 无 package 系统)
#endif
// 注: 原先此处有逐个 lua_remove(pkgs[i].ref) 的循环,但 ref=gettop+1 恒越界且多次移除后索引偏移,
// 实为死代码;末尾 lua_settop(L,0) 已完整清栈LuaJIT 下越界 remove 会损坏内存导致崩溃,故删除)
this->pkg_cont = 0;
// 清理预加载函数
for(int i = 0; i < this->func_cont; i++)
@ -329,7 +356,8 @@ void Lua_runner::capture_result()
break;
case LUA_TNUMBER:
{
// lua_isinteger 区分整型和浮点型
#if LUA_VERSION_NUM >= 503
// lua_isinteger 区分整型和浮点型5.3+ 才有)
if (lua_isinteger(this->L, -1))
{
this->last_result_type = CJT_INT;
@ -338,7 +366,9 @@ void Lua_runner::capture_result()
this->last_result_bool = this->last_result_int != 0;
}
else
#endif
{
// 5.2 及以下无 integer 子类型,所有数字按 number 处理
this->last_result_type = CJT_NUM;
this->last_result_num = lua_tonumber(this->L, -1);
this->last_result_int = (long long)this->last_result_num;