diff --git a/App/lib/core/Gen/Translator.vp b/App/lib/core/Gen/Translator.vp index 80e2457..f9fdd8d 100644 --- a/App/lib/core/Gen/Translator.vp +++ b/App/lib/core/Gen/Translator.vp @@ -10,6 +10,7 @@ import stdio import stdlib import viperlib import lib.core.VLogger as VLogger +import lib.core.CompilerFactory as CompilerFactory import lib.Projectrans.Config as Config import lib.Stub.StubMerger.StubMergerBuild as StubMergerBuild import lib.Stub.StubMerger.StubMergerStore as StubMergerStore @@ -413,34 +414,43 @@ novirtual class Translator: i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool) i8_ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, i8_ty) + # 模块前言里 C 库声明的**名字**必须落在 PermPool:create_declare 会 _str_dup(pool, name) + # 把名字拷进传入的池,而本模块池(trans.Pool)在大模块上会被复用/回绕,覆盖早期分配 → + # 名字悬空(现场:@malloc 被渲染成乱码 @"PL\xEF\xBF\xBDp…",mlir-opt 报 + # "'llvm.call' op 'malloc' does not reference a symbol in the current scope"; + # 类型是 mlirlite 内部 interned 的,所以只有名字坏、参数类型正常)。 + # PermPool 是"persistent data; never reset",正好符合声明名的生命周期。 + decl_pool: memhub.MemBuddy* = CompilerFactory.factory.PermPool + if decl_pool is None: decl_pool = pool + # Declare printf - printf_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "printf", i32_ty) + printf_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "printf", i32_ty) if printf_func is None: VLogger.error("CreateDeclare printf returned NULL", "TR") return 1 - mlirlite.add_param(pool, printf_func, i8_ptr_ty, "fmt") + mlirlite.add_param(decl_pool, printf_func, i8_ptr_ty, "fmt") printf_func.IsVarArg = 1 # Declare LLVM va_start/va_end intrinsics (used inside *args function bodies): # declare void @llvm.va_start(i8*) / declare void @llvm.va_end(i8*) void_ty_decl: mlirlite.LLVMType* = mlirlite.Void(pool) - va_start_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "llvm.va_start", void_ty_decl) - if va_start_func is not None: mlirlite.add_param(pool, va_start_func, i8_ptr_ty, "ap") - va_end_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "llvm.va_end", void_ty_decl) - if va_end_func is not None: mlirlite.add_param(pool, va_end_func, i8_ptr_ty, "ap") + va_start_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "llvm.va_start", void_ty_decl) + if va_start_func is not None: mlirlite.add_param(decl_pool, va_start_func, i8_ptr_ty, "ap") + va_end_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "llvm.va_end", void_ty_decl) + if va_end_func is not None: mlirlite.add_param(decl_pool, va_end_func, i8_ptr_ty, "ap") # Declare malloc (for closure allocation) - malloc_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "malloc", i8_ptr_ty) + malloc_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "malloc", i8_ptr_ty) if malloc_func is not None: i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool) - mlirlite.add_param(pool, malloc_func, i64_ty, "size") + mlirlite.add_param(decl_pool, malloc_func, i64_ty, "size") # Declare free (counterpart of malloc): M3 owned slife 的出口释放要用它。 # 必须在这里(模块前言)声明:释放点只做**查表 + fail-fast**(VarGenMixin._SlifeEmitGuardedFree),不再现场建 declare—— # 否则同一模块的每个出口各建一份重复 declare。缺了它 mlir-opt 会报 # "'llvm.call' op 'free' does not reference a symbol in the current scope" # (现场:Test/NewLifetimeTest 未 import stdlib,拿不到 stdlib vpi 的 declare)。 - free_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "free", void_ty_decl) - if free_func is not None: mlirlite.add_param(pool, free_func, i8_ptr_ty, "p") + free_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "free", void_ty_decl) + if free_func is not None: mlirlite.add_param(decl_pool, free_func, i8_ptr_ty, "p") # Check whether the user defined a main function has_user_main: int = 0