feat: 适配 LuaJIT 2.1 (luajit_2.1 分支)

- lib/lua 替换为完整 LuaJIT 2.1 仓库(Makefile+src+dynasm, 官方结构)
- 构建系统改造: lib/lua/CMakeLists.txt 改为调用 LuaJIT 自带 make
  (BUILDMODE=static CFLAGS=-fPIC) 产出 libluajit.a; 顶层链接该静态库
  并加 -Wl,-E 导出符号(静态链 LuaJIT 必需)
- 补充 lua.hpp 转发头兼容桥接层 'lua/lua.hpp' include 路径
- 桥接层沿用 5.1 方案: Registry 存 iopath / luaL_tolstring 兜底 /
  typed interop 无 integer 子类型(LUA_VERSION_NUM=501)
- [关键修复] lua_remove 栈越界 bug(各版本共有, LuaJIT 下显性崩溃):
  * unload_lib: ref 记录的是 gettop+1, 实际移除应用 ref-1
  * clean(): 原逐个 remove 循环恒越界且多次移除后索引偏移,
    属死代码(末尾 settop(L,0) 已清栈), 直接删除
  该 bug 在 Lua 5.4 中被隐式容忍, 在 LuaJIT 的 GC finalizer 中
  表现为 lj_gc_finalize_cdata 段错误
- 测试跨版本断言同步(自 5.1.5)
- 验证: GTest 44/44 通过
This commit is contained in:
JianFeeeee
2026-08-25 11:57:32 +08:00
parent 4af121c1f3
commit cc40a49ae6
280 changed files with 144368 additions and 30240 deletions

View File

@ -2,6 +2,11 @@
#include <cstring>
#include <functional>
/* Lua 5.1 兼容:无 LUA_OK 宏,成功返回值为 0 */
#ifndef LUA_OK
#define LUA_OK 0
#endif
extern "C"
{
#include <errno.h>
@ -136,7 +141,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];//保持数据结构
@ -162,10 +167,8 @@ int Lua_runner::clean()//进行新一轮调用前一定要先clean清除上个
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);
}
// 注: 原先此处有逐个 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 +332,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 +342,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;