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

@ -282,7 +282,12 @@ TEST_F(LuaCjApiTest, PackagePathConfig) {
EXPECT_EQ(ret, 0) << "Require failed, maybe pkgpath not set correctly. Errno: " << get_errno();
char* res = getresult(runner);
EXPECT_STREQ(res, lib_path.c_str());
// 跨版本语义适配:
// - Lua 5.3 的 require 返回 1 个值模块本身run() 读栈顶得模块返回值 "LoadedViaPkgPath"
// - Lua 5.4+ 的 require 返回 2 个值(模块 + loader datarun() 读栈顶得 loader data文件路径
// 两者都表明 require 经 pkgpath 成功定位并加载了模块
EXPECT_TRUE(strcmp(res, lib_path.c_str()) == 0 || strcmp(res, "LoadedViaPkgPath") == 0)
<< "unexpected require result: " << (res ? res : "(null)");
}
// ==================== 新增测试doString 功能 ====================
@ -487,13 +492,21 @@ TEST_F(LuaCjApiTest, CallFunctionAfterCleanup) {
}
// ==================== typed interop 测试v0.2.2====================
// 版本自适应Lua 5.3+ 有 integer 子类型CJT_INT5.2 及以下所有数字均为
// numberCJT_NUM。数值断言用 INT_OR_NUM 宏兼容两种情况。
#if LUA_VERSION_NUM >= 503
#define EXPECT_INT_OR_NUM(type) EXPECT_EQ(type, CJT_INT)
#else
// 5.2 及以下:整型结果也报为 CJT_NUM且 lua_tostring(10.0) 输出 "10"
#define EXPECT_INT_OR_NUM(type) EXPECT_EQ(type, CJT_NUM)
#endif
// 整型参数直通Lua 收到 integer返回 integer+1仓颉侧读回 Int64
TEST_F(LuaCjApiTest, TypedCallInt) {
ASSERT_EQ(loadfunction(runner, get_script_path("func_typed_add.lua").c_str(), "inc"), 0);
EXPECT_EQ(callfunction_int(runner, "inc", 41), 0);
EXPECT_EQ(result_type(runner), CJT_INT);
EXPECT_INT_OR_NUM(result_type(runner));
EXPECT_EQ(result_int(runner), 42);
// 字符串形式同步可用(向后兼容)
EXPECT_STREQ(getresult(runner), "42");
@ -506,7 +519,12 @@ TEST_F(LuaCjApiTest, TypedCallNum) {
EXPECT_EQ(callfunction_num(runner, "mul", 4.0), 0);
EXPECT_EQ(result_type(runner), CJT_NUM);
EXPECT_DOUBLE_EQ(result_num(runner), 10.0);
#if LUA_VERSION_NUM >= 503
EXPECT_STREQ(getresult(runner), "10.0");
#else
// 5.2 的 %.14g 格式化把 10.0 输出为 "10"
EXPECT_STREQ(getresult(runner), "10");
#endif
}
// 布尔参数直通:返回逻辑非,读回 Bool
@ -529,7 +547,7 @@ TEST_F(LuaCjApiTest, TypedCallVoid) {
ASSERT_EQ(loadfunction(runner, get_script_path("func_typed_void.lua").c_str(), "forty_two"), 0);
EXPECT_EQ(callfunction_void(runner, "forty_two"), 0);
EXPECT_EQ(result_type(runner), CJT_INT);
EXPECT_INT_OR_NUM(result_type(runner));
EXPECT_EQ(result_int(runner), 42);
}
@ -539,13 +557,21 @@ TEST_F(LuaCjApiTest, TypedEchoRoundTrip) {
// int 往返
EXPECT_EQ(callfunction_int(runner, "echo", -123456789LL), 0);
EXPECT_EQ(result_type(runner), CJT_INT);
EXPECT_INT_OR_NUM(result_type(runner));
EXPECT_EQ(result_int(runner), -123456789LL);
// 大整数(超过 double 精确表示范围)往返
// 大整数(超过 double 精确表示范围)往返
// 仅 Lua 5.3+integer 类型可保真5.2 及以下经 double 必然丢精度
#if LUA_VERSION_NUM >= 503
EXPECT_EQ(callfunction_int(runner, "echo", 9007199254740993LL), 0);
EXPECT_EQ(result_type(runner), CJT_INT);
EXPECT_INT_OR_NUM(result_type(runner));
EXPECT_EQ(result_int(runner), 9007199254740993LL);
#else
EXPECT_EQ(callfunction_int(runner, "echo", 9007199254740993LL), 0);
EXPECT_EQ(result_type(runner), CJT_NUM);
// 经 double 往返,精度丢失为可预期值
EXPECT_EQ(result_int(runner), (long long)(double)9007199254740993LL);
#endif
// num 往返
EXPECT_EQ(callfunction_num(runner, "echo", 3.14159), 0);
@ -592,7 +618,7 @@ TEST_F(LuaCjApiTest, TypedRunVariants) {
// int
EXPECT_EQ(run_int(runner, path.c_str(), 777), 0);
EXPECT_EQ(result_type(runner), CJT_INT);
EXPECT_INT_OR_NUM(result_type(runner));
EXPECT_EQ(result_int(runner), 777);
// num
@ -638,7 +664,7 @@ TEST_F(LuaCjApiTest, TypedAndStringCoexist) {
TEST_F(LuaCjApiTest, TypedStateAfterCleanup) {
ASSERT_EQ(loadfunction(runner, get_script_path("func_typed_void.lua").c_str(), "v"), 0);
EXPECT_EQ(callfunction_void(runner, "v"), 0);
EXPECT_EQ(result_type(runner), CJT_INT);
EXPECT_INT_OR_NUM(result_type(runner));
EXPECT_EQ(cleanup(runner), 0);