From c656cba3938fee3d0ac040cc89cd61d895869085 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 26 Aug 2026 17:19:23 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20App=20=E7=9F=AD=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=90=8D=E9=94=AE=E4=BF=9D=E7=95=99=20+=20find=5Fstruct=20sha1?= =?UTF-8?q?=20=E5=AD=97=E9=9D=A2=E9=87=8F=E7=B2=BE=E7=A1=AE=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=90=8C=E5=90=8D=E7=B1=BB?= =?UTF-8?q?=E5=BD=92=E5=B1=9E=E9=94=99=E4=B9=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ViperOS 目录含两份同内容 gfx.vp:App 的 Apps/Scene3D/gfx.vp(9aab) 与 VKernel 的 VKernel/.../vesafb/gfx.vp(0ae),都定义 class Scene3D。includes 扫描("../.."=ViperOS)先以全路径模块名注册 9aab,AppendToSha1MapStore 按 sha1 去重吞掉 App 短模块名 "gfx" 键 → LookupSha1ByModName("gfx") 失败 → 后缀匹配劫持到 VKernel gfx(0ae) → Scene3D 类归属 0ae → 返回类型解析查 temp/0a/0ae*.text.ll(不存在)→ Phase A _deps_pending 永不收敛。 - AppendToSha1MapStore:去重改为 sha1 与模块名都相同才跳过,App 短模块名 键("gfx")保留,import gfx 精确查找可命中 - find_struct:限定名模块段为 16 位 hex(sha1 字面量,如 "9aab.Scene3D") 时直接按 name+sha1 精确匹配(find_struct_by_module),不再落到裸名回退 - find_struct 第二遍裸名回退加同名唯一性检查:跨模块同名类(VKernel 与 App 的 Scene3D)存在时返回 None 而非先注册的错误 entry --- App/lib/Stub/StubMerger/StubMergerStore.vp | 73 ++++++++++++++++++++-- App/lib/core/Gen/StructGenMixin.vp | 33 +++++++++- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/App/lib/Stub/StubMerger/StubMergerStore.vp b/App/lib/Stub/StubMerger/StubMergerStore.vp index 9f69656..1af2be6 100644 --- a/App/lib/Stub/StubMerger/StubMergerStore.vp +++ b/App/lib/Stub/StubMerger/StubMergerStore.vp @@ -163,11 +163,6 @@ def AppendToSha1MapStore(sha1: str, rel_path: str) -> int: StubMerger._sha1_store_count = 0 if StubMerger._sha1_store_count >= StubMerger.MAX_INCLUDES: return 1 - # 去重:若 SHA1 已存在则跳过 - for i in range(StubMerger._sha1_store_count): - sidx_d: t.CSizeT = t.CSizeT(i) * 17 - if string.strcmp(StubMerger._sha1_store_arr + sidx_d, sha1) == 0: - return 0 # 模块名:rel_path "lib/core/StubMerger.vp" → "lib.core.StubMerger" full_path_buf: bytes = stdlib.malloc(string.strlen(rel_path) + 10) if full_path_buf is None: @@ -177,6 +172,18 @@ def AppendToSha1MapStore(sha1: str, rel_path: str) -> int: stdlib.free(full_path_buf) if mod_name is None: return 1 + # 去重:SHA1 与模块名都相同才跳过。同一 SHA1 可能被 includes 扫描先以 + # 全路径模块名注册(如 App 源文件在 includes 目录下 → "Apps.Scene3D.gfx"), + # App 追加的短模块名("gfx")必须保留——否则 import gfx 的精确查找 + # LookupSha1ByModName("gfx") 失败 → 后缀匹配劫持到 VKernel 同名 gfx + # (VKernel/Kernel/drivers/video/vesafb/gfx.vp,类 Scene3D 归属错乱根因)。 + for i in range(StubMerger._sha1_store_count): + sidx_d: t.CSizeT = t.CSizeT(i) * 17 + if string.strcmp(StubMerger._sha1_store_arr + sidx_d, sha1) == 0: + midx_d: t.CSizeT = t.CSizeT(i) * 64 + if string.strcmp(StubMerger._sha1_store_mod + midx_d, mod_name) == 0: + stdlib.free(mod_name) + return 0 # 写入 SHA1 idx_a: t.CSizeT = t.CSizeT(StubMerger._sha1_store_count) * 17 string.strcpy(StubMerger._sha1_store_arr + idx_a, sha1) @@ -327,6 +334,62 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str: ci += 1 return None # ============================================================ +# LookupModNameByAlias - 从 from_imports 别名映射解析模块真名 +# +# import X as Y 时 ImportsGenMixin.add_from_import 写入 "Y:X"(Y=别名, +# X=模块真名)。本函数返回别名 Y 对应的模块真名 X(供限定名解析 +# "Y.Class" → 按 X 模块归属匹配,如 "types.fileinfo" → "fat32_types")。 +# +# Returns: +# 模块名字符串(stdlib 分配,调用方负责 free),None 未找到 +# ============================================================ +def LookupModNameByAlias(from_imports: str, alias: str) -> str: + """从 from_imports 别名映射解析模块真名(import X as Y → Y:X)""" + if from_imports is None or alias is None: + return None + alias_len: t.CSizeT = string.strlen(alias) + if alias_len == 0: + return None + total_len: t.CSizeT = string.strlen(from_imports) + ci: t.CSizeT = 0 + while ci < total_len: + # 跳过前导空格 + while ci < total_len and from_imports[ci] == ' ': + ci += 1 + if ci >= total_len: + break + # 条目起点 ci,找 ':'(local_name 结束) + colon: t.CSizeT = ci + while colon < total_len and from_imports[colon] != ':' and from_imports[colon] != ' ': + colon += 1 + local_len: t.CSizeT = colon - ci + if colon < total_len and from_imports[colon] == ':' and local_len == alias_len: + # 比较 local_name == alias + match: int = 1 + li: t.CSizeT = 0 + while li < alias_len: + if from_imports[ci + li] != alias[li]: + match = 0 + break + li += 1 + if match == 1: + # 提取 module(colon+1 到下一个 ':' 或空格) + m_start: t.CSizeT = colon + 1 + m_end: t.CSizeT = m_start + while m_end < total_len and from_imports[m_end] != ':' and from_imports[m_end] != ' ': + m_end += 1 + if m_end > m_start: + mbuf: str = stdlib.malloc(m_end - m_start + 1) + if mbuf is not None: + string.strncpy(mbuf, from_imports + m_start, m_end - m_start) + mbuf[m_end - m_start] = '\0' + return mbuf + return None + # 跳到下一条目 + while ci < total_len and from_imports[ci] != ' ': + ci += 1 + return None +# ============================================================ # PopulateIncludesDeps - 将 includes 文件的依赖存入内存 # # Phase B+ 前用 declare_only 翻译 includes 文件,提取 _imported_modules diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index 2601db4..73b6d07 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -512,6 +512,27 @@ class StructGenMixin: string.strncpy(mod_buf_f, name, mod_len_f) mod_buf_f[mod_len_f] = '\0' if string.strcmp(mod_buf_f, "t") != 0 and string.strcmp(mod_buf_f, "c") != 0: + # 模块段是 16 位 hex = SHA1 字面量(如 "{9aab}.Scene3D", + # TypeGenResolve L1397-1402 的 sha1 前缀形态):跳过 store + # 模块名查询(store 键是模块名不是 sha1),直接按 name+sha1 + # 精确匹配。否则 _resolve_module_sha1("9aab") 返回 None → + # 落到第二遍裸名回退 → 跨模块同名类(VKernel gfx 与 App gfx + # 都定义 Scene3D)返回先注册的错误 entry(Scene3D 归属错乱 + # → ret_sha1=0ae → Phase A _deps_pending 死锁根因)。 + mod_hex_ok: int = 1 + if string.strlen(mod_buf_f) == 16: + for hi_f in range(16): + ch_h: t.CChar = mod_buf_f[hi_f] + if not ((ch_h >= 48 and ch_h <= 57) or (ch_h >= 97 and ch_h <= 102)): + mod_hex_ok = 0 + break + else: + mod_hex_ok = 0 + if mod_hex_ok != 0: + me_h: GenTypes.StructEntry | t.CPtr = \ + self.find_struct_by_module(bare_f, mod_buf_f) + stdlib.free(mod_buf_f) + return me_h mod_sha1_f: str = self._resolve_module_sha1(mod_buf_f) if mod_sha1_f is not None: me_f: GenTypes.StructEntry | t.CPtr = \ @@ -539,11 +560,21 @@ class StructGenMixin: if dot_pos is not None: class_name: str = dot_pos + 1 if class_name is not None and class_name[0] != '\0': + # 同名唯一性检查(对齐上方限定名路径 L543-554):跨模块同名类 + # (如 VKernel gfx 与 App gfx 都定义 Scene3D)存在时不得返回 + # 先注册的错误 entry——否则模块段无法解析的限定名(如 + # "9aab.Scene3D")被劫持到错误模块 → 返回类型解析查错 text.ll + # → Phase A _deps_pending 死锁(Scene3D ret_sha1=0ae 根因)。 + same_cnt_b: int = 0 + same_entry_b: GenTypes.StructEntry | t.CPtr = None for i in range(self.StructCount): entry: GenTypes.StructEntry | t.CPtr = self._get_struct_entry(i) if entry is not None and entry.Name is not None: if string.strcmp(entry.Name, class_name) == 0: - return entry + same_cnt_b += 1 + same_entry_b = entry + if same_cnt_b == 1: + return same_entry_b return None def find_struct_by_module(self, name: str, sha1: str) -> GenTypes.StructEntry | t.CPtr: