fix(gen): 编译器生成方法 __before_init__ 跨模块调用放行,修复找不到模块 SHA1
- _tc_h6_method_dispatch 增加 hit_box 命中标记:_translate_method_call 返回 None(void 语义)不再被误判未命中,translate_call 不再把对象名当模块名查 SHA1 - AnnotClassName 回退分支新增编译器特殊方法放行:结构体未注册 + 模块 SHA1 不可查(Phase A 依赖未就绪)时,__before_init__/__init__ 由 _special_method_ret_ty 固定返回类型,走 _translate_method_call 处理并标记 _deps_pending 下遍重试 - ExprCallHandle._tc_h6_method_dispatch 委托透传 hit_box,对齐 c.Asm/c.LLVMIR hit_box 修复(2f3320f)
This commit is contained in:
1 parent
2f3320ffde
commit
51ae18a160
3 files changed
+64
-5
No files matched your search
@@ -806,8 +806,16 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
trans: HT.Translator | t.CPtr,
|
||||
func_name: str,
|
||||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||||
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
|
||||
"""静态类/方法调用/表达式接收者/self.field/list 内置(未命中返回 None)"""
|
||||
can: t.CSizeT,
|
||||
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""静态类/方法调用/表达式接收者/self.field/list 内置(未命中返回 None)
|
||||
|
||||
hit_box: 命中标记(t.CPtr,[0]=1 表示已识别为方法调用路径)。
|
||||
编译器生成方法(如 __before_init__/__init__)恒返回 void,
|
||||
_translate_method_call 处理后返回 None(无返回值)——若不标记,
|
||||
translate_call 会误判"未命中"继续走跨模块函数路径(把对象名
|
||||
当模块名查 SHA1 → "跨模块调用 'buf.__before_init__' 找不到模块 SHA1")。
|
||||
"""
|
||||
# 检测类名静态/类方法调用: ClassName.method(args)
|
||||
# 当 cl.func 是 Attribute、value 是已注册结构体类名(非普通变量)时,
|
||||
# 且方法带 @staticmethod/@classmethod 元数据,走静态调用路径
|
||||
@@ -927,6 +935,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
# vpi stub 均未命中)→ fail-fast。检测到 list 方法时
|
||||
# 跳过 method_call,落到内置分支(NewAstTest body.append 根因)。
|
||||
if ExprCallHandle._is_list_builtin_method(class_nm, func_name) == 0:
|
||||
if hit_box is not None:
|
||||
hit_box[0] = 1
|
||||
return ExprCallCtor._translate_method_call(
|
||||
pool, builder, mod, class_nm, func_name,
|
||||
obj_var, cl, trans)
|
||||
@@ -942,6 +952,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
obj_ptr: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
builder, obj_struct_ty, obj_var)
|
||||
if obj_ptr is not None:
|
||||
if hit_box is not None:
|
||||
hit_box[0] = 1
|
||||
return ExprCallCtor._translate_method_call(
|
||||
pool, builder, mod, inner_nm, func_name,
|
||||
obj_ptr, cl, trans)
|
||||
@@ -983,6 +995,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
obj_ptr2: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
builder, i8_ptr_ty2, obj_var)
|
||||
if obj_ptr2 is not None:
|
||||
if hit_box is not None:
|
||||
hit_box[0] = 1
|
||||
return ExprCallCtor._translate_method_call(
|
||||
pool, builder, mod, cls_nm2, func_name,
|
||||
obj_ptr2, cl, trans)
|
||||
@@ -1056,6 +1070,30 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
ret_ty3 = llvmlite.Void(pool)
|
||||
self._ensure_method_declare(pool, mod, mangled3, ret_ty3, head3, total3)
|
||||
return llvmlite.build_call(builder, mangled3, head3, total3, ret_ty3, 0)
|
||||
else:
|
||||
# 编译器生成特殊方法放行(__before_init__/__init__ 等):
|
||||
# 结构体未注册 + 模块 SHA1 均不可查(Phase A 依赖未就绪)时,
|
||||
# 方法返回类型由编译器确定性定义(_special_method_ret_ty),
|
||||
# 不依赖结构体注册即可精确解析。走 _translate_method_call 处理
|
||||
# (内部含 _special_method_ret_ty + mc_entry/类型名 SHA1 提取),
|
||||
# 绝不掉出返回 None 让 translate_call 把对象名当模块名
|
||||
# 报"跨模块调用 'buf.__before_init__' 找不到模块 SHA1"
|
||||
# (memhub.alloc_buf buf.__before_init__() 根因)。
|
||||
sp_ty4: llvmlite.LLVMType | t.CPtr = self._special_method_ret_ty(
|
||||
pool, cls_nm2, func_name)
|
||||
if sp_ty4 is not None:
|
||||
i8_ptr_ty4: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(
|
||||
pool, llvmlite.Int8(pool))
|
||||
obj_ptr4: llvmlite.Value | t.CPtr = llvmlite.build_load(
|
||||
builder, i8_ptr_ty4, obj_var)
|
||||
if obj_ptr4 is not None:
|
||||
if trans is not None:
|
||||
trans._deps_pending = 1
|
||||
if hit_box is not None:
|
||||
hit_box[0] = 1
|
||||
return ExprCallCtor._translate_method_call(
|
||||
pool, builder, mod, cls_nm2, func_name,
|
||||
obj_ptr4, cl, trans)
|
||||
|
||||
# ============================================================
|
||||
# 检测表达式接收者方法调用: (expr).method(args)
|
||||
@@ -1133,6 +1171,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
builder, pool, mod, expr_method_at.value, trans)
|
||||
if expr_addr is not None:
|
||||
expr_obj = expr_addr
|
||||
if hit_box is not None:
|
||||
hit_box[0] = 1
|
||||
return ExprCallCtor._translate_method_call(
|
||||
pool, builder, mod, expr_cls_nm, func_name,
|
||||
expr_obj, cl, trans)
|
||||
@@ -1206,6 +1246,8 @@ class CallGenDispatch(CallGenBase.CallGenBase):
|
||||
builder, pool, mod, attr_method_at.value, trans)
|
||||
if field_addr is not None:
|
||||
field_obj = field_addr
|
||||
if hit_box is not None:
|
||||
hit_box[0] = 1
|
||||
return ExprCallCtor._translate_method_call(
|
||||
pool, builder, mod, field_cls_nm, func_name,
|
||||
field_obj, cl, trans)
|
||||
|
||||
@@ -190,10 +190,26 @@ class CallGenMixin(CallGenBase.CallGenBase):
|
||||
if _tc_h5_sizeof_len_isinst_res is not None:
|
||||
return _tc_h5_sizeof_len_isinst_res
|
||||
|
||||
# c.Asm/c.LLVMIR 等方法调用分派:方法调用识别成功但返回 None
|
||||
# (如编译器生成方法 __before_init__/__init__ 恒返回 void,_translate_
|
||||
# method_call 或 _emit_eh_guarded_call 处理后可能返回 None)时,须用
|
||||
# hit_box 区分"已识别为方法调用"与"未命中",否则 translate_call 误判
|
||||
# 未命中继续走跨模块函数路径,把对象名当模块名查 SHA1 →
|
||||
# "跨模块调用 'buf.__before_init__' 找不到模块 SHA1"(memhub.alloc_buf 根因)。
|
||||
h6_hit: t.CPtr = stdlib.malloc(4)
|
||||
if h6_hit is not None:
|
||||
h6_hit[0] = 0
|
||||
_tc_h6_method_dispatch_res: llvmlite.Value | t.CPtr = ExprCallHandle._tc_h6_method_dispatch(
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
|
||||
pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, h6_hit)
|
||||
h6_hit_val: int = 0
|
||||
if h6_hit is not None:
|
||||
h6_hit_val = h6_hit[0]
|
||||
stdlib.free(h6_hit)
|
||||
if _tc_h6_method_dispatch_res is not None:
|
||||
return _tc_h6_method_dispatch_res
|
||||
if h6_hit_val != 0:
|
||||
# 命中方法调用路径但无返回值(编译器生成方法等 void 语义):视为已处理
|
||||
return None
|
||||
|
||||
# 获取关键字参数
|
||||
keywords: list[ast.AST | t.CPtr] | t.CPtr = cl.keywords
|
||||
|
||||
@@ -228,12 +228,13 @@ def _tc_h6_method_dispatch(pool: memhub.MemBuddy | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
func_name: str,
|
||||
cargs: list[ast.AST | t.CPtr] | t.CPtr,
|
||||
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
|
||||
can: t.CSizeT,
|
||||
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""静态类/方法调用/表达式接收者/self.field/list 内置(委托到 gen._tc_h6_method_dispatch)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g._tc_h6_method_dispatch(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
|
||||
return g._tc_h6_method_dispatch(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, hit_box)
|
||||
return None
|
||||
# ============================================================
|
||||
# FuncGen 跨 Mixin 委托(阶段 D:FuncGenMixin 拆 Base/Def 后顶层经
|
||||
|
||||
Reference in new issue
Block a user