fix(gen): c.Asm/c.LLVMIR void 调用 hit_box 命中标记,修复 StringTest 编译报 Asm 外部函数未登记

拆分后 _tc_h2_c_special 以 None 表示未命中,但 translate_c_asm/
translate_c_llvmir 对 void(无输出)asm 返回 None 表示已处理无返回值,
两者混淆导致 translate_call 继续走外部函数路径 → WARN 外部函数返回
类型未登记 Asm/AsmInp + t.ASM_DESCR 被当 CDefine 常量赋值 FATAL。
新增 hit_box(t.CPtr,[0]=1)区分命中,Asm/LLVMIR 分支置位,
translate_call 命中且返回 None 时视为已处理直接返回。
This commit is contained in:
TermiNexus committed 2026-08-17 12:43:49 +08:00
1 parent 9f44abe645
commit 2f3320ffde
3 files changed
+34 -5

No files matched your search

+16 -2
View File
@@ -98,8 +98,15 @@ class CallGenDispatch(CallGenBase.CallGenBase):
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
"""c.Deref/Asm/LLVMIR 等特殊调用(未命中返回 None)"""
can: t.CSizeT,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""c.Deref/Asm/LLVMIR 等特殊调用(未命中返回 None)
hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为 c.* 特殊调用)。
仅对 c.Asm/c.LLVMIR 等返回 None(void,无返回值)的调用置位——
translate_c_asm/translate_c_llvmir 成功处理 void 时返回 None,
若不加 hit_box 会被 translate_call 误判为"未命中"继续走外部函数路径。
"""
# 检测 c.Deref / c.DerefAs / c.Addr 等特殊调用(内联 IR,不生成 call)
if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute:
at_node: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl.func)
@@ -119,8 +126,15 @@ class CallGenDispatch(CallGenBase.CallGenBase):
elif string.strcmp(func_name, "Load") == 0:
return ExprCallDeref.translate_c_load(pool, builder, mod, cl, trans)
elif string.strcmp(func_name, "Asm") == 0:
# c.Asm 无输出(void)时 translate_c_asm 返回 None:
# 置命中标记,避免 translate_call 误判未命中继续走外部函数
if hit_box is not None:
hit_box[0] = 1
return ExprCallDeref.translate_c_asm(pool, builder, mod, cl, trans)
elif string.strcmp(func_name, "LLVMIR") == 0:
# c.LLVMIR 总是无返回值(返回 None):置命中标记
if hit_box is not None:
hit_box[0] = 1
return ExprCallDeref.translate_c_llvmir(pool, builder, mod, cl, trans)
elif string.strcmp(func_name, "LInp") == 0 or string.strcmp(func_name, "LOut") == 0:
# c.LInp/c.LOut 独立调用时返回 0(仅在 c.LLVMIR 的 f-string 内有意义)
+15 -1
View File
@@ -156,10 +156,24 @@ class CallGenMixin(CallGenBase.CallGenBase):
return ExprCallCtor._translate_t_type_cast(pool, builder, binop_arg_val, binop_ty)
return None
# c.Asm/c.LLVMIR 等特殊调用:void(无输出)时 translate_c_asm/llvmir
# 返回 None 表示"已处理无返回值",需用 hit_box 区分"未命中",
# 否则会误判未命中继续走外部函数路径(外部函数返回类型未登记 Asm +
# t.ASM_DESCR 被当 CDefine 常量赋值)
h2_hit: t.CPtr = stdlib.malloc(4)
if h2_hit is not None:
h2_hit[0] = 0
_tc_h2_c_special_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h2_c_special(
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, h2_hit)
h2_hit_val: int = 0
if h2_hit is not None:
h2_hit_val = h2_hit[0]
stdlib.free(h2_hit)
if _tc_h2_c_special_res is not None:
return _tc_h2_c_special_res
if h2_hit_val != 0:
# 命中 c.Asm/c.LLVMIR 但无返回值(void):视为已处理
return None
_tc_h3_stdarg_cast_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h3_stdarg_cast(
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
+3 -2
View File
@@ -163,12 +163,13 @@ def _tc_h2_c_special(pool: memhub.MemBuddy | t.CPtr,
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
can: t.CSizeT,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""c.Deref/Asm/LLVMIR 等特殊调用(委托到 gen._tc_h2_c_special)"""
import lib.core.Gen.Generator as Generator
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
if g is not None:
return g._tc_h2_c_special(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
return g._tc_h2_c_special(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, hit_box)
return None
def _tc_h3_stdarg_cast(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,