fix(gen): 模块前言 C 库声明名改落 PermPool,避免被回绕的模块池覆盖

现象:@malloc 的声明名被渲染成乱码,mlir-opt 报 llvm.call @malloc does not reference a symbol in the current scope。根因:create_declare 用 _str_dup(pool, name) 把名字拷进传入的池,而前言用的是模块池(大模块上会被复用/回绕),早期分配的声明名被后续分配覆盖;类型是 mlirlite 内部 interned 的,所以只有名字坏、参数类型正常。修法:声明与参数名改落 CompilerFactory.PermPool(never reset)。
This commit is contained in:
TermiNexus committed 2026-10-08 22:30:07 +08:00
1 parent 8fb0e38f4c
commit 8b2008031d
1 file changed
+20 -10
+20 -10
View File
@@ -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