修正了 TPC 的一些错误,包括 Test 维护后 TPV 无法重新编译或重编译后越界的部分问题

This commit is contained in:
2026-07-20 11:12:30 +08:00
parent ab73420b4f
commit a277ded8d4
476 changed files with 4000 additions and 3439 deletions

View File

@@ -860,7 +860,10 @@ class FunctionHandle(BaseHandle):
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name) and node.func.id in type_map:
replacement: str = type_map[node.func.id]
node.func = ast.Name(id=replacement, ctx=ast.Load())
# 使用 _make_replacement_node 处理含点号的类型名(如 't.CUnsignedChar'
# 避免 T(0) 替换为 CUnsignedChar(0) 后因 CUnsignedChar 不在顶层作用域
# 而报 "Undefined function: 'CUnsignedChar'"
node.func = self._make_replacement_node(replacement)
elif isinstance(node.func, ast.Attribute):
if isinstance(node.func.value, ast.Name) and node.func.value.id in type_map:
replacement: str = type_map[node.func.value.id]
@@ -874,7 +877,7 @@ class FunctionHandle(BaseHandle):
right=ast.Attribute(value=ast.Name(id='t', ctx=ast.Load()), attr='CPtr', ctx=ast.Load())
)
else:
node.func.value = ast.Name(id=replacement, ctx=ast.Load())
node.func.value = self._make_name_node(replacement)
else:
self._apply_type_map_to_expr(node.func.value, type_map, cptr_params)
for arg in node.args:
@@ -1630,6 +1633,14 @@ class FunctionHandle(BaseHandle):
saved_var_to_heap_ptr = dict(Gen._var_to_heap_ptr)
Gen._local_heap_ptrs = []
Gen._var_to_heap_ptr = {}
# 治本修复:保存 var_struct_class / global_struct_class。
# 当方法调用(如 a.delete())触发 _try_complete_generic_specialization 时,
# 该路径走 _EmitFunctionLlvm 编译方法体,函数结尾会清空 var_struct_class。
# 若不保存/恢复,外层函数中已设置的 var_struct_class如 b='ndarray[double]'
# 会被清空,导致后续方法调用 fallback 匹配 opaque 基础类型(如 ndarray
# 生成对 stub declare无方法体的调用 → 链接报 undefined reference。
saved_var_struct_class = dict(Gen.var_struct_class) if Gen.var_struct_class else {}
saved_global_struct_class = dict(Gen.global_struct_class) if getattr(Gen, 'global_struct_class', None) else {}
# 函数内部定义的变量会在赋值时添加到 var_type_info 中
# 这样函数内部定义的元类型变量(如 a = t.CInt32T就能被正确处理
for stmt in Node.body:
@@ -1671,6 +1682,13 @@ class FunctionHandle(BaseHandle):
if arg.annotation and isinstance(arg.annotation, ast.BinOp) and isinstance(arg.annotation.op, ast.BitOr):
param_name: str = ParamNames[i] if i < len(ParamNames) else arg.arg
if param_name in Gen.variables:
# 若 L1650-1657 已根据 param.type.pointee 匹配到正确的特化名
# (如 ndarray[double]不覆盖FindStructNameInAnnotation 对
# 泛型注解 ndarray[t.CDouble] 会构造 ndarray[CDouble](与实际
# ndarray[double] 不匹配),回退到裸模板类名 ndarrayopaque
# 导致方法调用查找 ndarray.sum 而非 ndarray[double].sum。
if param_name in Gen.var_struct_class:
continue
found_struct: str | None = FindStructNameInAnnotation(arg.annotation, Gen.structs)
if found_struct:
Gen.var_struct_class[param_name] = found_struct
@@ -1831,6 +1849,11 @@ class FunctionHandle(BaseHandle):
# 恢复外层作用域的 _local_heap_ptrs / _var_to_heap_ptr
Gen._local_heap_ptrs = saved_local_heap_ptrs
Gen._var_to_heap_ptr = saved_var_to_heap_ptr
# 恢复外层作用域的 var_struct_class / global_struct_class
# (内层方法体编译不应污染外层函数的变量-类型映射)
Gen.var_struct_class = saved_var_struct_class
if hasattr(Gen, 'global_struct_class'):
Gen.global_struct_class = saved_global_struct_class
Gen._variadic_info = None
self.Trans._CurrentCpythonObjectClass = saved_cpython_class
self.Trans.CurrentCReturnTypes = None