From ce62546e90226a3ad85335dc00a4820cd8e0ddb1 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 27 Aug 2026 16:10:48 +0800 Subject: [PATCH] =?UTF-8?q?fix(structgen):=20lookup=5Ffield=5Fby=5Fclass?= =?UTF-8?q?=20=E6=A8=A1=E5=9D=97=E5=BD=92=E5=B1=9E=E6=9C=AA=E5=91=BD?= =?UTF-8?q?=E4=B8=AD=E5=9B=9E=E9=80=80=E8=A3=B8=E5=90=8D=E5=90=8C=E5=90=8D?= =?UTF-8?q?=E7=B1=BB=EF=BC=88=E5=94=AF=E4=B8=80=E6=97=B6=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20ast.Attribute=20=E5=BD=92=E5=B1=9E?= =?UTF-8?q?=E9=94=99=E4=BD=8D=E8=AF=AF=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 场景:ast.Attribute(ast/exprs.vp 定义,ModuleSha1=c0def010dcebadb1)经 lookup_field_by_class 模块归属解析,模块段 "ast" 走包名回退 → ast/__init__.vp 的 sha1 (35245c385b0ddd7b)→ find_struct_by_module 不匹配 → 误报 "类 ast.Attribute 未找到"(AssignGenMixin.is_cdefine_annotation 的 at.attr 触发) - 修复:模块可解析但类未注册时,统计裸名同名类数量,唯一时回退查找字段 (Attribute 短名无跨模块同名,安全);多同名仍 fail-fast(防 sched.Thread 顶掉) --- App/lib/core/Gen/StructGenMixin.vp | 48 ++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index 1008461..40b28da 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -141,7 +141,7 @@ class StructGenMixin: entry_size: t.CSizeT = GenTypes.StructEntry.__sizeof__() table_pool: memhub.MemBuddy | t.CPtr = pool if self.StdlibAlloc != 0: - table_pool = CompilerFactory.get_perm_pool() + table_pool = CompilerFactory.factory.PermPool if table_pool is None: table_pool = pool self.StructTable = table_pool.alloc(entry_size * STRUCT_MAX) @@ -201,7 +201,7 @@ class StructGenMixin: # 分配字段数组(1b 阶段用永久池,避免 reset 回收后 Fields 悬空) field_size: t.CSizeT = GenTypes.FieldEntry.__sizeof__() if self.StdlibAlloc != 0: - perm_sg: memhub.MemBuddy | t.CPtr = CompilerFactory.get_perm_pool() + perm_sg: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool if perm_sg is None: perm_sg = pool entry.Fields = perm_sg.alloc(field_size * FIELD_MAX) @@ -217,7 +217,7 @@ class StructGenMixin: # 曾读悬空 Name 越界 → G3 LinkedNode.prepend 挂起根因) name_pool: memhub.MemBuddy | t.CPtr = pool if self.StdlibAlloc != 0: - name_pool = CompilerFactory.get_perm_pool() + name_pool = CompilerFactory.factory.PermPool if name_pool is None: name_pool = pool name_len: t.CSizeT = string.strlen(name) @@ -253,7 +253,7 @@ class StructGenMixin: sha1_len: t.CSizeT = string.strlen(sha1) sha1_pool: memhub.MemBuddy | t.CPtr = pool if self.StdlibAlloc != 0: - sha1_pool = CompilerFactory.get_perm_pool() + sha1_pool = CompilerFactory.factory.PermPool if sha1_pool is None: sha1_pool = pool sha1_buf: str = sha1_pool.alloc(sha1_len + 1) @@ -301,7 +301,7 @@ class StructGenMixin: # 与 register_struct 的 Name 悬空同根因) fname_pool: memhub.MemBuddy | t.CPtr = pool if self.StdlibAlloc != 0: - fname_pool = CompilerFactory.get_perm_pool() + fname_pool = CompilerFactory.factory.PermPool if fname_pool is None: fname_pool = pool name_len: t.CSizeT = string.strlen(field_name) @@ -318,7 +318,7 @@ class StructGenMixin: # AnnotClassName 回退、_apply_struct_defaults 的 build_gep_struct 用 fe.Ty # 作 GEP 结果类型)解引用悬空内存 → 崩溃点漂移(json/string/builtins 之间)。 if self.StdlibAlloc != 0: - dp_pool_sg: memhub.MemBuddy | t.CPtr = CompilerFactory.get_perm_pool() + dp_pool_sg: memhub.MemBuddy | t.CPtr = CompilerFactory.factory.PermPool if dp_pool_sg is None: dp_pool_sg = pool ty_copy: llvmlite.LLVMType | t.CPtr = llvmlite.DeepCopyType(dp_pool_sg, field_ty) @@ -328,7 +328,7 @@ class StructGenMixin: fe.Ty = field_ty if annot_class_name is not None: annot_len: t.CSizeT = string.strlen(annot_class_name) - annot_buf: str = CompilerFactory.get_perm_pool().alloc(annot_len + 1) + annot_buf: str = CompilerFactory.factory.PermPool.alloc(annot_len + 1) if annot_buf is not None: string.strcpy(annot_buf, annot_class_name) fe.AnnotClassName = annot_buf @@ -832,7 +832,37 @@ class StructGenMixin: self.Gen.TypeGenErr.fatal_error(node, fb, "AttributeError") stdlib.free(mod_buf_q) return None - # 模块可解析但类未注册:fail-fast(暴露 vpi 注入/注册缺陷, + # 模块可解析但类未注册:先看裸名同名类是否唯一—— + # 模块归属错位场景(如 "ast.Attribute":模块 'ast' 经包名 + # 回退解析到 ast/__init__.vp 的 sha1,但 Attribute 类实际 + # 注册在子模块 ast/exprs.vp,ModuleSha1 不匹配 → 查不到)。 + # 裸名唯一时回退(Attribute 短名无跨模块同名,安全); + # 多同名时保持 fail-fast(防 sched.Thread 被顶掉的同类问题)。 + same_cnt_q: int = 0 + same_entry_q: GenTypes.StructEntry | t.CPtr = None + for i_sq in range(self.StructCount): + e_sq: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i_sq) + if e_sq is not None and e_sq.Name is not None: + if string.strcmp(e_sq.Name, bare_q) == 0: + same_cnt_q += 1 + same_entry_q = e_sq + if same_cnt_q == 1 and same_entry_q is not None: + for fi_q2 in range(same_entry_q.FieldCount): + fe_q2: GenTypes.FieldEntry | t.CPtr = \ + self._get_field_entry(same_entry_q, fi_q2) + if fe_q2 is not None and fe_q2.Name is not None: + if string.strcmp(fe_q2.Name, field_name) == 0: + stdlib.free(mod_buf_q) + return fe_q2 + # 裸名类命中但字段未找到:可读化报错 + viperlib.snprintf(fb, 1024, + "lookup_field_by_class: 类 '%s' 裸名回退" + "(ModuleSha1=%s, FieldCount=%d)但字段 '%s' 未找到", + class_name, mod_sha1_q, same_entry_q.FieldCount, field_name) + self.Gen.TypeGenErr.fatal_error(node, fb, "AttributeError") + stdlib.free(mod_buf_q) + return None + # 裸名也不唯一/不存在:fail-fast(暴露 vpi 注入/注册缺陷, # 不再裸名跨库抓其他模块同名类) viperlib.snprintf(fb, 1024, "lookup_field_by_class: 类 '%s' 未找到(模块 '%s' 可解析" @@ -1230,7 +1260,7 @@ class StructGenMixin: count = PARENT_MAX pn_pool: memhub.MemBuddy | t.CPtr = pool if self.StdlibAlloc != 0: - pn_pool = CompilerFactory.get_perm_pool() + pn_pool = CompilerFactory.factory.PermPool if pn_pool is None: pn_pool = pool arr: t.CSizeT | t.CPtr = pn_pool.alloc(8 * count)