diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index 92b5c7c..dfe1a50 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -2780,6 +2780,14 @@ 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-GEN] 一次性取证(用完删除) + _dg_v_isgen: int = 0 + if string.strcmp(real_name, "Generator") == 0: + _dg_v_isgen = 1 + _dg_v_s: str = "" + if src_sha1 is not None: + _dg_v_s = src_sha1 + stdio.printf("[DBG-GEN] vpi inject_class IN name=Generator src_sha1=%s\n", _dg_v_s) # REPL(ReplStubLayoutMode,见文件末"REPL:includes 类完整布局与虚表恢复"): # 本类若已由 .stub.ll 驱动的路径接管 ⇒ 这里整类让位——已登记(或本遍就地 # 登记成功)只标可见;父类未就绪 ⇒ 本遍不登记(收尾遍补齐);布局不可信 ⇒ @@ -2799,6 +2807,9 @@ 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 _dg_v_isgen != 0: + stdio.printf("[DBG-GEN] vpi inject_class EXISTING name=Generator fcount=%d\n", + existing_c.FieldCount) return 1 # REnum 类(class X(t.REnum))跳过:布局 {i32 __tag, } 由 # ClassGenEnum._translate_renum_def 按变体计算;vpi 侧按普通 struct 注册 @@ -2806,6 +2817,8 @@ def _inject_class_struct_declare(pool: memhub.MemBuddy*, # 留给源模块正式翻译注册。LLVMType 本就因 field_count==0 早退,此守卫把 # 该行为显式化,避免将来 REnum 带直接字段时被误注册为普通 struct。 if _vpi_class_is_renum(class_cd) != 0: + if _dg_v_isgen != 0: + stdio.printf("[DBG-GEN] vpi inject_class RENUM-SKIP name=Generator\n") return 0 # 规则 5.5 的证据前置(**必须早于**下方字段注解解析): # 本函数在**注入期**解析字段注解(GenApi.resolve_annotation_type → @@ -2862,6 +2875,12 @@ 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 _dg_v_isgen != 0: + _dg_v_fn: str = "" + if m_tgt_c.id is not None: + _dg_v_fn = m_tgt_c.id + stdio.printf("[DBG-GEN] vpi inject_class FIELD-FAIL name=Generator field=%s\n", + _dg_v_fn) return 0 if field_count < GenTypes.FIELD_MAX: field_names_buf[field_count] = sizet(m_tgt_c.id) @@ -2870,6 +2889,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 _dg_v_isgen != 0: + stdio.printf("[DBG-GEN] vpi inject_class EMPTY name=Generator\n") return 0 # 4. 构建 ParamNode 链表 first_node_c: rawptr[llvmlite.ParamNode] = None @@ -2941,6 +2962,9 @@ 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 _dg_v_isgen != 0: + stdio.printf("[DBG-GEN] vpi inject_class REGISTERED name=Generator fcount=%d ty=%s\n", + field_count, type_name_c) return 1 diff --git a/App/lib/core/Gen/Class/ClassGenDef.vp b/App/lib/core/Gen/Class/ClassGenDef.vp index b8ca19f..90ca9d3 100644 --- a/App/lib/core/Gen/Class/ClassGenDef.vp +++ b/App/lib/core/Gen/Class/ClassGenDef.vp @@ -94,6 +94,16 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase): # 检查是否已注册(用 SHA1 区分跨模块同名类) existing: GenTypes.StructEntry* = self.Gen.StructGen.find_struct_by_module(class_name, trans.ModuleSha1) + # [DBG-GEN] 一次性取证(用完删除) + _dg_cd_isgen: int = 0 + if class_name is not None and string.strcmp(class_name, "Generator") == 0: + _dg_cd_isgen = 1 + if existing is not None: + stdio.printf("[DBG-GEN] classdef Generator EXISTING fcount=%d declare_only=%d\n", + existing.FieldCount, trans._declare_only) + else: + stdio.printf("[DBG-GEN] classdef Generator EXISTING none declare_only=%d\n", + trans._declare_only) # 空类注册不完整检测:existing FieldCount==0 但源类体声明了字段(vpi 注入/注册缺陷)。 # 标记 _deps_pending 延迟会让空 entry 持久存在、多遍死锁不收敛 ⇒ 改为中和旧 entry # (置空 Name + Ty=None,使 find_struct_by_module 不再命中),走下方完整注册路径重建。 @@ -571,6 +581,9 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase): if entry is None: VLogger.error(f"failed to register {class_name}", "CLASS") return 0 + if _dg_cd_isgen != 0: + stdio.printf("[DBG-GEN] classdef Generator REGISTER field_count=%d declare_only=%d\n", + field_count, trans._declare_only) # B5:记录 packed 标记到 StructEntry(供 __sizeof__/字段布局等派生查询) if is_packed_cd != 0: @@ -649,6 +662,9 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase): if fe_c is not None: fe_c.IsConst = 1 + if _dg_cd_isgen != 0: + stdio.printf("[DBG-GEN] classdef Generator DONE fcount=%d\n", entry.FieldCount) + # Phase 1a 声明模式:只注册 struct + 设置 OOP 标志,不翻译方法体 if trans._declare_only == 1: self.Gen.ClassGenVTable._translate_oop_methods(trans, cd, struct_ty, class_name, 1) diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index f0bb818..af74d0c 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -594,12 +594,35 @@ novirtual class StructGenMixin: sha1 参数在注册时直接设置 ModuleSha1(避免 set_struct_sha1 找错 entry)。 """ if self.init_struct_table(pool) == 0: return None + # [DBG-GEN] 一次性取证(用完删除) + _dg_isgen: int = 0 + if name is not None and string.strcmp(name, "Generator") == 0: + _dg_isgen = 1 + _dg_sh0: str = "" + if sha1 is not None: + _dg_sh0 = sha1 + _dg_tn0: str = "" + _dg_g0: str = llvmlite.get_struct_name(struct_ty) + if _dg_g0 is not None: + _dg_tn0 = _dg_g0 + stdio.printf("[DBG-GEN] register_struct IN name=Generator sha1=%s ty=%s count_before=%d\n", + _dg_sh0, _dg_tn0, self.StructCount) # 用类型指针去重(同一类型不重复注册,支持跨模块同名类) # 用 uint64 指针值比较(is 比较会触发类型安全检查解引用悬空 Ty) # 走 find_struct_by_type(其 Ty 索引判定已整体停用、恢复原线性扫描), # 去重语义 = 原去重扫描"首个 Ty 指针相等条目"(首注册优先),逐字节一致。 existing: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty) - if existing is not None: return existing + if existing is not None: + if _dg_isgen != 0: + _dg_en: str = "" + if existing.Name is not None: + _dg_en = existing.Name + _dg_es: str = "" + if existing.ModuleSha1 is not None: + _dg_es = existing.ModuleSha1 + stdio.printf("[DBG-GEN] register_struct DEDUP name=Generator -> existing name=%s sha1=%s fcount=%d\n", + _dg_en, _dg_es, existing.FieldCount) + return existing if self.StructCount >= STRUCT_MAX: VLogger.error(f"table full, cannot register {name}", "STRUCT") return None @@ -748,6 +771,10 @@ novirtual class StructGenMixin: if struct_entry.FieldCount >= FIELD_MAX: VLogger.error(f"field table full for {struct_entry.Name}", "STRUCT") return -1 + # [DBG-GEN] 一次性取证(用完删除) + if struct_entry.Name is not None and string.strcmp(struct_entry.Name, "Generator") == 0: + stdio.printf("[DBG-GEN] add_field Generator[%d] name=%s\n", + struct_entry.FieldCount, field_name) idx: int = struct_entry.FieldCount fe: GenTypes.FieldEntry* = self._get_field_entry(struct_entry, idx) if fe is None: return -1 @@ -1118,6 +1145,14 @@ novirtual class StructGenMixin: if self.StructCount < 0 or self.StructCount > 200000: VLogger.error(f"StructCount 异常: {self.StructCount} (find_struct_by_module)", "STRUCT") stdlib.exit(1) + # [DBG-GEN] 一次性取证(用完删除) + _dg_fbm_isgen: int = 0 + if string.strcmp(name, "Generator") == 0: + _dg_fbm_isgen = 1 + _dg_fbm_s: str = "" + if sha1 is not None: + _dg_fbm_s = sha1 + stdio.printf("[DBG-GEN] find_struct_by_module IN name=Generator sha1=%s\n", _dg_fbm_s) if sha1 is not None: # 名索引快速路径:同名条目都位于 >= 首个同名下标处,故可从该下标起扫描 # name+sha1(等价原全表扫描"首个 name 且 sha1 命中")。 @@ -1134,9 +1169,14 @@ novirtual class StructGenMixin: if entry.ModuleSha1 is not None: # 同上:sha1 判等蕴含首字符相等,先比首字符再 strcmp。 if entry.ModuleSha1[0] == sha1[0] and string.strcmp(entry.ModuleSha1, sha1) == 0: + if _dg_fbm_isgen != 0: + stdio.printf("[DBG-GEN] find_struct_by_module HIT name=Generator sha1=%s fcount=%d\n", + entry.ModuleSha1, entry.FieldCount) return entry # SHA1 查找失败:不回退到 find_struct(会返回跨模块同名错误 entry) # 返回 None 让调用方创建新类型,避免 Phase B 用错误类型短路 + if _dg_fbm_isgen != 0: + stdio.printf("[DBG-GEN] find_struct_by_module MISS name=Generator\n") return None # 无 SHA1:按类名查找第一个 return self.find_struct(name) @@ -1304,6 +1344,43 @@ novirtual class StructGenMixin: if struct_ty is None or field_name is None or self.StructTable is None: return None + # [DBG-GEN] 一次性取证(用完删除) + if string.strcmp(field_name, "FuncGenBase") == 0: + _dg_ty: str = self._extract_struct_name(struct_ty) + _dg_ty_t: str = "" + if _dg_ty is not None: + _dg_ty_t = _dg_ty + stdio.printf("[DBG-GEN] lookup_field 'FuncGenBase' struct_ty=%s\n", _dg_ty_t) + _dg_pm: GenTypes.StructEntry* = self.find_struct_by_type(struct_ty) + if _dg_pm is not None: + _dg_pn: str = "" + if _dg_pm.Name is not None: + _dg_pn = _dg_pm.Name + _dg_ps: str = "" + if _dg_pm.ModuleSha1 is not None: + _dg_ps = _dg_pm.ModuleSha1 + stdio.printf("[DBG-GEN] ptr-match name=%s sha1=%s fcount=%d\n", + _dg_pn, _dg_ps, _dg_pm.FieldCount) + _dg_fi: int = 0 + while _dg_fi < _dg_pm.FieldCount: + _dg_fe: GenTypes.FieldEntry* = self._get_field_entry(_dg_pm, _dg_fi) + if _dg_fe is not None and _dg_fe.Name is not None: + stdio.printf("[DBG-GEN] field[%d]=%s\n", _dg_fi, _dg_fe.Name) + _dg_fi += 1 + else: + stdio.printf("[DBG-GEN] ptr-match NONE\n") + _dg_i: int = 0 + while _dg_i < self.StructCount: + _dg_e: GenTypes.StructEntry* = self._get_struct_entry(_dg_i) + if _dg_e is not None and _dg_e.Name is not None: + if string.strstr(_dg_e.Name, "Generator") is not None: + _dg_sh: str = "" + if _dg_e.ModuleSha1 is not None: + _dg_sh = _dg_e.ModuleSha1 + stdio.printf("[DBG-GEN] tbl[%d] name=%s fcount=%d sha1=%s\n", + _dg_i, _dg_e.Name, _dg_e.FieldCount, _dg_sh) + _dg_i += 1 + # ============================================================ # 两遍查找策略(跨模块同名类冲突的根本修复): #