From 8a0da2946115b5de45f35ceeb814375956f294fc Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 21 Aug 2026 01:26:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(exprcall):=20=E5=85=84=E5=BC=9F=20Mixin=20?= =?UTF-8?q?=E5=85=9C=E5=BA=95=E6=8C=89=E8=B0=83=E7=94=A8=E7=B1=BB=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E5=A3=B0=E6=98=8E=E8=AF=A5=E6=96=B9=E6=B3=95=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=EF=BC=8C=E4=BF=AE=E5=A4=8D=20NoVTable=20=E5=9B=9E?= =?UTF-8?q?=E5=BD=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 780cd4a 用 MRO/组合类判断 _is_mixin_parent 不可靠:Combined 定义在 BaseB 之后,BaseB.caller 翻译时组合类未注册、MRO 查询失败 → 兜底静默跳过 → NoVTableCrossMixinTest 的 TPC 编译 fallback 生成不存在的 BaseB.helper(定义在 BaseA)→ ld.lld undefined symbol(回归)。 改为:调用类自身声明了该方法(class_methods 含 MethodName)但 stub 未命中(如 JsonValue.__getitem__ 跨模块 stub 注册问题)→ 不兜底,fail-fast 暴露上游 stub 问题(防误绑 HashTable,1.LOG 根因);调用类未声明(BaseB.helper / MixinC2.mid2)→ 跨 Mixin,全量遍历找定义类。保留 list 特化过滤(3fd875d)。 --- lib/core/Handles/HandlesExprCall.py | 54 ++++++++++++----------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index 696b00e..7a225af 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -3165,38 +3165,28 @@ class ExprCallHandle(BaseHandle): method_anc = anc break if not func or len(list(func.blocks)) == 0: - # 兄弟 Mixin 兜底:方法不在本类 MRO 链(如 BaseB 内 self.helper() - # 调兄弟 BaseA.helper,BaseB 自身无 BaseA 的继承信息)。全局扫描 - # 已注册类找定义类,this 由 _adjust_this_for_inherited_method 按 - # 组合布局前移 sizeof(定义类 struct)。修复 TPC 编译 TPV 的 - # undefined symbol: .BaseB.helper / StmtGenDeclMixin.translate_*。 - # 仅对普通类名兜底:泛型特化类名(list[X]/dict[K,V],含 '[')是 - # 模板容器,其特化函数(如 list[ASTptr].__getitem__)在模块中存在 - # 但绝非"兄弟 Mixin"——若不过滤,JsonValue.__getitem__ 等普通 - # 方法调用在找不到时会误绑定到 list 特化函数,this 按 list 布局 - # 前移 sizeof(list) → 运行期读 -1 崩溃(Config.vp 的 - # root.__getitem__ 根因,与 TPV CallGenCall.vp 兜底修复一致)。 - # 进一步加固:兄弟 Mixin 兜底仅在 class_name 是多继承组合类的 - # 父类(存在以 class_name 为父类的类,如 Generator 的 44 个 Mixin / - # Combined(BaseA, BaseB))时才启用。普通类(JsonValue 等)方法 - # 未命中时不应回退到无关类——3fd875d 只过滤了 list 特化, - # HashTable.__getitem__ 仍被误绑(JsonValue.__getitem__ 未命中时 - # 遍历 class_methods 命中 HashTable),this 前移 sizeof(HashTable) - # =-48 → Load_project_config root.__getitem__ 读 -1 崩溃 - # (1.LOG 4c1f8f779b98eab9.HashTable._slot_hash)。 - _is_mixin_parent: bool = False - try: - for _s_cls in Gen.structs: - if _s_cls == ClassName: - continue - if '[' in _s_cls: - continue - if ClassName in Gen._get_mro_chain(_s_cls): - _is_mixin_parent = True - break - except Exception: - _is_mixin_parent = False - if _is_mixin_parent: + # 兄弟 Mixin 兜底:仅当"调用类自身未声明该方法"时启用。 + # 判断依据 class_methods[ClassName]: + # * BaseB.caller 调 self.helper()——BaseB 无 helper(源码未定义) + # → 跨 Mixin → 在其它注册类中找定义类(BaseA.helper)✓ + # * JsonValue.__getitem__ 源码定义存在但 stub 未命中(如 TPV 自身 + # 编译 Config.vp 时跨模块 stub 注册/时序问题)→ 不兜底, + # fail-fast(Undefined method)暴露上游 stub 问题——避免误绑 + # 无关类 HashTable.__getitem__(this 前移 sizeof(HashTable)=-48 + # → Load_project_config 读 -1 崩溃,1.LOG 根因;3fd875d 只 + # 过滤 list 特化,普通类仍被误绑)。 + # 注:不能用 MRO/组合类判断(Combined 定义在 BaseB 之后,BaseB.caller + # 翻译时组合类未注册,MRO 查询不可靠——780cd4a 引入 NoVTable 回归)。 + _self_has_method: bool = False + _cm_map = getattr(Gen, 'class_methods', None) + if isinstance(_cm_map, dict): + _self_methods = _cm_map.get(ClassName) + if _self_methods: + for _sm in _self_methods: + if _sm == MethodName or _sm.endswith(f'.{MethodName}'): + _self_has_method = True + break + if not _self_has_method: for _cand_cls, _cand_methods in list(Gen.class_methods.items()): if _cand_cls == ClassName: continue