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

@ -1,4 +1,14 @@
#include "lua_cj_api.h"
#include <new>
// Lua 5.1 兼容:无 LUA_OK 宏,成功返回值为 0
#ifndef LUA_OK
#define LUA_OK 0
#endif
// Lua 5.2/5.1 无 lua_getextraspace改用 Registry 固定索引存储 iopath 指针
#define IOPATH_REG_IDX 1
extern "C"
{
#include <string.h>
@ -351,15 +361,36 @@ int cleanup(void *selfd)
int free_lua(void *selfd)
{
lua_runner* self = (lua_runner*)selfd;
// 释放 Registry 中的 iopath若存在
Lua_runner *runner = (Lua_runner*)self->lua_obj;
if (runner != NULL) {
lua_State *L = runner->get_lua_State();
if (L != NULL) {
lua_rawgeti(L, LUA_REGISTRYINDEX, IOPATH_REG_IDX);
iopath *p = (iopath*)lua_touserdata(L, -1);
lua_pop(L, 1);
delete p; // NULL 也安全
}
}
delete((Lua_runner*)self->lua_obj);
free(self);
return 0;
}
/*-------------重定向io操作------------------------*/
/* Lua 5.2/5.1 无 lua_getextraspace改用 Registry 固定索引存储 iopath 指针 */
static iopath *get_iopath(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, IOPATH_REG_IDX);
iopath *r = (iopath *)lua_touserdata(L, -1);
lua_pop(L, 1);
return r;
}
static const char *full_path(lua_State *L, int isOut)
{
iopath *r = (iopath *)lua_getextraspace(L);
iopath *r = get_iopath(L);
static char buf[512];
snprintf(buf, sizeof(buf), "%s/%s", r->iopath, isOut ? "output" : "input");
return buf;
@ -368,7 +399,7 @@ static const char *full_path(lua_State *L, int isOut)
//劫持读取终端输入,触发回调
static int l_tty_read(lua_State *L)
{
iopath *r = (iopath *)lua_getextraspace(L);
iopath *r = get_iopath(L);
if (r->funcs.io_input) r->funcs.io_input();
const char *fname = full_path(L, 0);
FILE *fp = fopen(fname, "rb");
@ -394,7 +425,7 @@ static int l_tty_read(lua_State *L)
//劫持到终端输出,输出结束触发回调
static int l_tty_write(lua_State *L)
{
iopath *r = (iopath *)lua_getextraspace(L);
iopath *r = get_iopath(L);
const char *fname = full_path(L, 1);
FILE *fp = fopen(fname, "a");
if (!fp) return luaL_error(L, "tty write open fail: %s", fname);
@ -406,7 +437,7 @@ static int l_tty_write(lua_State *L)
return 0;
}
static int l_print(lua_State *L) {
iopath *r = (iopath *)lua_getextraspace(L);
iopath *r = get_iopath(L);
const char *fname = full_path(L, 1); // 输出到 output 文件
FILE *fp = fopen(fname, "a");
if (!fp) return luaL_error(L, "print redirect open fail: %s", fname);
@ -414,9 +445,18 @@ static int l_print(lua_State *L) {
int n = lua_gettop(L);
for (int i = 1; i <= n; ++i) {
if (i > 1) fputc('\t', fp);
#if LUA_VERSION_NUM >= 502
const char *str = luaL_tolstring(L, i, NULL);
#else
/* Lua 5.1 无 luaL_tolstringlua_tostring 对非字符串做 tostring 元方法转换,
转换失败(如 table/function)时返回 NULL退化为类型名 */
const char *str = lua_tostring(L, i);
if (!str) str = lua_typename(L, lua_type(L, i));
#endif
fputs(str, fp);
lua_pop(L, 1);
#if LUA_VERSION_NUM >= 502
lua_pop(L, 1); /* luaL_tolstring 压入的结果需弹出lua_tostring 不压栈 */
#endif
}
fputc('\n', fp);
fclose(fp);
@ -451,7 +491,15 @@ static void push_tty_file(lua_State *L, int isout, const luaL_Reg *fake_tty_meta
lua_newuserdata(L, sizeof(int));
luaL_newmetatable(L, isout ? "tty_out" : "tty_in");
#if LUA_VERSION_NUM >= 502
luaL_setfuncs(L, fake_tty_meta, 0);
#else
/* Lua 5.1 无 luaL_setfuncs手动注册函数表 */
for (const luaL_Reg *l = fake_tty_meta; l->name; l++) {
lua_pushcfunction(L, l->func);
lua_setfield(L, -2, l->name);
}
#endif
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
@ -475,7 +523,7 @@ int redirecct_path(lua_State *L)
errno = LUAERR_LUA_STATE;
return -1;
}
iopath *p = (iopath*)lua_getextraspace(L);
iopath *p = get_iopath(L);
static const luaL_Reg fake_methods[] = {
{"read", l_tty_read},
{"write", l_tty_write},
@ -547,15 +595,16 @@ void *init_lua_runner(const char *pathio,const char *pkgpath,int(*input)(),int(*
errno = LUAERR_LUA_STATE;
return NULL;
}
iopath *io_path = (iopath*)lua_getextraspace(L);
//申请额外空间
// Lua 5.2/5.1 无 extraspacenew 一个 iopath 存入 Registry
iopath *io_path = new (std::nothrow) iopath();
if(pathio == NULL)
{
delete io_path;
goto WITHOUT_REDIRECT;
}
if(io_path == NULL){
errno = LUAERR_CALLBACK;
errno = LUAERR_CLASS_LOST;
return NULL;
}
@ -564,6 +613,9 @@ void *init_lua_runner(const char *pathio,const char *pkgpath,int(*input)(),int(*
io_path->funcs.io_output = output;
//装载重定向路径
strcpy(io_path->iopath,pathio);
//存入 Registry 固定索引供回调取用
lua_pushlightuserdata(L, (void*)io_path);
lua_rawseti(L, LUA_REGISTRYINDEX, IOPATH_REG_IDX);
//注册重定向
if(redirecct_path(L)==-1){
errno = LUAERR_LUA_STATE;