From 0a108e62894606be43df387632150e87f8a369e2 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 11 Sep 2026 21:33:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(tpv):=20=E5=88=A0=E9=99=A4=20FuncEntry?= =?UTF-8?q?.TypeStr=20=E6=97=A7=E8=B7=AF=E5=BE=84=EF=BC=8C=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E7=B1=BB=E5=9E=8B=E6=96=87=E6=9C=AC=E6=94=B9=E7=94=B1?= =?UTF-8?q?=20Spec=20=E6=B4=BE=E7=94=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删 FuncEntry.TypeStr 字段、_build_func_type_str 生产者、_check_func_spec_text 闸门 - update_global_func_typestr 改名 update_global_func_spec,仅填 Spec(去 pool 参数) - ClassGenVTable vtable 合并 func_valid 分支,统一 SpecToLLVMText 派生 - 同步 FuncGenDef/ClassGenVTable/GenApi/VpiReader 调用点 --- App/lib/Stub/StubGen/VpiReader.vp | 16 ++-- App/lib/core/Gen/Call/CallGenLeafKit.vp | 114 +++-------------------- App/lib/core/Gen/Class/ClassGenVTable.vp | 66 ++----------- App/lib/core/Gen/Func/FuncGenDef.vp | 12 +-- App/lib/core/Gen/GenApi.vp | 11 +-- App/lib/core/Gen/GenTypes.vp | 6 +- App/lib/core/Gen/Type/TypeSpec.vp | 4 +- 7 files changed, 44 insertions(+), 185 deletions(-) diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 4afa1ce..43a1d26 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -2349,10 +2349,10 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr, if GenApi.add_func_to_table(funcs_ptr, cur_count, fd.name, func, max_funcs, fd_defaults, fd_default_count, param_count, None, src_sha1) == 0: trans._func_count = cur_count + 1 - # 补全全局函数表 TypeStr(参数已全部添加,对齐 FuncGenDef L211 行为): - # vpi 注入路径若不补全,跨模块 vtable/调用解析 find_func_entry_global() - # 时 TypeStr 为空 → "vtable 方法找不到函数实现"(依赖模块晚于本模块编译时必现) - GenApi.update_global_func_typestr(pool, fd.name, func) + # 补全全局函数表 Spec(参数已全部添加,对齐 FuncGenDef 行为): + # vpi 注入路径若不补全,跨模块 vtable 生成 find_func_entry_global() + # 时 Spec 为空 → "vtable 方法找不到函数类型"(依赖模块晚于本模块编译时必现) + GenApi.update_global_func_spec(fd.name, func) # ============================================================ @@ -2541,11 +2541,11 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr, if GenApi.add_func_to_table(funcs_ptr, cur_count, lookup_name, func, max_funcs, md_defaults, md_default_count, param_count_no_self, None, src_sha1) == 0: trans._func_count = cur_count + 1 - # 补全全局函数表 TypeStr(参数已全部添加,对齐 ClassGenVTable L832 行为): - # vpi 注入的方法声明若不补全 TypeStr,跨模块继承 vtable 生成时 - # find_func_entry_global().TypeStr 为空 → "vtable 方法找不到函数实现" + # 补全全局函数表 Spec(参数已全部添加,对齐 ClassGenVTable 行为): + # vpi 注入的方法声明若不补全 Spec,跨模块继承 vtable 生成时 + # find_func_entry_global().Spec 为空 → "vtable 方法找不到函数类型" # (astaux.vp 先于 ast.base.vp 编译时必现:AST.accept 仅有 vpi 注入条目) - GenApi.update_global_func_typestr(pool, lookup_name, func) + GenApi.update_global_func_spec(lookup_name, func) # ============================================================ diff --git a/App/lib/core/Gen/Call/CallGenLeafKit.vp b/App/lib/core/Gen/Call/CallGenLeafKit.vp index caf5d3a..b3eed92 100644 --- a/App/lib/core/Gen/Call/CallGenLeafKit.vp +++ b/App/lib/core/Gen/Call/CallGenLeafKit.vp @@ -1003,7 +1003,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): defaults: ast.Arguments.defaults 列表节点指针,None=无默认值 default_count: 默认值数量(len(defaults)) param_count: 形参数量(不含 self,len(args.args)) - pool: 内存池(用于生成 TypeStr;None 时 TypeStr 为空,vtable 回退读 Func 对象) + pool: 内存池(保留兼容参数;Spec 由 arena/PermPool 分配) """ if name is None or func is None or funcs is None: return 1 @@ -1017,7 +1017,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): entry.Defaults = defaults entry.DefaultCount = default_count entry.ParamCount = param_count - # [S3 条目双写] Spec 在形参 add_param 完成后由 update_global_func_typestr 填 + # [S3 条目双写] Spec 在形参 add_param 完成后由 update_global_func_spec 填 entry.Spec = None # 同时注册到全局函数表(供跨模块 vtable 初始化查找) self._register_global_func(name, func, pool) @@ -1040,67 +1040,11 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 1 - def _build_func_type_str(self, pool: memhub.MemBuddy | t.CPtr, - func: llvmlite.Function | t.CPtr) -> str: - """生成函数类型文本(stdlib 分配)""" - if func is None: - return None - # 类型文本可能较长(SHA1 限定命名结构体 + 多参数),用 1024 缓冲 - ty_buf: str = pool.alloc(1024) - if ty_buf is None: - return None - ty_buf[0] = '\0' - - # 返回类型 - ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.function_get_ret_ty(func) - ret_part: str = pool.alloc(512) - if ret_part is not None and ret_ty is not None: - ret_part[0] = '\0' - llvmlite.TypePrint(ret_part, 512, ret_ty, pool) - self._asm_append_cstr(ty_buf, 1024, ret_part) - self._asm_append_cstr(ty_buf, 1024, " (") - - # 参数类型(全部经 _asm_append_cstr 有界追加,防止 strcat 无界写穿 1024 缓冲) - cur: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(func) - first: int = 1 - param_part: str = pool.alloc(512) - while cur is not None: - if first == 0: - self._asm_append_cstr(ty_buf, 1024, ", ") - if param_part is not None: - param_part[0] = '\0' - param_ty: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(cur) - if param_ty is not None: - llvmlite.TypePrint(param_part, 512, param_ty, pool) - self._asm_append_cstr(ty_buf, 1024, param_part) - cur = llvmlite.param_get_next(cur) - first = 0 - # 变参函数追加 ...(对齐 llvmlite IR 打印规则,见 includes/llvmlite/__function.vp - # L1145-1150:有参数时 ", ...",无参数时 "...")。此前遗漏 → 跨模块继承方法的 - # vtable 回退路径(ClassGenVTable 对继承方法强制 func_valid=0,只能用本文本) - # 生成的函数类型缺 ...,与真实签名不符(本函数为 TypeStr 的唯一生产者)。 - if func.IsVarArg == 1: - if first != 0: - self._asm_append_cstr(ty_buf, 1024, "...") - else: - self._asm_append_cstr(ty_buf, 1024, ", ...") - self._asm_append_cstr(ty_buf, 1024, ")") - - # 深拷贝到 stdlib 区(TypeStr 跨文件永久存活) - ts_len: sizet = string.strlen(ty_buf) - ts_copy: str = CompilerFactory.factory.PermPool.alloc(ts_len + 1) - if ts_copy is None: - return None - string.strcpy(ts_copy, ty_buf) - return ts_copy - - def _register_global_func(self, name: str, func: llvmlite.Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr = None) -> int: """注册函数到全局表(已存在则跳过),返回 0 成功 直接操作全局表,不调用 add_func_to_table,避免递归。 - pool 用于生成 TypeStr(None 时 TypeStr 为空)。 """ if name is None or func is None: return 1 @@ -1124,34 +1068,28 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): string.strcpy(name_copy, name) entry.Name = name_copy entry.Func = func - # [S3 条目双写] Spec 待 update_global_func_typestr 填(形参未 add 完) + # [S3 条目双写] Spec 待 update_global_func_spec 填(形参未 add 完) entry.Spec = None - # TypeStr 不在此生成:函数参数在 add_func_to_table 之后才添加, - # 需由调用方在参数添加完成后调用 update_global_func_typestr 补全。 + # Spec 不在此生成:函数参数在 add_func_to_table 之后才添加, + # 需由调用方在参数添加完成后调用 update_global_func_spec 补全。 self.GlobalFuncCount += 1 return 0 - def update_global_func_typestr(self, pool: memhub.MemBuddy | t.CPtr, - name: str, - func: llvmlite.Function | t.CPtr) -> int: - """更新全局函数表的 TypeStr(在函数参数全部添加完成后调用) + def update_global_func_spec(self, name: str, + func: llvmlite.Function | t.CPtr) -> int: + """更新全局函数表的 Spec(在函数参数全部添加完成后调用) 调用时机:add_func_to_table 注册后、llvmlite.add_param 全部执行完。 - 生成 ret_ty (param1_ty, ...) 类型文本(stdlib 深拷贝), - 供 vtable 生成在 func 被 1b reset 后使用。 + 用 NewTypeFunc 构造整签名 Spec(PermPool 驻留,跨 1b reset 安全), + 供 vtable 生成在 func 被 1b reset 后经 SpecToLLVMText 派生类型文本。 """ if name is None or func is None: return 1 entry: GenTypes.FuncEntry | t.CPtr = self.find_func_entry_global(name) if entry is None: return 1 - entry.TypeStr = self._build_func_type_str(pool, func) - # [S3 条目双写] 整签名 Spec(与 TypeStr 同源同表;此处形参已全部 add_param) entry.Spec = self._build_func_spec(func) - # [S3 格式化闸门] Spec 侧 LLVM 文本与旧生产者逐字节比对 —— 后续 - # 「删掉 _build_func_type_str、TypeStr 改由 Spec 派生」的前置实证。 - self._check_func_spec_text(pool, entry) return 0 @@ -1159,7 +1097,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): # _build_func_spec - 由函数对象构造整签名 TypeSpec(S3 条目双写) # # Kind=TS_FUNC:Ret + 形参 Spec 数组 + ParamCount + IsVarArg。必须在形参 - # 全部 add_param 完成后调用(同 _build_func_type_str 的时机)。 + # 全部 add_param 完成后调用。 # 参数沿 `llvmlite.function_get_param_head` 的 Param 链表**两遍遍历**(先计数 # 再填充)——llvmlite 无按下标取参,且无法预知长度以一次分配。 # 注意与 `TSpec.SpecFromLLVMType` 的 Func 分支的区别:后者只能看到 @@ -1207,34 +1145,6 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return TSpec.NewTypeFunc(arena, ret_s, params_arr, cnt, func.IsVarArg) - # ============================================================ - # _check_func_spec_text - 格式化闸门:Spec 侧 LLVM 文本 vs 旧生产者 - # - # 用 `TSpec.SpecToLLVMText(entry.Spec)` 与 `entry.TypeStr`(`_build_func_type_str` - # 经 llvmlite.TypePrint 产出)**逐字节**比对,不一致即 fatal —— 这是"删掉旧生产者、 - # TypeStr 改由 Spec 派生"的前置实证(Debugger/_Type.md:暴露而非静默)。 - # 跳过条件(「不适用」≠「不一致」):Spec 为 None、TypeStr 为 None、 - # 或 SpecToLLVMText 返回 1(如匿名结构体 Spec 未保留字段列表,无法还原 "{...}")。 - # ============================================================ - def _check_func_spec_text(self, pool: memhub.MemBuddy | t.CPtr, - entry: GenTypes.FuncEntry | t.CPtr) -> None: - """Spec 侧 LLVM 文本与旧 TypeStr 一致性比对(闸门)""" - if pool is None or entry is None or entry.Spec is None: - return - if entry.TypeStr is None: - return - spec_txt: str = pool.alloc(1024) - if spec_txt is None: - return - spec_txt[0] = '\0' - if TSpec.SpecToLLVMText(entry.Spec, spec_txt, 1024) != 0: - return - if string.strcmp(entry.TypeStr, spec_txt) == 0: - return - msg: str = f"[S3 格式化闸门] 函数签名文本不一致 旧={entry.TypeStr} 新={spec_txt}" - self.Gen.TypeGenErr.fatal_error(None, msg, "TypeError") - - def find_func_global(self, name: str) -> llvmlite.Function | t.CPtr: """在全局函数表中按名称查找,返回 Function 指针或 None""" if name is None or self.GlobalFuncs is None: @@ -1243,7 +1153,7 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): def find_func_entry_global(self, name: str) -> GenTypes.FuncEntry | t.CPtr: - """在全局函数表中按名称查找,返回完整 FuncEntry(含 TypeStr)或 None""" + """在全局函数表中按名称查找,返回完整 FuncEntry(含 Spec)或 None""" if name is None or self.GlobalFuncs is None: return None entry_size: sizet = GenTypes.FuncEntry.__sizeof__() diff --git a/App/lib/core/Gen/Class/ClassGenVTable.vp b/App/lib/core/Gen/Class/ClassGenVTable.vp index 1734010..6c344cc 100644 --- a/App/lib/core/Gen/Class/ClassGenVTable.vp +++ b/App/lib/core/Gen/Class/ClassGenVTable.vp @@ -355,67 +355,21 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 继承方法: 用父类模块 SHA1 做 mangling parent_sha1: str = (str | t.CPtr)(t.CVoid(parent_sha1_addr, t.CPtr)) mangled_name: str = self.Gen.FuncGenBase._mangle_name_with_sha1(parent_sha1, full_name) - # 从全局函数表查找(跨模块函数不在当前模块表中) - func: llvmlite.Function | t.CPtr = self.Gen.CallGenLeafKit.find_func_global(full_name) else: # 当前类方法: 用当前模块 SHA1 mangled_name: str = self.Gen.FuncGenBase._mangle_name(trans, full_name) - func: llvmlite.Function | t.CPtr = self.Gen.CallGenLeafKit.find_func_in_table( - trans._funcs, trans._func_count, full_name) - # 当前模块表找不到时,回退到全局表 - if func is None: - func = self.Gen.CallGenLeafKit.find_func_global(full_name) - # func 可能已被 1b reset_to(mark1) 回收(跨模块继承方法在定义文件翻译后被 reset)。 - # 悬空指针非 NULL 但内容已被复用,解引用会沿垃圾 Next 链指针追逐导致无限分配。 - # 因此 func 非 NULL 时也须用 _is_valid_ptr 校验,失败回退到全局表 TypeStr。 - func_valid: int = 0 - if func is not None: - if trans.Pool is not None: - # 继承方法(parent_sha1_addr != 0):func 来自其他模块,该模块 1b 翻译 - # 后已被 reset_to(mark1) 回收,_is_valid_ptr 存在假阳性(块头复用后仍 - # 看似有效),直接判定无效走 TypeStr 回退,避免解引用悬空 func 崩溃。 - if parent_sha1_addr != 0: - func_valid = 0 - elif trans.Pool._is_valid_ptr(func) != 0: - func_valid = 1 - if func_valid == 0: - # 回退到全局表完整 entry 的 TypeStr(stdlib 深拷贝,跨文件永久存活)。 - ge: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_global(full_name) - if ge is not None and ge.TypeStr is not None: - self._vtable_strcat(init_buf, 16384, "i8* bitcast (") - self._vtable_strcat(init_buf, 16384, ge.TypeStr) - self._vtable_strcat(init_buf, 16384, "* @") - if self._vtable_name_needs_quote(mangled_name) != 0: - self._vtable_strcat(init_buf, 16384, "\"") - self._vtable_strcat(init_buf, 16384, mangled_name) - self._vtable_strcat(init_buf, 16384, "\"") - else: - self._vtable_strcat(init_buf, 16384, mangled_name) - self._vtable_strcat(init_buf, 16384, " to i8*)") - continue - # fail-fast:func 无效且全局表 TypeStr 回退也失败, - # 不再写 "i8* null" 静默掩盖缺失实现。 - self.Gen.TypeGenErr.fatal_error( - cd, f"vtable 方法 '{full_name}' 找不到函数实现", "InternalCompilerError") - continue - - # 构造函数类型字符串(S3 切读:优先 SpecToLLVMText 派生,回退全局表 TypeStr; - # 替代 _format_func_type_str 那份 512 缓冲 + >100 参截断的 TypePrint 重复实现) + # 统一从全局表 entry.Spec 用 SpecToLLVMText 派生函数类型文本。 + # 全局表 entry.Spec 在方法 add_param 完成后由 update_global_func_spec 填 + # (PermPool 驻留,跨 1b reset 安全),故不再解引用 func(func 可能已被 + # reset_to(mark1) 回收悬空)。 + ge: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_global(full_name) func_ty_buf: str = pool.alloc(1024) if func_ty_buf is None: self._vtable_strcat(init_buf, 16384, "i8* null") continue func_ty_buf[0] = '\0' - ty_ok: int = 0 - spec_entry2: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_global(full_name) - if spec_entry2 is not None and spec_entry2.Spec is not None: - if TSpec.SpecToLLVMText(spec_entry2.Spec, func_ty_buf, 1024) == 0: - ty_ok = 1 - if ty_ok == 0 and spec_entry2 is not None and spec_entry2.TypeStr is not None: - string.strcpy(func_ty_buf, spec_entry2.TypeStr) - ty_ok = 1 - if ty_ok == 0: + if ge is None or ge.Spec is None or TSpec.SpecToLLVMText(ge.Spec, func_ty_buf, 1024) != 0: self.Gen.TypeGenErr.fatal_error( cd, f"vtable 方法 '{full_name}' 找不到函数类型", "InternalCompilerError") continue @@ -827,8 +781,8 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): if i1_ptr_ty_si is not None: llvmlite.add_param(pool, func, i1_ptr_ty_si, "%__stop_iter_flag__") - # 参数添加完成,补全全局函数表的 TypeStr(供 vtable 在 func 被 reset 后使用) - self.Gen.CallGenLeafKit.update_global_func_typestr(pool, full_name, func) + # 参数添加完成,补全全局函数表的 Spec(供 vtable 在 func 被 reset 后派生类型文本) + self.Gen.CallGenLeafKit.update_global_func_spec(full_name, func) # 创建 entry 块 entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry") @@ -1171,8 +1125,8 @@ class ClassGenVTable(ClassGenBase.ClassGenBase): # 添加 self 参数 llvmlite.add_param(pool, func, self_ptr_ty, "%self") - # 参数添加完成,补全全局函数表的 TypeStr - rc_ut: int = self.Gen.CallGenLeafKit.update_global_func_typestr(pool, full_name, func) + # 参数添加完成,补全全局函数表的 Spec + rc_ut: int = self.Gen.CallGenLeafKit.update_global_func_spec(full_name, func) # 创建 entry 块 + builder entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry") diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index 6c99e10..2d76f6f 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -278,8 +278,8 @@ class FuncGenDef(CallGenBase.CallGenBase): if ags.vararg is not None: func.IsVarArg = 1 - # 参数添加完成,补全全局函数表的 TypeStr(供 vtable 在 func 被 reset 后使用) - self.Gen.CallGenLeafKit.update_global_func_typestr(trans.Pool, fd.name, func) + # 参数添加完成,补全全局函数表的 Spec(供 vtable 在 func 被 reset 后派生类型文本) + self.Gen.CallGenLeafKit.update_global_func_spec(fd.name, func) # 泛型函数上下文用完即清(防泄漏到后续函数的注解解析) if tp_names_fd is not None: @@ -546,8 +546,8 @@ class FuncGenDef(CallGenBase.CallGenBase): if func_section_e is not None: llvmlite.function_set_attr_group(func, func_section_e) - # 参数添加完成,补全全局函数表的 TypeStr - self.Gen.CallGenLeafKit.update_global_func_typestr(pool, fd.name, func) + # 参数添加完成,补全全局函数表的 Spec + self.Gen.CallGenLeafKit.update_global_func_spec(fd.name, func) return 0 @@ -662,8 +662,8 @@ class FuncGenDef(CallGenBase.CallGenBase): llvmlite.add_param(pool, func, i8_ptr_ptr_ty_eh, "%__eh_msg_out__") llvmlite.add_param(pool, func, i32_ptr_ty_eh, "%__eh_code_out__") - # 参数添加完成,补全全局函数表的 TypeStr - self.Gen.CallGenLeafKit.update_global_func_typestr(trans.Pool, fd.name, func) + # 参数添加完成,补全全局函数表的 Spec + self.Gen.CallGenLeafKit.update_global_func_spec(fd.name, func) # 创建 entry 块 entry_blk: llvmlite.BasicBlock | t.CPtr = llvmlite.create_block(pool, func, "entry") diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index 3eab20b..95b0e75 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -577,11 +577,10 @@ def clear_scope_names(trans: HT.Translator | t.CPtr): _g_gen.TranslatorGen.clear_scope_names(trans) -# ---------------- update_global_func_typestr(委托 CallGenLeafKit.update_global_func_typestr) ---------------- -def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr, - name: str, - func: llvmlite.Function | t.CPtr) -> int: - """委托到 gen.CallGenLeafKit.update_global_func_typestr(原 ExprCallTable 壳)""" +# ---------------- update_global_func_spec(委托 CallGenLeafKit.update_global_func_spec) ---------------- +def update_global_func_spec(name: str, + func: llvmlite.Function | t.CPtr) -> int: + """委托到 gen.CallGenLeafKit.update_global_func_spec(原 ExprCallTable 壳)""" if _g_gen is not None: - return _g_gen.CallGenLeafKit.update_global_func_typestr(pool, name, func) + return _g_gen.CallGenLeafKit.update_global_func_spec(name, func) return 0 diff --git a/App/lib/core/Gen/GenTypes.vp b/App/lib/core/Gen/GenTypes.vp index e30f400..85824e0 100644 --- a/App/lib/core/Gen/GenTypes.vp +++ b/App/lib/core/Gen/GenTypes.vp @@ -182,12 +182,8 @@ class FuncEntry: Defaults: t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值 DefaultCount: int # 默认值数量 ParamCount: int # 形参数量(不含 self) - # TypeStr: 函数类型文本(stdlib 深拷贝,跨文件安全) - # 1b 每文件 reset_to(mark1) 回收 pool 内 Function 对象后, - # vtable 生成 find_func_global 读类型改用此文本,避免悬空。 - TypeStr: str # TypeSpec(S3 条目双写):Kind=TS_FUNC 的**整签名**(Ret/Params/ParamCount/ - # IsVarArg 都在其内),由 update_global_func_typestr 在形参 add_param 完成后 + # IsVarArg 都在其内),由 update_global_func_spec 在形参 add_param 完成后 # 用 NewTypeFunc 构造(含 func.IsVarArg)。PermPool 驻留 ⇒ 跨 1b reset 安全。 # 说明:设计 D4 原写 RetSpec+ParamSpecs 两字段,此处合并为单个 Spec —— 单字段 # 即可完整表达签名,且与 VarEntry/FieldEntry 的 Spec 命名一致,避免参数数组重复。 diff --git a/App/lib/core/Gen/Type/TypeSpec.vp b/App/lib/core/Gen/Type/TypeSpec.vp index 7289938..c05ca20 100644 --- a/App/lib/core/Gen/Type/TypeSpec.vp +++ b/App/lib/core/Gen/Type/TypeSpec.vp @@ -865,8 +865,8 @@ def SpecTypePtrLevel(ty: llvmlite.LLVMType | t.CPtr) -> int: # ============================================================ # SpecToLLVMText - TypeSpec → LLVM IR 类型文本(**逐字节对齐 llvmlite.TypePrint**) # -# 用途:让 `FuncEntry.TypeStr` 改由 Spec 派生(随后即可删掉字符串生产者), -# 推进去字符串化(Debugger/_Type.md D14 起)。当前阶段先用作**比对闸门**。 +# 用途:作为 FuncEntry.Spec 的 LLVM 文本派生源(旧 FuncEntry.TypeStr 字符串生产者 +# 已在 S4 删除),推进去字符串化(Debugger/_Type.md D14 起)。 # # 对齐依据:`includes/llvmlite/__types.vp:395-511` 的 `_TypePrintDepth`,逐分支照搬: # Int(bits) → "iN"(**无符号也是 iN** —— LLVM 文本层不分符号)