debug(stub): 补全 [DBG-P7] 插桩覆盖所有票名产生路径(定位后删除)

在 96c1102 基础上把"可能产出该票名"的路径一次打全,保证一次重建即可定死根因:

- TypeGenResolve._class_true_def_sha1:MISS 时额外 dump 结构体表里所有名字含
  ClassDef 的条目(下标/名字/归属 sha1/Ty 的 IR 名前缀)——直接看出别名 entry
  到底有没有、挂在哪个 sha1 上。
- TypeGenResolve.extract_class_name_from_annotation:AnnotClassName 通道算出的
  泛型票名(含 ClassDef 才打)。
- TypeGenResolve._resolve_generic_subscript_ty:注解/字段侧算出的泛型特化名
  gen_mangled(含 ClassDef 才打)。
- CallGenCtor._extract_type_args_from_slice:构造函数侧实参串的 raw/norm 两态。
- VpiReader._inject_class_struct_declare:进入 + 各出口
  (already / renum_skip / field_unresolved / zero_fields / registered)。
- VpiReader._inject_reexport_class_declare:调用现场与四个出口
  (already / no_src_entry / alias_reg_fail / alias_ok)。
This commit is contained in:
TermiNexus committed 2026-10-02 00:34:38 +08:00
1 parent 96c110242e
commit 3b8a2b225f
3 files changed
+66 -6

No files matched your search

