summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-11-22 18:07:36 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-11-22 18:07:36 +0100
commitc80032d83707e61fa2487f73ff7717166298eccd (patch)
tree0c83f8dbe02dc874f65b912e713ed57fe360dfe9 /src
parentf30d124704d69d2a24d2160a589f541940b8bc43 (diff)
Made fast delegates work on VS x64 builds (nw)
Diffstat (limited to 'src')
-rw-r--r--src/lib/util/delegate.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/lib/util/delegate.h b/src/lib/util/delegate.h
index 1c57fd25d28..3a717de9f86 100644
--- a/src/lib/util/delegate.h
+++ b/src/lib/util/delegate.h
@@ -90,6 +90,7 @@
// types of delegates supported
#define DELEGATE_TYPE_COMPATIBLE 0
#define DELEGATE_TYPE_INTERNAL 1
+#define DELEGATE_TYPE_MSVC 2
// select which one we will be using
#if defined(__GNUC__)
@@ -110,6 +111,10 @@
#define MEMBER_ABI
#define HAS_DIFFERENT_ABI 0
#endif
+#elif defined(_MSC_VER) && defined (PTR64)
+#define MEMBER_ABI
+#define HAS_DIFFERENT_ABI 0
+#define USE_DELEGATE_TYPE DELEGATE_TYPE_MSVC
#else
#define USE_DELEGATE_TYPE DELEGATE_TYPE_COMPATIBLE
#endif
@@ -541,6 +546,64 @@ private:
int m_this_delta; // delta to apply to the 'this' pointer
};
+#elif (USE_DELEGATE_TYPE == DELEGATE_TYPE_MSVC)
+
+// ======================> delegate_mfp
+const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (delegate_generic_class::*)());
+
+// struct describing the contents of a member function pointer
+class delegate_mfp
+{
+public:
+ // default constructor
+ delegate_mfp()
+ : m_function(0) { }
+
+ // copy constructor
+ delegate_mfp(const delegate_mfp &src)
+ : m_function(src.m_function) { }
+
+ // construct from any member function pointer
+ template<typename _MemberFunctionType, class _MemberFunctionClass, typename _ReturnType, typename _StaticFunctionType>
+ delegate_mfp(_MemberFunctionType mfp, _MemberFunctionClass *, _ReturnType *, _StaticFunctionType)
+ {
+ //assert(sizeof(mfp) == 12 || sizeof(mfp) == 16);
+ m_size = sizeof(mfp);
+ *reinterpret_cast<_MemberFunctionType *>(this) = mfp;
+ }
+
+ // comparison helpers
+ bool operator==(const delegate_mfp &rhs) const { return (m_function == rhs.m_function); }
+ bool isnull() const { return (m_function == 0); }
+
+ // getters
+ delegate_generic_class *real_object(delegate_generic_class *original) const { return original; }
+
+ // binding helper
+ template<typename _FunctionType>
+ void update_after_bind(_FunctionType &funcptr, delegate_generic_class *&object)
+ {
+ funcptr = reinterpret_cast<_FunctionType>(m_function);
+ if (m_size == SINGLE_MEMFUNCPTR_SIZE + sizeof(int))
+ object = reinterpret_cast<delegate_generic_class *>(reinterpret_cast<UINT8 *>(object) + m_this_delta);
+ }
+
+private:
+ // extract the generic function and adjust the object pointer
+ delegate_generic_function convert_to_generic(delegate_generic_class *&object) const;
+
+ // actual state
+ FPTR m_function; // first item can be one of two things:
+ // if even, it's a pointer to the function
+ // if odd, it's the byte offset into the vtable
+ int m_this_delta; // delta to apply to the 'this' pointer
+
+ int m_dummy1;
+ int m_dummy2;
+
+ int m_size;
+};
+
#endif