summaryrefslogtreecommitdiff
path: root/Objective-C/PyObjC/objc-runtime-compat.h
blob: b548755a06d14c1ae79e1e96dc428a95fea1457a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/* This file is part of the PyObjC package. */
#ifdef __NEXT_RUNTIME__

#ifndef PyObjC_RUNTIME_COMPAT
#define PyObjC_RUNTIME_COMPAT
/*
 * Objective-C 2.0 runtime compatibility.
 *
 * This files makes it possible to use the Objective-C 2.0 API on versions
 * of Mac OS X before 10.5. Use PyObjC_FUNCNAME to access FUNCNAME from the 
 * Objective-C 2.0 API, see the Objective-C 2.0 runtime documentation to see
 * how it should be used.
 *
 * TODO: 
 * - completely move PyObjC to the Objective-C 2.0 API
 * - add more wizardry to ensure that this code compiles on OSX 10.4
 *
 * Special:
 *  - PyObjC_class_addMethodList is not a function in the ObjC 2.0 runtime API,
 *    but added here to (a) get semantics that are slightly nicer for what
 *    we do and (b) can be implemented efficiently on the "1.0" runtime.
 *  - PyObjC_methodlist_magic is meant to be used to determine if a class has
 *    changed in some way (such by loading a category). 
 *  - Modifying a created but not yet registered class should be done using
 *    the preclass_* functions, not the regular ones because it isn't possible
 *    to emulate the entire ObjC 2.0 API on Tiger.
 */
#include "pyobjc.h"
#include <objc/objc-runtime.h>
#include <objc/Protocol.h>

#define _C_CONST    'r'
#define _C_IN       'n'
#define _C_INOUT    'N'
#define _C_OUT      'o'
#define _C_BYCOPY   'O'
#define _C_ONEWAY   'V'
#define _C_LNG_LNG   'q'
#define _C_ULNG_LNG  'Q'
#define _C_BOOL     'B'         /* (Objective-)C++ 'bool' */

struct PyObjC_method {
	SEL	    name;
	IMP	    imp;
	const char* type;
};

#define objc_superSetReceiver(super, val) (super).receiver = (val)
#define objc_superGetReceiver(super) ((super).receiver)

#ifdef __OBJC2__

#define objc_superSetClass(super, cls) (super).super_class = (cls)
#define objc_superGetClass(super) ((super).super_class)

#else

#define objc_superSetClass(super, cls) (super).class = (cls)
#define objc_superGetClass(super) ((super).class)

#endif

/* Some functions that are missing (oddly enough) */
BOOL PyObjC_class_isSubclassOf(Class child, Class parent);
#define class_isSubclassOf PyObjC_class_isSubclassOf

#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)  && !defined(__OBJC2__)

#define preclass_addIvar		PyObjC_preclass_addIvar
#define preclass_addMethod		PyObjC_preclass_addMethod
#define preclass_addProtocol		PyObjC_preclass_addProtocol

extern void PyObjC_SetupRuntimeCompat(void);

extern BOOL (*PyObjC_preclass_addMethod)(Class, SEL, IMP, const char*);
extern BOOL (*PyObjC_preclass_addIvar)(Class cls, 
		const char *name, size_t size, uint8_t alignment, 
		const char *types);
extern BOOL (*PyObjC_preclass_addProtocol)(Class cls, Protocol *protocol);


extern Class (*PyObjC_objc_allocateClassPair)(Class, const char*, size_t);
extern void (*PyObjC_objc_registerClassPair)(Class);
extern void (*PyObjC_objc_disposeClassPair)(Class cls);


extern Class (*PyObjC_object_getClass)(id obj);
extern Class (*PyObjC_object_setClass)(id obj, Class cls);
extern const char* (*PyObjC_object_getClassName)(id obj);

extern Method* (*PyObjC_class_copyMethodList)(Class, unsigned int*);
extern const char* (*PyObjC_class_getName)(Class);
extern Class (*PyObjC_class_getSuperclass)(Class);
extern BOOL (*PyObjC_class_addMethod)(Class, SEL, IMP, const char*);
extern BOOL (*PyObjC_class_addMethodList)(Class, 
		struct PyObjC_method*, unsigned int);
extern Ivar* (*PyObjC_class_copyIvarList)(Class, unsigned int*);
extern Protocol** (*PyObjC_class_copyProtocolList)(Class, unsigned int*);

extern BOOL (*PyObjC_class_isMetaClass)(Class);

extern SEL (*PyObjC_method_getName)(Method m);
extern const char *(*PyObjC_method_getTypeEncoding)(Method m);
extern IMP (*PyObjC_method_getImplementation)(Method m);
extern IMP (*PyObjC_method_setImplementation)(Method m, IMP imp);

extern BOOL (*PyObjC_sel_isEqual)(SEL, SEL);

extern size_t (*PyObjC_methodlist_magic)(Class cls);

