fix(gentype): CTypedef/注解类型名处理改用 ast 字段访问器,修 stdint.vp 访问违规崩溃
断点确认 AnnAssign 字段地址全部合理(stub 字段访问正常),崩溃在 _is_ctypedef_annotation / _get_type_name_from_annotation 对 Attribute. attr/Name.id 等字段的访问(跨模块 stub GEP 偏移错 → strcmp 读垃圾 0xC0000005)。改用 ast.name_get_id/attribute_get_attr/attribute_get_ value/binop_get_*/constant_get_str_val 访问器(ast 模块完整类型内读取)。 并加 kind() 虚调用断点,若 vtable 错可立即确认。
This commit is contained in:
1 parent
2847d358c8
commit
7a7c3939db
2 files changed
+38
-22
No files matched your search
@@ -130,19 +130,30 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
"""
|
||||
if annotation is None:
|
||||
return 0
|
||||
if annotation.kind() != ast.ASTKind.Attribute:
|
||||
# 诊断(stdint.vp 崩溃定位):kind() 是 @t.CVTable 虚调用,若节点
|
||||
# vtable 指针错会直接 0xC0000005——打印确认虚调用是否正常。
|
||||
stdio.printf("[DIAG] ctypedef 检查: ann=%llu\n", t.CUInt64T(annotation))
|
||||
k_v: int = annotation.kind()
|
||||
stdio.printf("[DIAG] ctypedef 检查: kind=%d\n", k_v)
|
||||
if k_v != ast.ASTKind.Attribute:
|
||||
return 0
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(annotation)
|
||||
if at.attr is None:
|
||||
# 字段访问改用 ast 模块访问器(跨模块 stub 字段访问陷阱防护:
|
||||
# TypeGenCType 直接访问 at.attr 可能按 stub 类型生成错误 GEP,
|
||||
# 读垃圾地址 → strcmp 0xC0000005 崩溃,stdint.vp 根因)。
|
||||
at_attr_v: str = ast.attribute_get_attr(at)
|
||||
if at_attr_v is None:
|
||||
return 0
|
||||
if string.strcmp(at.attr, "CTypedef") != 0:
|
||||
if string.strcmp(at_attr_v, "CTypedef") != 0:
|
||||
return 0
|
||||
if at.value is None or at.value.kind() != ast.ASTKind.Name:
|
||||
at_val_v: ast.AST | t.CPtr = ast.attribute_get_value(at)
|
||||
if at_val_v is None or at_val_v.kind() != ast.ASTKind.Name:
|
||||
return 0
|
||||
mod_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at.value)
|
||||
if mod_nm.id is None:
|
||||
mod_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at_val_v)
|
||||
mod_id_v: str = ast.name_get_id(mod_nm)
|
||||
if mod_id_v is None:
|
||||
return 0
|
||||
if string.strcmp(mod_nm.id, "t") != 0:
|
||||
if string.strcmp(mod_id_v, "t") != 0:
|
||||
return 0
|
||||
return 1
|
||||
def ScanCTypedefDeclarations(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
@@ -188,7 +199,8 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
if aa.target is None or aa.target.kind() != ast.ASTKind.Name:
|
||||
continue
|
||||
tgt: ast.Name | t.CPtr = (ast.Name | t.CPtr)(aa.target)
|
||||
if tgt.id is None:
|
||||
tgt_id_v: str = ast.name_get_id(tgt)
|
||||
if tgt_id_v is None:
|
||||
continue
|
||||
# 提取类型表达式字符串(从 value AST 节点)
|
||||
if aa.value is None:
|
||||
@@ -197,7 +209,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
if type_str is None:
|
||||
continue
|
||||
# 注册 CTypedef
|
||||
self.register_ctypedef(pool, tgt.id, type_str)
|
||||
self.register_ctypedef(pool, tgt_id_v, type_str)
|
||||
count += 1
|
||||
return count
|
||||
def _eval_const_int_expr(self, node: ast.AST | t.CPtr,
|
||||
|
||||
@@ -47,37 +47,41 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# Constant: 字符串注解,直接返回字符串值
|
||||
if k == ast.ASTKind.Constant:
|
||||
cn: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(node)
|
||||
if cn.const_kind == ast.CONST_STR and cn.str_val is not None:
|
||||
return cn.str_val
|
||||
cn_val_v: str = ast.constant_get_str_val(cn)
|
||||
if cn.const_kind == ast.CONST_STR and cn_val_v is not None:
|
||||
return cn_val_v
|
||||
return None
|
||||
# Name: 直接返回 id(泛型特化上下文内先做 T 替换,避免 ndarray[T] 中 T 未解析
|
||||
# 导致 _specialize_generic_class("ndarray", ["T"]) 二次递归崩溃)
|
||||
if k == ast.ASTKind.Name:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
|
||||
return HandlesType.resolve_generic_type_name(nm.id)
|
||||
return HandlesType.resolve_generic_type_name(ast.name_get_id(nm))
|
||||
# Attribute: 构造 "module.attr" 格式
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
|
||||
if at.attr is None:
|
||||
at_attr_v: str = ast.attribute_get_attr(at)
|
||||
if at_attr_v is None:
|
||||
return None
|
||||
if at.value is not None and at.value.kind() == ast.ASTKind.Name:
|
||||
mod_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at.value)
|
||||
if mod_nm.id is not None:
|
||||
total: t.CSizeT = string.strlen(mod_nm.id) + 1 + string.strlen(at.attr) + 1
|
||||
at_val_v: ast.AST | t.CPtr = ast.attribute_get_value(at)
|
||||
if at_val_v is not None and at_val_v.kind() == ast.ASTKind.Name:
|
||||
mod_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at_val_v)
|
||||
mod_id_v: str = ast.name_get_id(mod_nm)
|
||||
if mod_id_v is not None:
|
||||
total: t.CSizeT = string.strlen(mod_id_v) + 1 + string.strlen(at_attr_v) + 1
|
||||
buf: str = pool.alloc(total)
|
||||
if buf is not None:
|
||||
buf[0] = '\0'
|
||||
string.strcat(buf, mod_nm.id)
|
||||
string.strcat(buf, mod_id_v)
|
||||
string.strcat(buf, ".")
|
||||
string.strcat(buf, at.attr)
|
||||
string.strcat(buf, at_attr_v)
|
||||
return buf
|
||||
return at.attr
|
||||
return at_attr_v
|
||||
# BinOp (BitOr): 构造 "left|right" 格式
|
||||
if k == ast.ASTKind.BinOp:
|
||||
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
||||
if bop.op == ast.OpKind.BitOr:
|
||||
left_str: str = self._get_type_name_from_annotation(pool, bop.left)
|
||||
right_str: str = self._get_type_name_from_annotation(pool, bop.right)
|
||||
left_str: str = self._get_type_name_from_annotation(pool, ast.binop_get_left(bop))
|
||||
right_str: str = self._get_type_name_from_annotation(pool, ast.binop_get_right(bop))
|
||||
if left_str is not None and right_str is not None:
|
||||
total2: t.CSizeT = string.strlen(left_str) + 1 + string.strlen(right_str) + 1
|
||||
buf2: str = pool.alloc(total2)
|
||||
|
||||
Reference in new issue
Block a user