refactor(tpv): ClassGenVTable vtable 类型文本切到 SpecToLLVMText
- 删除 _format_func_type_str(512 缓冲 + >100 参截断的 TypePrint 重复实现) - _generate_vtable 当前类方法分支改为 SpecToLLVMText 派生,回退全局表 TypeStr - Spec/TypeStr 皆失败时 fail-fast
This commit is contained in:
1 parent
0e973d5f23
commit
a173ba0296
1 file changed
+19
-56
@@ -1,4 +1,5 @@
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import lib.core.Gen.Type.TypeSpec as TSpec
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
@@ -65,56 +66,6 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
return 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _format_func_type_str — 从 Function 对象生成函数类型字符串
|
||||
#
|
||||
# 格式: ret_ty (param1_ty, param2_ty, ...)
|
||||
# 例如: void ({i32, i32}*, i32)
|
||||
# ============================================================
|
||||
def _format_func_type_str(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
buf: str, buf_size: sizet,
|
||||
func: llvmlite.Function | t.CPtr) -> int:
|
||||
"""从 Function 对象生成函数类型字符串"""
|
||||
if buf is None or func is None or buf_size == 0:
|
||||
return 0
|
||||
buf[0] = '\0'
|
||||
# 打印返回类型(使用访问器函数避免跨模块直接字段访问)
|
||||
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.function_get_ret_ty(func)
|
||||
ret_buf: str = pool.alloc(128)
|
||||
if ret_buf is not None and ret_ty is not None:
|
||||
ret_buf[0] = '\0'
|
||||
llvmlite.TypePrint(ret_buf, 128, ret_ty, pool)
|
||||
self._vtable_strcat(buf, buf_size, ret_buf)
|
||||
self._vtable_strcat(buf, buf_size, " (")
|
||||
|
||||
# 遍历参数(使用访问器函数避免跨模块直接字段访问)
|
||||
cur: llvmlite.Param | t.CPtr = llvmlite.function_get_param_head(func)
|
||||
first: int = 1
|
||||
param_buf: str = pool.alloc(128)
|
||||
_pc: int = 0
|
||||
while cur is not None:
|
||||
_pc += 1
|
||||
if _pc > 100:
|
||||
break
|
||||
if first == 0:
|
||||
self._vtable_strcat(buf, buf_size, ", ")
|
||||
if param_buf is not None:
|
||||
param_buf[0] = '\0'
|
||||
param_ty: llvmlite.LLVMType | t.CPtr = llvmlite.param_get_ty(cur)
|
||||
if param_ty is not None:
|
||||
llvmlite.TypePrint(param_buf, 128, param_ty, pool)
|
||||
self._vtable_strcat(buf, buf_size, param_buf)
|
||||
cur = llvmlite.param_get_next(cur)
|
||||
first = 0
|
||||
# 变参函数追加 ...(对齐 llvmlite IR 打印规则与 CallGenLeafKit._build_func_type_str:
|
||||
# 有参数时 ", ...",无参数时 "...")。此前遗漏 → 该回退文本生成的函数类型缺 ...。
|
||||
if func.IsVarArg == 1:
|
||||
if first != 0:
|
||||
self._vtable_strcat(buf, buf_size, "...")
|
||||
else:
|
||||
self._vtable_strcat(buf, buf_size, ", ...")
|
||||
self._vtable_strcat(buf, buf_size, ")")
|
||||
return 1
|
||||
# ============================================================
|
||||
# _collect_vtable_methods — 收集类的虚方法信息
|
||||
#
|
||||
# 1. 继承父类虚方法(父类方法排在子类方法之前,保持槽位顺序一致)
|
||||
@@ -416,9 +367,8 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
func = self.Gen.CallGenLeafKit.find_func_global(full_name)
|
||||
|
||||
# func 可能已被 1b reset_to(mark1) 回收(跨模块继承方法在定义文件翻译后被 reset)。
|
||||
# 悬空指针非 NULL 但内容已被复用,_format_func_type_str 解引用会沿垃圾 Next 链
|
||||
# 指针追逐导致无限分配(TypePrint 每次 pool.alloc(512) → 单文件暴涨 900MB OOM)。
|
||||
# 因此 func 非 NULL 时也须用 _is_valid_ptr 校验,失败回退到 TypeStr。
|
||||
# 悬空指针非 NULL 但内容已被复用,解引用会沿垃圾 Next 链指针追逐导致无限分配。
|
||||
# 因此 func 非 NULL 时也须用 _is_valid_ptr 校验,失败回退到全局表 TypeStr。
|
||||
func_valid: int = 0
|
||||
if func is not None:
|
||||
if trans.Pool is not None:
|
||||
@@ -450,12 +400,25 @@ class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
cd, f"vtable 方法 '{full_name}' 找不到函数实现", "InternalCompilerError")
|
||||
continue
|
||||
|
||||
# 构造函数类型字符串
|
||||
func_ty_buf: str = pool.alloc(512)
|
||||
# 构造函数类型字符串(S3 切读:优先 SpecToLLVMText 派生,回退全局表 TypeStr;
|
||||
# 替代 _format_func_type_str 那份 512 缓冲 + >100 参截断的 TypePrint 重复实现)
|
||||
func_ty_buf: str = pool.alloc(1024)
|
||||
if func_ty_buf is None:
|
||||
self._vtable_strcat(init_buf, 16384, "i8* null")
|
||||
continue
|
||||
self._format_func_type_str(pool, func_ty_buf, 512, func)
|
||||
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:
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
cd, f"vtable 方法 '{full_name}' 找不到函数类型", "InternalCompilerError")
|
||||
continue
|
||||
|
||||
# 构造 bitcast 字符串: i8* bitcast (func_ty* @mangled to i8*)
|
||||
self._vtable_strcat(init_buf, 16384, "i8* bitcast (")
|
||||
|
||||
Reference in new issue
Block a user