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