diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index 8d15244..696b00e 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -3176,21 +3176,42 @@ class ExprCallHandle(BaseHandle): # 方法调用在找不到时会误绑定到 list 特化函数,this 按 list 布局 # 前移 sizeof(list) → 运行期读 -1 崩溃(Config.vp 的 # root.__getitem__ 根因,与 TPV CallGenCall.vp 兜底修复一致)。 - for _cand_cls, _cand_methods in list(Gen.class_methods.items()): - if _cand_cls == ClassName: - continue - if '[' in _cand_cls: - continue - if not any(_cm.endswith(f'.{MethodName}') or _cm == MethodName for _cm in _cand_methods): - continue - _cand_full = f'{_cand_cls}.{MethodName}' - _cand_func = Gen._find_function(_cand_full) - if not _cand_func: - _cand_func = Gen._find_function(f'{_cand_full}__') - if _cand_func: - func = _cand_func - method_anc = _cand_cls - break + # 进一步加固:兄弟 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: + for _cand_cls, _cand_methods in list(Gen.class_methods.items()): + if _cand_cls == ClassName: + continue + if '[' in _cand_cls: + continue + if not any(_cm.endswith(f'.{MethodName}') or _cm == MethodName for _cm in _cand_methods): + continue + _cand_full = f'{_cand_cls}.{MethodName}' + _cand_func = Gen._find_function(_cand_full) + if not _cand_func: + _cand_func = Gen._find_function(f'{_cand_full}__') + if _cand_func: + func = _cand_func + method_anc = _cand_cls + break if func: # 多继承 this 调整:继承方法定义在无 vtable 父类且字段区偏移 > 0 时, # 把 self 定位到父类第一个用户字段在子类中的位置并 bitcast 成父类指针。