Repository navigation
fix: JIT multi-return specialization, tail-arg stmt splicing, varargs UB, reserved C names - #21
Merged
Conversation
Fix four JIT codegen defects found via FAKELUA_JIT_BUG_REPORT: 1. Multi-return/vararg/tail-call functions are no longer math-specialized. A scalar specialization could emit "return FlMakeMulti(...)" inside an int64_t/double function, producing illegal C (TCC: cannot convert 'struct CVar' to 'long long'). TypeInferencer now runs an eligibility walk over every return statement; "return f()" is allowed only when f's effective return count is statically 1, solved by a new function_effective_returns fixed-point in SemanticAnalysis that also resolves transitive tail calls and recursion with a single-value base. 2. Tail-argument expansion no longer splices statement macros into expression position: CompileExp is evaluated before streaming the assignment in CompileCallArgs, and generic-for discarded expressions (>3 exps) use the same evaluate-then-emit ordering (TCC: expression expected before 'do'). 3. FlMakeClosure's is_vararg parameter is int instead of bool: using a bool as the va_start anchor is undefined behavior per C17 7.16.1.4 and triggered -Wvarargs. 4. Top-level user functions are emitted with a unified flua_fn_ C-symbol prefix, avoiding Clang's main() signature check and redefinition conflicts with libc symbols (e.g. sin, TCC redefinition error). Lua names are unchanged. Add infer regression tests (all JIT backends x debug modes) covering multi-return/vararg/tail-transparency/recursive-anchor eligibility, tail-expansion statement ordering, and reserved function naming.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #21 +/- ##
==========================================
+ Coverage 87.80% 87.82% +0.02%
==========================================
Files 119 119
Lines 24042 24161 +119
==========================================
+ Hits 21110 21220 +110
- Misses 2932 2941 +9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
修复外部 JIT bug 报告(
FAKELUA_JIT_BUG_REPORT.md)中的 4 个缺陷,全部在最新 master 上复现并修复,TCC / GCC / INTERP 三后端验证通过。1. 多返回值函数被数学参数特化,生成非法 C(严重)
mr(x)返回y, y+1, y+2时,特化变体mr_0(int64_t)/mr_1(double)在标量返回值函数体里生成return FlMakeMulti(...)(CVar),TCC 报cannot convert 'struct CVar' to 'long long',GCC 同理。return ...、return f()(f 可能返回多值)同属此类。修复:
TypeInferencer新增IsEligibleForMathSpec,遍历函数全部语句(含 if/while/repeat/for/do 嵌套,不进入嵌套函数定义),凡存在多值 return、尾 vararg 展开、或尾调用无法静态证明为单返回值者,一律不做特化,只生成通用 CVar 变体;裸return仍允许(返回类型安全退化为 CVar)。SemanticAnalysis新增function_effective_returns:把「return f()沿被调链的有效返回数」做定点求解,可穿透多层尾调用,并为带单值基线的递归(如阶乘)保留特化;vararg/未知外部被调/无锚点递归环保守判为不可知。该字段仅用于资格判定,不改变既有代码生成路径。2. 尾参数展开把语句宏拼进表达式位置(严重)
CompileCallArgs中Out() << ... << CompileExp(...) << ...的链式输出,会被 CompileExp 中途写入的慢路径语句(OpAdd展开的do{}while(0)、math.floor的 if/else 类型分支)撕成x = do{...}while(0);,TCC 报expression expected before 'do'。generic-for 超过 3 个表达式时的丢弃位((void)(...))有完全相同的隐患。修复:两处都改为「先求值 CompileExp,再拼接输出」。
3.
FlMakeClosure用 bool 作 va_start 锚点(UB)C17 7.16.1.4 规定 va_start 最后一个具名形参若受默认实参提升影响(bool→int)行为未定义,Clang 产生
-Wvarargs。参数类型bool is_vararg改为int is_vararg,调用处 true/false 隐式转换,改后 GCC JIT 编译零警告。4. 用户函数占用 C 保留/外部符号名
Lua 顶层函数名为
main时 Clang 报first parameter of 'main' must be of type 'int';名为sin时连 TCC 都报incompatible types for redefinition of 'sin'(与 libc 冲突)。修复:顶层用户函数的 C 符号统一加
flua_fn_前缀(嵌套函数本就是__fl_func_N),Lua 侧函数名与调用方式完全不变;去重逻辑保留。Tests
test/lua/infer/test_jitbug_*.lua+test/test_infer.cpp),每个用例经InferRunHelper在 TCC/GCC/INTERP × debug/release 共 6 种配置下运行:test_jitbug_multi_return_no_spec:多返回值/vararg/尾透传不生成标量特化且多返回值语义正确(115/235、120/240),并反向锁定带单值基线的尾递归仍特化(factacc_0_0);test_jitbug_tail_expand_stmt:尾实参展开 + generic-for 第 4 表达式,语句宏不再撕裂表达式;test_jitbug_reserved_func_name:main/sin生成flua_fn_main/flua_fn_sin,Lua 原名调用正常。flua_fn_前缀)。unit_tests:1553 中 1549 通过;唯一 4 个失败为test_redis.integration_*,原因是本机无 Redis(connect failed: Connection refused),与本改动无关。