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