fix(exprcall): 兄弟 Mixin 兜底仅对组合类父类启用——防误绑 HashTable 方法
3fd875d 只过滤了 list 特化类名,普通类(HashTable)仍被误绑:JsonValue.__getitem__ 未命中时遍历 class_methods 命中 HashTable.__getitem__,this 前移 sizeof(HashTable)=-48 → Load_project_config root.__getitem__ 读 -1 崩溃(1.LOG 4c1f8f779b98eab9.HashTable._slot_hash)。
加固:兜底前检查 class_name 是否是多继承组合类的父类(存在以它为父类的类,如 Generator 的 44 个 Mixin / Combined(BaseA,BaseB))。普通类方法未命中时不再回退到无关类,走 fail-fast(Undefined method)暴露上游 stub 注册/时序问题。
This commit is contained in:
1 parent
51c0e026f4
commit
780cd4a13b
1 file changed
+36
-15
@@ -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 成父类指针。
|
||||
|
||||
Reference in new issue
Block a user