#ifndef __WX_COCOA_OBJC_CLASS_H__
#define __WX_COCOA_OBJC_CLASS_H__
+/* A note about this header:
+Nothing in here is guaranteed to exist in future versions of wxCocoa. There
+are other ways of adding Objective-C classes at runtime and a future wxCocoa
+might use these instead of this ugly hack. You may use this header file in
+your own wxCocoa code if you need your own Objective-C classes to be
+unqiuified.
+
+You cannot turn this on for 64-bit mode. It will not compile due to opaque
+Objective-C data structures and it is not needed because it is a workaround
+for a bug that does not exist in the 64-bit runtime.
+
+You should not use this when wxCocoa is built as a dynamic library. This has
+only been tested for the case when wxCocoa is built as a static library and
+statically linked to user code to form a loadable bundle (e.g. a Cocoa plugin).
+It forces each plugin (when multiple wxCocoa-using plugins are used) to use
+its own internal Objective-C classes which is desirable when wxCocoa is
+statically linked to the rest of the code.
+
+Do not use uniquifying on your principal class. That one should be named
+differently for different bundles.
+ */
+
#if wxUSE_OBJC_UNIQUIFYING
// objc_getClass and stuff
}
};
+/*! @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
{
// 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.
- 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;
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.
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(); \
}
+// 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
#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