From 4f95867209471c57d3cbb63cb648a46e45007f73 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 18 Aug 2026 08:26:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(llvmlite):=20PrintModule=20param=5Fscan=20?= =?UTF-8?q?=E6=94=B9=E7=94=A8=E8=AE=BF=E9=97=AE=E5=99=A8=E7=BB=95=E5=BC=80?= =?UTF-8?q?=20stub=20=E5=AD=97=E6=AE=B5=E8=AE=BF=E9=97=AE=E9=99=B7?= =?UTF-8?q?=E9=98=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit printf.fmt Param 创建后 next=0(正常)、dump_ir 诊断访问器读 next=0, 但 PrintModule 直接访问 param_scan.Next 遍历超限死循环——同一指针两次 读取结果不同,指向跨模块 stub 字段访问生成错误 GEP/静默跳过 (param_scan 永不更新 → 死循环)。param_scan 遍历改用 param_get_next/ param_get_ty(__function.vp 完整类型内读取),并打印首节点 param/next 供对比验证。 --- includes/llvmlite/__module.vp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/includes/llvmlite/__module.vp b/includes/llvmlite/__module.vp index 0ba5cff..39ed6e3 100644 --- a/includes/llvmlite/__module.vp +++ b/includes/llvmlite/__module.vp @@ -7,7 +7,7 @@ import viperlib import memhub from linkedlist import GSList, GSListNode from .__types import LLVMType, TypePrint, Array, PrintStructDefinition, get_struct_name, Struct, ParamNode -from .__function import Function, FunctionPrint, _ll_name_needs_quote, Param +from .__function import Function, FunctionPrint, _ll_name_needs_quote, Param, param_get_next, param_get_ty # ============================================================ @@ -239,15 +239,25 @@ class LLVMModule: if func_scan.Params is not None: param_scan: Param | t.CPtr = func_scan.Params.Head param_scan_steps: t.CSizeT = 0 + if param_scan is not None: + # 诊断(builtins.vp dump 卡死根因排查):对比访问器与 + # 直接字段访问的 param0/next——stub 字段访问若生成错误 + # GEP 会读到垃圾导致死循环。 + stdio.printf("[DIAG] param_scan 首节点: param=%llu next=%llu(函数名=%s)\n", + t.CUInt64T(param_scan), t.CUInt64T(param_scan.Next), func_scan.Name) while param_scan is not None: param_scan_steps += 1 if param_scan_steps > IR_DUMP_CHAIN_LIMIT: - stdio.printf("[IR-DUMP] 链表异常: func params(函数名=%s,Params.Count=%zu,遍历超 %d 步,终止)\n", - func_scan.Name, func_scan.Params.Count, IR_DUMP_CHAIN_LIMIT) + stdio.printf("[IR-DUMP] 链表异常: func params(函数名=%s,Params.Count=%zu,param=%llu next=%llu,遍历超 %d 步,终止)\n", + func_scan.Name, func_scan.Params.Count, + t.CUInt64T(param_scan), t.CUInt64T(param_scan.Next), IR_DUMP_CHAIN_LIMIT) stdlib.exit(1) - if param_scan.Ty is not None: - self.ensure_opaque_for_type(pool, param_scan.Ty) - param_scan = param_scan.Next + # 用访问器(__function.vp 完整类型内)绕开 stub 字段访问 + # 陷阱:跨模块 struct 字段访问可能生成错误 GEP/静默跳过, + # 导致 param_scan 永不更新死循环。 + if param_get_ty(param_scan) is not None: + self.ensure_opaque_for_type(pool, param_get_ty(param_scan)) + param_scan = param_get_next(param_scan) func_scan = func_scan.Next nt: NamedTypeNode | t.CPtr = self.NamedTypeHead # 结构体定义缓冲区:48 字段 × ~50 字节/字段类型名 ≈ 2400 字节,4096 足够