fix(gen): this-adjust 补兄弟 Mixin 分支——BaseB 内调 BaseA.helper 前移 sizeof(BaseA)

兄弟 Mixin 兜底(086e792)找到 BaseA.helper 后,this 调整在 BaseB 中查不到 BaseA 首字段'a'走 fail-fast(NoVTableCrossMixinTest BaseB.caller 根因)。对齐 TPC _adjust_this_for_inherited_method 的 sibling 分支:this 前移 -sizeof(定义类 struct),使 BaseA.helper 按自身布局读 self 字段。
This commit is contained in:
TermiNexus committed 2026-08-20 11:35:35 +08:00
1 parent 086e792b30
commit 765702bb5f
1 file changed
+32
+32
View File
@@ -1015,6 +1015,38 @@ class CallGenCall(CallGenBase.CallGenBase):
# 函数体内的 bitcast 类型不会被自动声明)。
llvmlite.module_ensure_opaque_for_type(mod, pool, anc_ptr_ty_th)
self_arg = llvmlite.build_bitcast(builder, adj_th, anc_ptr_ty_th)
elif sub_field_th is None and anc_field_th is not None:
# 兄弟 Mixin 场景(对齐 TPC _adjust_this_for_inherited_method):
# 调用类(class_name=BaseB)不含定义类(mc_anc=BaseA)字段——
# BaseA 在组合类 MRO 中位于 BaseB 之前(如 Combined(BaseA, BaseB),
# BaseB 内 self.helper() 调 BaseA.helper)。BaseB.this 指向组合类中
# BaseB 字段区起点,BaseA 区在它前面,this 前移 sizeof(定义类)。
# 若无此分支,sub_field_th 查找失败 → 下方 fail-fast,兄弟 Mixin
# 调用永远编译不过(NoVTableCrossMixinTest BaseB.caller 根因)。
anc_size_th: int = self._get_type_size(anc_entry_th.Ty)
if anc_size_th > 0:
i8_ty_th2: llvmlite.LLVMType | t.CPtr = llvmlite.Int8(pool)
i8_ptr_th2: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(pool, i8_ty_th2)
obj_i8_th2: llvmlite.Value | t.CPtr = llvmlite.build_bitcast(
builder, obj_ptr, i8_ptr_th2)
sib_delta_th: llvmlite.Value | t.CPtr = llvmlite.const_int32(
pool, 0 - anc_size_th)
adj_th2: llvmlite.Value | t.CPtr = llvmlite.build_gep(
builder, i8_ty_th2, obj_i8_th2, sib_delta_th)
if adj_th2 is not None:
anc_ptr_ty_th2: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(
pool, anc_entry_th.Ty)
llvmlite.module_ensure_opaque_for_type(
mod, pool, anc_ptr_ty_th2)
self_arg = llvmlite.build_bitcast(
builder, adj_th2, anc_ptr_ty_th2)
else:
# 定义类 struct 大小不可得(opaque/未加载):fail-fast
HandlesType.fatal_error(
cl,
f"this-adjust 兄弟 Mixin 定义类大小未知: 方法'{method_name}'"
f"定义类'{mc_anc}'的 struct 大小计算失败",
"InternalCompilerError")
elif is_first_parent_th == 0:
HandlesType.fatal_error(
cl,