通过了 Memhub BuddyTest 测试
This commit is contained in:
1 parent
f8436c74d2
commit
6d3fc4569c
2 files changed
+95
-2
No files matched your search
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user