From 2f3320ffde22f6b60e713402695fa3cee6d27898 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 17 Aug 2026 12:43:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20c.Asm/c.LLVMIR=20void=20=E8=B0=83?= =?UTF-8?q?=E7=94=A8=20hit=5Fbox=20=E5=91=BD=E4=B8=AD=E6=A0=87=E8=AE=B0?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=20StringTest=20=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=8A=A5=20Asm=20=E5=A4=96=E9=83=A8=E5=87=BD=E6=95=B0=E6=9C=AA?= =?UTF-8?q?=E7=99=BB=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 拆分后 _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 时视为已处理直接返回。 --- App/lib/core/Gen/CallGenDispatch.vp | 18 ++++++++++++++++-- App/lib/core/Gen/CallGenMixin.vp | 16 +++++++++++++++- App/lib/core/Handles/ExprCallHandle.vp | 5 +++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/App/lib/core/Gen/CallGenDispatch.vp b/App/lib/core/Gen/CallGenDispatch.vp index f38746c..552611c 100644 --- a/App/lib/core/Gen/CallGenDispatch.vp +++ b/App/lib/core/Gen/CallGenDispatch.vp @@ -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 内有意义) diff --git a/App/lib/core/Gen/CallGenMixin.vp b/App/lib/core/Gen/CallGenMixin.vp index eb485ec..0a6e05a 100644 --- a/App/lib/core/Gen/CallGenMixin.vp +++ b/App/lib/core/Gen/CallGenMixin.vp @@ -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) diff --git a/App/lib/core/Handles/ExprCallHandle.vp b/App/lib/core/Handles/ExprCallHandle.vp index d179567..7524d11 100644 --- a/App/lib/core/Handles/ExprCallHandle.vp +++ b/App/lib/core/Handles/ExprCallHandle.vp @@ -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,