diff --git a/App/lib/core/Gen/Call/CallGenLib.vp b/App/lib/core/Gen/Call/CallGenLib.vp index de6e91e..0bd5265 100644 --- a/App/lib/core/Gen/Call/CallGenLib.vp +++ b/App/lib/core/Gen/Call/CallGenLib.vp @@ -565,8 +565,15 @@ novirtual class CallGenLib(CallGenBase.CallGenBase): param_idx: int) -> mlirlite.LLVMType*: """获取外部函数第 param_idx 个参数的期望类型,None 表示用字面量原类型 - 对 Win32 API 函数的所有非指针参数返回 i64,匹配 declare 中 - ULONG/SIZE_T 被统一翻译为 i64 的情况。 + ⚠ **兜底专用**:调用方应先按**定义侧 vpi 形参注解**取真实类型 + (CallGenMixin 的模块限定调用分支,见 _resolve_vpi_param_annot_seg), + 只有注解不可得时才落到本白名单。 + + 本白名单把 Win32 API 的**所有**非指针参数一律当 i64,其依据是旧口径 + "DWORD/ULONG/SIZE_T 在 stubs 翻译时都被映射为 i64";该口径**已过时** + (现实:SIZE_T→i64、ULONG/DWORD→i32),若据此提升实参会让 call(i64) + 与 declare(i32) 不匹配(mlir-opt: "llvm.call op operand type mismatch", + 现场 FuncTest VirtualAlloc)。故仅在拿不到定义侧注解时才用。 """ if pool is None or func_name is None: return None diff --git a/App/lib/core/Gen/Call/CallGenMixin.vp b/App/lib/core/Gen/Call/CallGenMixin.vp index 8b674f6..a4a5214 100644 --- a/App/lib/core/Gen/Call/CallGenMixin.vp +++ b/App/lib/core/Gen/Call/CallGenMixin.vp @@ -1120,7 +1120,37 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): kvc_ty: mlirlite.LLVMType* = self.Gen.CallGenVa._get_known_vararg_cfunc_param_ty(pool, func_name, ai) if kvc_ty is not None: arg_val = self.Gen.ExprGenBase.coerce_to_type(builder, arg_val, kvc_ty, arg) - ext_param_ty: mlirlite.LLVMType* = self.Gen.CallGenLib._get_external_func_param_ty(pool, func_name, ai) + # ① 模块限定调用的**定义侧 vpi 形参注解优先**(真实类型)。 + # 白名单 _get_external_func_param_ty 把 Win32 API 的**所有** + # 非指针参数一律当 i64(其注释基于"DWORD/ULONG 在 stubs 里 + # 都被映射为 i64"的旧口径),而现状 ULONG → i32 ⇒ 实参被 + # sext 到 i64、声明却是 i32,call 与 declare 不匹配: + # mlir-opt 报 "llvm.call op operand type mismatch for + # operand N: 'i64' != 'i32'"(现场 FuncTest VirtualAlloc)。 + # 模块级函数:vpi 段下标 == 形参下标(cls=None,无 self 占位段)。 + ext_param_ty: mlirlite.LLVMType* = None + if cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: + at_pt: ast.Attribute* = ast.Attribute*(cl.func) + mpath_pt: str = None + if at_pt.value is not None and at_pt.value.kind() == ast.ASTKind.Name: + nm_pt: ast.Name* = ast.Name*(at_pt.value) + mpath_pt = nm_pt.id + elif at_pt.value is not None and at_pt.value.kind() == ast.ASTKind.Attribute: + mpath_pt = self.Gen.ExprGenAttr._attr_module_path_str(pool, at_pt.value) + if mpath_pt is not None: + fi_pt: str = None + if trans is not None: + fi_pt = trans._from_imports + sha_pt: str = self.Gen.StructGen._resolve_module_sha1(mpath_pt, fi_pt) + if sha_pt is not None: + if self.Gen.CallGenBase.TempDir is not None and self.Gen.CallGenBase.TempDirLen > 0: + VpiReader._ensure_vpi_param_annot_loaded(sha_pt, self.Gen.CallGenBase.TempDir) + ext_param_ty = VpiReader._resolve_vpi_param_annot_seg( + pool, sha_pt, None, func_name, ai, + mlirlite.Int32(pool), mlirlite.Ptr(pool, mlirlite.Int8(pool))) + # ② 白名单仅作**兜底**(定义侧注解不可得时) + if ext_param_ty is None: + ext_param_ty = self.Gen.CallGenLib._get_external_func_param_ty(pool, func_name, ai) if ext_param_ty is not None: val_bits_ap: int = self.Gen.ExprGenBase.get_llvm_type_bits(arg_val.Ty) tgt_bits_ap: int = self.Gen.ExprGenBase.get_llvm_type_bits(ext_param_ty)