mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Support __stdcall nsRunnableMethods (part 2/3 of bug 558498). r=dwitte sr=dbaron
This commit is contained in:
parent
2b2bd4076f
commit
ec00ae01fb
12
configure.in
12
configure.in
@ -2842,6 +2842,18 @@ AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_MSG_CHECKING(for __stdcall)
|
||||
AC_CACHE_VAL(ac_cv___stdcall,
|
||||
[AC_TRY_COMPILE([],
|
||||
[void foo(); void __stdcall foo();],
|
||||
[ac_cv___stdcall=true],
|
||||
[ac_cv___stdcall=false])])
|
||||
if test "$ac_cv___stdcall" = true ; then
|
||||
AC_DEFINE(HAVE_STDCALL)
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
AC_MSG_CHECKING(for ssize_t)
|
||||
AC_CACHE_VAL(ac_cv_type_ssize_t,
|
||||
[AC_TRY_COMPILE([#include <stdio.h>
|
||||
|
@ -262,21 +262,6 @@ protected:
|
||||
#undef IMETHOD_VISIBILITY
|
||||
#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
|
||||
|
||||
template <class ClassType, bool Owning>
|
||||
struct RunnableMethodReceiver {
|
||||
ClassType *mObj;
|
||||
RunnableMethodReceiver(ClassType *obj) : mObj(obj) { NS_IF_ADDREF(mObj); }
|
||||
~RunnableMethodReceiver() { Revoke(); }
|
||||
void Revoke() { NS_IF_RELEASE(mObj); }
|
||||
};
|
||||
|
||||
template <class ClassType>
|
||||
struct RunnableMethodReceiver<ClassType, false> {
|
||||
ClassType *mObj;
|
||||
RunnableMethodReceiver(ClassType *obj) : mObj(obj) {}
|
||||
void Revoke() { mObj = nsnull; }
|
||||
};
|
||||
|
||||
// An event that can be used to call a method on a class. The class type must
|
||||
// support reference counting. This event supports Revoke for use
|
||||
// with nsRevocableEventPtr.
|
||||
@ -286,23 +271,7 @@ template <class ClassType,
|
||||
class nsRunnableMethod : public nsRunnable
|
||||
{
|
||||
public:
|
||||
typedef ReturnType (ClassType::*Method)();
|
||||
|
||||
nsRunnableMethod(ClassType *obj, Method method)
|
||||
: mReceiver(obj)
|
||||
, mMethod(method)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
if (!mReceiver.mObj)
|
||||
return NS_OK;
|
||||
(mReceiver.mObj->*mMethod)();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Revoke() {
|
||||
mReceiver.Revoke();
|
||||
}
|
||||
virtual void Revoke() = 0;
|
||||
|
||||
// These ReturnTypeEnforcer classes set up a blacklist for return types that
|
||||
// we know are not safe. The default ReturnTypeEnforcer compiles just fine but
|
||||
@ -322,38 +291,91 @@ public:
|
||||
|
||||
// Make sure this return type is safe.
|
||||
typedef typename ReturnTypeEnforcer<ReturnType>::ReturnTypeIsSafe check;
|
||||
|
||||
protected:
|
||||
virtual ~nsRunnableMethod() {
|
||||
Revoke();
|
||||
}
|
||||
|
||||
private:
|
||||
RunnableMethodReceiver<ClassType, Owning> mReceiver;
|
||||
Method mMethod;
|
||||
};
|
||||
|
||||
// Use this helper macro like so:
|
||||
template <class ClassType, bool Owning>
|
||||
struct nsRunnableMethodReceiver {
|
||||
ClassType *mObj;
|
||||
nsRunnableMethodReceiver(ClassType *obj) : mObj(obj) { NS_IF_ADDREF(mObj); }
|
||||
~nsRunnableMethodReceiver() { Revoke(); }
|
||||
void Revoke() { NS_IF_RELEASE(mObj); }
|
||||
};
|
||||
|
||||
template <class ClassType>
|
||||
struct nsRunnableMethodReceiver<ClassType, false> {
|
||||
ClassType *mObj;
|
||||
nsRunnableMethodReceiver(ClassType *obj) : mObj(obj) {}
|
||||
void Revoke() { mObj = nsnull; }
|
||||
};
|
||||
|
||||
template <typename Method, bool Owning> struct nsRunnableMethodTraits;
|
||||
|
||||
template <class C, typename R, bool Owning>
|
||||
struct nsRunnableMethodTraits<R (C::*)(), Owning> {
|
||||
typedef C class_type;
|
||||
typedef R return_type;
|
||||
typedef nsRunnableMethod<C, R, Owning> base_type;
|
||||
};
|
||||
|
||||
#ifdef HAVE_STDCALL
|
||||
template <class C, typename R, bool Owning>
|
||||
struct nsRunnableMethodTraits<R (__stdcall C::*)(), Owning> {
|
||||
typedef C class_type;
|
||||
typedef R return_type;
|
||||
typedef nsRunnableMethod<C, R, Owning> base_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename Method, bool Owning>
|
||||
class nsRunnableMethodImpl
|
||||
: public nsRunnableMethodTraits<Method, Owning>::base_type
|
||||
{
|
||||
typedef typename nsRunnableMethodTraits<Method, Owning>::class_type ClassType;
|
||||
nsRunnableMethodReceiver<ClassType, Owning> mReceiver;
|
||||
Method mMethod;
|
||||
|
||||
public:
|
||||
nsRunnableMethodImpl(ClassType *obj,
|
||||
Method method)
|
||||
: mReceiver(obj)
|
||||
, mMethod(method)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
if (NS_LIKELY(mReceiver.mObj))
|
||||
((*mReceiver.mObj).*mMethod)();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Revoke() {
|
||||
mReceiver.Revoke();
|
||||
}
|
||||
};
|
||||
|
||||
// Use this template function like so:
|
||||
//
|
||||
// nsCOMPtr<nsIRunnable> event =
|
||||
// NS_NEW_RUNNABLE_METHOD(MyClass, myObject, HandleEvent);
|
||||
// NS_NewRunnableMethod(myObject, &MyClass::HandleEvent);
|
||||
// NS_DispatchToCurrentThread(event);
|
||||
//
|
||||
// Constraints:
|
||||
// - myObject must be of type MyClass
|
||||
// Statically enforced constraints:
|
||||
// - myObject must be of (or implicitly convertible to) type MyClass
|
||||
// - MyClass must defined AddRef and Release methods
|
||||
//
|
||||
// NOTE: Attempts to make this a template function caused VC6 to barf :-(
|
||||
//
|
||||
|
||||
#define NS_NEW_RUNNABLE_METHOD(class_, obj_, method_) \
|
||||
ns_new_runnable_method(obj_, &class_::method_)
|
||||
|
||||
template<class ClassType, typename ReturnType>
|
||||
nsRunnableMethod<ClassType, ReturnType>*
|
||||
ns_new_runnable_method(ClassType* obj, ReturnType (ClassType::*method)())
|
||||
template<typename PtrType, typename Method>
|
||||
NS_COM_GLUE
|
||||
typename nsRunnableMethodTraits<Method, true>::base_type*
|
||||
NS_NewRunnableMethod(PtrType ptr, Method method)
|
||||
{
|
||||
return new nsRunnableMethod<ClassType, ReturnType>(obj, method);
|
||||
return new nsRunnableMethodImpl<Method, true>(ptr, method);
|
||||
}
|
||||
|
||||
template<typename PtrType, typename Method>
|
||||
NS_COM_GLUE
|
||||
typename nsRunnableMethodTraits<Method, false>::base_type*
|
||||
NS_NewNonOwningRunnableMethod(PtrType ptr, Method method)
|
||||
{
|
||||
return new nsRunnableMethodImpl<Method, false>(ptr, method);
|
||||
}
|
||||
|
||||
#endif // XPCOM_GLUE_AVOID_NSPR
|
||||
|
Loading…
Reference in New Issue
Block a user