summaryrefslogtreecommitdiff
path: root/library/include
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-08-26 13:23:59 +0400
committerAlexander Gavrilov2012-08-26 14:43:14 +0400
commit7f1e4b46bc102014533c015f09a20eef38aab13c (patch)
tree8ba3066af58ccaa4c3d0b84fd87ef3b6e03fae31 /library/include
parentf6e4969e1988422f854989fdde85a8b691d64c73 (diff)
downloaddfhack-7f1e4b46bc102014533c015f09a20eef38aab13c.tar.gz
dfhack-7f1e4b46bc102014533c015f09a20eef38aab13c.tar.bz2
dfhack-7f1e4b46bc102014533c015f09a20eef38aab13c.tar.xz
Implement inheritance-aware vmethod interposing.
I.e. overwriting the vmethod in all vtables that use it, not only one.
Diffstat (limited to 'library/include')
-rw-r--r--library/include/DataDefs.h2
-rw-r--r--library/include/VTableInterpose.h12
2 files changed, 12 insertions, 2 deletions
diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h
index ccb29b0e..591a0c3f 100644
--- a/library/include/DataDefs.h
+++ b/library/include/DataDefs.h
@@ -303,7 +303,7 @@ namespace DFHack
void *vtable_ptr;
friend class VMethodInterposeLinkBase;
- std::vector<VMethodInterposeLinkBase*> interpose_list;
+ std::map<int,VMethodInterposeLinkBase*> interpose_list;
protected:
virtual void doInit(Core *core);
diff --git a/library/include/VTableInterpose.h b/library/include/VTableInterpose.h
index bb7a37ce..c9482f82 100644
--- a/library/include/VTableInterpose.h
+++ b/library/include/VTableInterpose.h
@@ -134,21 +134,31 @@ namespace DFHack
1) Allow multiple hooks into the same vmethod
2) Auto-remove hooks when a plugin is unloaded.
*/
+ friend class virtual_identity;
virtual_identity *host; // Class with the vtable
int vmethod_idx;
void *interpose_method; // Pointer to the code of the interposing method
void *chain_mptr; // Pointer to the chain field below
+ bool applied;
void *saved_chain; // Previous pointer to the code
VMethodInterposeLinkBase *next, *prev; // Other hooks for the same method
+ // inherited vtable members
+ std::set<virtual_identity*> child_hosts;
+ std::set<VMethodInterposeLinkBase*> child_next;
+
void set_chain(void *chain);
+ void on_host_delete(virtual_identity *host);
+
+ VMethodInterposeLinkBase *get_first_interpose(virtual_identity *id);
+ void find_child_hosts(virtual_identity *cur, void *vmptr);
public:
VMethodInterposeLinkBase(virtual_identity *host, int vmethod_idx, void *interpose_method, void *chain_mptr);
~VMethodInterposeLinkBase();
- bool is_applied() { return saved_chain != NULL; }
+ bool is_applied() { return applied; }
bool apply();
void remove();
};