fix(gen): App 短模块名键保留 + find_struct sha1 字面量精确匹配,修复同名类归属错乱
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
This commit is contained in:
1 parent
00606057c4
commit
c656cba393
2 files changed
+100
-6
No files matched your search
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user