From 522075097ed4e088fb6b3150ceabedc56a737213 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 24 Oct 2026 22:33:14 +0800 Subject: [PATCH] =?UTF-8?q?fix(ffilib):=20translate=5Ffunction=5Fdef=20?= =?UTF-8?q?=E7=9A=84=20extern=20=E5=88=86=E6=94=AF=E4=B9=9F=E7=94=9F?= =?UTF-8?q?=E6=88=90=20runtime=20thunk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现场 temp/02/029af3a930989beb.text.ll 里 @add 是普通直接调用、没有 _ffilib 引用,说明 App 文件的 extern 走的是 translate_function_def 而不是 forward_declare_functions,thunk 校验挂错了地方。两处都挂:各自先查 find_func_in_module 去重;runtime=True 生成 thunk,runtime=False 保持原 declare 路径。 --- App/lib/core/Gen/Func/FuncGenDef.vp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index f5c8687..d313c3c 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -767,6 +767,25 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase): if (has_export != 0 or has_state != 0) and trans.ModuleSha1 is not None: self.Gen.CallGenBase.register_cexport_func(trans.ModuleSha1, fd.name) if is_extern_decl != 0: + # extern name(...):runtime=True 在这里也生成 thunk(Phase A 的 extern 往往不走 + # forward_declare_functions,两处都挂才覆盖全部路径;另一处靠 find_func_in_module 去重)。 + if fd.ffi_lib is not None: + ffi_rt_d: int = ViperBuild.FfiHandleRuntime(fd.ffi_lib) + if ffi_rt_d < 0: + self.Gen.TypeGenErr.fatal_error(fd, f"extern library handle '{fd.ffi_lib}' is not a ffilib.CDLL binding (declare it with ffilib.CDLL(...) first)", "NameError") + return 0 + if ffi_rt_d != 0: + if self.Gen.CallGenBase.find_func_in_module(mod, mangled_name) is None: + ffi_path_d: str = ViperBuild.FfiHandlePath(fd.ffi_lib) + if ffi_path_d is None: + self.Gen.TypeGenErr.fatal_error(fd, f"extern '{fd.name}' is bound to '{fd.ffi_lib}' but its library path was not recorded by Pass 0", "InternalCompilerError") + return 0 + thunk_d: mlirlite.Function* = self._emit_runtime_ffi_thunk(pool, mod, trans, fd, ffi_path_d, ret_ty) + if thunk_d is None: return 0 + thunk_max_d: int = 256 + if self.Gen.CallGenLeafKit.add_func_to_table(funcs_ptr, func_count, fd.name, thunk_d, thunk_max_d, None, 0, 0, pool) == 0: trans._func_count = func_count + 1 + self.Gen.CallGenLeafKit.update_global_func_spec(fd.name, thunk_d) + return 0 # Extern declaration function: emit a declare (declare only, no definition). First check whether # forward_declare_functions already created it to avoid a duplicate declare. existing_extern: mlirlite.Function* = self.Gen.CallGenBase.find_func_in_module(mod, mangled_name)