| Index: third_party/WebKit/Source/wtf/StdLibExtras.h
|
| diff --git a/third_party/WebKit/Source/wtf/StdLibExtras.h b/third_party/WebKit/Source/wtf/StdLibExtras.h
|
| index 62acd8582e0fdf7eee3a7b68cec156a9236f5512..14a52c717662023338a697095619b0a7224e8d2f 100644
|
| --- a/third_party/WebKit/Source/wtf/StdLibExtras.h
|
| +++ b/third_party/WebKit/Source/wtf/StdLibExtras.h
|
| @@ -29,6 +29,7 @@
|
| #include "wtf/Assertions.h"
|
| #include "wtf/CPU.h"
|
| #include "wtf/CheckedArithmetic.h"
|
| +#include "wtf/TypeTraits.h"
|
| #include <cstddef>
|
|
|
| #if ENABLE(ASSERT)
|
| @@ -62,18 +63,56 @@ private:
|
| // it is leaked so that its destructors are not called at exit.
|
| #ifndef DEFINE_STATIC_LOCAL
|
|
|
| +template<typename T>
|
| +class CanRegisterStaticLocalReference {
|
| + typedef char YesType;
|
| + typedef struct NoType {
|
| + char padding[8];
|
| + } NoType;
|
| +
|
| + // Check if class T has public method "T* registerAsStaticReference()".
|
| + template<typename V> static YesType checkHasRegisterAsStaticReferenceMethod(V* p, typename WTF::EnableIf<WTF::IsSubclass<V, typename std::remove_pointer<decltype(p->registerAsStaticReference())>::type>::value>::Type* = 0);
|
| + template<typename V> static NoType checkHasRegisterAsStaticReferenceMethod(...);
|
| +public:
|
| +
|
| + static const bool value = sizeof(YesType) + sizeof(T) == sizeof(checkHasRegisterAsStaticReferenceMethod<T>(nullptr)) + sizeof(T);
|
| +};
|
| +
|
| +template<typename T, bool = CanRegisterStaticLocalReference<T>::value>
|
| +class RegisterStaticLocalReference {
|
| +public:
|
| + static T* registerStatic(T* ptr)
|
| + {
|
| + return ptr;
|
| + }
|
| +};
|
| +
|
| +template<typename T>
|
| +class RegisterStaticLocalReference<T, true> {
|
| +public:
|
| + static T* registerStatic(T* ptr)
|
| + {
|
| + return static_cast<T*>(ptr->registerAsStaticReference());
|
| + }
|
| +};
|
| +
|
| #if ENABLE(ASSERT)
|
| #define DEFINE_STATIC_LOCAL(type, name, arguments) \
|
| static StaticLocalVerifier name##StaticLocalVerifier; \
|
| - ASSERT(name##StaticLocalVerifier.isNotRacy()); \
|
| + ASSERT(name##StaticLocalVerifier.isNotRacy()); \
|
| + static type& name = *RegisterStaticLocalReference<type>::registerStatic(new type arguments)
|
| +#define DEFINE_STATIC_LOCAL_NO_REGISTER(type, name, arguments) \
|
| + static StaticLocalVerifier name##StaticLocalVerifier; \
|
| + ASSERT(name##StaticLocalVerifier.isNotRacy()); \
|
| static type& name = *new type arguments
|
| #else
|
| #define DEFINE_STATIC_LOCAL(type, name, arguments) \
|
| + static type& name = *RegisterStaticLocalReference<type>::registerStatic(new type arguments)
|
| +#define DEFINE_STATIC_LOCAL_NO_REGISTER(type, name, arguments) \
|
| static type& name = *new type arguments
|
| #endif
|
|
|
| -#endif
|
| -
|
| +#endif // DEFINE_STATIC_LOCAL
|
|
|
| // Use this to declare and define a static local pointer to a ref-counted object so that
|
| // it is leaked so that the object's destructors are not called at exit.
|
|
|