From f19c63594a2ed2601360208410b6cde7f9abd73f Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 13 Aug 2026 04:55:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(vpi):=20=E6=B3=A8=E5=85=A5=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E7=BA=A7=E5=85=A8=E5=B1=80=E5=8F=98=E9=87=8F=20extern?= =?UTF-8?q?al=20declare=EF=BC=8C=E4=BF=AE=E5=A4=8D=E8=B7=A8=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=20stub=20=E8=AF=AF=E6=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 走全局变量注入)。 --- App/lib/StubGen/VpiReader.vp | 63 +++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/App/lib/StubGen/VpiReader.vp b/App/lib/StubGen/VpiReader.vp index a65b084..5bdceb4 100644 --- a/App/lib/StubGen/VpiReader.vp +++ b/App/lib/StubGen/VpiReader.vp @@ -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 声明 #