]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/cocoa/objc/objc_uniquifying.h
Applied rowspan patch #15276 (dghart)
[wxWidgets.git] / include / wx / cocoa / objc / objc_uniquifying.h
index 9d4014bb4a471adaa306fd8ddf95caedf8556672..a8a10e7a55a8c46c147bff2e464452322c67e56c 100644 (file)
@@ -83,6 +83,32 @@ struct UniquifiedName
     }
 };
 
     }
 };
 
+/*! @function   HidePointerFromGC
+    @abstract   Returns an l-value whose location the compiler cannot know.
+    @discussion
+    The compiler-generated Objective-C class structures are located in the static data area.
+    They are by design Objective-C objects in their own right which makes the compiler issue
+    write barriers as if they were located in the GC-managed heap as most Objective-C objects.
+
+    By accepting and returning a reference to any pointer type we can set any i-var of an
+    Objective-C object that is a pointer to another Objective-C object without the compiler
+    generating an objc_assign_ivar write barrier.  It will instad generate an
+    objc_assign_strongCast write barrier which is the appropriate write-barrier when assigning
+    pointers to Objective-C objects located in unknown memory.
+
+    For instance:
+    Class *someClass = ...;
+    HidePointerFromGC(someClass->isa) = ...;
+ */
+template <typename ObjcType>
+inline ObjcType * & HidePointerFromGC(ObjcType * &p) __attribute__((always_inline));
+
+template <typename ObjcType>
+inline ObjcType * & HidePointerFromGC(ObjcType * &p)
+{
+    return p;
+}
+
 template <typename ObjcType>
 class wxObjcClassInitializer
 {
 template <typename ObjcType>
 class wxObjcClassInitializer
 {
@@ -131,9 +157,9 @@ private:
 
         // In any object hierarchy a metaclass's metaclass is always the root class's metaclass
         // Therefore, our superclass's metaclass's metaclass should already be the root class's metaclass
 
         // In any object hierarchy a metaclass's metaclass is always the root class's metaclass
         // Therefore, our superclass's metaclass's metaclass should already be the root class's metaclass
-        theClassData.isa->isa = theClassData.super_class->isa->isa;
+        HidePointerFromGC(theClassData.isa->isa) = theClassData.super_class->isa->isa;
         // A metaclass's superclass is always the superclass's metaclass.
         // A metaclass's superclass is always the superclass's metaclass.
-        theClassData.isa->super_class = theClassData.super_class->isa;
+        HidePointerFromGC(theClassData.isa->super_class) = theClassData.super_class->isa;
         // Fix up the compiler generated metaclass struct to use the new name
         theClassData.isa->name = sm_theUniquifiedClassName;
 
         // Fix up the compiler generated metaclass struct to use the new name
         theClassData.isa->name = sm_theUniquifiedClassName;
 
@@ -179,7 +205,7 @@ struct objc_class* wx_GetObjcClass_ ## ObjcClass();
 // _s_objc_class_ptr_ObjcClass:
 //     .long L_OBJC_CLASS_ObjcClass
 // Once that static symbol is defined, the function implementation is easy for GCC to generate.
 // _s_objc_class_ptr_ObjcClass:
 //     .long L_OBJC_CLASS_ObjcClass
 // Once that static symbol is defined, the function implementation is easy for GCC to generate.
-// Do note that return &s_objc_class_data_ObjcClass won't work.  The code is wrong in the case.
+// Do note that return &s_objc_class_data_ObjcClass won't work.  The code is wrong in this case.
 #define WX_IMPLEMENT_OBJC_GET_COMPILED_CLASS(ObjcClass) \
 extern "C" objc_class s_objc_class_data_ ## ObjcClass asm("L_OBJC_CLASS_" #ObjcClass); \
 static objc_class * s_objc_class_ptr_ ## ObjcClass = &s_objc_class_data_ ## ObjcClass; \
 #define WX_IMPLEMENT_OBJC_GET_COMPILED_CLASS(ObjcClass) \
 extern "C" objc_class s_objc_class_data_ ## ObjcClass asm("L_OBJC_CLASS_" #ObjcClass); \
 static objc_class * s_objc_class_ptr_ ## ObjcClass = &s_objc_class_data_ ## ObjcClass; \
@@ -252,7 +278,7 @@ inline objc_class * wxObjcCompilerInformation<ObjcClass>::GetCompiledClass() \
 }
 
 // TODO: __x86_64__, __ppc64__
 }
 
 // TODO: __x86_64__, __ppc64__
-#else // Can't wrie inline asm to bust into __OBJC segment
+#else // Can't write inline asm to bust into __OBJC segment
 // This won't be used since the generic implementation takes precedence.
 
 #warning "Don't know how to implement wxObjcCompilerInformation<ObjcClass>::GetCompiledClass on this platform"
 // This won't be used since the generic implementation takes precedence.
 
 #warning "Don't know how to implement wxObjcCompilerInformation<ObjcClass>::GetCompiledClass on this platform"
@@ -270,6 +296,16 @@ inline objc_class * wxObjcCompilerInformation<ObjcClass>::GetCompiledClass() \
         return objc_getClass(#ObjcSuperClass); \
     }
 
         return objc_getClass(#ObjcSuperClass); \
     }
 
