fix(vpi): 注入模块级全局变量 external declare,修复跨模块 stub 误杀

vpi 注入原只处理函数 declare 与 CTypedef,普通模块级全局变量
(tokens.vp 的 _op_head: OpEntry | t.CPtr)不创建 GlobalVariable,
lexer.vp from-import 读取时 find_global_in_module 找不到 →
"跨模块全局变量类型未知(stub 未注入)"。新增
_inject_global_variable_declare:解析注解类型(裸类→Ptr、CArray→
元素指针),创建短名 external global(COFF 按名链接),接入 AnnAssign
分支(非 CTypedef 走全局变量注入)。
This commit is contained in:
TermiNexus committed 2026-08-13 04:55:40 +08:00
1 parent eb002ece31
commit f19c63594a
1 file changed
+62 -1
+62 -1
View File
@@ -916,13 +916,18 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
funcs_ptr, max_funcs)
continue
# AnnAssign with t.CTypedef → 注册 CTypedef
# AnnAssign with t.CTypedef → 注册 CTypedef;
# 普通模块级全局变量(如 tokens._op_head)→ external global declare
if kd == ast.ASTKind.AnnAssign:
aa: ast.AnnAssign | t.CPtr = (ast.AnnAssign | t.CPtr)(child)
if aa is None:
continue
if HandlesType._is_ctypedef_annotation(aa.annotation) != 0:
_register_ctypedef_from_annassign(pool, aa)
else:
_inject_global_variable_declare(pool, mod, aa, trans,
stub_imported_modules, stub_from_imports,
i32_ty, i8_ptr_ty)
continue
# ClassDef → 递归注入类内方法(如 MemBuddy.__init__/alloc)
@@ -972,6 +977,62 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy | t.CPtr,
return 1
# ============================================================
# _inject_global_variable_declare - 从 vpi AnnAssign 创建模块级全局变量 declare
#
# 背景:vpi 里模块级全局变量(如 tokens.vp 的 _op_head: OpEntry | t.CPtr = None)
# 需在当前模块创建 external global 声明(短名 @name,COFF 按名链接),否则
# 跨模块 from-import 读取全局变量时 find_global_in_module 找不到 →
# "跨模块全局变量类型未知(stub 未注入)" 误杀(lexer.vp 读 tokens._op_head)。
# ============================================================
def _inject_global_variable_declare(pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
aa: ast.AnnAssign | t.CPtr,
trans: HT.Translator | 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)"""
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
if tgt_v is None or tgt_v.kind() != ast.ASTKind.Name:
return
nm_v: ast.Name | t.CPtr = (ast.Name | t.CPtr)(tgt_v)
if nm_v is None or nm_v.id is None:
return
gname_v: str = nm_v.id
if gname_v[0] == '\0':
return
# 去重:遍历模块全局变量链表(短名匹配)
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:
return
cur_v = cur_v.Next
# 解析注解类型(裸类 → Ptr(struct),CArray → 元素指针)
resolved_v: llvmlite.LLVMType | t.CPtr = None
if aa.annotation is not None:
resolved_v = HandlesType.resolve_annotation_type(
pool, aa.annotation, imported_modules, from_imports, trans)
if resolved_v is None:
return # 类型解析失败跳过:调用侧有 fail-fast 定位
gv_ty_v: llvmlite.LLVMType | t.CPtr = resolved_v
match resolved_v:
case llvmlite.LLVMType.Struct(_, _, _):
gv_ty_v = llvmlite.Ptr(pool, resolved_v)
case llvmlite.LLVMType.Array(aelem_v, _):
gv_ty_v = llvmlite.Ptr(pool, aelem_v)
case _:
gv_ty_v = resolved_v
gv_v: llvmlite.GlobalVariable | t.CPtr = llvmlite.new_global_variable(pool, gname_v, gv_ty_v)
if gv_v is None:
return
llvmlite.module_add_global(mod, gv_v)
gv_v.Linkage = "external"
# ============================================================
# _inject_function_declare - 为单个 FunctionDef 创建 declare 声明
#