fix(stub): vpi 全局注入补全 src_sha1 mangling——修复 a42923c 笔误致空名全局

a42923c 声称"注入名带 src_sha1 前缀",但实际把 new_global_variable 的
gname_v 写成未定义变量 gv_name_m(mangle 逻辑从未实现)→ 注入空名
"@ = external global %MemBuddy*" → llc "expected top-level entity"
(SlotsBugTest 回归)。

修复:_inject_global_variable_declare 签名加 src_sha1,计算 mangled 名
"<sha1>.<name>"(对齐定义端 5f7a873 与查找端 from-import 三方一致),
去重与创建均用 mangled 名;调用点传 ParseVpiIntoModule 的 src_sha1。
This commit is contained in:
TermiNexus committed 2026-08-20 08:06:12 +08:00
1 parent 281d26915c
commit 12e8d6bdf8
1 file changed
+16 -5
+16 -5
View File
@@ -942,7 +942,7 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
else:
_inject_global_variable_declare(pool, mod, aa, trans,
stub_imported_modules, stub_from_imports,
i32_ty, i8_ptr_ty)
i32_ty, i8_ptr_ty, src_sha1)
continue
# ClassDef → 递归注入类内方法(如 MemBuddy.__init__/alloc)
@@ -1007,8 +1007,9 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr,
imported_modules: str,
from_imports: str,
i32_ty: llvmlite.LLVMType | t.CPtr,
i8_ptr_ty: llvmlite.LLVMType | t.CPtr) -> None:
"""从 vpi AnnAssign 创建模块级全局变量 external declare(短名 @name)"""
i8_ptr_ty: llvmlite.LLVMType | t.CPtr,
src_sha1: str) -> None:
"""从 vpi AnnAssign 创建模块级全局变量 external declare(mangled 名 @<src_sha1>.<name>)"""
if pool is None or mod is None or aa is None or trans is None:
return
tgt_v: ast.AST | t.CPtr = aa.target
@@ -1020,10 +1021,20 @@ def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr,
gname_v: str = nm_v.id
if gname_v[0] == '\0':
return
# 去重:遍历模块全局变量链表(短名匹配)
# mangled 名:带源模块 SHA1 前缀(对齐定义端 5f7a873 的 @<sha1>.<name>
# 与查找端 from-import 精确查找三方一致;裸短名会退化为未定义)。
# 注:a42923c 曾把此处写成未定义变量 gv_name_m(笔误,mangle 未实现),
# 导致注入空名 @ = external global → llc "expected top-level entity"。
gv_name_m: str = gname_v
if src_sha1 is not None and src_sha1[0] != '\0':
ml_v: t.CSizeT = string.strlen(src_sha1) + 1 + string.strlen(gname_v) + 1
gv_name_m = pool.alloc(ml_v)
if gv_name_m is not None:
viperlib.snprintf(gv_name_m, ml_v, "%s.%s", src_sha1, gname_v)
# 去重:遍历模块全局变量链表(mangled 名匹配)
cur_v: llvmlite.GlobalVariable | t.CPtr = mod.GlobalHead
while cur_v is not None:
if cur_v.Name is not None and string.strcmp(cur_v.Name, gname_v) == 0:
if cur_v.Name is not None and string.strcmp(cur_v.Name, gv_name_m) == 0:
return
cur_v = cur_v.Next
# 解析注解类型(裸类 → Ptr(struct),CArray → 元素指针)