зеркало из https://github.com/mozilla/gecko-dev.git
Bug 805988. Add some asserts that new-binding objects are nsISupports if they claim to be or or can be safely reinterpret_cast to nsWrapperCache, if they have an nsWrapperCache at all, if they don't claim to be nsISupports. r=peterv
Note that everything except the new asserts just got moved with no changes.
This commit is contained in:
Родитель
f16bb7b8a1
Коммит
97b83582f6
|
@ -409,6 +409,64 @@ MaybeWrapValue(JSContext* cx, JSObject* obj, JS::Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define HAS_MEMBER_CHECK(_name) \
|
||||
template<typename V> static yes& Check(char (*)[(&V::_name == 0) + 1])
|
||||
#else
|
||||
#define HAS_MEMBER_CHECK(_name) \
|
||||
template<typename V> static yes& Check(char (*)[sizeof(&V::_name) + 1])
|
||||
#endif
|
||||
|
||||
#define HAS_MEMBER(_name) \
|
||||
template<typename T> \
|
||||
class Has##_name##Member { \
|
||||
typedef char yes[1]; \
|
||||
typedef char no[2]; \
|
||||
HAS_MEMBER_CHECK(_name); \
|
||||
template<typename V> static no& Check(...); \
|
||||
\
|
||||
public: \
|
||||
static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes); \
|
||||
};
|
||||
|
||||
HAS_MEMBER(AddRef)
|
||||
HAS_MEMBER(Release)
|
||||
HAS_MEMBER(QueryInterface)
|
||||
|
||||
template<typename T>
|
||||
struct IsRefCounted
|
||||
{
|
||||
static bool const Value = HasAddRefMember<T>::Value &&
|
||||
HasReleaseMember<T>::Value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct IsISupports
|
||||
{
|
||||
static bool const Value = IsRefCounted<T>::Value &&
|
||||
HasQueryInterfaceMember<T>::Value;
|
||||
};
|
||||
|
||||
HAS_MEMBER(WrapObject)
|
||||
|
||||
// HasWrapObject<T>::Value will be true if T has a WrapObject member but it's
|
||||
// not nsWrapperCache::WrapObject.
|
||||
template<typename T>
|
||||
struct HasWrapObject
|
||||
{
|
||||
private:
|
||||
typedef char yes[1];
|
||||
typedef char no[2];
|
||||
typedef JSObject* (nsWrapperCache::*WrapObject)(JSContext*, JSObject*, bool*);
|
||||
template<typename U, U> struct SFINAE;
|
||||
template <typename V> static no& Check(SFINAE<WrapObject, &V::WrapObject>*);
|
||||
template <typename V> static yes& Check(...);
|
||||
|
||||
public:
|
||||
static bool const Value = HasWrapObjectMember<T>::Value &&
|
||||
sizeof(Check<T>(nullptr)) == sizeof(yes);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline bool
|
||||
WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp)
|
||||
|
@ -431,6 +489,24 @@ WrapNewBindingObject(JSContext* cx, JSObject* scope, T* value, JS::Value* vp)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Some sanity asserts about our object. Specifically:
|
||||
// 1) If our class claims we're nsISupports, we better be nsISupports
|
||||
// XXXbz ideally, we could assert that reinterpret_cast to nsISupports
|
||||
// does the right thing, but I don't see a way to do it. :(
|
||||
// 2) If our class doesn't claim we're nsISupports we better be
|
||||
// reinterpret_castable to nsWrapperCache.
|
||||
const DOMClass* clasp = nullptr;
|
||||
DOMObjectSlot slot = GetDOMClass(obj, clasp);
|
||||
MOZ_ASSERT(slot != eNonDOMObject, "Totally unexpected object here");
|
||||
MOZ_ASSERT(clasp, "What happened here?");
|
||||
MOZ_ASSERT_IF(clasp->mDOMObjectIsISupports, IsISupports<T>::Value);
|
||||
MOZ_ASSERT_IF(!clasp->mDOMObjectIsISupports,
|
||||
reinterpret_cast<uintptr_t>(
|
||||
static_cast<nsWrapperCache*>(
|
||||
reinterpret_cast<T*>(1))) == 1);
|
||||
#endif
|
||||
|
||||
// When called via XrayWrapper, we end up here while running in the
|
||||
// chrome compartment. But the obj we have would be created in
|
||||
// whatever the content compartment is. So at this point we need to
|
||||
|
@ -745,64 +821,6 @@ bool
|
|||
WrapCallbackInterface(JSContext *cx, JSObject *scope, nsISupports* callback,
|
||||
JS::Value* vp);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define HAS_MEMBER_CHECK(_name) \
|
||||
template<typename V> static yes& Check(char (*)[(&V::_name == 0) + 1])
|
||||
#else
|
||||
#define HAS_MEMBER_CHECK(_name) \
|
||||
template<typename V> static yes& Check(char (*)[sizeof(&V::_name) + 1])
|
||||
#endif
|
||||
|
||||
#define HAS_MEMBER(_name) \
|
||||
template<typename T> \
|
||||
class Has##_name##Member { \
|
||||
typedef char yes[1]; \
|
||||
typedef char no[2]; \
|
||||
HAS_MEMBER_CHECK(_name); \
|
||||
template<typename V> static no& Check(...); \
|
||||
\
|
||||
public: \
|
||||
static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes); \
|
||||
};
|
||||
|
||||
HAS_MEMBER(AddRef)
|
||||
HAS_MEMBER(Release)
|
||||
HAS_MEMBER(QueryInterface)
|
||||
|
||||
template<typename T>
|
||||
struct IsRefCounted
|
||||
{
|
||||
static bool const Value = HasAddRefMember<T>::Value &&
|
||||
HasReleaseMember<T>::Value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct IsISupports
|
||||
{
|
||||
static bool const Value = IsRefCounted<T>::Value &&
|
||||
HasQueryInterfaceMember<T>::Value;
|
||||
};
|
||||
|
||||
HAS_MEMBER(WrapObject)
|
||||
|
||||
// HasWrapObject<T>::Value will be true if T has a WrapObject member but it's
|
||||
// not nsWrapperCache::WrapObject.
|
||||
template<typename T>
|
||||
struct HasWrapObject
|
||||
{
|
||||
private:
|
||||
typedef char yes[1];
|
||||
typedef char no[2];
|
||||
typedef JSObject* (nsWrapperCache::*WrapObject)(JSContext*, JSObject*, bool*);
|
||||
template<typename U, U> struct SFINAE;
|
||||
template <typename V> static no& Check(SFINAE<WrapObject, &V::WrapObject>*);
|
||||
template <typename V> static yes& Check(...);
|
||||
|
||||
public:
|
||||
static bool const Value = HasWrapObjectMember<T>::Value &&
|
||||
sizeof(Check<T>(nullptr)) == sizeof(yes);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static inline JSObject*
|
||||
WrapNativeISupportsParent(JSContext* cx, JSObject* scope, T* p,
|
||||
|
|
Загрузка…
Ссылка в новой задаче