diff options
| author | Alexander Gavrilov | 2012-08-26 13:23:59 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-08-26 14:43:14 +0400 |
| commit | 7f1e4b46bc102014533c015f09a20eef38aab13c (patch) | |
| tree | 8ba3066af58ccaa4c3d0b84fd87ef3b6e03fae31 /library/include | |
| parent | f6e4969e1988422f854989fdde85a8b691d64c73 (diff) | |
| download | dfhack-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.h | 2 | ||||
| -rw-r--r-- | library/include/VTableInterpose.h | 12 |
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(); }; |