+28
View File
@@ -2638,7 +2638,9 @@ def _inject_reexport_class_declare(pool: memhub.MemBuddy*,
# [DBG-P7] 临时诊断(定位 ast.ClassDef 票名前缀分裂后删除):只盯 ClassDef,
# 打印"源 entry 是否已注册 / 别名是否已存在"——src_entry=0 即别名必然建不起来
# (上游:子模块 vpi 未注入或该类未被注册)。
_dbg_p7: int = 0
if string.strcmp(local_name, "ClassDef") == 0 or string.strcmp(src_name, "ClassDef") == 0:
_dbg_p7 = 1
_se_dbg: GenTypes.StructEntry* = GenApi.find_struct_by_module(src_name, sub_sha1)
_se_ok_dbg: int = 0
if _se_dbg is not None and _se_dbg.Ty is not None:
@@ -2650,6 +2652,8 @@ def _inject_reexport_class_declare(pool: memhub.MemBuddy*,
src_name, local_name, sub_sha1, pkg_sha1, _se_ok_dbg, _al_dbg)
# 幂等:包 sha1 下 local_name 已注册则跳过(重复 import 不重复注册)
if GenApi.find_struct_by_module(local_name, pkg_sha1) is not None:
if _dbg_p7 != 0:
stdio.printf("[DBG-P7] reexport-res src=%s res=already\n", src_name)
return 1
# 找子模块源 entry(仅类有 entry;函数/常量查不到自然跳过)
src_entry: GenTypes.StructEntry* = GenApi.find_struct_by_module(src_name, sub_sha1)
@@ -2660,11 +2664,18 @@ def _inject_reexport_class_declare(pool: memhub.MemBuddy*,
if _ensure_dep_vpi_injected(pool, mod, sub_sha1, trans) != 0:
src_entry = GenApi.find_struct_by_module(src_name, sub_sha1)
if src_entry is None or src_entry.Ty is None:
if _dbg_p7 != 0:
stdio.printf("[DBG-P7] reexport-res src=%s sub=%s res=no_src_entry\n", src_name, sub_sha1)
return 0
# 注册别名 entry(绕过 register_struct 的 Ty 去重)
if GenApi.register_struct_alias(pool, local_name, pkg_sha1, src_entry) is None:
if _dbg_p7 != 0:
stdio.printf("[DBG-P7] reexport-res src=%s res=alias_reg_fail\n", src_name)
return 0
GenApi.add_visible_struct(pool, local_name)
if _dbg_p7 != 0:
stdio.printf("[DBG-P7] reexport-res src=%s local=%s pkg=%s res=alias_ok\n",
src_name, local_name, pkg_sha1)
return 1
@@ -2791,6 +2802,12 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
flat_buf_c[p_len] = '_'
string.strcpy(flat_buf_c + p_len + 1, cls_name)
real_name = flat_buf_c
# [DBG-P7] 临时诊断(定位 ast.ClassDef 票名前缀分裂后删除):只盯 ClassDef,
# 看注入期到底有没有把该类注册进来、在哪一步退出(字段解析失败/零字段/REnum)。
_dbg_p7c: int = 0
if string.strstr(real_name, "ClassDef") is not None:
_dbg_p7c = 1
stdio.printf("[DBG-P7] cls_inject name=%s src=%s\n", real_name, src_sha1)
# REPL(ReplStubLayoutMode,见文件末"REPL:includes 类完整布局与虚表恢复"):
# 本类若已由 .stub.ll 驱动的路径接管 ⇒ 这里整类让位——已登记(或本遍就地
# 登记成功)只标可见;父类未就绪 ⇒ 本遍不登记(收尾遍补齐);布局不可信 ⇒
@@ -2810,6 +2827,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
existing_c: GenTypes.StructEntry* = GenApi.find_struct_by_module(real_name, src_sha1)
if existing_c is not None and existing_c.Ty is not None:
GenApi.add_visible_struct(pool, real_name)
if _dbg_p7c != 0:
stdio.printf("[DBG-P7] cls_inject res=already src=%s\n", src_sha1)
return 1
# REnum 类(class X(t.REnum))跳过:布局 {i32 __tag, <payload>} 由
# ClassGenEnum._translate_renum_def 按变体计算;vpi 侧按普通 struct 注册
@@ -2817,6 +2836,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# 留给源模块正式翻译注册。LLVMType 本就因 field_count==0 早退,此守卫把
# 该行为显式化,避免将来 REnum 带直接字段时被误注册为普通 struct。
if _vpi_class_is_renum(class_cd) != 0:
if _dbg_p7c != 0:
stdio.printf("[DBG-P7] cls_inject res=renum_skip src=%s\n", src_sha1)
return 0
# 规则 5.5 的证据前置(**必须早于**下方字段注解解析):
# 本函数在**注入期**解析字段注解(GenApi.resolve_annotation_type →
@@ -2873,6 +2894,9 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
pool, m_aa_c.annotation, imported_modules, from_imports, trans, 0)
if field_ty_c is None:
# 字段类型解析失败:不注册该类(留给源模块编译注册),不 fatal
if _dbg_p7c != 0:
stdio.printf("[DBG-P7] cls_inject res=field_unresolved field=%s src=%s\n",
m_tgt_c.id, src_sha1)
return 0
if field_count < GenTypes.FIELD_MAX:
field_names_buf[field_count] = sizet(m_tgt_c.id)
@@ -2881,6 +2905,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
# 3. vpi 存根不含类字段(只序列化 class 名 + def 签名)→ field_count 恒为 0;注册空类会让源模块编译时 find_struct_by_module 命中空类
# → "结构体已注册但字段数为0" InternalCompilerError。故改为不注册:依赖模块已编译时命中真实类(上方已处理),未编译时由 _deps_pending 多遍收敛。
if field_count == 0:
if _dbg_p7c != 0:
stdio.printf("[DBG-P7] cls_inject res=zero_fields src=%s\n", src_sha1)
return 0
# 4. 构建 ParamNode 链表
first_node_c: rawptr[llvmlite.ParamNode] = None
@@ -2952,6 +2978,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*,
af_ty_c: llvmlite.LLVMType* = (llvmlite.LLVMType*)(field_types_buf[afi_c])
GenApi.add_field(pool, entry_c, af_name_c, af_ty_c)
GenApi.add_visible_struct(pool, real_name)
if _dbg_p7c != 0:
stdio.printf("[DBG-P7] cls_inject res=registered src=%s fields=%d\n", src_sha1, field_count)
return 1