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 79 80extern BOOL (*PyObjC_preclass_addMethod)(Class, SEL, IMP, const char*); 81extern BOOL (*PyObjC_preclass_addIvar)(Class cls, 82 const char *name, size_t size, uint8_t alignment, 83 const char *types); 84extern BOOL (*PyObjC_preclass_addProtocol)(Class cls, Protocol *protocol); 85 86 87extern Class (*PyObjC_objc_allocateClassPair)(Class, const char*, size_t); 88extern void (*PyObjC_objc_registerClassPair)(Class); 89extern void (*PyObjC_objc_disposeClassPair)(Class cls); 90 91 92extern Class (*PyObjC_object_getClass)(id obj); 93extern Class (*PyObjC_object_setClass)(id obj, Class cls); 94extern const char* (*PyObjC_object_getClassName)(id obj); 95 96extern Method* (*PyObjC_class_copyMethodList)(Class, unsigned int*); 97extern const char* (*PyObjC_class_getName)(Class); 98extern Class (*PyObjC_class_getSuperclass)(Class); 99extern BOOL (*PyObjC_class_addMethod)(Class, SEL, IMP, const char*); 100extern BOOL (*PyObjC_class_addMethodList)(Class, 101 struct PyObjC_method*, unsigned int); 102extern Ivar* (*PyObjC_class_copyIvarList)(Class, unsigned int*); 103extern Protocol** (*PyObjC_class_copyProtocolList)(Class, unsigned int*); 104 105extern BOOL (*PyObjC_class_isMetaClass)(Class); 106 107extern SEL (*PyObjC_method_getName)(Method m); 108extern const char *(*PyObjC_method_getTypeEncoding)(Method m); 109extern IMP (*PyObjC_method_getImplementation)(Method m); 110extern IMP (*PyObjC_method_setImplementation)(Method m, IMP imp); 111 112extern BOOL (*PyObjC_sel_isEqual)(SEL, SEL); 113 114extern size_t (*PyObjC_methodlist_magic)(Class cls); 115 116extern const char* (*PyObjC_ivar_getName)(Ivar); 117extern const char* (*PyObjC_ivar_getTypeEncoding)(Ivar); 118extern ptrdiff_t (*PyObjC_ivar_getOffset)(Ivar); 119 120extern Protocol** (*PyObjC_objc_copyProtocolList)(unsigned int* outCount); 121extern Protocol* (*PyObjC_objc_getProtocol)(const char* name); 122extern struct objc_method_description_list* (*PyObjC_protocol_copyInstanceMethodDescriptionList)(Protocol* proto); 123extern struct objc_method_description_list* (*PyObjC_protocol_copyClassMethodDescriptionList)(Protocol *proto); 124extern struct objc_method_description_list* (*PyObjC_protocol_copyOptionalInstanceMethodDescriptionList)(Protocol *proto); 125extern struct objc_method_description_list* (*PyObjC_protocol_copyOptionalClassMethodDescriptionList)(Protocol *proto); 126 127extern BOOL (*PyObjC_protocol_conformsToProtocol)(Protocol *proto, Protocol *other); 128extern const char *(*PyObjC_protocol_getName)(Protocol *p); 129extern struct objc_method_description *(*PyObjC_protocol_copyMethodDescriptionList)(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount); 130extern Protocol **(*PyObjC_protocol_copyProtocolList)(Protocol *proto, unsigned int *outCount); 131extern struct objc_method_description (*PyObjC_protocol_getMethodDescription)(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod); 132 133extern id (*PyObjC_object_getIvar)(id obj, Ivar ivar); 134extern void (*PyObjC_object_setIvar)(id obj, Ivar ivar, id value); 135 136#ifndef PYOBJC_COMPAT_IMPL 137#define object_getIvar PyObjC_object_getIvar 138#define object_setIvar PyObjC_object_setIvar 139#define protocol_getName PyObjC_protocol_getName 140#define protocol_conformsToProtocol PyObjC_protocol_conformsToProtocol 141#define protocol_copyMethodDescriptionList PyObjC_protocol_copyMethodDescriptionList 142#define protocol_copyProtocolList PyObjC_protocol_copyProtocolList 143#define protocol_getMethodDescription PyObjC_protocol_getMethodDescription 144 145#define objc_allocateClassPair PyObjC_objc_allocateClassPair 146#define objc_registerClassPair PyObjC_objc_registerClassPair 147#define objc_disposeClassPair PyObjC_objc_disposeClassPair 148 149#define object_getClass PyObjC_object_getClass 150#define object_setClass PyObjC_object_setClass 151#define object_getClassName PyObjC_object_getClassName 152 153#define class_copyMethodList PyObjC_class_copyMethodList 154#define class_getName PyObjC_class_getName 155#define class_getSuperclass PyObjC_class_getSuperclass 156#define class_addMethod PyObjC_class_addMethod 157#define class_addMethodList PyObjC_class_addMethodList 158#define class_copyIvarList PyObjC_class_copyIvarList 159#define class_copyProtocolList PyObjC_class_copyProtocolList 160#define class_conformsToProtocol PyObjC_class_conformsToProtocol 161#define class_isMetaClass PyObjC_class_isMetaClass 162 163#define method_getName PyObjC_method_getName 164#define method_getTypeEncoding PyObjC_method_getTypeEncoding 165#define method_getImplementation PyObjC_method_getImplementation 166#define method_setImplementation PyObjC_method_setImplementation 167 168#define sel_isEqual PyObjC_sel_isEqual 169 170#define ivar_getName PyObjC_ivar_getName 171#define ivar_getTypeEncoding PyObjC_ivar_getTypeEncoding 172#define ivar_getOffset PyObjC_ivar_getOffset 173 174#define objc_copyProtocolList PyObjC_objc_copyProtocolList 175#define objc_getProtocol PyObjC_objc_getProtocol 176#define protocol_copyInstanceMethodDescriptionList PyObjC_protocol_copyInstanceMethodDescriptionList 177#define protocol_copyClassMethodDescriptionList PyObjC_protocol_copyClassMethodDescriptionList 178#define protocol_copyOptionalInstanceMethodDescriptionList PyObjC_protocol_copyOptionalInstanceMethodDescriptionList 179#define protocol_copyOptionalClassMethodDescriptionList PyObjC_protocol_copyOptionalClassMethodDescriptionList 180 181#endif /* !PYOBJC_COMPAT_IMPL */ 182 183#else 184 185/* 186 * Compiled for 10.5 or later, use ObjC 2.0 runtime exclusively. 187 * 188 * 189 * Use the preclass_ versions to modify a Class between allocating it and 190 * registering it. This is needed for the 10.4 compatibility layer. 191 */ 192 193#define preclass_addIvar class_addIvar 194#define preclass_addMethod class_addMethod 195#define preclass_addProtocol class_addProtocol 196 197extern BOOL PyObjC_class_addMethodList(Class class, 198 struct PyObjC_method* list, unsigned int count); 199 200 201extern size_t PyObjC_methodlist_magic(Class cls); 202 203#define class_addMethodList PyObjC_class_addMethodList 204 205#endif 206 207 208 209#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7) 210extern Protocol* (*PyObjC_objc_allocateProtocol)(const char *); 211extern void (*PyObjC_objc_registerProtocol)(Protocol*); 212extern void (*PyObjC_protocol_addMethodDescription)(Protocol*, SEL, const char*, BOOL, BOOL); 213extern void (*PyObjC_protocol_addProtocol)(Protocol*, Protocol*); 214 215#ifndef PYOBJC_COMPAT_IMPL 216#define objc_allocateProtocol PyObjC_objc_allocateProtocol 217#define objc_registerProtocol PyObjC_objc_registerProtocol 218#define protocol_addMethodDescription PyObjC_protocol_addMethodDescription 219#define protocol_addProtocol PyObjC_protocol_addProtocol 220#endif 221 222#endif 223 224 225 226extern void PyObjC_SetupRuntimeCompat(void); 227 228#endif /* PyObjC_RUNTIME_COMPAT */ 229