1#ifndef PyObjC_API_H
2#define PyObjC_API_H
3
4/*
5 * Use this in helper modules for the objc package, and in wrappers
6 * for functions that deal with objective-C objects/classes
7 *
8 * This header defines some utility wrappers for importing and using
9 * the core bridge.
10 *
11 * This is the *only* header file that should be used to access
12 * functionality in the core bridge.
13 *
14 * WARNING: this file is not part of the public interface of PyObjC and
15 * might change or be removed without warning or regard for backward
16 * compatibility.
17 */
18
19#include <objc/objc.h>
20
21#import <Foundation/Foundation.h>
22
23#include "pyobjc-compat.h"
24
25
26
27
28
29#import <Foundation/NSException.h>
30
31struct PyObjC_WeakLink {
32	const char* name;
33	void (*func)(void);
34};
35
36
37/* threading support */
38#ifdef NO_OBJC2_RUNTIME
39#define PyObjC_DURING \
40		Py_BEGIN_ALLOW_THREADS \
41		NS_DURING
42
43#define PyObjC_HANDLER NS_HANDLER
44
45#define PyObjC_ENDHANDLER \
46		NS_ENDHANDLER \
47		Py_END_ALLOW_THREADS
48#else
49
50#define	PyObjC_DURING \
51		Py_BEGIN_ALLOW_THREADS \
52		@try {
53
54#define PyObjC_HANDLER } @catch(volatile NSObject* _localException) { \
55		NSException* localException __attribute__((__unused__))= (NSException*)_localException;
56
57#define PyObjC_ENDHANDLER \
58		} \
59		Py_END_ALLOW_THREADS
60
61#endif
62
63#define PyObjC_BEGIN_WITH_GIL \
64	{ \
65		PyGILState_STATE _GILState; \
66		_GILState = PyGILState_Ensure();
67
68#define PyObjC_GIL_FORWARD_EXC() \
69		do { \
70            PyObjCErr_ToObjCWithGILState(&_GILState); \
71		} while (0)
72
73
74#define PyObjC_GIL_RETURN(val) \
75		do { \
76			PyGILState_Release(_GILState); \
77			return (val); \
78		} while (0)
79
80#define PyObjC_GIL_RETURNVOID \
81		do { \
82			PyGILState_Release(_GILState); \
83			return; \
84		} while (0)
85
86
87#define PyObjC_END_WITH_GIL \
88		PyGILState_Release(_GILState); \
89	}
90
91
92
93#include <objc/objc-runtime.h>
94
95/* On 10.1 there are no defines for the OS version. */
96#ifndef MAC_OS_X_VERSION_10_1
97#define MAC_OS_X_VERSION_10_1 1010
98#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_1
99
100#error "MAC_OS_X_VERSION_10_1 not defined. You aren't running 10.1 are you?"
101
102#endif
103
104#ifndef MAC_OS_X_VERSION_10_2
105#define MAC_OS_X_VERSION_10_2 1020
106#endif
107
108#ifndef MAC_OS_X_VERSION_10_3
109#define MAC_OS_X_VERSION_10_3 1030
110#endif
111
112#ifndef MAC_OS_X_VERSION_10_4
113#define MAC_OS_X_VERSION_10_4 1040
114#endif
115
116#ifndef MAC_OS_X_VERSION_10_5
117#define MAC_OS_X_VERSION_10_5 1050
118#endif
119
120/* Current API version, increase whenever:
121 * - Semantics of current functions change
122 * - Functions are removed
123 * Do not increase when adding a new function, the struct_len field
124 * can be used for detecting if a function has been added.
125 *
126 * HISTORY:
127 * - Version 2.2 adds PyObjCUnsupportedMethod_IMP
128 *       and PyObjCUnsupportedMethod_Caller
129 * - Version 2.1 adds PyObjCPointerWrapper_Register
130 * - Version 2 adds an argument to PyObjC_InitSuper
131 * - Version 3 adds another argument to PyObjC_CallPython
132 * - Version 4 adds PyObjCErr_ToObjCGILState
133 * - Version 4.1 adds PyObjCRT_AlignOfType and PyObjCRT_SizeOfType
134 *         (PyObjC_SizeOfType is now deprecated)
135 * - Version 4.2 adds PyObjCRT_SELName
136 * - Version 4.3 adds PyObjCRT_SimplifySignature
137 * - Version 4.4 adds PyObjC_FreeCArray, PyObjC_PythonToCArray and
138 *   		PyObjC_CArrayToPython
139 * - Version 5 modifies the signature for PyObjC_RegisterMethodMapping,
140 *	PyObjC_RegisterSignatureMapping and PyObjCUnsupportedMethod_IMP,
141 *      adds PyObjC_RegisterStructType and removes PyObjC_CallPython
142 * - Version 6 adds PyObjCIMP_Type, PyObjCIMP_GetIMP and PyObjCIMP_GetSelector
143 * - Version 7 adds PyObjCErr_AsExc, PyGILState_Ensure
144 * - Version 8 adds PyObjCObject_IsUninitialized,
145        removes PyObjCSelector_IsInitializer
146 * - Version 9 (???)
147 * - Version 10 changes the signature of PyObjCRT_SimplifySignature
148 * - Version 11 adds PyObjCObject_Convert, PyObjCSelector_Convert,
149     PyObjCClass_Convert, PyObjC_ConvertBOOL, and PyObjC_ConvertChar
150 * - Version 12 adds PyObjCObject_New
151 * - Version 13 adds PyObjCCreateOpaquePointerType
152 * - Version 14 adds PyObjCObject_NewTransient, PyObjCObject_ReleaseTransient
153 * - Version 15 changes the interface of PyObjCObject_New
154 * - Version 16 adds PyObjC_PerformWeaklinking
155 * - Version 17 introduces Py_ssize_t support
156 * - Version 18 introduces several API incompatibilities
157 * - Version 19 removes some old junk
158 */
159#define PYOBJC_API_VERSION 19
160
161#define PYOBJC_API_NAME "__C_API__"
162
163/*
164 * Only add items to the end of this list!
165 */
166typedef int (RegisterMethodMappingFunctionType)(
167			Class,
168			SEL,
169			PyObject *(*)(PyObject*, PyObject*, PyObject*),
170			void (*)(void*, void*, void**, void*));
171
172struct pyobjc_api {
173	int	      api_version;	/* API version */
174	size_t	      struct_len;	/* Length of this struct */
175	PyTypeObject* class_type;	/* PyObjCClass_Type    */
176	PyTypeObject* object_type;	/* PyObjCObject_Type   */
177	PyTypeObject* select_type;	/* PyObjCSelector_Type */
178
179	/* PyObjC_RegisterMethodMapping */
180	RegisterMethodMappingFunctionType *register_method_mapping;
181
182	/* PyObjC_RegisterSignatureMapping */
183	int (*register_signature_mapping)(
184			char*,
185			PyObject *(*)(PyObject*, PyObject*, PyObject*),
186			void (*)(void*, void*, void**, void*));
187
188	/* PyObjCObject_GetObject */
189	id (*obj_get_object)(PyObject*);
190
191	/* PyObjCObject_ClearObject */
192	void (*obj_clear_object)(PyObject*);
193
194	/* PyObjCClass_GetClass */
195	Class (*cls_get_class)(PyObject*);
196
197	/* PyObjCClass_New */
198	PyObject* (*cls_to_python)(Class cls);
199
200	/* PyObjC_PythonToId */
201	id (*python_to_id)(PyObject*);
202
203	/* PyObjC_IdToPython */
204	PyObject* (*id_to_python)(id);
205
206	/* PyObjCErr_FromObjC */
207	void (*err_objc_to_python)(NSException*);
208
209	/* PyObjCErr_ToObjC */
210	void (*err_python_to_objc)(void);
211
212	/* PyObjC_PythonToObjC */
213	int (*py_to_objc)(const char*, PyObject*, void*);
214
215	/* PyObjC_ObjCToPython */
216	PyObject* (*objc_to_py)(const char*, void*);
217
218	/* PyObjC_SizeOfType */
219	Py_ssize_t   (*sizeof_type)(const char*);
220
221	/* PyObjCSelector_GetClass */
222	Class	   (*sel_get_class)(PyObject* sel);
223
224	/* PyObjCSelector_GetSelector */
225	SEL	   (*sel_get_sel)(PyObject* sel);
226
227	/* PyObjC_InitSuper */
228	void	(*fill_super)(struct objc_super*, Class, id);
229
230	/* PyObjC_InitSuperCls */
231	void	(*fill_super_cls)(struct objc_super*, Class, Class);
232
233	/* PyObjCPointerWrapper_Register */
234	int  (*register_pointer_wrapper)(
235		        const char*, PyObject* (*pythonify)(void*),
236			int (*depythonify)(PyObject*, void*)
237		);
238
239	void (*unsupported_method_imp)(void*, void*, void**, void*);
240	PyObject* (*unsupported_method_caller)(PyObject*, PyObject*, PyObject*);
241
242	/* PyObjCErr_ToObjCWithGILState */
243	void (*err_python_to_objc_gil)(PyGILState_STATE* state);
244
245	/* PyObjCRT_AlignOfType */
246	Py_ssize_t (*alignof_type)(const char* typestr);
247
248	/* PyObjCRT_SELName */
249	const char* (*selname)(SEL sel);
250
251	/* PyObjCRT_SimplifySignature */
252	int (*simplify_sig)(const char* signature, char* buf, size_t buflen);
253
254	/* PyObjC_FreeCArray */
255	void    (*free_c_array)(int,void*);
256
257	/* PyObjC_PythonToCArray */
258	int     (*py_to_c_array)(BOOL, BOOL, const char*, PyObject*, void**, Py_ssize_t*, PyObject**);
259
260	/* PyObjC_CArrayToPython */
261	PyObject* (*c_array_to_py)(const char*, void*, Py_ssize_t);
262
263	/* PyObjC_RegisterStructType */
264	PyObject* (*register_struct)(const char*, const char*, const char*, initproc, Py_ssize_t, const char**, Py_ssize_t);
265
266	/* PyObjCIMP_Type */
267	PyTypeObject* imp_type;
268
269	/* PyObjCIMP_GetIMP */
270	IMP  (*imp_get_imp)(PyObject*);
271
272	/* PyObjCIMP_GetSelector */
273	SEL  (*imp_get_sel)(PyObject*);
274
275	/* PyObjCErr_AsExc */
276	NSException* (*err_python_to_nsexception)(void);
277
278	/* PyGILState_Ensure */
279	PyGILState_STATE (*gilstate_ensure)(void);
280
281	/* PyObjCObject_IsUninitialized */
282	int (*obj_is_uninitialized)(PyObject*);
283
284	/* PyObjCObject_New */
285	PyObject* (*pyobjc_object_new)(id, int , int);
286
287	/* PyObjCCreateOpaquePointerType */
288	PyObject* (*pointer_type_new)(const char*, const char*, const char*);
289
290	/* PyObject* PyObjCObject_NewTransient(id objc_object, int* cookie); */
291	PyObject* (*newtransient)(id objc_object, int* cookie);
292
293	/* void PyObjCObject_ReleaseTransient(PyObject* proxy, int cookie); */
294	void (*releasetransient)(PyObject* proxy, int cookie);
295
296	void (*doweaklink)(PyObject*, struct PyObjC_WeakLink*);
297
298	const char* (*removefields)(char*, const char*);
299
300	PyObject** pyobjc_null;
301
302	int (*dep_c_array_count)(const char* type, Py_ssize_t count, BOOL strict, PyObject* value, void* datum);
303
304	PyObject* (*varlistnew)(const char* tp, void* array);
305
306	int (*is_ascii_string)(PyObject* unicode_string, const char* ascii_string);
307	int (*is_ascii_prefix)(PyObject* unicode_string, const char* ascii_string, size_t n);
308
309	int (*pyobjcobject_convert)(PyObject*,void*);
310};
311
312#ifndef PYOBJC_BUILD
313
314#ifndef PYOBJC_METHOD_STUB_IMPL
315static struct pyobjc_api*	PyObjC_API;
316#endif /* PYOBJC_METHOD_STUB_IMPL */
317
318#define PyObjC_is_ascii_string (PyObjC_API->is_ascii_string)
319#define PyObjC_is_ascii_prefix (PyObjC_API->is_ascii_prefix)
320
321#define PyObjCObject_Check(obj) PyObject_TypeCheck(obj, PyObjC_API->object_type)
322#define PyObjCClass_Check(obj)  PyObject_TypeCheck(obj, PyObjC_API->class_type)
323#define PyObjCSelector_Check(obj)  PyObject_TypeCheck(obj, PyObjC_API->select_type)
324#define PyObjCIMP_Check(obj)  PyObject_TypeCheck(obj, PyObjC_API->imp_type)
325#define PyObjCObject_GetObject (PyObjC_API->obj_get_object)
326#define PyObjCObject_ClearObject (PyObjC_API->obj_clear_object)
327#define PyObjCClass_GetClass   (PyObjC_API->cls_get_class)
328#define PyObjCClass_New 	     (PyObjC_API->cls_to_python)
329#define PyObjCSelector_GetClass (PyObjC_API->sel_get_class)
330#define PyObjCSelector_GetSelector (PyObjC_API->sel_get_sel)
331#define PyObjC_PythonToId      (PyObjC_API->python_to_id)
332#define PyObjC_IdToPython      (PyObjC_API->id_to_python)
333#define PyObjCErr_FromObjC     (PyObjC_API->err_objc_to_python)
334#define PyObjCErr_ToObjC       (PyObjC_API->err_python_to_objc)
335#define PyObjCErr_ToObjCWithGILState       (PyObjC_API->err_python_to_objc_gil)
336#define PyObjCErr_AsExc        (PyObjC_API->err_python_to_nsexception)
337#define PyObjC_PythonToObjC    (PyObjC_API->py_to_objc)
338#define PyObjC_ObjCToPython    (PyObjC_API->objc_to_py)
339#define PyObjC_RegisterMethodMapping (PyObjC_API->register_method_mapping)
340#define PyObjC_RegisterSignatureMapping (PyObjC_API->register_signature_mapping)
341#define PyObjC_SizeOfType      (PyObjC_API->sizeof_type)
342#define PyObjC_PythonToObjC   (PyObjC_API->py_to_objc)
343#define PyObjC_ObjCToPython   (PyObjC_API->objc_to_py)
344#define PyObjC_InitSuper	(PyObjC_API->fill_super)
345#define PyObjC_InitSuperCls	(PyObjC_API->fill_super_cls)
346#define PyObjCPointerWrapper_Register (PyObjC_API->register_pointer_wrapper)
347#define PyObjCUnsupportedMethod_IMP (PyObjC_API->unsupported_method_imp)
348#define PyObjCUnsupportedMethod_Caller (PyObjC_API->unsupported_method_caller)
349#define PyObjCRT_SizeOfType      (PyObjC_API->sizeof_type)
350#define PyObjCRT_AlignOfType	(PyObjC_API->alignof_type)
351#define PyObjCRT_SELName	(PyObjC_API->selname)
352#define PyObjCRT_SimplifySignature	(PyObjC_API->simplify_sig)
353#define PyObjC_FreeCArray	(PyObjC_API->free_c_array)
354#define PyObjC_PythonToCArray	(PyObjC_API->py_to_c_array)
355#define PyObjC_CArrayToPython	(PyObjC_API->c_array_to_py)
356#define PyObjC_RegisterStructType   (PyObjC_API->register_struct)
357#define PyObjCIMP_GetIMP   (PyObjC_API->imp_get_imp)
358#define PyObjCIMP_GetSelector   (PyObjC_API->imp_get_sel)
359#define PyObjCObject_IsUninitialized (PyObjC_API->obj_is_uninitialized)
360#define PyObjCObject_New (PyObjC_API->pyobjc_object_new)
361#define PyObjCCreateOpaquePointerType (PyObjC_API->pointer_type_new)
362#define PyObjCObject_NewTransient (PyObjC_API->newtransient)
363#define PyObjCObject_ReleaseTransient (PyObjC_API->releasetransient)
364#define PyObjC_PerformWeaklinking (PyObjC_API->doweaklink)
365#define PyObjCRT_RemoveFieldNames (PyObjC_API->removefields)
366#define PyObjC_NULL		  (*(PyObjC_API->pyobjc_null))
367#define PyObjC_DepythonifyCArray  (PyObjC_API->dep_c_array_count)
368#define PyObjC_VarList_New  (PyObjC_API->varlistnew)
369#define PyObjCObject_Convert (PyObjC_API->pyobjcobject_convert)
370
371typedef void (*PyObjC_Function_Pointer)(void);
372
373typedef struct PyObjC_function_map {
374    const char* 		name;
375    PyObjC_Function_Pointer     function;
376} PyObjC_function_map;
377
378
379
380#ifndef PYOBJC_METHOD_STUB_IMPL
381
382static inline PyObject*
383PyObjC_CreateInlineTab(PyObjC_function_map* map)
384{
385#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
386	return PyCObject_FromVoidPtr(map, NULL);
387#else
388	return PyCapsule_New(map, "objc.__inline__", NULL);
389#endif
390}
391
392static inline int
393PyObjC_ImportAPI(PyObject* calling_module)
394{
395	PyObject* m;
396	PyObject* d;
397	PyObject* api_obj;
398#if PY_MAJOR_VERSION == 2
399	PyObject* name = PyString_FromString("objc");
400#else
401	PyObject* name = PyUnicode_FromString("objc");
402#endif
403
404	m = PyImport_Import(name);
405	Py_DECREF(name);
406	if (m == NULL) {
407		return -1;
408	}
409
410	d = PyModule_GetDict(m);
411	if (d == NULL) {
412		PyErr_SetString(PyExc_RuntimeError,
413			"No dict in objc module");
414		return -1;
415	}
416
417	api_obj = PyDict_GetItemString(d, PYOBJC_API_NAME);
418	if (api_obj == NULL) {
419		PyErr_SetString(PyExc_RuntimeError,
420			"No C_API in objc module");
421		return -1;
422	}
423#if PY_MAJOR_VERSION == 2 && PY_VERSION_MAJOR < 7
424	PyObjC_API = PyCObject_AsVoidPtr(api_obj);
425#else
426	PyObjC_API = PyCapsule_GetPointer(api_obj, "objc." PYOBJC_API_NAME);
427#endif
428	if (PyObjC_API == NULL) {
429		return 0;
430	}
431	if (PyObjC_API->api_version != PYOBJC_API_VERSION) {
432		PyErr_SetString(PyExc_RuntimeError,
433			"Wrong version of PyObjC C API");
434		return -1;
435	}
436
437	if (PyObjC_API->struct_len < sizeof(struct pyobjc_api)) {
438		PyErr_SetString(PyExc_RuntimeError,
439			"Wrong struct-size of PyObjC C API");
440		return -1;
441	}
442
443	Py_INCREF(api_obj);
444
445	/* Current pyobjc implementation doesn't allow deregistering
446	 * information, avoid unloading of users of the C-API.
447	 * (Yes this is ugle, patches to fix this situation are apriciated)
448	 */
449	Py_INCREF(calling_module);
450
451	return 0;
452}
453#endif /* PYOBJC_METHOD_STUB_IMPL */
454
455#else /* PyObjC_BUILD */
456
457extern struct pyobjc_api	objc_api;
458
459#endif /* !PYOBJC_BUILD */
460
461/*
462 * Helper macros to simplify module init functions.
463 */
464#define PyObjC__STR(x) #x
465#define PyObjC_STR(x) PyObjC__STR(x)
466
467#if PY_MAJOR_VERSION == 3
468
469#define PyObjC_INITERROR() return NULL
470#define PyObjC_INITDONE() return m
471
472
473#define PyObjC_MODULE_INIT(name) \
474	static struct PyModuleDef mod_module = { \
475		PyModuleDef_HEAD_INIT, \
476	 	PyObjC_STR(name), \
477		NULL, \
478		0, \
479		mod_methods, \
480		NULL, \
481		NULL, \
482		NULL, \
483		NULL \
484	}; \
485	\
486	PyObject* PyInit_##name(void); \
487	PyObject* PyInit_##name(void)
488
489#define PyObjC_MODULE_CREATE(name) \
490	PyModule_Create(&mod_module);
491
492#else
493
494#define PyObjC_INITERROR() return
495#define PyObjC_INITDONE() return
496
497#define PyObjC_MODULE_INIT(name) \
498	void init##name(void); \
499	void init##name(void)
500
501#define PyObjC_MODULE_CREATE(name) \
502	Py_InitModule4(PyObjC_STR(name), mod_methods, \
503			NULL, NULL, PYTHON_API_VERSION);
504
505#endif
506
507#endif /*  PyObjC_API_H */
508