extern const char*  (*PyObjC_ivar_getName)(Ivar);
extern const char*  (*PyObjC_ivar_getTypeEncoding)(Ivar);
extern ptrdiff_t    (*PyObjC_ivar_getOffset)(Ivar);

extern Protocol** (*PyObjC_objc_copyProtocolList)(unsigned int* outCount);
extern Protocol*  (*PyObjC_objc_getProtocol)(char* name);
extern struct objc_method_description_list* (*PyObjC_protocol_copyInstanceMethodDescriptionList)(Protocol* proto);
extern struct objc_method_description_list* (*PyObjC_protocol_copyClassMethodDescriptionList)(Protocol *proto);
extern struct objc_method_description_list* (*PyObjC_protocol_copyOptionalInstanceMethodDescriptionList)(Protocol *proto);
extern struct objc_method_description_list* (*PyObjC_protocol_copyOptionalClassMethodDescriptionList)(Protocol *proto);

extern BOOL (*PyObjC_protocol_conformsToProtocol)(Protocol *proto, Protocol *other);
extern const char *(*PyObjC_protocol_getName)(Protocol *p);
extern struct objc_method_description *(*PyObjC_protocol_copyMethodDescriptionList)(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount);
extern Protocol **(*PyObjC_protocol_copyProtocolList)(Protocol *proto, unsigned int *outCount);
extern struct objc_method_description (*PyObjC_protocol_getMethodDescription)(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod);

extern id (*PyObjC_object_getIvar)(id obj, Ivar ivar);
extern void (*PyObjC_object_setIvar)(id obj, Ivar ivar, id value);

#define object_getIvar			PyObjC_object_getIvar
#define object_setIvar			PyObjC_object_setIvar
#define protocol_getName		PyObjC_protocol_getName
#define protocol_conformsToProtocol     PyObjC_protocol_conformsToProtocol
#define protocol_copyMethodDescriptionList PyObjC_protocol_copyMethodDescriptionList
#define protocol_copyProtocolList	PyObjC_protocol_copyProtocolList
#define protocol_getMethodDescription   PyObjC_protocol_getMethodDescription

#define objc_allocateClassPair		PyObjC_objc_allocateClassPair
#define objc_registerClassPair		PyObjC_objc_registerClassPair
#define objc_disposeClassPair		PyObjC_objc_disposeClassPair

#define object_getClass 		PyObjC_object_getClass
#define object_setClass 		PyObjC_object_setClass
#define object_getClassName		PyObjC_object_getClassName

#define class_copyMethodList 		PyObjC_class_copyMethodList
#define class_getName 			PyObjC_class_getName
#define class_getSuperclass 		PyObjC_class_getSuperclass
#define class_addMethod	 		PyObjC_class_addMethod
#define class_addMethodList		PyObjC_class_addMethodList
#define class_copyIvarList		PyObjC_class_copyIvarList
#define class_copyProtocolList		PyObjC_class_copyProtocolList
#define class_conformsToProtocol	PyObjC_class_conformsToProtocol
#define class_isMetaClass		PyObjC_class_isMetaClass

#define method_getName 			PyObjC_method_getName
#define method_getTypeEncoding   	PyObjC_method_getTypeEncoding
#define method_getImplementation 	PyObjC_method_getImplementation
#define method_setImplementation 	PyObjC_method_setImplementation

#define sel_isEqual			PyObjC_sel_isEqual

#define ivar_getName			PyObjC_ivar_getName
#define ivar_getTypeEncoding		PyObjC_ivar_getTypeEncoding
#define ivar_getOffset			PyObjC_ivar_getOffset

#define objc_copyProtocolList 					PyObjC_objc_copyProtocolList
#define objc_getProtocol 					PyObjC_objc_getProtocol
#define protocol_copyInstanceMethodDescriptionList 		PyObjC_protocol_copyInstanceMethodDescriptionList
#define protocol_copyClassMethodDescriptionList 		PyObjC_protocol_copyClassMethodDescriptionList
#define protocol_copyOptionalInstanceMethodDescriptionList	PyObjC_protocol_copyOptionalInstanceMethodDescriptionList
#define protocol_copyOptionalClassMethodDescriptionList 	PyObjC_protocol_copyOptionalClassMethodDescriptionList

#else

/*
 * Compiled for 10.5 or later, use ObjC 2.0 runtime exclusively.
 *
 *
 * Use the preclass_ versions to modify a Class between allocating it and
 * registering it. This is needed for the 10.4 compatibility layer.
 */

#define preclass_addIvar		class_addIvar
#define preclass_addMethod		class_addMethod
#define preclass_addProtocol		class_addProtocol

static inline void PyObjC_SetupRuntimeCompat(void) { }
extern BOOL PyObjC_class_addMethodList(Class class, 
		struct PyObjC_method* list, unsigned int count);


extern size_t PyObjC_methodlist_magic(Class cls);

#define class_addMethodList	PyObjC_class_addMethodList


#endif


#endif /* PyObjC_RUNTIME_COMPAT */
#endif /* __NEXT_RUNTIME__ */