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 布局
|
# 方法调用在找不到时会误绑定到 list 特化函数,this 按 list 布局
|
||||||
# 前移 sizeof(list) → 运行期读 -1 崩溃(Config.vp 的
|
# 前移 sizeof(list) → 运行期读 -1 崩溃(Config.vp 的
|
||||||
# root.__getitem__ 根因,与 TPV CallGenCall.vp 兜底修复一致)。
|
# root.__getitem__ 根因,与 TPV CallGenCall.vp 兜底修复一致)。
|
||||||
for _cand_cls, _cand_methods in list(Gen.class_methods.items()):
|
# 进一步加固:兄弟 Mixin 兜底仅在 class_name 是多继承组合类的
|
||||||
if _cand_cls == ClassName:
|
# 父类(存在以 class_name 为父类的类,如 Generator 的 44 个 Mixin /
|
||||||
continue
|
# Combined(BaseA, BaseB))时才启用。普通类(JsonValue 等)方法
|
||||||
if '[' in _cand_cls:
|
# 未命中时不应回退到无关类——3fd875d 只过滤了 list 特化,
|
||||||
continue
|
# HashTable.__getitem__ 仍被误绑(JsonValue.__getitem__ 未命中时
|
||||||
if not any(_cm.endswith(f'.{MethodName}') or _cm == MethodName for _cm in _cand_methods):
|
# 遍历 class_methods 命中 HashTable),this 前移 sizeof(HashTable)
|
||||||
continue
|
# =-48 → Load_project_config root.__getitem__ 读 -1 崩溃
|
||||||
_cand_full = f'{_cand_cls}.{MethodName}'
|
# (1.LOG 4c1f8f779b98eab9.HashTable._slot_hash)。
|
||||||
_cand_func = Gen._find_function(_cand_full)
|
_is_mixin_parent: bool = False
|
||||||
if not _cand_func:
|
try:
|
||||||
_cand_func = Gen._find_function(f'{_cand_full}__')
|
for _s_cls in Gen.structs:
|
||||||
if _cand_func:
|
if _s_cls == ClassName:
|
||||||
func = _cand_func
|
continue
|
||||||
method_anc = _cand_cls
|
if '[' in _s_cls:
|
||||||
break
|
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:
|
if func:
|
||||||
# 多继承 this 调整:继承方法定义在无 vtable 父类且字段区偏移 > 0 时,
|
# 多继承 this 调整:继承方法定义在无 vtable 父类且字段区偏移 > 0 时,
|
||||||
# 把 self 定位到父类第一个用户字段在子类中的位置并 bitcast 成父类指针。
|
# 把 self 定位到父类第一个用户字段在子类中的位置并 bitcast 成父类指针。
|
||||||
|
|||||||
Reference in new issue
Block a user