Look through missing intermediate bases when interposing subclasses.

develop
Alexander Gavrilov 2012-10-11 15:10:19 +04:00
parent 010417c812
commit 5206236b01
2 changed files with 19 additions and 3 deletions

@ -281,9 +281,10 @@ VMethodInterposeLinkBase *VMethodInterposeLinkBase::get_first_interpose(virtual_
return item; return item;
} }
void VMethodInterposeLinkBase::find_child_hosts(virtual_identity *cur, void *vmptr) bool VMethodInterposeLinkBase::find_child_hosts(virtual_identity *cur, void *vmptr)
{ {
auto &children = cur->getChildren(); auto &children = cur->getChildren();
bool found = false;
for (size_t i = 0; i < children.size(); i++) for (size_t i = 0; i < children.size(); i++)
{ {
@ -298,17 +299,32 @@ void VMethodInterposeLinkBase::find_child_hosts(virtual_identity *cur, void *vmp
continue; continue;
child_next.insert(base); child_next.insert(base);
found = true;
} }
else else if (child->vtable_ptr)
{ {
void *cptr = child->get_vmethod_ptr(vmethod_idx); void *cptr = child->get_vmethod_ptr(vmethod_idx);
if (cptr != vmptr) if (cptr != vmptr)
continue; continue;
child_hosts.insert(child); child_hosts.insert(child);
found = true;
find_child_hosts(child, vmptr); find_child_hosts(child, vmptr);
} }
else
{
// If this vtable is not known, but any of the children
// have the same vmethod, this one definitely does too
if (find_child_hosts(child, vmptr))
{
child_hosts.insert(child);
found = true;
}
}
} }
return found;
} }
void VMethodInterposeLinkBase::on_host_delete(virtual_identity *from) void VMethodInterposeLinkBase::on_host_delete(virtual_identity *from)

@ -159,7 +159,7 @@ namespace DFHack
void on_host_delete(virtual_identity *host); void on_host_delete(virtual_identity *host);
VMethodInterposeLinkBase *get_first_interpose(virtual_identity *id); VMethodInterposeLinkBase *get_first_interpose(virtual_identity *id);
void find_child_hosts(virtual_identity *cur, void *vmptr); bool find_child_hosts(virtual_identity *cur, void *vmptr);
public: public:
VMethodInterposeLinkBase(virtual_identity *host, int vmethod_idx, void *interpose_method, void *chain_mptr, int priority); VMethodInterposeLinkBase(virtual_identity *host, int vmethod_idx, void *interpose_method, void *chain_mptr, int priority);
~VMethodInterposeLinkBase(); ~VMethodInterposeLinkBase();