TermiNexus
f748cae562
fix(TPV/CallGenCall): 判据化重加兄弟 Mixin 方法解析(修 NoVTableCrossMixinTest 未定义符号)
现场:Test/NoVTableCrossMixinTest 链接期报
ld.lld: error: undefined symbol: 1e19037e6cfdce36.BaseB.helper
>>> referenced by ...(1e19037e6cfdce36.BaseB.caller)
ld.lld: error: undefined symbol: 1e19037e6cfdce36.MixinC2.mid2
>>> referenced by ...(1e19037e6cfdce36.MixinC2.outer2)
这是 455c760 删除"兄弟 Mixin 兜底"的必然结果:NoVTable 多继承下,Mixin 内的
self.<兄弟方法>()(Combined(BaseA, BaseB) 中 BaseB.caller 调 BaseA.helper)本类
MRO 查不到、跨模块 stub 也没有 ⇒ 调用名退化成 {sha1}.BaseB.helper(该符号不存在)。
改动(不是恢复原兜底,而是**判据化解析**,不做"同名即绑"的猜测):
- CallGenCall._translate_method_call:在自身 MRO 查找失败后新增兄弟 Mixin 解析,
两条**正向判据**缺一不可:
① 接收类必须是某个已注册类的**直接父类**(它确实被组合使用,是真 Mixin)——
挡掉 includes/w32/fileio.vp 的 FileW.__init__ → self.seek() 误绑 File.seek
(FileW 无人继承,不是任何人的 Mixin);
② 候选类与接收类必须同处某个已注册**组合类的 MRO**(真·兄弟)。
命中后 found_func / mc_anc 都指向定义类 ⇒ 调用名用定义类 SHA1 前缀(符号存在),
this 由既有的 mc_anc this-adjust 分支按组合布局前移(该分支未改动)。
只取**本模块内已有函数**的候选(跨模块定义类需经其 text.ll 取签名,本轮不启用);
接收类为跨模块类时不启用(沿用原 sib_recv_local 守卫,避免误绑跨模块同名方法)。
- 新增两个判据辅助方法:_recv_is_mixin_base / _mixin_sibling_same_composite。
待验证:重编译 TransPyV(自举两遍)→ NoVTableCrossMixinTest / WebTest / FileIoTest。