feat(gen): ListTest 联合下标修复 + DocTest docstring 完整保留
- CallGenMixin: 默认参数快照无条件查询、静态类调用识别、len() 走 __len__ - TypeGenMixin/AssignGenMixin: T | t.CPtr 泛型标量元素宽度修复 - ExprGenMixin: / → __truediv__、指针判空走 icmp null、__doc__ 完整保留(登记表+跨模块符号解析) - BuildPipeline: 翻译后提取模块 docstring(预注册阶段跨模块可用) - Generator: DocKeys/DocValues/DocCount 登记表字段
This commit is contained in:
1 parent
83d46dd646
commit
882c78c67a
6 files changed
+394
-16
No files matched your search
@@ -357,10 +357,27 @@ class AssignGenMixin:
|
||||
if self._annotation_contains_name(annot, "bytes") != 0:
|
||||
return 1
|
||||
# 泛型类型参数/嵌套联合 | t.CPtr(如 _list.vp 的 elem_ptr: T | t.CPtr):
|
||||
# T 特化后为具体类型(AST|t.CPtr 等指针),联合在解析时可能退化为 i8*,
|
||||
# 但元素是 8 字节指针,下标必须按 8 字节步长访问——
|
||||
# 否则 list.get/append 只读写 1 字节,指针被截断 inttoptr 崩溃。
|
||||
# 先经泛型上下文解析 T 的具体类型——纯标量(int/float 等 sizeof≠8)时
|
||||
# 元素按标量自身大小(list[int] elem_size=4 匹配 i32),不能按 8 字节
|
||||
# 指针槽(否则 8 字节写 / 4 字节步长互相覆盖,pop 读到 0);
|
||||
# 指针/嵌套联合/64 位标量/double(sizeof==8)才按 8 字节。
|
||||
if self._is_generic_tp_or_nested(bop.left) != 0 or self._is_generic_tp_or_nested(bop.right) != 0:
|
||||
gp_nm: str = None
|
||||
if bop.left is not None and bop.left.kind() == ast.ASTKind.Name:
|
||||
gp_left_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(bop.left)
|
||||
gp_nm = gp_left_nm.id
|
||||
elif bop.right is not None and bop.right.kind() == ast.ASTKind.Name:
|
||||
gp_right_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(bop.right)
|
||||
gp_nm = gp_right_nm.id
|
||||
if gp_nm is not None:
|
||||
# 经全局 gen 委托解析泛型参数(T → 具体类型名)。不能 self.GenericTpNames
|
||||
# 直读(Mixin @t.NoVTable 静态绑定:字段声明在 TypeGenMixin,AssignGenMixin
|
||||
# 访问会生成不存在的属性引用 → TPC fast-fail 编译崩溃)
|
||||
gp_resolved: str = HandlesType.resolve_generic_type_name(gp_nm)
|
||||
if gp_resolved is not None and string.strcmp(gp_resolved, gp_nm) != 0:
|
||||
# 泛型参数解析为纯标量 → 元素按标量自身大小(非 8 字节指针槽)
|
||||
if self._is_scalar_ty_name(gp_resolved) != 0:
|
||||
return 0
|
||||
return 1
|
||||
# 64 位标量数值类型 | CPtr(如 CUInt64T | CPtr / CSizeT | CPtr):
|
||||
# 联合解析后同样退化为指针表示,元素为 8 字节(i64 或指针)。
|
||||
@@ -393,6 +410,33 @@ class AssignGenMixin:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def _is_scalar_ty_name(self, ty_name: str) -> int:
|
||||
"""判断类型名是否为纯标量(不含指针标记),用于泛型 T 的联合元素类型判定
|
||||
|
||||
泛型 T | t.CPtr(如 _list.vp 的 elem_ptr)经 Fix A(TypeGenMixin 联合
|
||||
解析保留泛型标量)后 alloca 变 Ptr(标量):T 为纯标量(int/float/double/
|
||||
i64 等)时下标按标量自身大小步长,不能再按 8 字节指针槽——否则
|
||||
Ptr(标量) alloca + IsPtrElement 路径(load 标量当指针)产生非法 IR。
|
||||
指针/联合/str/bytes 才保持 8 字节指针槽语义。
|
||||
"""
|
||||
if ty_name is None:
|
||||
return 0
|
||||
if string.strchr(ty_name, '|') is not None:
|
||||
return 0
|
||||
if string.strchr(ty_name, '*') is not None:
|
||||
return 0
|
||||
if string.strcmp(ty_name, "str") == 0:
|
||||
return 0
|
||||
if string.strcmp(ty_name, "bytes") == 0:
|
||||
return 0
|
||||
if string.strcmp(ty_name, "t.CPtr") == 0:
|
||||
return 0
|
||||
if string.strcmp(ty_name, "CPtr") == 0:
|
||||
return 0
|
||||
if string.strstr(ty_name, "Ptr") is not None:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def _is_generic_tp_or_nested(self, node: ast.AST | t.CPtr) -> int:
|
||||
"""判断注解节点是否为泛型类型参数名(单字母大写,如 T)或嵌套联合(BinOp)"""
|
||||
if node is None:
|
||||
|
||||
Reference in new issue
Block a user