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:
1 parent
eb002ece31
commit
f19c63594a
1 file changed
+62
-1
@@ -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 声明
|
||||
#
|
||||
|
||||
Reference in new issue
Block a user