fix(link): 补 CallGenLib._promote_clib_call_args 定义;BuildPipeline PYI_BUF_SIZE 改 t.CDefine 宏

CallGenMixin.translate_call 调用 self.Gen.CallGenLib._promote_clib_call_args(B3 裸名 C 库函数第三参 i64 提升),但 CallGenLib 缺该方法 → ld.lld undefined symbol。按 TPVAppBK 旧语法移植完整方法。

PYI_BUF_SIZE 是跨模块共享裸全局(@PYI_BUF_SIZE),Phase1/__init__ 与 BuildPipeline 两模块各定义强符号 → duplicate symbol。BuildPipeline 侧改用 t.CDefine 宏(同 SRC_BUF_SIZE),不再产生全局。
This commit is contained in:
TermiNexus committed 2026-09-05 12:48:03 +08:00
1 parent 8dda9f7c2d
commit 50d53d3ce6
2 files changed
+77 -1

No files matched your search

+3 -1
View File
@@ -50,7 +50,9 @@ _phase2_bat_init: int = 0
SRC_BUF_SIZE: t.CDefine = 1048576 # 2^20 = 1MB
# .vpi 存根缓冲区大小(256KB,与 Phase1 一致)
PYI_BUF_SIZE: t.CSizeT = 262144
# 用 t.CDefine 宏而非模块级全局:模块级全局是跨模块共享裸符号(@PYI_BUF_SIZE),
# Phase1/__init__.vp 已定义同名全局 → 两模块各定义强符号 → ld.lld duplicate symbol。
PYI_BUF_SIZE: t.CDefine = 262144
# ============================================================
# TranslateFileGetTrans - 翻译单个文件,返回 Translator 对象
+74
View File
@@ -109,6 +109,80 @@ class CallGenLib(CallGenBase.CallGenBase):
llvmlite.add_param(pool, fn, i8_ptr_ty, "src")
llvmlite.add_param(pool, fn, i64_ty, "n")
return fn
def _promote_clib_call_args(self, pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
call_name: str,
head: llvmlite.Value | t.CPtr,
count: int) -> llvmlite.Value | t.CPtr:
"""裸名 C 库函数实参按标准签名提升(B3)。
跨模块裸名调用(string.memset → @memset)时 _ensure_method_declare 用
实参类型建 declare:第三参字面量 32=i32 把定义 t.CSizeT(i64) 固化窄
→ declare/call @memset(i8*,i32,i32) vs 定义 @memset(i8*,i32,i64),
ABI 宽度不一致(VKernel process.vp B3)。调用点先把第三参窄整数
实参提升到 i64,declare 与 call 均按 i64 生成 → 与定义一致。
未命中白名单原样返回 head。
"""
if pool is None or builder is None or call_name is None or head is None:
return head
# 仅裸名(无 '.' 分隔 → 无 sha1 前缀);带前缀走 vpi 定义侧解析
if string.strchr(call_name, 46) is not None:
return head
# 白名单:第三参 size_t(i64) 的函数(与 _ensure_c_lib_declare 一致)
is_3rd_i64: int = 0
if string.strcmp(call_name, "memset") == 0: is_3rd_i64 = 1
elif string.strcmp(call_name, "memcpy") == 0: is_3rd_i64 = 1
elif string.strcmp(call_name, "memmove") == 0: is_3rd_i64 = 1
elif string.strcmp(call_name, "memcmp") == 0: is_3rd_i64 = 1
elif string.strcmp(call_name, "strncmp") == 0: is_3rd_i64 = 1
elif string.strcmp(call_name, "strncpy") == 0: is_3rd_i64 = 1
elif string.strcmp(call_name, "strncat") == 0: is_3rd_i64 = 1
if is_3rd_i64 == 0 or count < 3:
return head
# 定位第三参(index 2)
cur: llvmlite.Value | t.CPtr = head
idx: int = 0
while cur is not None and idx < 2:
cur = cur.Next
idx += 1
if cur is None or cur.Ty is None:
return head
i64_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int64(pool)
promoted: llvmlite.Value | t.CPtr = None
match cur.Ty:
case llvmlite.LLVMType.Int(bits):
if bits >= 64:
return head
if cur.IsConst != 0:
# 常量:直接 i64 常量(位模式保留,无符号长度语义)
promoted = llvmlite.const_int(pool, 64, cur.IntVal)
else:
# SSA 值:zext 到 i64(size_t 无符号长度)
promoted = llvmlite.build_zext(builder, cur, i64_ty)
case _:
return head
if promoted is None:
return head
# 重建实参链表:index 2 替换为提升后的值
new_head: llvmlite.Value | t.CPtr = None
new_tail: llvmlite.Value | t.CPtr = None
cur2: llvmlite.Value | t.CPtr = head
i2: int = 0
while cur2 is not None:
node_v: llvmlite.Value | t.CPtr = cur2
if i2 == 2:
node_v = promoted
if new_head is None:
new_head = node_v
else:
new_tail.Next = node_v
new_tail = node_v
cur2 = cur2.Next
i2 += 1
return new_head
def _infer_external_func_ret_ty(self, pool: memhub.MemBuddy | t.CPtr,
func_name: str,
node: ast.AST | t.CPtr,