+// The WX_IMPLEMENT_OBJC_GET_UNIQUIFIED_SUPERCLASS macro implements the template
+// specialization to get the superclass when the superclass is another uniquified
+// Objective-C class.
+#define WX_IMPLEMENT_OBJC_GET_UNIQUIFIED_SUPERCLASS(ObjcClass,ObjcSuperClass) \
+    template <> \
+    inline objc_class* wxObjcCompilerInformation<ObjcClass>::GetSuperclass() \
+    { \
+        return wx_GetObjcClass_ ## ObjcSuperClass(); \
+    }
+
 // The WX_IMPLEMENT_OBJC_CLASS_NAME macro implements the template specialization
 // of the sm_theClassName constant.  As soon as this specialization is in place
 // sizeof(sm_theClassName) will return the number of bytes at compile time.
 // The WX_IMPLEMENT_OBJC_CLASS_NAME macro implements the template specialization
 // of the sm_theClassName constant.  As soon as this specialization is in place
 // sizeof(sm_theClassName) will return the number of bytes at compile time.
@@ -277,17 +313,31 @@ inline objc_class * wxObjcCompilerInformation<ObjcClass>::GetCompiledClass() \
     template <> \
     const char wxObjcCompilerInformation<ObjcClass>::sm_theClassName[] = #ObjcClass;
 
     template <> \
     const char wxObjcCompilerInformation<ObjcClass>::sm_theClassName[] = #ObjcClass;
 
-// The WX_IMPLEMENT_GET_OBJC_CLASS macro combines all of these together and adds
-// a global wx_GetObjcClass_ObjcClass() function.
-#define WX_IMPLEMENT_GET_OBJC_CLASS(ObjcClass,ObjcSuperClass) \
-    WX_IMPLEMENT_OBJC_GET_COMPILED_CLASS(ObjcClass) \
-    WX_IMPLEMENT_OBJC_GET_SUPERCLASS(ObjcClass,ObjcSuperClass) \
-    WX_IMPLEMENT_OBJC_CLASS_NAME(ObjcClass) \
+// The WX_IMPLEMENT_OBJC_GET_OBJC_CLASS macro is the final one that actually provides
+// the wx_GetObjcClass_XXX function that will be called in lieu of asking the Objective-C
+// runtime for the class.  All the others are really machinery to make this happen.
+#define WX_IMPLEMENT_OBJC_GET_OBJC_CLASS(ObjcClass) \
     objc_class* wx_GetObjcClass_ ## ObjcClass() \
     { \
         return wxObjcClassInitializer<ObjcClass>::Get(); \
     }
 
     objc_class* wx_GetObjcClass_ ## ObjcClass() \
     { \
         return wxObjcClassInitializer<ObjcClass>::Get(); \
     }
 
+// The WX_IMPLEMENT_GET_OBJC_CLASS macro combines all of these together
+// for the case when the superclass is a non-uniquified class.
+#define WX_IMPLEMENT_GET_OBJC_CLASS(ObjcClass,ObjcSuperClass) \
+    WX_IMPLEMENT_OBJC_GET_COMPILED_CLASS(ObjcClass) \
+    WX_IMPLEMENT_OBJC_GET_SUPERCLASS(ObjcClass,ObjcSuperClass) \
+    WX_IMPLEMENT_OBJC_CLASS_NAME(ObjcClass) \
+    WX_IMPLEMENT_OBJC_GET_OBJC_CLASS(ObjcClass)
+
+// The WX_IMPLEMENT_GET_OBJC_CLASS_WITH_UNIQUIFIED_SUPERCLASS macro combines all
+// of these together for the case when the superclass is another uniquified class.
+#define WX_IMPLEMENT_GET_OBJC_CLASS_WITH_UNIQUIFIED_SUPERCLASS(ObjcClass,ObjcSuperClass) \
+    WX_IMPLEMENT_OBJC_GET_COMPILED_CLASS(ObjcClass) \
+    WX_IMPLEMENT_OBJC_GET_UNIQUIFIED_SUPERCLASS(ObjcClass,ObjcSuperClass) \
+    WX_IMPLEMENT_OBJC_CLASS_NAME(ObjcClass) \
+    WX_IMPLEMENT_OBJC_GET_OBJC_CLASS(ObjcClass)
+
 // The WX_GET_OBJC_CLASS macro is intended to wrap the class name when the class
 // is used as a message receiver (e.g. for calling class methods).  When
 // class name uniquifying is used, this calls the global function implemented
 // The WX_GET_OBJC_CLASS macro is intended to wrap the class name when the class
 // is used as a message receiver (e.g. for calling class methods).  When
 // class name uniquifying is used, this calls the global function implemented
@@ -300,6 +350,8 @@ inline objc_class * wxObjcCompilerInformation<ObjcClass>::GetCompiledClass() \
 #define WX_DECLARE_GET_OBJC_CLASS(ObjcClass,ObjcSuperClass)
 // Define WX_IMPLEMENT_GET_OBJC_CLASS as nothing
 #define WX_IMPLEMENT_GET_OBJC_CLASS(ObjcClass,ObjcSuperClass)
 #define WX_DECLARE_GET_OBJC_CLASS(ObjcClass,ObjcSuperClass)
 // Define WX_IMPLEMENT_GET_OBJC_CLASS as nothing
 #define WX_IMPLEMENT_GET_OBJC_CLASS(ObjcClass,ObjcSuperClass)
+// Define WX_IMPLEMENT_GET_OBJC_CLASS_WITH_UNIQUIFIED_SUPERCLASS as nothing
+#define WX_IMPLEMENT_GET_OBJC_CLASS_WITH_UNIQUIFIED_SUPERCLASS(ObjcClass,ObjcSuperClass)
 
 // Define WX_GET_OBJC_CLASS macro to output the class name and let the compiler do the normal thing
 // The WX_GET_OBJC_CLASS macro is intended to wrap the class name when the class
 
 // Define WX_GET_OBJC_CLASS macro to output the class name and let the compiler do the normal thing
 // The WX_GET_OBJC_CLASS macro is intended to wrap the class name when the class