fix(gen): from-import 模块名截断后再查 SHA1(非 NUL 结尾退化裸名)
undefined symbol: _op_head 根因:lookup_from_import 返回指向 from_imports 内部的指针(非 NUL 结尾,后随空格分隔的其他条目,如 "ast.tokens TokenType:ast.tokens ...")。ExprGenName 的 from-import 全局查找直接用 该值 LookupSha1ByModName → 整串查不到 → _mangle_name_with_sha1(None) 退化裸名 → 引用 @_op_head 而非 @<tokens_sha1>._op_head → 链接 undefined (tokens 定义端已带 SHA1 前缀)。ExprGenAttr 别名解析同病。 修复:ExprGenName 新增 _cut_from_import_mod(截断到空格/冒号/NUL), 两处 from-import 分支截断后再查 SHA1;ExprGenAttr 别名解析内联截断。 对齐 CallGenBase._lookup_sha1_from_modname_raw / ExprGenCdef 既有截断逻辑。
This commit is contained in:
1 parent
99df2aef99
commit
601db9e265
2 files changed
+48
-5
No files matched your search
@@ -248,11 +248,21 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
# 得原始模块名。否则 _lookup_module_sha1("GenGenerator") 查不到(Sha1Store
|
||||
# 用原始模块名)→ 退化裸名 → 全局带 SHA1 前缀后 undefined symbol。
|
||||
# 别名属性访问(GenGenerator._g_gen = gen)依赖此解析才能命中目标模块定义。
|
||||
# 注意:lookup_from_import 返回指针非 NUL 结尾,须截断到空格/冒号/NUL
|
||||
# 再查 SHA1(否则整串 "lib.core.Gen.Generator Config:lib... " 查不到)。
|
||||
if trans._from_imports is not None:
|
||||
orig_mw: str = HandlesImports.lookup_from_import(
|
||||
trans._from_imports, mod_path_w, 0)
|
||||
if orig_mw is not None:
|
||||
mod_path_w = orig_mw
|
||||
oml_a: t.CSizeT = 0
|
||||
while orig_mw[oml_a] != ' ' and orig_mw[oml_a] != '\0' and orig_mw[oml_a] != ':':
|
||||
oml_a += 1
|
||||
if oml_a > 0:
|
||||
om_buf_a: str = pool.alloc(oml_a + 1)
|
||||
if om_buf_a is not None:
|
||||
string.strncpy(om_buf_a, orig_mw, oml_a)
|
||||
om_buf_a[oml_a] = '\0'
|
||||
mod_path_w = om_buf_a
|
||||
# 检查是否是已导入模块
|
||||
if HandlesImports.is_module_imported(trans._imported_modules, mod_path_w) == 0:
|
||||
return None
|
||||
|
||||
@@ -44,6 +44,31 @@ import lib.core.Handles.ExprCallCtor as ExprCallCtor
|
||||
class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
"""Name/Subscript/下标访问"""
|
||||
|
||||
def _cut_from_import_mod(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
raw: str) -> str:
|
||||
"""截断 lookup_from_import 返回的模块名到独立缓冲
|
||||
|
||||
lookup_from_import 返回指向 from_imports 内部的指针(非 NUL 结尾,
|
||||
后随空格分隔的其他条目,如 "ast.tokens TokenType:ast.tokens ...")。
|
||||
不截断则 LookupSha1ByModName 收到整串查不到 → mangle 退化裸名 →
|
||||
全局引用不带 SHA1 前缀 → 链接 undefined symbol(_op_head 根因,
|
||||
对齐 ExprGenCdef._lookup_cross_module_cdefine 的截断逻辑)。
|
||||
截断到空格/冒号/NUL;raw 无效返回 None。
|
||||
"""
|
||||
if raw is None:
|
||||
return None
|
||||
mbl_c: t.CSizeT = 0
|
||||
while raw[mbl_c] != ' ' and raw[mbl_c] != '\0' and raw[mbl_c] != ':':
|
||||
mbl_c += 1
|
||||
if mbl_c == 0:
|
||||
return None
|
||||
buf_c: str = pool.alloc(mbl_c + 1)
|
||||
if buf_c is None:
|
||||
return None
|
||||
string.strncpy(buf_c, raw, mbl_c)
|
||||
buf_c[mbl_c] = '\0'
|
||||
return buf_c
|
||||
|
||||
def translate_name_value(self, builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
@@ -109,9 +134,13 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
fi_mod_raw: str = HandlesImports.lookup_from_import(
|
||||
trans._from_imports, nm_id, 0)
|
||||
if fi_mod_raw is not None:
|
||||
# 带源模块 SHA1 前缀精确查找,避免多模块同名全局后缀匹配串扰
|
||||
# 带源模块 SHA1 前缀精确查找,避免多模块同名全局后缀匹配串扰。
|
||||
# fi_mod_raw 非 NUL 结尾,先截断再查 SHA1(否则整串查不到退化裸名)
|
||||
fi_mod_cut: str = self._cut_from_import_mod(pool, fi_mod_raw)
|
||||
if fi_mod_cut is None:
|
||||
fi_mod_cut = fi_mod_raw
|
||||
fi_gv_q: str = HandlesFunctions._mangle_name_with_sha1(
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_raw), nm_id)
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_cut), nm_id)
|
||||
fi_gv: llvmlite.GlobalVariable | t.CPtr = HandlesExpr.find_global_in_module(
|
||||
trans.Module, fi_gv_q)
|
||||
if fi_gv is not None and fi_gv.Ty is not None:
|
||||
@@ -297,9 +326,13 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# stub 已注入全局(精确类型)→ 直接引用;未注入 → fail-fast
|
||||
# (不再创建 external i8* 声明,否则 llc 报 "use of undefined value",
|
||||
# 静默回退掩盖 stub 未注入的上游根因)
|
||||
# 带源模块 SHA1 前缀精确查找(避免多模块同名全局后缀匹配串扰)
|
||||
# 带源模块 SHA1 前缀精确查找(避免多模块同名全局后缀匹配串扰);
|
||||
# fi_mod 非 NUL 结尾,先截断再查 SHA1(否则退化裸名 → undefined)
|
||||
fi_mod_cut2: str = self._cut_from_import_mod(pool, fi_mod)
|
||||
if fi_mod_cut2 is None:
|
||||
fi_mod_cut2 = fi_mod
|
||||
gv_fi_q: str = HandlesFunctions._mangle_name_with_sha1(
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod), fi_gname)
|
||||
StubMergerStore.LookupSha1ByModName(fi_mod_cut2), fi_gname)
|
||||
gv_fi: llvmlite.GlobalVariable | t.CPtr = HandlesExpr.find_global_in_module(
|
||||
trans.Module, gv_fi_q)
|
||||
ref_fi: llvmlite.Value | t.CPtr = None
|
||||
|
||||
Reference in new issue
Block a user