1#ifndef PyObjC_RUNTIME_COMPAT 2#define PyObjC_RUNTIME_COMPAT 3/* 4 * Objective-C 2.0 runtime compatibility. 5 * 6 * This files makes it possible to use the Objective-C 2.0 API on versions 7 * of Mac OS X before 10.5. Use PyObjC_FUNCNAME to access FUNCNAME from the 8 * Objective-C 2.0 API, see the Objective-C 2.0 runtime documentation to see 9 * how it should be used. 10 * 11 * TODO: 12 * - completely move PyObjC to the Objective-C 2.0 API 13 * - add more wizardry to ensure that this code compiles on OSX 10.4 14 * 15 * Special: 16 * - PyObjC_class_addMethodList is not a function in the ObjC 2.0 runtime API, 17 * but added here to (a) get semantics that are slightly nicer for what 18 * we do and (b) can be implemented efficiently on the "1.0" runtime. 19 * - PyObjC_methodlist_magic is meant to be used to determine if a class has 20 * changed in some way (such by loading a category). 21 * - Modifying a created but not yet registered class should be done using 22 * the preclass_* functions, not the regular ones because it isn't possible 23 * to emulate the entire ObjC 2.0 API on Tiger. 24 */ 25#include <objc/objc-runtime.h> 26#include <objc/Protocol.h> 27 28#define _C_CONST 'r' 29#define _C_IN 'n' 30#define _C_INOUT 'N' 31#define _C_OUT 'o' 32#define _C_BYCOPY 'O' 33#define _C_BYREF 'R' 34#define _C_ONEWAY 'V' 35#define _C_LNG_LNG 'q' 36#define _C_ULNG_LNG 'Q' 37#define _C_BOOL 'B' /* (Objective-)C++ 'bool' */ 38 39 40/* These don't actually exist in the Objective-C runtime, but are used 41 * by the bridge to simplify code. 42 */ 43#define _C_UNICHAR 'T' 44#define _C_CHAR_AS_TEXT 't' 45#define _C_CHAR_AS_INT 'z' 46#define _C_NSBOOL 'Z' 47 48struct PyObjC_method { 49 SEL name; 50 IMP imp; 51 const char* type; 52}; 53 54#define objc_superSetReceiver(super, val) (super).receiver = (val) 55#define objc_superGetReceiver(super) ((super).receiver) 56 57#ifdef __OBJC2__ 58 59#define objc_superSetClass(super, cls) (super).super_class = (cls) 60#define objc_superGetClass(super) ((super).super_class) 61 62#else 63 64#define objc_superSetClass(super, cls) (super).class = (cls) 65#define objc_superGetClass(super) ((super).class) 66 67#endif 68 69/* Some functions that are missing (oddly enough) */ 70BOOL PyObjC_class_isSubclassOf(Class child, Class parent); 71#define class_isSubclassOf PyObjC_class_isSubclassOf 72 73#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) && !defined(__OBJC2__) 74 75#define preclass_addIvar PyObjC_preclass_addIvar 76#define preclass_addMethod PyObjC_preclass_addMethod 77#define preclass_addProtocol PyObjC_preclass_addProtocol 78 79extern void PyObjC_SetupRuntimeCompat(void); 80 81extern BOOL (*PyObjC_preclass_addMethod)(Class, SEL, IMP, const char*); 82extern BOOL (*PyObjC_preclass_addIvar)(Class cls, 83 const char *name, size_t size, uint8_t alignment, 84 const char *types); 85extern BOOL (*PyObjC_preclass_addProtocol)(Class cls, Protocol *protocol); 86 87 88extern Class (*PyObjC_objc_allocateClassPair)(Class, const char*, size_t); 89extern void (*PyObjC_objc_registerClassPair)(Class); 90extern void (*PyObjC_objc_disposeClassPair)(Class cls); 91 92 93extern Class (*PyObjC_object_getClass)(id obj); 94extern Class (*PyObjC_object_setClass)(id obj, Class cls); 95extern const char* (*PyObjC_object_getClassName)(id obj); 96 97extern Method* (*PyObjC_class_copyMethodList)(Class, unsigned int*); 98extern const char* (*PyObjC_class_getName)(Class); 99extern Class (*PyObjC_class_getSuperclass)(Class); 100extern BOOL (*PyObjC_class_addMethod)(Class, SEL, IMP, const char*); 101extern BOOL (*PyObjC_class_addMethodList)(Class, 102 struct PyObjC_method*, unsigned int); 103extern Ivar* (*PyObjC_class_copyIvarList)(Class, unsigned int*); 104extern Protocol** (*PyObjC_class_copyProtocolList)(Class, unsigned int*); 105 106extern BOOL (*PyObjC_class_isMetaClass)(Class); 107 108extern SEL (*PyObjC_method_getName)(Method m); 109extern const char *(*PyObjC_method_getTypeEncoding)(Method m); 110extern IMP (*PyObjC_method_getImplementation)(Method m); 111extern IMP (*PyObjC_method_setImplementation)(Method m, IMP imp); 112 113extern BOOL (*PyObjC_sel_isEqual)(SEL, SEL); 114 115extern size_t (*PyObjC_methodlist_magic)(Class cls); 116 117extern const char* (*PyObjC_ivar_getName)(Ivar); 118extern const char* (*PyObjC_ivar_getTypeEncoding)(Ivar); 119extern ptrdiff_t (*PyObjC_ivar_getOffset)(Ivar); 120 121extern Protocol** (*PyObjC_objc_copyProtocolList)(unsigned int* outCount); 122extern Protocol* (*PyObjC_objc_getProtocol)(char* name); 123extern struct objc_method_description_list* (*PyObjC_protocol_copyInstanceMethodDescriptionList)(Protocol* proto); 124extern struct objc_method_description_list* (*PyObjC_protocol_copyClassMethodDescriptionList)(Protocol *proto); 125extern struct objc_method_description_list* (*PyObjC_protocol_copyOptionalInstanceMethodDescriptionList)(Protocol *proto); 126extern struct objc_method_description_list* (*PyObjC_protocol_copyOptionalClassMethodDescriptionList)(Protocol *proto); 127 128extern BOOL (*PyObjC_protocol_conformsToProtocol)(Protocol *proto, Protocol *other); 129extern const char *(*PyObjC_protocol_getName)(Protocol *p); 130extern struct objc_method_description *(*PyObjC_protocol_copyMethodDescriptionList)(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount); 131extern Protocol **(*PyObjC_protocol_copyProtocolList)(Protocol *proto, unsigned int *outCount); 132extern struct objc_method_description (*PyObjC_protocol_getMethodDescription)(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod); 133 134extern id (*PyObjC_object_getIvar)(id obj, Ivar ivar); 135extern void (*PyObjC_object_setIvar)(id obj, Ivar ivar, id value); 136 137#ifndef PYOBJC_COMPAT_IMPL 138#define object_getIvar PyObjC_object_getIvar 139#define object_setIvar PyObjC_object_setIvar 140#define protocol_getName PyObjC_protocol_getName 141#define protocol_conformsToProtocol PyObjC_protocol_conformsToProtocol 142#define protocol_copyMethodDescriptionList PyObjC_protocol_copyMethodDescriptionList 143#define protocol_copyProtocolList PyObjC_protocol_copyProtocolList 144#define protocol_getMethodDescription PyObjC_protocol_getMethodDescription 145 146#define objc_allocateClassPair PyObjC_objc_allocateClassPair 147#define objc_registerClassPair PyObjC_objc_registerClassPair 148#define objc_disposeClassPair PyObjC_objc_disposeClassPair 149 150#define object_getClass PyObjC_object_getClass 151#define object_setClass PyObjC_object_setClass 152#define object_getClassName PyObjC_object_getClassName 153 154#define class_copyMethodList PyObjC_class_copyMethodList 155#define class_getName PyObjC_class_getName 156#define class_getSuperclass PyObjC_class_getSuperclass 157#define class_addMethod PyObjC_class_addMethod 158#define class_addMethodList PyObjC_class_addMethodList 159#define class_copyIvarList PyObjC_class_copyIvarList 160#define class_copyProtocolList PyObjC_class_copyProtocolList 161#define class_conformsToProtocol PyObjC_class_conformsToProtocol 162#define class_isMetaClass PyObjC_class_isMetaClass 163 164#define method_getName PyObjC_method_getName 165#define method_getTypeEncoding PyObjC_method_getTypeEncoding 166#define method_getImplementation PyObjC_method_getImplementation 167#define method_setImplementation PyObjC_method_setImplementation 168 169#define sel_isEqual PyObjC_sel_isEqual 170 171#define ivar_getName PyObjC_ivar_getName 172#define ivar_getTypeEncoding PyObjC_ivar_getTypeEncoding 173#define ivar_getOffset PyObjC_ivar_getOffset 174 175#define objc_copyProtocolList PyObjC_objc_copyProtocolList 176#define objc_getProtocol PyObjC_objc_getProtocol 177#define protocol_copyInstanceMethodDescriptionList PyObjC_protocol_copyInstanceMethodDescriptionList 178#define protocol_copyClassMethodDescriptionList PyObjC_protocol_copyClassMethodDescriptionList 179#define protocol_copyOptionalInstanceMethodDescriptionList PyObjC_protocol_copyOptionalInstanceMethodDescriptionList 180#define protocol_copyOptionalClassMethodDescriptionList PyObjC_protocol_copyOptionalClassMethodDescriptionList 181 182#endif /* !PYOBJC_COMPAT_IMPL */ 183 184#else 185 186/* 187 * Compiled for 10.5 or later, use ObjC 2.0 runtime exclusively. 188 * 189 * 190 * Use the preclass_ versions to modify a Class between allocating it and 191 * registering it. This is needed for the 10.4 compatibility layer. 192 */ 193 194#define preclass_addIvar class_addIvar 195#define preclass_addMethod class_addMethod 196#define preclass_addProtocol class_addProtocol 197 198static inline void PyObjC_SetupRuntimeCompat(void) { } 199extern BOOL PyObjC_class_addMethodList(Class class, 200 struct PyObjC_method* list, unsigned int count); 201 202 203extern size_t PyObjC_methodlist_magic(Class cls); 204 205#define class_addMethodList PyObjC_class_addMethodList 206 207#if __OBJC2__ 208@interface Object 209{ 210} 211- (id)self; 212@end 213#endif // __OBJC2__ 214 215#endif 216 217 218#endif /* PyObjC_RUNTIME_COMPAT */ 219