通过了 Memhub BuddyTest 测试

This commit is contained in:
TermiNexus committed 2026-08-06 19:50:46 +08:00
1 parent f8436c74d2
commit 6d3fc4569c
2 files changed
+95 -2

No files matched your search

+46 -1
View File
@@ -5182,6 +5182,11 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
# 查找函数:优先从函数表按裸名精确匹配(同模块函数),
# 再从模块函数链表按后缀匹配(SHA1 前缀名)。
# 注意:模块限定/属性调用(如 stdlib.free)不能做后缀匹配——
# "free" 会误命中 viperio.Buf.free 等方法,导致普通 malloc 指针被
# 当作 Buf 对象释放(Buf.free 读 self 字段/写 self.data),
# 传入句柄数组等指针时把句柄值当地址写入直接崩溃。
# 后缀匹配仅用于裸名调用(cl.func 是 Name,如 _thread_alloc_free)。
# stubs 在翻译后才注入,翻译时跨模块函数 found_func 通常为 None,
# 此时根据函数名推断 includes 库函数的返回类型(如 strchr 返回 i8*)
# 如果调用方未传 funcs_ptr/func_count(如 AnnAssign 路径),从 trans 获取
@@ -5190,7 +5195,47 @@ def translate_call(pool: memhub.MemBuddy | t.CPtr,
if actual_funcs is None and trans is not None:
actual_funcs = trans._funcs
actual_func_count = trans._func_count
found_func: llvmlite.Function | t.CPtr = find_func_in_module(mod, func_name)
found_func: llvmlite.Function | t.CPtr = None
if cl.func is not None and cl.func.kind() == ast.ASTKind.Name:
# 裸名调用:允许精确 + 后缀匹配
found_func = find_func_in_module(mod, func_name)
else:
# 模块限定/属性调用:精确匹配优先,后缀匹配仅接受模块函数。
# 后缀匹配命中的"方法"(SHA1.Class.method,Class 是已注册类)必须拒绝——
# 短方法名(free/reset/close 等)会误命中其他模块的方法
# (如 stdlib.free 命中 viperio.Buf.free,普通指针被当 Buf 释放崩溃;
# 且 atom.__atomic_test_and_set 若被误拒,返回类型从 i1 推断成 i32,
# 调用按 i32 读 i1 返回值读到垃圾高位,spinlock 恒非 0 卡死)。
# 模块函数(SHA1.func)或子模块函数(SHA1.submod.func)的后缀匹配保留。
found_func = find_func_in_module(mod, func_name)
if found_func is not None:
ff_name: t.CChar | t.CPtr = llvmlite.function_get_name(found_func)
if ff_name is not None:
ff_dots: int = 0
ffi2: t.CSizeT = 0
while ff_name[ffi2] != '\0':
if ff_name[ffi2] == '.':
ff_dots += 1
ffi2 += 1
if ff_dots >= 2:
# 提取第 2 段(SHA1.Class.method → Class;SHA1.submod.func → submod)
seg2: t.CChar | t.CPtr = pool.alloc(64)
if seg2 is not None:
seg2[0] = '\0'
si: t.CSizeT = 0
while ff_name[si] != '\0' and si < 17:
si += 1
seg_start: t.CSizeT = si
seg_end: t.CSizeT = si
while ff_name[seg_end] != '\0' and ff_name[seg_end] != '.':
seg_end += 1
seg_len: t.CSizeT = seg_end - seg_start
if seg_len > 0 and seg_len < 63:
string.strncpy(seg2, ff_name + seg_start, seg_len)
seg2[seg_len] = '\0'
# 第 2 段是已注册结构体类 → 是方法,拒绝(走模块 SHA1 路径)
if HandlesStruct.get_struct_type(seg2) is not None:
found_func = None
# C 库函数裸名调用支持:若模块中找不到且是已知 C 库函数,自动创建 declare
# 对应 TPC 的 _C_LIB_FUNCS 机制,支持 memset/memmove/memcmp/strcmp 等裸名调用
if found_func is None and cl.func is not None and cl.func.kind() == ast.ASTKind.Name: