diff --git a/App/lib/core/Gen/CallGenCall.vp b/App/lib/core/Gen/CallGenCall.vp index 02d43b3..d867e88 100644 --- a/App/lib/core/Gen/CallGenCall.vp +++ b/App/lib/core/Gen/CallGenCall.vp @@ -952,6 +952,16 @@ class CallGenCall(CallGenBase.CallGenBase): # → AB 场景 B.get_b 按 B 布局读 self.b@12 落到 a → AB 字段/方法 FAILED。 self_arg: llvmlite.Value | t.CPtr = obj_ptr if mc_anc is not None and string.strcmp(mc_anc, class_name) != 0: + # 判断 mc_anc 是否为 class_name 的第一父类:第一父类字段区前缀对齐 + # (delta==0)无需调整;非第一父类必须调整 self,任何一步失败都 + # fail-fast——绝不静默用未调整的 obj_ptr 当 self,否则方法按自身 + # 布局读字段读到垃圾(lookup_reexport strcmp 概率崩溃根因候选)。 + is_first_parent_th: int = 0 + mro_fp_th: t.CSizeT | t.CPtr = HandlesStruct.get_mro_chain(pool, class_name) + if mro_fp_th is not None and mro_fp_th[1] != 0: + first_parent_th: str = (str | t.CPtr)(t.CVoid(mro_fp_th[1], t.CPtr)) + if first_parent_th is not None and string.strcmp(first_parent_th, mc_anc) == 0: + is_first_parent_th = 1 anc_entry_th: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct(mc_anc) if anc_entry_th is not None and anc_entry_th.FieldCount > 0: anc_first_name_th: str = None @@ -995,6 +1005,28 @@ 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 is_first_parent_th == 0: + HandlesType.fatal_error( + cl, + f"this-adjust 字段查找失败: 方法'{method_name}'定义类'{mc_anc}'" + f"首字段'{anc_first_name_th}'在类'{class_name}'/'{mc_anc}'布局中未找到", + "InternalCompilerError") + elif is_first_parent_th == 0: + HandlesType.fatal_error( + cl, + f"this-adjust 子类结构体未注册: 方法'{method_name}'定义类'{mc_anc}'," + f"接收类'{class_name}'的 struct 未找到", + "InternalCompilerError") + elif is_first_parent_th == 0: + HandlesType.fatal_error( + cl, + f"this-adjust 首字段缺失: 方法'{method_name}'定义类'{mc_anc}'无非 vtable 字段", + "InternalCompilerError") + elif is_first_parent_th == 0: + HandlesType.fatal_error( + cl, + f"this-adjust 父类结构体未注册: 方法'{method_name}'定义类'{mc_anc}'的 struct 未找到", + "InternalCompilerError") # 构建参数链表: self → arg1 → arg2 → ... llvmlite.value_set_next(self_arg, None) head: llvmlite.Value | t.CPtr = self_arg