1/*
2 * This file contains the code that is used to create proxy-classes for Python
3 * classes in the objective-C runtime.
4 */
5#include "pyobjc.h"
6
7#import <Foundation/NSInvocation.h>
8
9PyObject* PyObjC_class_setup_hook = NULL;
10
11#if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
12
13/*
14 * KVO was introduced in 10.3, but wasn't perfect and needs workarounds. Starting from 10.4 we can
15 * use KVO as-is without causing problems.
16 *
17 * Code to be removed when we no longer whish to support 10.3.
18 */
19
20#define TO_CHECK (0)		// Didn't check yet
21#define NO_KVO   (-1)		// No KVO available
22#define BROKEN_KVO (1)		// KVO available, but needs workaround
23#define OK_KVO (2)		// KVO available
24
25static int
26_KVOHackLevel(void) {
27	static int _checkedKVO = TO_CHECK;
28	if (_checkedKVO == TO_CHECK) {
29		if ([NSObject instancesRespondToSelector:@selector(willChangeValueForKey:)] &&
30			[NSObject instancesRespondToSelector:@selector(didChangeValueForKey:)]) {
31			_checkedKVO = BROKEN_KVO;
32			if ([NSObject instancesRespondToSelector:@selector(willChangeValueForKey:withSetMutation:usingObjects:)]) {
33				_checkedKVO = OK_KVO;
34			}
35		} else {
36			_checkedKVO = NO_KVO;
37		}
38	}
39	return _checkedKVO;
40}
41
42static BOOL
43_UseKVO(NSObject *self, NSString *key, BOOL isSet)
44{
45	int _checkedKVO = _KVOHackLevel();
46	NSNumber *n;
47	if (_checkedKVO == NO_KVO) {
48		return NO;
49	} else if (_checkedKVO == OK_KVO) {
50		return YES;
51	}
52	static NSMapTable* kvo_stack = nil;
53	if (kvo_stack == nil) {
54		kvo_stack = NSCreateMapTable(
55			PyObjCUtil_ObjCIdentityKeyCallBacks,
56			PyObjCUtil_ObjCValueCallBacks,
57			0);
58	}
59	// Hacks for Panther so that you don't get nested observations
60	NSMutableDictionary *kvoDict = (NSMutableDictionary *)NSMapGet(kvo_stack, (const void *)self);
61	if (!kvoDict) {
62		kvoDict = [[NSMutableDictionary alloc] initWithCapacity:0];
63		NSMapInsert(kvo_stack, (const void *)self, (const void *)kvoDict);
64		[kvoDict release];
65	}
66	if (isSet) {
67		int setCount = [(NSNumber *)[kvoDict objectForKey:key] intValue] + 1;
68		n = [[NSNumber alloc] initWithInt:setCount];
69		[kvoDict setValue:n forKey:key];
70		[n release];
71		if (setCount != 1) {
72			return NO;
73		}
74	} else {
75		int setCount = [(NSNumber *)[kvoDict objectForKey:key] intValue] - 1;
76		if (setCount != 0) {
77			n = [[NSNumber alloc] initWithInt:setCount];
78			[kvoDict setValue:n forKey:key];
79			[n release];
80			return NO;
81		} else {
82			[kvoDict removeObjectForKey:key];
83			if (![kvoDict count]) {
84				NSMapRemove(kvo_stack, (const void *)self);
85			}
86		}
87	}
88	return YES;
89}
90
91#endif
92
93/* Special methods for Python subclasses of Objective-C objects */
94static void object_method_finalize(
95		ffi_cif* cif,
96		void* retval,
97		void** args,
98		void* userarg);
99static void object_method_dealloc(
100		ffi_cif* cif,
101		void* retval,
102		void** args,
103		void* userarg);
104static void object_method_respondsToSelector(
105		ffi_cif* cif,
106		void* retval,
107		void** args,
108		void* userarg);
109static void object_method_methodSignatureForSelector(
110		ffi_cif* cif,
111		void* retval,
112		void** args,
113		void* userarg);
114static void object_method_forwardInvocation(
115		ffi_cif* cif,
116		void* retval,
117		void** args,
118		void* userarg);
119static void object_method_valueForKey_(
120		ffi_cif* cif,
121		void* retval,
122		void** args,
123		void* userarg);
124static void object_method_setValue_forKey_(
125		ffi_cif* cif,
126		void* retval,
127		void** args,
128		void* userarg);
129
130#if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
131
132static void object_method_willOrDidChangeValueForKey_(
133		ffi_cif* cif,
134		void* retval,
135		void** args,
136		void* userarg);
137#endif
138
139static char copyWithZone_signature[132] = { '\0' };
140static void object_method_copyWithZone_(
141		ffi_cif* cif __attribute__((__unused__)),
142		void* resp,
143		void** args,
144		void* userdata);
145
146#define IDENT_CHARS "ABCDEFGHIJKLMNOPQSRTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"
147
148/*
149 * Last step of the construction a python subclass of an objective-C class.
150 *
151 * Set reference to the python half in the objective-C half of the class.
152 *
153 * Return 0 on success, -1 on failure.
154 */
155int
156PyObjCClass_FinishClass(Class objc_class)
157{
158	PyObjC_Assert(objc_class != nil, -1);
159
160	objc_registerClassPair(objc_class);
161	return 0;
162}
163
164/*
165 * Call this when the python half of the class could not be created.
166 *
167 * Due to technical restrictions it is not allowed to unbuild a class that
168 * is already registered with the Objective-C runtime.
169 */
170int
171PyObjCClass_UnbuildClass(Class objc_class __attribute__((__unused__)))
172{
173	PyObjC_Assert(objc_class != nil, -1);
174	PyObjC_Assert(objc_lookUpClass(class_getName(objc_class)) == nil, -1);
175
176	//objc_disposeClassPair(objc_class);
177	return 0;
178}
179
180/*
181 * The Python proxy for an object should not contain any state, even if
182 * the class is defined in Python. Therefore transfer all slots to the
183 * Objective-C class and add '__slots__ = ()' to the Python class.
184 */
185static int
186do_slots(PyObject* super_class, PyObject* clsdict)
187{
188	PyObject* slot_value;
189	PyObject* slots;
190	Py_ssize_t len, i;
191
192	slot_value = PyDict_GetItemString(clsdict, "__slots__");
193	if (slot_value == NULL) {
194		PyObject* v;
195
196		/* Add an __dict__ unless it is already there */
197		PyErr_Clear();
198
199		slot_value = PyTuple_New(0);
200		if (slot_value == NULL) {
201			return 0;
202		}
203
204		if (PyDict_SetItemString(clsdict, "__slots__", slot_value) < 0){
205			Py_DECREF(slot_value);
206			return -1;
207		}
208		Py_DECREF(slot_value);
209
210		if (PyObjCClass_DictOffset(super_class) != 0) {
211			/* We already have an __dict__ */
212			return 0;
213		}
214
215		v = PyObjCInstanceVariable_New("__dict__");
216		if (v == NULL) {
217			return -1;
218		}
219		((PyObjCInstanceVariable*)v)->type = PyObjCUtil_Strdup(@encode(PyObject*));
220		((PyObjCInstanceVariable*)v)->isSlot = 1;
221		if (PyDict_SetItemString(clsdict, "__dict__", v) < 0) {
222			Py_DECREF(v);
223			return -1;
224		}
225		Py_DECREF(v);
226
227		return 0;
228	}
229
230	slots = PySequence_Fast(slot_value, "__slots__ must be a sequence");
231	if (slots == NULL) {
232		return -1;
233	}
234
235	len = PySequence_Fast_GET_SIZE(slots);
236	for (i = 0; i < len; i++) {
237		PyObjCInstanceVariable* var;
238		slot_value = PySequence_Fast_GET_ITEM(slots, i);
239
240		if (PyUnicode_Check(slot_value)) {
241			PyObject* bytes = PyUnicode_AsEncodedString(slot_value, NULL, NULL);
242			if (bytes == NULL) {
243				return -1;
244			}
245			var = (PyObjCInstanceVariable*)PyObjCInstanceVariable_New(
246				PyBytes_AsString(bytes));
247			Py_DECREF(bytes);
248
249#if PY_MAJOR_VERSION == 2
250		}  else if (PyString_Check(slot_value)) {
251			var = (PyObjCInstanceVariable*)PyObjCInstanceVariable_New(
252				PyString_AS_STRING(slot_value));
253
254#endif
255		} else {
256
257			PyErr_Format(PyExc_TypeError,
258				"__slots__ entry %" PY_FORMAT_SIZE_T
259				"d is not a string", i);
260			Py_DECREF(slots);
261			return -1;
262		}
263
264		if (var == NULL) {
265			Py_DECREF(slots);
266			return -1;
267		}
268		((PyObjCInstanceVariable*)var)->type = PyObjCUtil_Strdup(@encode(PyObject*));
269		((PyObjCInstanceVariable*)var)->isSlot = 1;
270
271		if (PyDict_SetItem(clsdict, slot_value, (PyObject*)var) < 0) {
272			Py_DECREF(slots);
273			Py_DECREF(var);
274			return -1;
275		}
276		Py_DECREF(var);
277	}
278	Py_DECREF(slots);
279
280	slot_value = PyTuple_New(0);
281	if (slot_value == NULL) {
282		return 0;
283	}
284	if (PyDict_SetItemString(clsdict, "__slots__", slot_value) < 0) {
285		Py_DECREF(slot_value);
286		return -1;
287	}
288	Py_DECREF(slot_value);
289	return 0;
290}
291
292/*
293 * Built a (pure Objective-C) subclass of base_class that defines our version
294 */
295
296static Class
297build_intermediate_class(Class base_class, char* name)
298{
299	Class intermediate_class = nil;
300	IMP closure;
301	PyObjCMethodSignature* methinfo = NULL;
302
303	if (copyWithZone_signature[0] == '\0') {
304		snprintf(copyWithZone_signature,
305			sizeof(copyWithZone_signature),
306			"@@:%s", @encode(NSZone*));
307	}
308
309	intermediate_class = objc_allocateClassPair(
310			base_class, strdup(name), 0);
311	if (intermediate_class == NULL) {
312		PyErr_NoMemory();
313		goto error_cleanup;
314	}
315
316	if ([base_class instancesRespondToSelector:@selector(copyWithZone:)]) {
317		methinfo = PyObjCMethodSignature_FromSignature(
318				copyWithZone_signature, NO);
319		if (methinfo == NULL) goto error_cleanup;
320		closure = PyObjCFFI_MakeClosure(methinfo,
321				object_method_copyWithZone_, base_class);
322		Py_DECREF(methinfo); methinfo = NULL;
323		if (closure == NULL) goto error_cleanup;
324
325		preclass_addMethod(
326			intermediate_class,
327			@selector(copyWithZone:),
328			(IMP)closure,
329			copyWithZone_signature);
330	}
331	if ([base_class instancesRespondToSelector:@selector(mutableCopyWithZone:)]) {
332		methinfo = PyObjCMethodSignature_FromSignature(
333				copyWithZone_signature, NO);
334		if (methinfo == NULL) goto error_cleanup;
335		closure = PyObjCFFI_MakeClosure(methinfo,
336				object_method_copyWithZone_, base_class);
337		Py_DECREF(methinfo); methinfo = NULL;
338		if (closure == NULL) goto error_cleanup;
339
340		preclass_addMethod(
341			intermediate_class,
342			@selector(mutableCopyWithZone:),
343			(IMP)closure,
344			copyWithZone_signature);
345	}
346
347	methinfo = PyObjCMethodSignature_FromSignature("v@:", NO);
348	if (methinfo == NULL) goto error_cleanup;
349	closure = PyObjCFFI_MakeClosure(methinfo, object_method_dealloc,
350		base_class);
351	Py_DECREF(methinfo); methinfo = NULL;
352	if (closure == NULL) goto error_cleanup;
353
354	preclass_addMethod( intermediate_class, @selector(dealloc),
355			(IMP)closure, "v@:");
356
357	methinfo = PyObjCMethodSignature_FromSignature("v@:", NO);
358	if (methinfo == NULL) goto error_cleanup;
359	closure = PyObjCFFI_MakeClosure(methinfo, object_method_finalize,
360		base_class);
361	Py_DECREF(methinfo); methinfo = NULL;
362	if (closure == NULL) goto error_cleanup;
363
364	preclass_addMethod( intermediate_class, @selector(finalize),
365			(IMP)closure, "v@:");
366
367	methinfo = PyObjCMethodSignature_FromSignature("@@:@", NO);
368	if (methinfo == NULL) goto error_cleanup;
369	closure = PyObjCFFI_MakeClosure(methinfo, object_method_valueForKey_,
370		base_class);
371	Py_DECREF(methinfo); methinfo = NULL;
372	if (closure == NULL) goto error_cleanup;
373
374	preclass_addMethod(intermediate_class, @selector(valueForKey:),
375		(IMP)closure, "@@:@");
376	preclass_addMethod(intermediate_class, @selector(storedValueForKey:),
377		(IMP)closure, "@@:@");
378
379	methinfo = PyObjCMethodSignature_FromSignature("v@:@@", NO);
380	if (methinfo == NULL) goto error_cleanup;
381	closure = PyObjCFFI_MakeClosure(methinfo, object_method_setValue_forKey_,
382		base_class);
383	Py_DECREF(methinfo); methinfo = NULL;
384	if (closure == NULL) goto error_cleanup;
385	preclass_addMethod(intermediate_class,
386		@selector(setValue:forKey:),        (IMP)closure, "v@:@@");
387	preclass_addMethod(intermediate_class,
388		@selector(takeStoredValue:forKey:), (IMP)closure, "v@:@@");
389	preclass_addMethod(intermediate_class,
390		@selector(takeValue:forKey:),       (IMP)closure, "v@:@@");
391
392
393	methinfo = PyObjCMethodSignature_FromSignature("c@::", NO);
394	if (methinfo == NULL) goto error_cleanup;
395	closure = PyObjCFFI_MakeClosure(methinfo,
396		object_method_respondsToSelector,
397		base_class);
398	Py_DECREF(methinfo); methinfo = NULL;
399	if (closure == NULL) goto error_cleanup;
400	preclass_addMethod(intermediate_class,
401		@selector(respondsToSelector:),
402		(IMP)closure, "c@::");
403
404	methinfo = PyObjCMethodSignature_FromSignature("@@::", NO);
405	if (methinfo == NULL) goto error_cleanup;
406	closure = PyObjCFFI_MakeClosure(methinfo,
407		object_method_methodSignatureForSelector,
408		base_class);
409	Py_DECREF(methinfo); methinfo = NULL;
410	if (closure == NULL) goto error_cleanup;
411	preclass_addMethod(intermediate_class,
412		@selector(methodSignatureForSelector:),
413		(IMP)closure, "@@::");
414
415	methinfo = PyObjCMethodSignature_FromSignature("v@:@", NO);
416	if (methinfo == NULL) goto error_cleanup;
417	closure = PyObjCFFI_MakeClosure(methinfo,
418		object_method_forwardInvocation,
419		base_class);
420	Py_DECREF(methinfo); methinfo = NULL;
421	if (closure == NULL) goto error_cleanup;
422	preclass_addMethod(intermediate_class,
423		@selector(forwardInvocation:),
424		(IMP)closure, "v@:@");
425
426
427
428#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
429	if (_KVOHackLevel() == BROKEN_KVO) {
430		methinfo = PyObjCMethodSignature_FromSignature("v@:@", NO);
431		if (methinfo == NULL) goto error_cleanup;
432		closure = PyObjCFFI_MakeClosure(methinfo, object_method_willOrDidChangeValueForKey_,
433			base_class);
434		Py_DECREF(methinfo); methinfo = NULL;
435		if (closure == NULL) goto error_cleanup;
436		preclass_addMethod(intermediate_class,
437			@selector(willChangeValueForKey:),
438			(IMP)closure, "v@:@");
439		preclass_addMethod(intermediate_class,
440			@selector(didChangeValueForKey:),
441			(IMP)closure, "v@:@");
442	}
443#endif
444
445	objc_registerClassPair(intermediate_class);
446
447	return (Class)intermediate_class;
448
449error_cleanup:
450	if (intermediate_class) {
451		objc_disposeClassPair(intermediate_class);
452	}
453	if (methinfo) {
454		Py_DECREF(methinfo);
455	}
456
457	return NULL;
458}
459
460
461
462/*
463 * First step of creating a python subclass of an objective-C class
464 *
465 * Returns NULL or the newly created objective-C class. 'class_dict' may
466 * be modified by this function.
467 *
468 * TODO:
469 * - Set 'sel_class' of PyObjCPythonSelector instances
470 * - This function complete ignores other base-classes, even though they
471 *   might override methods. Need to check the MRO documentation to check
472 *   if this is a problem.
473 * - It is a problem when the user tries to use mixins to define common
474 *   methods (like a NSTableViewDataSource mixin), this works but slowly
475 *   because this calls will always be resolved through forwardInvocation:
476 * - Add an 'override' flag that makes it possible to replace an existing
477 *   PyObjC class, feature request for the Python-IDE  (write class, run,
478 *   oops this doesn't work, rewrite class, reload and continue testing in
479 *   the running app)
480 */
481
482
483/* PyObjC uses a number of typecode descriptors that aren't available in
484 * the objc runtime.  Remove these from the type string (inline).
485 */
486static void tc2tc(char* buf)
487{
488	/* Skip pointer declarations and anotations */
489	for (;;) {
490		switch(*buf) {
491		case _C_PTR:
492		case _C_IN:
493		case _C_OUT:
494		case _C_INOUT:
495		case _C_ONEWAY:
496		case _C_CONST:
497			buf++;
498			break;
499		default:
500			goto exit;
501		}
502	}
503exit:
504
505	switch (*buf) {
506	case _C_NSBOOL:
507	case _C_CHAR_AS_INT:
508	case _C_CHAR_AS_TEXT:
509		*buf = _C_CHR;
510		break;
511
512	case _C_UNICHAR:
513		*buf = _C_SHT;
514		break;
515
516	case _C_STRUCT_B:
517		while (*buf != _C_STRUCT_E && *buf && *buf++ != '=') {
518		}
519		while (*buf && *buf != _C_STRUCT_E) {
520			if (*buf == '"') {
521				/* embedded field name */
522				buf = strchr(buf+1, '"');
523				if (buf == NULL) {
524					return;
525				}
526				buf++;
527			}
528			tc2tc(buf);
529			buf = (char*)PyObjCRT_SkipTypeSpec(buf);
530		}
531		break;
532
533	case _C_UNION_B:
534		while (*buf != _C_UNION_E && *buf && *buf++ != '=') {
535		}
536		while (*buf && *buf != _C_UNION_E) {
537			if (*buf == '"') {
538				/* embedded field name */
539				buf = strchr(buf+1, '"');
540				if (buf == NULL) {
541					return;
542				}
543				buf++;
544			}
545			tc2tc(buf);
546			buf = (char*)PyObjCRT_SkipTypeSpec(buf);
547		}
548		break;
549
550
551	case _C_ARY_B:
552		while (isdigit(*++buf));
553		tc2tc(buf);
554		break;
555	}
556}
557void PyObjC_RemoveInternalTypeCodes(char* buf)
558{
559	while(buf && *buf) {
560		tc2tc(buf);
561		buf = (char*)PyObjCRT_SkipTypeSpec(buf);
562	}
563}
564
565static BOOL same_signature(const char* sig1, const char* sig2)
566{
567	while (sig1 && *sig1 && sig2 && *sig2) {
568		const char* end1 = PyObjCRT_SkipTypeSpec(sig1);
569		const char* end2 = PyObjCRT_SkipTypeSpec(sig2);
570
571		/* Check for an invalid signature: */
572		if (end1 == NULL) return NO;
573		if (end2 == NULL) return NO;
574
575		const char* t1 = end1 - 1;
576		while (t1 != sig1 && isdigit(*t1)) {
577			t1--;
578		}
579		t1++;
580
581		const char* t2 = end2 - 1;
582		while (t2 != sig2 && isdigit(*t2)) {
583			t2--;
584		}
585		t2++;
586
587		if (t1 - sig1 != t2 - sig2) {
588			/* Elements don't have same size */
589			return NO;
590		}
591		if (strncmp(sig1, sig2, t1-sig1) != 0) {
592			/* Elements don't have same value */
593			return NO;
594		}
595		sig1 = end1;
596		sig2 = end2;
597	}
598
599	/* We reached the end of one of the signatures,
600	 * check that we reached both ends
601	 */
602	if (sig1 && *sig1) {
603		return NO;
604	}
605	if (sig2 && *sig2) {
606		return NO;
607	}
608	return YES;
609}
610
611Class
612PyObjCClass_BuildClass(Class super_class,  PyObject* protocols,
613		char* name, PyObject* class_dict, PyObject* meta_dict,
614		PyObject* hiddenSelectors, PyObject* hiddenClassSelectors)
615{
616	PyObject* seq;
617	PyObject*                key_list = NULL;
618	PyObject*                key = NULL;
619	PyObject*                value = NULL;
620	Py_ssize_t		 i;
621	Py_ssize_t		 key_count;
622	Py_ssize_t               protocol_count = 0;
623	int                      first_python_gen = 0;
624	Class		 	 new_class = NULL;
625	Class		 	 new_meta_class = NULL;
626	Class                    cur_class;
627	PyObject*                py_superclass = NULL;
628	int			 have_intermediate = 0;
629	int			 need_intermediate = 0;
630	PyObject* 		 instance_variables = NULL;
631	PyObject* 		 instance_methods = NULL;
632	PyObject* 		 class_methods = NULL;
633
634	if (!PyList_Check(protocols)) {
635		PyErr_Format(PyObjCExc_InternalError,
636			"protocol list not a python 'list' but '%s'",
637			Py_TYPE(protocols)->tp_name);
638		goto error_cleanup;
639	}
640	if (!PyDict_Check(class_dict)) {
641		PyErr_Format(PyObjCExc_InternalError,
642			"class dict not a python 'dict', but '%s'",
643			Py_TYPE(class_dict)->tp_name);
644		goto error_cleanup;
645	}
646	if (super_class == NULL) {
647		PyErr_SetString(PyObjCExc_InternalError,
648			"must have super_class");
649		goto error_cleanup;
650	}
651
652	if ((cur_class = objc_lookUpClass(name)) != NULL) {
653		/*
654		 * NOTE: we used to allow redefinition of a class if the
655		 * redefinition is in the same module. This code was removed
656		 * because that functionality isn't possible with the ObjC 2.0
657		 * runtime API.
658		 */
659
660		PyErr_Format(PyObjCExc_Error,
661			"%s is overriding existing Objective-C class",
662			name);
663		goto error_cleanup;
664	}
665	if (strspn(name, IDENT_CHARS) != strlen(name)) {
666		PyErr_Format(PyObjCExc_Error, "'%s' not a valid name", name);
667		goto error_cleanup;
668	}
669
670	PyDict_SetItemString(class_dict, "__objc_python_subclass__", Py_True);
671
672	py_superclass = PyObjCClass_New(super_class);
673	if (py_superclass == NULL) {
674		return NULL;
675	}
676
677	instance_variables = PySet_New(NULL);
678	if (instance_variables == NULL) {
679		return NULL;
680	}
681
682	instance_methods = PySet_New(NULL);
683	if (instance_methods == NULL) {
684		Py_DECREF(instance_variables);
685		return NULL;
686	}
687	class_methods = PySet_New(NULL);
688	if (class_methods == NULL) {
689		Py_DECREF(instance_variables);
690		Py_DECREF(instance_methods);
691		return NULL;
692	}
693
694	/* We must override copyWithZone: for python classes because the
695	 * refcounts of python slots might be off otherwise. Yet it should
696	 * be possible to override copyWithZone: in those classes.
697	 *
698	 * The solution: introduce an intermediate class that contains our
699	 * implementation of copyWithZone:. This intermediate class is only
700	 * needed when (1) the superclass implements copyWithZone: and (2)
701	 * the python subclass overrides that method.
702	 *
703	 * The same issue is present with a number of other methods.
704	 */
705
706	need_intermediate = 0;
707
708	if (PyDict_GetItemString(class_dict, "copyWithZone_") == NULL) {
709		PyErr_Clear();
710	} else {
711		if ([super_class instancesRespondToSelector:@selector(copyWithZone:)]) {
712			need_intermediate = 1;
713		}
714	}
715	if (PyDict_GetItemString(class_dict, "mutableCopyWithZone_") == NULL) {
716		PyErr_Clear();
717	} else {
718		if ([super_class instancesRespondToSelector:@selector(mutableCopyWithZone:)]) {
719			need_intermediate = 1;
720		}
721	}
722
723	if (PyDict_GetItemString(class_dict, "dealloc") == NULL) {
724		PyErr_Clear();
725	} else {
726		need_intermediate = 1;
727	}
728	if (PyDict_GetItemString(class_dict, "finalize") == NULL) {
729		PyErr_Clear();
730	} else {
731		need_intermediate = 1;
732	}
733	if (PyDict_GetItemString(class_dict, "valueForKey_") == NULL) {
734		PyErr_Clear();
735	} else {
736		need_intermediate = 1;
737	}
738	if (PyDict_GetItemString(class_dict, "storedValueForKey_") == NULL) {
739		PyErr_Clear();
740	} else {
741		need_intermediate = 1;
742	}
743	if (PyDict_GetItemString(class_dict, "setValue_forKey_") == NULL) {
744		PyErr_Clear();
745	} else {
746		need_intermediate = 1;
747	}
748	if (PyDict_GetItemString(class_dict, "takeValue_forKey_") == NULL) {
749		PyErr_Clear();
750	} else {
751		need_intermediate = 1;
752	}
753	if (PyDict_GetItemString(class_dict, "takeStoredValue_forKey_") == NULL) {
754		PyErr_Clear();
755	} else {
756		need_intermediate = 1;
757	}
758	if (PyDict_GetItemString(class_dict, "respondsToSelector_") == NULL) {
759		PyErr_Clear();
760	} else {
761		need_intermediate = 1;
762	}
763	if (PyDict_GetItemString(class_dict, "instancesRespondToSelector_") == NULL) {
764		PyErr_Clear();
765	} else {
766		need_intermediate = 1;
767	}
768
769	if (PyDict_GetItemString(class_dict, "methodSignatureForSelector_") == NULL) {
770		PyErr_Clear();
771	} else {
772		need_intermediate = 1;
773	}
774	if (PyDict_GetItemString(class_dict, "forwardInvocation_") == NULL) {
775		PyErr_Clear();
776	} else {
777		need_intermediate = 1;
778	}
779
780#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
781	if (_KVOHackLevel() == BROKEN_KVO) {
782		if (PyDict_GetItemString(class_dict, "willChangeValueForKey_") == NULL) {
783			PyErr_Clear();
784		} else {
785			need_intermediate = 1;
786		}
787		if (PyDict_GetItemString(class_dict, "didChangeValueForKey_") == NULL) {
788			PyErr_Clear();
789		} else {
790			need_intermediate = 1;
791		}
792	}
793#endif
794
795	if (!PyObjCClass_HasPythonImplementation(py_superclass) && need_intermediate) {
796		Class intermediate_class;
797		char  buf[1024];
798
799		have_intermediate = 1;
800
801		snprintf(buf, 1024, "_PyObjCCopying_%s", class_getName(super_class));
802		intermediate_class = objc_lookUpClass(buf);
803		if (intermediate_class == NULL) {
804			intermediate_class = build_intermediate_class(
805					super_class, buf);
806			if (intermediate_class == NULL) goto error_cleanup;
807		}
808		Py_DECREF(py_superclass);
809
810		super_class = intermediate_class;
811		py_superclass = PyObjCClass_New(super_class);
812		if (py_superclass == NULL) return NULL;
813	}
814
815
816	if (do_slots(py_superclass, class_dict) < 0) {
817		goto error_cleanup;
818	}
819
820
821
822	if (!PyObjCClass_HasPythonImplementation(py_superclass)) {
823		/*
824		 * This class has a super_class that is pure objective-C
825		 * We'll add some instance variables and methods that are
826		 * needed for the correct functioning of the class.
827		 *
828		 * See the code below the next loop.
829		 */
830		first_python_gen = 1;
831	}
832
833
834	key_list = PyDict_Keys(class_dict);
835	if (key_list == NULL) {
836		goto error_cleanup;
837	}
838
839	key_count = PyList_Size(key_list);
840	if (PyErr_Occurred()) {
841		Py_DECREF(key_list);
842		goto error_cleanup;
843	}
844
845	/* Allocate the class as soon as possible, for new selector objects */
846	new_class = objc_allocateClassPair(super_class, name, 0);
847	if (new_class == 0) {
848		PyErr_Format(PyObjCExc_Error,
849			"Cannot allocateClassPair for %s", name);
850		goto error_cleanup;
851	}
852
853	new_meta_class = object_getClass(new_class);
854
855	/* 0th round: protocols */
856	protocol_count = PyList_Size(protocols);
857	if (protocol_count > 0) {
858		for (i=0; i < protocol_count; i++) {
859			PyObject *wrapped_protocol;
860			wrapped_protocol = PyList_GET_ITEM(protocols, i);
861			if (!PyObjCFormalProtocol_Check(wrapped_protocol)) {
862				continue;
863			}
864
865			if (!preclass_addProtocol(new_class,
866					PyObjCFormalProtocol_GetProtocol(wrapped_protocol))) {
867				goto error_cleanup;
868			}
869		}
870	}
871	if (PyErr_Occurred()) {
872		goto error_cleanup;
873	}
874
875	/* First step: call class setup hooks of entries in the class dict */
876	for (i = 0; i < key_count; i++) {
877		key = PyList_GET_ITEM(key_list, i);
878
879		value = PyDict_GetItem(class_dict, key);
880		if (value == NULL) {
881			PyErr_SetString(PyObjCExc_InternalError,
882				"PyObjCClass_BuildClass: "
883				"Cannot fetch item in keylist");
884			goto error_cleanup;
885		}
886
887		/*
888		 * Check if the value has a class-setup hook, and if it does
889		 * call said hook.
890		 */
891		PyObject* m = PyObject_GetAttrString(value,
892				"__pyobjc_class_setup__");
893		if (m == NULL) {
894			PyErr_Clear();
895
896		} else {
897			PyObject* rv = PyObject_CallFunction(m, "OOOO",
898					key, class_dict,
899					instance_methods,
900					class_methods);
901			Py_DECREF(m);
902			if (rv == NULL) {
903				goto error_cleanup;
904			}
905			Py_DECREF(rv);
906		}
907	}
908
909	Py_DECREF(key_list);
910
911	/* Second step: call global class construction hook */
912	if (PyObjC_class_setup_hook != NULL) {
913		PyObject* rv = PyObject_CallFunction(
914			PyObjC_class_setup_hook,
915			"sOOOOO", name, py_superclass,
916			class_dict, instance_variables,
917			instance_methods, class_methods);
918		if (rv == NULL) {
919			goto error_cleanup;
920		}
921
922		/* Todo: do we need to do something with a result? */
923		Py_XDECREF(rv);
924	}
925
926
927	/* The class hooks can modify the class dict, recalculate the key list */
928	key_list = PyDict_Keys(class_dict);
929	if (key_list == NULL) {
930		goto error_cleanup;
931	}
932
933	key_count = PyList_Size(key_list);
934	if (PyErr_Occurred()) {
935		Py_DECREF(key_list);
936		goto error_cleanup;
937	}
938
939	/* Step 2b: Collect methods and instance variables in the class dict
940	 *          into the 3 sets.
941	 *
942	 * FIXME: This work should be done by the class setup hook instead.
943	 */
944	for (i = 0; i < key_count; i++) {
945		key = PyList_GET_ITEM(key_list, i);
946
947		value = PyDict_GetItem(class_dict, key);
948		if (value == NULL) {
949			PyErr_SetString(PyObjCExc_InternalError,
950				"PyObjCClass_BuildClass: "
951				"Cannot fetch item in keylist");
952			goto error_cleanup;
953		}
954
955		if (PyObjCInstanceVariable_Check(value)) {
956			if (PySet_Add(instance_variables, value) == -1) {
957				goto error_cleanup;
958			}
959
960		} else if (PyObjCSelector_Check(value)) {
961			int r;
962
963			/* Check if the 'key' is the name as the python
964			 * representation of our selector. If not: add the
965			 * python representation of our selector to the
966			 * dict as well to ensure that the ObjC interface works
967			 * from Python as well.
968			 *
969			 * NOTE: This also allows one to add both a class
970			 * and instance method for the same selector in one
971			 * generation.
972			 */
973			char buf[1024];
974			PyObject* pyname = PyText_FromString(
975				PyObjC_SELToPythonName(
976					PyObjCSelector_GetSelector(value),
977					buf, sizeof(buf)));
978			if (pyname == NULL) {
979				goto error_cleanup;
980			}
981			int shouldCopy = PyObject_RichCompareBool(pyname, key, Py_EQ);
982			if (shouldCopy == -1) {
983				goto error_cleanup;
984			} else if (!shouldCopy) {
985				Py_DECREF(pyname); pyname = NULL;
986			}
987
988			if (PyObjCSelector_GetClass(value) != NULL) {
989				PyObject* new_value;
990				new_value = PyObjCSelector_Copy(value);
991				if (new_value == NULL) {
992					goto error_cleanup;
993				}
994				if (PyDict_SetItem(class_dict, key, new_value) == -1) {
995					Py_DECREF(new_value);
996					goto error_cleanup;
997				}
998				value = new_value;
999				Py_DECREF(new_value); /* The value is still in the dict, and hence safe to use */
1000			}
1001
1002			if (PyObjCSelector_IsClassMethod(value)) {
1003				r = PySet_Add(class_methods, value);
1004				if (r == -1) {
1005					goto error_cleanup;
1006				}
1007
1008
1009				if (!PyObjCSelector_IsHidden(value)) {
1010					if (PyDict_SetItem(meta_dict, key, value) == -1) {
1011						goto error_cleanup;
1012					}
1013				} else {
1014					shouldCopy = NO;
1015				}
1016
1017				if (shouldCopy) {
1018					r = PyDict_SetItem(meta_dict, pyname, value);
1019					Py_DECREF(pyname);
1020					if (r == -1)  {
1021						goto error_cleanup;
1022					}
1023				}
1024				if (PyDict_DelItem(class_dict, key) == -1) {
1025					goto error_cleanup;
1026				}
1027			} else {
1028				r = PySet_Add(instance_methods, value);
1029				if (r == -1) {
1030					goto error_cleanup;
1031				}
1032				if (PyObjCSelector_IsHidden(value)) {
1033					r = PyDict_DelItem(class_dict, key);
1034					if (r == -1) {
1035						goto error_cleanup;
1036					}
1037					shouldCopy = NO;
1038				}
1039				if (shouldCopy) {
1040					r = PyDict_SetItem(class_dict, pyname, value);
1041					Py_DECREF(pyname);
1042					if (r == -1) {
1043						goto error_cleanup;
1044					}
1045				}
1046			}
1047
1048
1049		} else if (
1050				PyMethod_Check(value)
1051			     || PyFunction_Check(value)
1052			     || PyObject_TypeCheck(value, &PyClassMethod_Type)){
1053
1054
1055			PyObject* pyname;
1056			char*     ocname;
1057			pyname = key;
1058			PyObject* pyname_bytes = NULL;
1059			if (pyname == NULL) continue;
1060
1061			if (PyUnicode_Check(pyname)) {
1062				pyname_bytes = PyUnicode_AsEncodedString(pyname, NULL, NULL);
1063				if (pyname_bytes == NULL) {
1064					goto error_cleanup;
1065				}
1066				ocname = PyBytes_AsString(pyname_bytes);
1067				if (ocname == NULL) {
1068					PyErr_SetString(PyExc_ValueError, "empty name");
1069					goto error_cleanup;
1070				}
1071#if PY_MAJOR_VERSION == 2
1072			} else if (PyString_Check(pyname)) {
1073				ocname = PyString_AS_STRING(pyname);
1074#endif
1075			} else {
1076				PyErr_Format(PyExc_TypeError,
1077					"method name is of type %s, not a string",
1078					Py_TYPE(pyname)->tp_name);
1079				goto error_cleanup;
1080			}
1081
1082			if (ocname[0] != '_' || ocname[1] != '_') {
1083				/* Skip special methods (like __getattr__) to
1084				 * avoid confusing type().
1085				 */
1086				PyObject* new_value;
1087
1088				new_value = PyObjCSelector_FromFunction(
1089					pyname,
1090					value,
1091					py_superclass,
1092					protocols);
1093				if (new_value == NULL) {
1094					Py_CLEAR(pyname_bytes);
1095					goto error_cleanup;
1096				}
1097				value = new_value;
1098
1099				Py_CLEAR(pyname_bytes);
1100
1101				if (PyObjCSelector_Check(value)) {
1102					int r;
1103
1104
1105					if (PyObjCSelector_IsClassMethod(value)) {
1106						if (!PyObjCSelector_IsHidden(value)) {
1107							if (PyDict_SetItem(meta_dict, key, value) == -1) {
1108								goto error_cleanup;
1109							}
1110						}
1111						if (PyDict_DelItem(class_dict, key) == -1) {
1112							goto error_cleanup;
1113						}
1114
1115						r = PySet_Add(class_methods, value);
1116
1117					} else {
1118						if (PyObjCSelector_IsHidden(value)) {
1119							if (PyDict_DelItem(class_dict, key) == -1) {
1120								goto error_cleanup;
1121							}
1122						} else {
1123
1124							if (PyDict_SetItem(class_dict, key, value) < 0) {
1125								Py_CLEAR(value);
1126								goto error_cleanup;
1127							}
1128						}
1129
1130						r = PySet_Add(instance_methods, value);
1131					}
1132					if (r == -1) {
1133						goto error_cleanup;
1134					}
1135				}
1136			}
1137			Py_CLEAR(pyname_bytes);
1138		}
1139	}
1140
1141	/* Keylist is not needed anymore */
1142	Py_DECREF(key_list); key_list = NULL;
1143
1144	/* Step 3: Check instance variables */
1145
1146	/*    convert to 'fast sequence' to ensure stable order when accessing */
1147	seq = PySequence_Fast(instance_variables, "converting instance variable set to sequence");
1148	if (seq == NULL) {
1149		goto error_cleanup;
1150	}
1151	Py_DECREF(instance_variables);
1152	instance_variables = seq;
1153	for (i = 0; i < PySequence_Fast_GET_SIZE(instance_variables); i++) {
1154		value = PySequence_Fast_GET_ITEM(instance_variables, i);
1155
1156		if (!PyObjCInstanceVariable_Check(value)) {
1157			continue;
1158		}
1159
1160		/* Our only check for now is that instance variable names must be unique */
1161		/* XXX: Is this really necessary? */
1162		if (class_getInstanceVariable(super_class, PyObjCInstanceVariable_GetName(value)) != NULL) {
1163			PyErr_Format(PyObjCExc_Error,
1164				"a superclass already has an instance "
1165				"variable with this name: %s",
1166				PyObjCInstanceVariable_GetName(value));
1167			goto error_cleanup;
1168		}
1169	}
1170
1171	/* Step 4: Verify instance and class methods sets */
1172
1173	/*   first convert then to 'Fast' sequences for easier access */
1174	seq = PySequence_Fast(instance_methods, "converting instance method set to sequence");
1175	if (seq == NULL) {
1176		goto error_cleanup;
1177	}
1178	Py_DECREF(instance_methods);
1179	instance_methods = seq;
1180
1181	seq = PySequence_Fast(class_methods, "converting class method set to sequence");
1182	if (seq == NULL) {
1183		goto error_cleanup;
1184	}
1185	Py_DECREF(class_methods);
1186	class_methods = seq;
1187
1188	for (i = 0; i < PySequence_Fast_GET_SIZE(instance_methods); i++) {
1189		value = PySequence_Fast_GET_ITEM(instance_methods, i);
1190
1191		if (PyBytes_Check(value)) {
1192			int r = PyDict_SetItem(hiddenSelectors, value, Py_None);
1193			if (r == -1) {
1194				goto error_cleanup;
1195			}
1196		}
1197
1198		if (!PyObjCSelector_Check(value)) {
1199			continue;
1200		}
1201
1202		if (PyObjCSelector_IsClassMethod(value)) {
1203			PyErr_Format(PyExc_TypeError,
1204				"class method in instance method set: -%s",
1205				sel_getName(PyObjCSelector_GetSelector(value)));
1206			goto error_cleanup;
1207		}
1208
1209		if (PyObjCNativeSelector_Check(value)) {
1210			PyErr_Format(PyExc_TypeError,
1211				"native selector -%s of %s",
1212				sel_getName(PyObjCSelector_GetSelector(value)),
1213				class_getName(PyObjCSelector_GetClass(value)));
1214			goto error_cleanup;
1215		} else if (PyObjCSelector_Check(value)) {
1216			PyObjCSelector* sel = (PyObjCSelector*)value;
1217
1218			/* Set sel_class */
1219			sel->sel_class = new_class;
1220
1221			if (sel->sel_flags & PyObjCSelector_kHIDDEN) {
1222				PyObject* v = PyBytes_InternFromString(
1223					sel_getName(PyObjCSelector_GetSelector(value)));
1224				if (v == NULL) {
1225					goto error_cleanup;
1226				}
1227				int r = PyDict_SetItem(hiddenSelectors, v,
1228						(PyObject*)PyObjCSelector_GetMetadata(value));
1229				Py_DECREF(v);
1230				if (r == -1) {
1231					goto error_cleanup;
1232				}
1233			}
1234		}
1235	}
1236	for (i = 0; i < PySequence_Fast_GET_SIZE(class_methods); i++) {
1237		value = PySequence_Fast_GET_ITEM(class_methods, i);
1238
1239		if (PyBytes_Check(value)) {
1240			int r = PyDict_SetItem(hiddenClassSelectors, value, Py_None);
1241			if (r == -1) {
1242				goto error_cleanup;
1243			}
1244		}
1245
1246		if (!PyObjCSelector_Check(value)) {
1247			continue;
1248		}
1249
1250		if (!PyObjCSelector_IsClassMethod(value)) {
1251			PyErr_Format(PyExc_TypeError,
1252				"instance method in class method set: -%s",
1253				sel_getName(PyObjCSelector_GetSelector(value)));
1254			goto error_cleanup;
1255		}
1256
1257
1258		if (PyObjCNativeSelector_Check(value)) {
1259			PyErr_Format(PyExc_TypeError,
1260				"native selector +%s of %s",
1261				sel_getName(PyObjCSelector_GetSelector(value)),
1262				class_getName(PyObjCSelector_GetClass(value)));
1263			goto error_cleanup;
1264		} else if (PyObjCSelector_Check(value)) {
1265			PyObjCSelector* sel = (PyObjCSelector*)value;
1266
1267			/* Set sel_class */
1268			sel->sel_class = new_class;
1269
1270			if (sel->sel_flags & PyObjCSelector_kHIDDEN) {
1271				PyObject* v = PyBytes_InternFromString(
1272					sel_getName(PyObjCSelector_GetSelector(value)));
1273				if (v == NULL) {
1274					goto error_cleanup;
1275				}
1276				int r = PyDict_SetItem(hiddenClassSelectors, v,
1277						(PyObject*)PyObjCSelector_GetMetadata(value));
1278				Py_DECREF(v);
1279				if (r == -1) {
1280					goto error_cleanup;
1281				}
1282			}
1283		}
1284	}
1285
1286	/* Allocate space for the new instance variables and methods */
1287	if (first_python_gen) {
1288		/* Our parent is a pure Objective-C class, add our magic
1289		 * methods and variables
1290		 */
1291
1292		PyObject* sel;
1293		IMP closure;
1294		PyObjCMethodSignature* methinfo;
1295
1296#		define METH(pyname, selector, types, imp) 		\
1297		        methinfo = PyObjCMethodSignature_FromSignature(types, NO); \
1298			if (methinfo == NULL) goto error_cleanup; \
1299			closure = PyObjCFFI_MakeClosure(methinfo, imp, \
1300					super_class); \
1301			Py_DECREF(methinfo); methinfo = NULL; \
1302			if (closure == NULL) goto error_cleanup; \
1303			preclass_addMethod(new_class, selector, \
1304					closure, types); \
1305			sel = PyObjCSelector_NewNative(new_class, \
1306				selector,  types, 0);			\
1307			if (sel == NULL) goto error_cleanup;		\
1308			PyDict_SetItemString(class_dict, pyname, sel);	\
1309			Py_DECREF(sel)
1310
1311		if (!have_intermediate) {
1312			METH(
1313				"dealloc",
1314				@selector(dealloc),
1315				"v@:",
1316				object_method_dealloc);
1317			METH(
1318				"finalize",
1319				@selector(finalize),
1320				"v@:",
1321				object_method_finalize);
1322			METH(
1323				"storedValueForKey_",
1324				@selector(storedValueForKey:),
1325				"@@:@",
1326				object_method_valueForKey_);
1327			METH(
1328				"valueForKey_",
1329				@selector(valueForKey:),
1330				"@@:@",
1331				object_method_valueForKey_);
1332			METH(
1333				"takeStoredValue_forKey_",
1334				@selector(takeStoredValue:forKey:),
1335				"v@:@@",
1336				object_method_setValue_forKey_);
1337			METH(
1338				"takeValue_forKey_",
1339				@selector(takeValue:forKey:),
1340				"v@:@@",
1341				object_method_setValue_forKey_);
1342			METH(
1343				"setValue_forKey_",
1344				@selector(setValue:forKey:),
1345				"v@:@@",
1346				object_method_setValue_forKey_);
1347
1348			METH(
1349				"forwardInvocation_",
1350				@selector(forwardInvocation:),
1351				"v@:@",
1352				object_method_forwardInvocation);
1353			METH(
1354				"methodSignatureForSelector_",
1355				@selector(methodSignatureForSelector:),
1356				"@@::",
1357				object_method_methodSignatureForSelector);
1358			METH(
1359				"respondsToSelector",
1360				@selector(respondsToSelector:),
1361				"c@::",
1362				object_method_respondsToSelector);
1363
1364#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
1365			if (_KVOHackLevel() == BROKEN_KVO) {
1366				METH(
1367					"willChangeValueForKey_",
1368					@selector(willChangeValueForKey:),
1369					"v@:@",
1370					object_method_willOrDidChangeValueForKey_);
1371				METH(
1372					"didChangeValueForKey_",
1373					@selector(didChangeValueForKey:),
1374					"v@:@",
1375					object_method_willOrDidChangeValueForKey_);
1376			}
1377#endif
1378		}
1379
1380
1381		if (!have_intermediate && [super_class instancesRespondToSelector:@selector(copyWithZone:)]) {
1382			if (copyWithZone_signature[0] == '\0') {
1383				snprintf(copyWithZone_signature,
1384					sizeof(copyWithZone_signature),
1385					"@@:%s", @encode(NSZone*));
1386			}
1387
1388			METH(
1389				"copyWithZone_",
1390				@selector(copyWithZone:),
1391				copyWithZone_signature,
1392				object_method_copyWithZone_);
1393		}
1394		if (!have_intermediate && [super_class instancesRespondToSelector:@selector(mutableCopyWithZone:)]) {
1395			if (copyWithZone_signature[0] == '\0') {
1396				snprintf(copyWithZone_signature,
1397					sizeof(copyWithZone_signature),
1398					"@@:%s", @encode(NSZone*));
1399			}
1400
1401			METH(
1402				"mutableCopyWithZone_",
1403				@selector(copyWithZone:),
1404				copyWithZone_signature,
1405				object_method_copyWithZone_);
1406		}
1407#undef		METH
1408	}
1409
1410	/* add instance variables */
1411	for (i = 0; i < PySequence_Fast_GET_SIZE(instance_variables); i++) {
1412		value = PySequence_Fast_GET_ITEM(instance_variables, i);
1413
1414		if (!PyObjCInstanceVariable_Check(value)) {
1415			continue;
1416		}
1417
1418		char* type;
1419		size_t size;
1420		size_t align;
1421
1422
1423		if (PyObjCInstanceVariable_IsSlot(value)) {
1424			type = @encode(PyObject*);
1425			size = sizeof(PyObject*);
1426		} else {
1427			type = PyObjCInstanceVariable_GetType(value);
1428			size = PyObjCRT_SizeOfType(type);
1429		}
1430		align = PyObjCRT_AlignOfType(type);
1431
1432
1433		if (PyObjCInstanceVariable_GetName(value) == NULL) {
1434			PyErr_SetString(PyObjCExc_Error,
1435				"instance variable without a name");
1436			goto error_cleanup;
1437		}
1438
1439		if (!preclass_addIvar(new_class,
1440			PyObjCInstanceVariable_GetName(value),
1441			size,
1442			align,
1443			type
1444			)) {
1445
1446			goto error_cleanup;
1447		}
1448	}
1449
1450	/* instance methods */
1451	for (i = 0; i < PySequence_Fast_GET_SIZE(instance_methods); i++) {
1452		value = PySequence_Fast_GET_ITEM(instance_methods, i);
1453
1454		if (!PyObjCSelector_Check(value)) {
1455			continue;
1456		}
1457
1458		Method	      meth;
1459		int           is_override = 0;
1460		IMP	      imp;
1461
1462		meth = class_getInstanceMethod(super_class,
1463			PyObjCSelector_GetSelector(value));
1464		if (meth) {
1465			is_override = 1;
1466			if (!same_signature(method_getTypeEncoding(meth),
1467				PyObjCSelector_GetNativeSignature(value))) {
1468
1469				PyErr_Format(PyObjCExc_BadPrototypeError,
1470					"%R has signature that is not compatible with super-class",
1471					value);
1472				goto error_cleanup;
1473			}
1474		}
1475		if (is_override) {
1476			imp = PyObjC_MakeIMP(new_class, super_class, value, value);
1477		} else  {
1478			imp = PyObjC_MakeIMP(new_class, nil, value, value);
1479		}
1480		if (imp == NULL) {
1481			goto error_cleanup;
1482		}
1483
1484		if (!preclass_addMethod(new_class, PyObjCSelector_GetSelector(value), imp,
1485					PyObjCSelector_GetNativeSignature(value))) {
1486			goto error_cleanup;
1487		}
1488	}
1489
1490	/* class methods */
1491	for (i = 0; i < PySequence_Fast_GET_SIZE(class_methods); i++) {
1492		value = PySequence_Fast_GET_ITEM(class_methods, i);
1493
1494		if (!PyObjCSelector_Check(value)) {
1495			continue;
1496		}
1497
1498		Method	      meth;
1499		int           is_override = 0;
1500		IMP	      imp;
1501
1502
1503		meth = class_getClassMethod(super_class, PyObjCSelector_GetSelector(value));
1504		if (meth) {
1505			is_override = 1;
1506
1507			if (!same_signature(method_getTypeEncoding(meth),
1508					PyObjCSelector_GetNativeSignature(value))) {
1509
1510				PyErr_Format(PyObjCExc_BadPrototypeError,
1511					"%R has signature that is not compatible with super-class",
1512					value);
1513					goto error_cleanup;
1514			}
1515		}
1516
1517		if (is_override) {
1518			imp = PyObjC_MakeIMP(new_meta_class, super_class, value, value);
1519		} else  {
1520			imp = PyObjC_MakeIMP(new_meta_class, nil, value, value);
1521		}
1522		if (imp == NULL) {
1523			goto error_cleanup;
1524		}
1525
1526		if (!preclass_addMethod(new_meta_class, PyObjCSelector_GetSelector(value), imp,
1527					PyObjCSelector_GetNativeSignature(value))) {
1528			goto error_cleanup;
1529		}
1530	}
1531
1532	Py_XDECREF(py_superclass); py_superclass = NULL;
1533
1534	if (PyDict_DelItemString(class_dict, "__dict__") < 0) {
1535		PyErr_Clear();
1536	}
1537	Py_XDECREF(instance_variables); instance_variables = NULL;
1538	Py_XDECREF(instance_methods); instance_methods = NULL;
1539	Py_XDECREF(class_methods); class_methods = NULL;
1540
1541	/*
1542	 * NOTE: Class is not registered yet, we do that as lately as possible
1543	 * because it is impossible to remove the registration from the
1544	 * objective-C runtime (at least on MacOS X).
1545	 */
1546	return new_class;
1547
1548error_cleanup:
1549	Py_XDECREF(instance_variables);
1550	Py_XDECREF(instance_methods);
1551	Py_XDECREF(class_methods);
1552	Py_XDECREF(py_superclass);
1553
1554	if (key_list) {
1555		Py_DECREF(key_list);
1556		key_list = NULL;
1557	}
1558
1559	if (new_class) {
1560		objc_disposeClassPair(new_class);
1561	}
1562
1563	return NULL;
1564}
1565
1566/*
1567 * Below here are implementations of various methods needed to correctly
1568 * subclass Objective-C classes from Python.
1569 *
1570 * These are added to the new Objective-C class by  PyObjCClass_BuildClass (but
1571 * only if the super_class is a 'pure' objective-C class)
1572 *
1573 * NOTE:
1574 * - These functions will be used as methods, but as far as the compiler
1575 *   knows these are normal functions. You cannot use [super call]s here.
1576 */
1577
1578
1579static void
1580free_ivars(id self, PyObject* volatile cls )
1581{
1582	/* Free all instance variables introduced through python */
1583	volatile Ivar var;
1584
1585	var = class_getInstanceVariable(PyObjCClass_GetClass(cls), "__dict__");
1586	if (var != NULL) {
1587		ptrdiff_t offset = ivar_getOffset(var);
1588		Py_XDECREF(*(PyObject**)(((char*)self) + offset));
1589		*(PyObject**)(((char*)self) + offset) = NULL;
1590	}
1591
1592	while (cls != NULL) {
1593		Class objcClass = PyObjCClass_GetClass(cls);
1594		PyObject* clsDict;
1595		PyObject* clsValues;
1596		PyObject* o;
1597		volatile Py_ssize_t i;
1598		Py_ssize_t len;
1599
1600		if (objcClass == nil) break;
1601
1602
1603		clsDict = PyObject_GetAttrString(cls, "__dict__");
1604		if (clsDict == NULL) {
1605			PyErr_Clear();
1606			break;
1607		}
1608
1609		/* Class.__dict__ is a dictproxy, which is not a dict and
1610		 * therefore PyDict_Values doesn't work.
1611		 */
1612		clsValues = PyObject_CallMethod(clsDict, "values", NULL);
1613		Py_DECREF(clsDict);
1614		if (clsValues == NULL) {
1615			PyErr_Clear();
1616			break;
1617		}
1618
1619		len = PyList_Size(clsValues);
1620		/* Check type */
1621		for (i = 0; i < len; i++) {
1622			PyObjCInstanceVariable* iv;
1623
1624			o = PyList_GET_ITEM(clsValues, i);
1625
1626			if (o == NULL) continue;
1627			if (!PyObjCInstanceVariable_Check(o)) continue;
1628
1629			iv = ((PyObjCInstanceVariable*)o);
1630
1631			if (iv->isOutlet) continue;
1632			if (strcmp(iv->type, "@") != 0 && strcmp(iv->type, @encode(PyObject*)) != 0) continue;
1633
1634			var = class_getInstanceVariable(objcClass, iv->name);
1635			if (var == NULL) continue;
1636
1637			if (iv->isSlot) {
1638				Py_XDECREF(*(PyObject**)(((char*)self) +
1639					ivar_getOffset(var)));
1640				(*(PyObject**)(((char*)self) +
1641					ivar_getOffset(var))) = NULL;
1642			} else {
1643				PyObjC_DURING
1644					[*(id*)(((char*)self) + ivar_getOffset(var)) autorelease];
1645
1646				PyObjC_HANDLER
1647					NSLog(@"ignoring exception %@ in destructor",
1648						localException);
1649
1650				PyObjC_ENDHANDLER
1651				*(id*)(((char*)self) + ivar_getOffset(var)) = NULL;
1652			}
1653		}
1654
1655		Py_DECREF(clsValues);
1656
1657		o = PyObject_GetAttrString(cls, "__bases__");
1658		if (o == NULL) {
1659			PyErr_Clear();
1660			cls = NULL;
1661		}  else if (PyTuple_Size(o) == 0) {
1662			PyErr_Clear();
1663			cls = NULL;
1664			Py_DECREF(o);
1665		} else {
1666			cls = PyTuple_GET_ITEM(o, 0);
1667			if (cls == (PyObject*)&PyObjCClass_Type) {
1668				cls = NULL;
1669			}
1670			Py_DECREF(o);
1671		}
1672	}
1673}
1674
1675/* -finalize */
1676static void
1677object_method_finalize(
1678		ffi_cif* cif __attribute__((__unused__)),
1679		void* retval __attribute__((__unused__)),
1680		void** args,
1681		void* userdata)
1682{
1683	id self = *(id*)(args[0]);
1684	SEL _meth = *(SEL*)(args[1]);
1685
1686	struct objc_super spr;
1687	PyObject* obj;
1688	PyObject* delmethod;
1689	PyObject* cls;
1690	PyObject* ptype, *pvalue, *ptraceback;
1691
1692	PyObjC_BEGIN_WITH_GIL
1693
1694		PyErr_Fetch(&ptype, &pvalue, &ptraceback);
1695
1696		cls = PyObjCClass_New(object_getClass(self));
1697
1698		delmethod = PyObjCClass_GetDelMethod(cls);
1699		if (delmethod != NULL) {
1700			PyObject* s = _PyObjCObject_NewDeallocHelper(self);
1701			obj = PyObject_CallFunction(delmethod, "O", s);
1702			_PyObjCObject_FreeDeallocHelper(s);
1703			if (obj == NULL) {
1704				PyErr_WriteUnraisable(delmethod);
1705			} else {
1706				Py_DECREF(obj);
1707			}
1708			Py_DECREF(delmethod);
1709		}
1710
1711		free_ivars(self, cls);
1712
1713		PyErr_Restore(ptype, pvalue, ptraceback);
1714
1715	PyObjC_END_WITH_GIL
1716
1717	objc_superSetClass(spr, (Class)userdata);
1718	objc_superSetReceiver(spr, self);
1719
1720	objc_msgSendSuper(&spr, _meth);
1721}
1722
1723/* -dealloc */
1724static void
1725object_method_dealloc(
1726		ffi_cif* cif __attribute__((__unused__)),
1727		void* retval __attribute__((__unused__)),
1728		void** args,
1729		void* userdata)
1730{
1731	id self = *(id*)(args[0]);
1732	SEL _meth = *(SEL*)(args[1]);
1733
1734	struct objc_super spr;
1735	PyObject* obj;
1736	PyObject* delmethod;
1737	PyObject* cls;
1738	PyObject* ptype, *pvalue, *ptraceback;
1739
1740	PyObjC_BEGIN_WITH_GIL
1741
1742		PyErr_Fetch(&ptype, &pvalue, &ptraceback);
1743
1744		cls = PyObjCClass_New(object_getClass(self));
1745
1746		delmethod = PyObjCClass_GetDelMethod(cls);
1747		if (delmethod != NULL) {
1748			PyObject* s = _PyObjCObject_NewDeallocHelper(self);
1749			obj = PyObject_CallFunction(delmethod, "O", s);
1750			_PyObjCObject_FreeDeallocHelper(s);
1751			if (obj == NULL) {
1752				PyErr_WriteUnraisable(delmethod);
1753			} else {
1754				Py_DECREF(obj);
1755			}
1756			Py_DECREF(delmethod);
1757		}
1758
1759		free_ivars(self, cls);
1760
1761		PyErr_Restore(ptype, pvalue, ptraceback);
1762
1763	PyObjC_END_WITH_GIL
1764
1765	objc_superSetClass(spr, (Class)userdata);
1766	objc_superSetReceiver(spr, self);
1767
1768	objc_msgSendSuper(&spr, _meth);
1769}
1770
1771/* -copyWithZone:(NSZone*)zone */
1772static void
1773object_method_copyWithZone_(
1774		ffi_cif* cif __attribute__((__unused__)),
1775		void* resp,
1776		void** args,
1777		void* userdata)
1778{
1779	id self = *(id*)args[0];
1780	id copy;
1781	SEL _meth = *(SEL*)args[1];
1782	NSZone* zone = *(NSZone**)args[2];
1783	Class cls;
1784
1785	struct objc_super spr;
1786	PyGILState_STATE state;
1787
1788	/* Ask super to create a copy */
1789
1790	objc_superSetClass(spr, (Class)userdata);
1791	objc_superSetReceiver(spr, self);
1792	copy = objc_msgSendSuper(&spr, _meth, zone);
1793
1794	if (copy == nil) {
1795		*(id*)resp = nil;
1796		return;
1797	}
1798
1799	state = PyGILState_Ensure();
1800
1801	cls = object_getClass(self);
1802	while (cls != (Class)userdata) {
1803		unsigned ivarCount, i;
1804		Ivar* ivarList = class_copyIvarList(cls, &ivarCount);
1805
1806		for (i = 0; i < ivarCount; i++) {
1807			Ivar v = ivarList[i];
1808			const char*  typestr;
1809			ptrdiff_t offset;
1810			PyObject** p;
1811
1812			typestr = ivar_getTypeEncoding(v);
1813			offset  = ivar_getOffset(v);
1814
1815			if (strcmp(typestr, @encode(PyObject*))!=0)
1816				continue;
1817
1818			/* A PyObject, increase it's refcount */
1819			p = (PyObject**)(((char*)copy)+offset);
1820			if (*p == NULL) continue;
1821			if (strcmp(ivar_getName(v), "__dict__") == 0) {
1822				/* copy __dict__ */
1823				*p = PyDict_Copy(*p);
1824				if (*p == NULL) {
1825					[copy release];
1826					PyObjCErr_ToObjCWithGILState(
1827							&state);
1828					return;
1829				}
1830			} else {
1831				Py_INCREF(*p);
1832			}
1833		}
1834
1835		free(ivarList);
1836		cls = class_getSuperclass(cls);
1837	}
1838
1839	PyGILState_Release(state);
1840	*(id*)resp = copy;
1841}
1842
1843/* -respondsToSelector: */
1844static void
1845object_method_respondsToSelector(
1846		ffi_cif* cif __attribute__((__unused__)),
1847		void* retval,
1848		void** args,
1849		void* userdata)
1850{
1851	id self = *(id*)args[0];
1852	SEL _meth = *(SEL*)args[1];
1853	SEL aSelector = *(SEL*)args[2];
1854	int* pres = (int*)retval; // Actually BOOL.
1855
1856	struct objc_super spr;
1857	PyObject* pyself;
1858	PyObject* pymeth;
1859
1860	PyObjC_BEGIN_WITH_GIL
1861		/* First check if we respond */
1862		pyself = PyObjCObject_New(self, PyObjCObject_kDEFAULT, YES);
1863		if (pyself == NULL) {
1864			*pres = NO;
1865			PyObjC_GIL_RETURNVOID;
1866		}
1867		pymeth = PyObjCObject_FindSelector(pyself, aSelector);
1868		Py_DECREF(pyself);
1869		if (pymeth) {
1870			*pres = YES;
1871
1872			if (PyObjCSelector_Check(pymeth) && (((PyObjCSelector*)pymeth)->sel_flags & PyObjCSelector_kCLASS_METHOD)) {
1873				*pres = NO;
1874			}
1875
1876			Py_DECREF(pymeth);
1877			PyObjC_GIL_RETURNVOID;
1878		}
1879		PyErr_Clear();
1880
1881	PyObjC_END_WITH_GIL
1882
1883	/* Check superclass */
1884	objc_superSetClass(spr, (Class)userdata);
1885	objc_superSetReceiver(spr, self);
1886
1887	*pres = ((int(*)(struct objc_super*, SEL, SEL))objc_msgSendSuper)(&spr, _meth, aSelector);
1888	return;
1889}
1890
1891/* -methodSignatureForSelector */
1892static void
1893object_method_methodSignatureForSelector(
1894		ffi_cif* cif __attribute__((__unused__)),
1895		void* retval,
1896		void** args,
1897		void* userdata)
1898{
1899	id self = *(id*)args[0];
1900	SEL _meth = *(SEL*)args[1];
1901	SEL aSelector = *(SEL*)args[2];
1902
1903	struct objc_super  spr;
1904	PyObject*          pyself;
1905	PyObject*          pymeth;
1906	NSMethodSignature** presult = (NSMethodSignature**)retval;
1907
1908	*presult = nil;
1909
1910	objc_superSetClass(spr, (Class)userdata);
1911	objc_superSetReceiver(spr, self);
1912
1913	NS_DURING
1914		*presult = objc_msgSendSuper(&spr, _meth, aSelector);
1915	NS_HANDLER
1916		*presult = nil;
1917	NS_ENDHANDLER
1918
1919	if (*presult != nil) {
1920		return;
1921	}
1922
1923	PyObjC_BEGIN_WITH_GIL
1924		pyself = PyObjCObject_New(self, PyObjCObject_kDEFAULT, YES);
1925		if (pyself == NULL) {
1926			PyErr_Clear();
1927			PyObjC_GIL_RETURNVOID;
1928		}
1929
1930		pymeth = PyObjCObject_FindSelector(pyself, aSelector);
1931		if (!pymeth) {
1932			Py_DECREF(pyself);
1933			PyErr_Clear();
1934			PyObjC_GIL_RETURNVOID;
1935		}
1936
1937	PyObjC_END_WITH_GIL
1938
1939	NS_DURING
1940		*presult =  [NSMethodSignature signatureWithObjCTypes:(
1941				(PyObjCSelector*)pymeth)->sel_python_signature];
1942	NS_HANDLER
1943		PyObjC_BEGIN_WITH_GIL
1944			Py_DECREF(pymeth);
1945			Py_DECREF(pyself);
1946
1947		PyObjC_END_WITH_GIL
1948		[localException raise];
1949	NS_ENDHANDLER
1950
1951	PyObjC_BEGIN_WITH_GIL
1952		Py_DECREF(pymeth);
1953		Py_DECREF(pyself);
1954
1955	PyObjC_END_WITH_GIL
1956
1957}
1958
1959/* -forwardInvocation: */
1960static void
1961object_method_forwardInvocation(
1962		ffi_cif* cif __attribute__((__unused__)),
1963		void* retval __attribute__((__unused__)),
1964		void** args,
1965		void* userdata)
1966{
1967	id self = *(id*)args[0];
1968	SEL _meth = *(SEL*)args[1];
1969	NSInvocation* invocation = *(NSInvocation**)args[2];
1970	SEL theSelector;
1971
1972	PyObject*	arglist;
1973	PyObject* 	result;
1974	PyObject*       v;
1975	BOOL		isAlloc;
1976	BOOL		isCFAlloc;
1977	Py_ssize_t      i;
1978	Py_ssize_t	len;
1979	PyObjCMethodSignature* signature;
1980	/*char		   argbuf[1024]; */
1981	const char* 		type;
1982	void* argbuf = NULL;
1983	int  err;
1984	Py_ssize_t   arglen;
1985	PyObject* pymeth;
1986	PyObject* pyself;
1987	volatile int have_output = 0;
1988	PyGILState_STATE state = PyGILState_Ensure();
1989
1990	pyself = PyObjCObject_New(self, PyObjCObject_kDEFAULT, YES);
1991	if (pyself == NULL) {
1992		PyObjCErr_ToObjCWithGILState(&state);
1993		return;
1994	}
1995
1996
1997	PyObjC_DURING
1998		theSelector = [invocation selector];
1999	PyObjC_HANDLER
2000		PyGILState_Release(state);
2001		[localException raise];
2002
2003		/* Avoid compiler warnings */
2004		theSelector = @selector(init);
2005
2006	PyObjC_ENDHANDLER
2007
2008	pymeth = PyObjCObject_FindSelector(pyself, theSelector);
2009
2010	if ((pymeth == NULL) || PyObjCNativeSelector_Check(pymeth)) {
2011		struct objc_super spr;
2012
2013		if (pymeth == NULL) {
2014			PyErr_Clear();
2015		}
2016
2017		Py_XDECREF(pymeth);
2018		Py_XDECREF(pyself);
2019
2020		objc_superSetClass(spr, (Class)userdata);
2021		objc_superSetReceiver(spr, self);
2022		PyGILState_Release(state);
2023		objc_msgSendSuper(&spr, _meth, invocation);
2024		return;
2025	}
2026
2027
2028	signature = PyObjCMethodSignature_FromSignature(
2029		PyObjCSelector_Signature(pymeth), NO);
2030	len = Py_SIZE(signature);
2031
2032	Py_XDECREF(pymeth); pymeth = NULL;
2033
2034	arglist = PyList_New(1);
2035	if (arglist == NULL) {
2036		Py_DECREF(signature);
2037		PyObjCErr_ToObjCWithGILState(&state);
2038		return;
2039	}
2040
2041	PyList_SET_ITEM(arglist, 0, pyself);
2042	pyself = NULL;
2043
2044	for (i = 2; i < len; i++) {
2045		type = signature->argtype[i].type;
2046		if (type == NULL) {
2047			PyErr_SetString(PyObjCExc_InternalError, "corrupt metadata");
2048			Py_DECREF(arglist);
2049			Py_DECREF(signature);
2050			PyObjCErr_ToObjCWithGILState(&state);
2051			return;
2052		}
2053
2054		arglen = PyObjCRT_SizeOfType(type);
2055
2056		if (arglen == -1) {
2057			Py_DECREF(arglist);
2058			Py_DECREF(signature);
2059			PyObjCErr_ToObjCWithGILState(&state);
2060			return;
2061		}
2062
2063		argbuf = PyMem_Malloc(arglen+64);
2064
2065		[invocation getArgument:argbuf atIndex:i];
2066
2067		/* XXX: this needs a lot of work to adapt to the new metadata!!! */
2068
2069		switch (*type) {
2070		case _C_INOUT:
2071			if (type[1] == _C_PTR) {
2072				have_output ++;
2073			}
2074			/* FALL THROUGH */
2075		case _C_IN: case _C_CONST:
2076			if (type[1] == _C_PTR) {
2077				v = pythonify_c_value(type+2, *(void**)argbuf);
2078			} else {
2079				v = pythonify_c_value(type+1, argbuf);
2080			}
2081			break;
2082		case _C_OUT:
2083			if (type[1] == _C_PTR) {
2084				have_output ++;
2085			}
2086			PyMem_Free(argbuf); argbuf = NULL;
2087			continue;
2088		default:
2089			v = pythonify_c_value(type, argbuf);
2090		}
2091		PyMem_Free(argbuf); argbuf = NULL;
2092
2093		if (v == NULL) {
2094			Py_DECREF(arglist);
2095			Py_DECREF(signature);
2096			PyObjCErr_ToObjCWithGILState(&state);
2097			return;
2098		}
2099
2100		if (PyList_Append(arglist, v) < 0) {
2101			Py_DECREF(arglist);
2102			Py_DECREF(signature);
2103			PyObjCErr_ToObjCWithGILState(&state);
2104			return;
2105		}
2106	}
2107
2108	v = PyList_AsTuple(arglist);
2109	if (v == NULL) {
2110		Py_DECREF(arglist);
2111		Py_DECREF(signature);
2112		PyObjCErr_ToObjCWithGILState(&state);
2113		return;
2114	}
2115	Py_DECREF(arglist);
2116	arglist = v; v = NULL;
2117
2118	result = PyObjC_CallPython(self, theSelector, arglist, &isAlloc, &isCFAlloc);
2119	Py_DECREF(arglist);
2120	if (result == NULL) {
2121		Py_DECREF(signature);
2122		PyObjCErr_ToObjCWithGILState(&state);
2123		return;
2124	}
2125
2126	type = signature->rettype.type;
2127	arglen = PyObjCRT_SizeOfType(type);
2128
2129	if (arglen == -1) {
2130		Py_DECREF(signature);
2131		PyObjCErr_ToObjCWithGILState(&state);
2132		return;
2133	}
2134
2135	if (!have_output) {
2136		if (*type  != _C_VOID && *type != _C_ONEWAY) {
2137			argbuf = PyMem_Malloc(arglen+64);
2138
2139			err = depythonify_c_value(type, result, argbuf);
2140			if (err == -1) {
2141				PyMem_Free(argbuf);
2142				Py_DECREF(signature);
2143				PyObjCErr_ToObjCWithGILState(&state);
2144				return;
2145			}
2146			if (isAlloc) {
2147				[(*(id*)argbuf) retain];
2148			} else if (isCFAlloc) {
2149				if (*(id*)argbuf != nil) {
2150					CFRetain((*(id*)argbuf));
2151				}
2152			}
2153			[invocation setReturnValue:argbuf];
2154			PyMem_Free(argbuf);
2155		}
2156		Py_DECREF(result);
2157
2158	} else {
2159		Py_ssize_t idx;
2160		PyObject* real_res;
2161
2162		if (*type == _C_VOID && have_output == 1) {
2163			/* One output argument, and a 'void' return value,
2164			 * the python method returned just the output
2165			 * argument
2166			 */
2167			/* This should be cleaned up, unnecessary code
2168			 * duplication
2169			 */
2170
2171			for (i = 2; i < len;i++) {
2172				void* ptr;
2173				type = signature->argtype[i].type;
2174
2175				if (arglen == -1) {
2176					Py_DECREF(signature);
2177					PyObjCErr_ToObjCWithGILState(&state);
2178					return;
2179				}
2180
2181				switch (*type) {
2182				case _C_INOUT: case _C_OUT:
2183					if (type[1] != _C_PTR) {
2184						continue;
2185					}
2186					type += 2;
2187					break;
2188				default:
2189					continue;
2190				}
2191
2192				[invocation getArgument:&ptr atIndex:i];
2193				err = depythonify_c_value(type, result, ptr);
2194				if (err == -1) {
2195					Py_DECREF(signature);
2196					PyObjCErr_ToObjCWithGILState(&state);
2197					return;
2198				}
2199				if (Py_REFCNT(result) == 1 && type[0] == _C_ID) {
2200					/* make sure return value doesn't die before
2201					 * the caller can get its hands on it.
2202					 */
2203					[[*(id*)ptr retain] autorelease];
2204				}
2205
2206				/* We have exactly 1 output argument */
2207				break;
2208
2209			}
2210
2211			Py_DECREF(signature);
2212			Py_DECREF(result);
2213			PyGILState_Release(state);
2214			return;
2215		}
2216
2217		if (*type != _C_VOID) {
2218			if (!PyTuple_Check(result)
2219			     || PyTuple_Size(result) != have_output+1) {
2220				PyErr_Format(PyExc_TypeError,
2221					"%s: Need tuple of %d arguments as result",
2222					sel_getName(theSelector),
2223					have_output+1);
2224				Py_DECREF(result);
2225				Py_DECREF(signature);
2226				PyObjCErr_ToObjCWithGILState(&state);
2227				return;
2228			}
2229			idx = 1;
2230			real_res = PyTuple_GET_ITEM(result, 0);
2231
2232			argbuf = PyMem_Malloc(arglen+64);
2233
2234			err = depythonify_c_value(type, real_res, argbuf);
2235			if (err == -1) {
2236				Py_DECREF(signature);
2237				PyObjCErr_ToObjCWithGILState(&state);
2238				PyMem_Free(argbuf);
2239				return;
2240			}
2241			if (isAlloc) {
2242				[(*(id*)argbuf) retain];
2243			} else if (isCFAlloc) {
2244				CFRetain(*(id*)argbuf);
2245			}
2246			[invocation setReturnValue:argbuf];
2247			PyMem_Free(argbuf);
2248
2249		} else {
2250			if (!PyTuple_Check(result)
2251			     || PyTuple_Size(result) != have_output) {
2252				PyErr_Format(PyExc_TypeError,
2253					"%s: Need tuple of %d arguments as result",
2254					sel_getName(theSelector),
2255					have_output);
2256				Py_DECREF(signature);
2257				Py_DECREF(result);
2258				PyObjCErr_ToObjCWithGILState(&state);
2259				return;
2260			}
2261			idx = 0;
2262		}
2263
2264
2265		for (i = 2; i < len;i++) {
2266			void* ptr;
2267			type = signature->argtype[i].type;
2268
2269			if (arglen == -1) {
2270				Py_DECREF(signature);
2271				PyObjCErr_ToObjCWithGILState(&state);
2272				return;
2273			}
2274
2275			switch (*type) {
2276			case _C_INOUT: case _C_OUT:
2277				if (type[1] != _C_PTR) {
2278					continue;
2279				}
2280				type += 2;
2281				break;
2282			default:
2283				continue;
2284			}
2285
2286			[invocation getArgument:&ptr atIndex:i];
2287			v = PyTuple_GET_ITEM(result, idx++);
2288			err = depythonify_c_value(type, v, ptr);
2289			if (err == -1) {
2290				Py_DECREF(signature);
2291				PyObjCErr_ToObjCWithGILState(&state);
2292				return;
2293			}
2294			if (Py_REFCNT(v) == 1 && type[0] == _C_ID) {
2295				/* make sure return value doesn't die before
2296				 * the caller can get its hands on it.
2297			   	 */
2298				[[*(id*)ptr retain] autorelease];
2299			}
2300
2301		}
2302		Py_DECREF(result);
2303	}
2304	Py_DECREF(signature);
2305	PyGILState_Release(state);
2306}
2307
2308/*
2309 * XXX: Function PyObjC_CallPython should be moved
2310 */
2311PyObject*
2312PyObjC_CallPython(id self, SEL selector, PyObject* arglist, BOOL* isAlloc, BOOL* isCFAlloc)
2313{
2314	PyObject* pyself = NULL;
2315	PyObject* pymeth = NULL;
2316	PyObject* result;
2317
2318	pyself = pythonify_c_value(@encode(id), &self);
2319	if (pyself == NULL) {
2320		return NULL;
2321	}
2322
2323	if (PyObjCClass_Check(pyself)) {
2324		pymeth = PyObjCClass_FindSelector(pyself, selector, YES);
2325	} else {
2326		pymeth = PyObjCObject_FindSelector(pyself, selector);
2327	}
2328	if (pymeth == NULL) {
2329		Py_DECREF(pyself);
2330		return NULL;
2331	}
2332
2333	if (NULL != ((PyObjCSelector*)pymeth)->sel_self) {
2334		/* The selector is a bound selector, we didn't expect that...*/
2335		PyObject* arg_self;
2336
2337		arg_self = PyTuple_GET_ITEM(arglist, 0);
2338		if (arg_self == NULL) {
2339			return NULL;
2340		}
2341		if (arg_self != ((PyObjCSelector*)pymeth)->sel_self) {
2342
2343			PyErr_SetString(PyExc_TypeError,
2344				"PyObjC_CallPython called with 'self' and "
2345				"a method bound to another object");
2346			return NULL;
2347		}
2348
2349		arglist = PyTuple_GetSlice(arglist, 1, PyTuple_Size(arglist));
2350		if (arglist == NULL) {
2351			return NULL;
2352		}
2353	} else {
2354		Py_INCREF(arglist);
2355	}
2356
2357	if (isAlloc != NULL) {
2358		*isAlloc = PyObjCSelector_GetMetadata(pymeth)->rettype.alreadyRetained;
2359	}
2360	if (isCFAlloc != NULL) {
2361		*isCFAlloc = PyObjCSelector_GetMetadata(pymeth)->rettype.alreadyCFRetained;
2362	}
2363
2364	result = PyObject_Call(pymeth, arglist, NULL);
2365	Py_DECREF(arglist);
2366	Py_DECREF(pymeth);
2367	Py_DECREF(pyself);
2368
2369	if (result == NULL) {
2370		return NULL;
2371	}
2372
2373	return result;
2374}
2375
2376static void
2377object_method_valueForKey_(
2378		ffi_cif* cif __attribute__((__unused__)),
2379		void* retval,
2380		void** args,
2381		void* userdata)
2382{
2383	// This method does the following:
2384	//     - Checks super implementation
2385	//     - if [[self class] accessInstanceVariablesDirectly]
2386	//         - Checks for attribute key
2387	//         - Checks for attribute _key
2388	int r;
2389	id self = *(id*)args[0];
2390	SEL _meth = *(SEL*)args[1];
2391	NSString* key = *(NSString**)args[2];
2392
2393	struct objc_super spr;
2394
2395	// First check super
2396	NS_DURING
2397		objc_superSetClass(spr, (Class)userdata);
2398		objc_superSetReceiver(spr, self);
2399		*((id *)retval) = (id)objc_msgSendSuper(&spr, _meth, key);
2400	NS_HANDLER
2401
2402		/* Parent doesn't know the key, try to create in the
2403		 * python side, just like for plain python objects.
2404		 *
2405		 * NOTE: We have to be extermely careful in here, some classes,
2406		 * like NSManagedContext convert __getattr__ into a -valueForKey:,
2407		 * and that can cause infinite loops.
2408		 *
2409		 * This is why attribute access is hardcoded using PyObjCObject_GetAttrString
2410		 * rather than PyObject_GetAttrString.
2411		 */
2412		if (([[localException name] isEqual:@"NSUnknownKeyException"]
2413			) && [[self class] accessInstanceVariablesDirectly]) {
2414
2415			PyGILState_STATE state = PyGILState_Ensure();
2416			PyObject* selfObj = PyObjCObject_New(self, PyObjCObject_kDEFAULT, YES);
2417			PyObject *res = NULL;
2418			r = -1;
2419			do {
2420				res = PyObjCObject_GetAttrString(selfObj, (char *)[key UTF8String]);
2421				if (res == NULL) {
2422					PyErr_Clear();
2423					res = PyObjCObject_GetAttrString(selfObj, (char *)[[@"_" stringByAppendingString:key] UTF8String]);
2424					if (res == NULL) {
2425						break;
2426					}
2427				}
2428
2429				/* Check that we don't accidently return
2430				 * an accessor method.
2431				 */
2432				if (PyObjCSelector_Check(res) &&
2433					((PyObjCSelector*)res)->sel_self == selfObj) {
2434					Py_DECREF(res); res = NULL;
2435					break;
2436				}
2437				r = depythonify_c_value(@encode(id), res, retval);
2438			} while (0);
2439			Py_DECREF(selfObj);
2440			Py_XDECREF(res);
2441			if (r == -1) {
2442				PyErr_Clear();
2443				PyGILState_Release(state);
2444				[localException raise];
2445			}
2446			PyGILState_Release(state);
2447		} else {
2448			[localException raise];
2449		}
2450	NS_ENDHANDLER
2451
2452}
2453
2454
2455#if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
2456
2457static void
2458object_method_willOrDidChangeValueForKey_(
2459		ffi_cif* cif __attribute__((__unused__)),
2460		void* retval __attribute__((__unused__)),
2461		void** args,
2462		void* userdata) {
2463	struct objc_super spr;
2464	id self = *(id*)args[0];
2465	SEL _meth = *(SEL*)args[1];
2466	NSString* key = *(NSString**)args[2];
2467
2468#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
2469	BOOL isSet = (_meth == @selector(willChangeValueForKey:));
2470	if (_UseKVO(self, key, isSet)) {
2471		objc_superSetClass(spr, (Class)userdata);
2472		objc_superSetReceiver(spr, self);
2473		(void)objc_msgSendSuper(&spr, _meth, key);
2474	}
2475
2476#else
2477	objc_superSetClass(spr, (Class)userdata);
2478	objc_superSetReceiver(spr, self);
2479	(void)objc_msgSendSuper(&spr, _meth, key);
2480#endif
2481
2482}
2483
2484#endif
2485
2486static void
2487object_method_setValue_forKey_(
2488		ffi_cif* cif __attribute__((__unused__)),
2489		void* retval __attribute__((__unused__)),
2490		void** args,
2491		void* userdata)
2492{
2493	// This method does the following:
2494	//     - Checks super implementation
2495	//     - if [[self class] accessInstanceVariablesDirectly]
2496	//	       - Checks for attribute _key and sets if present
2497	//		   - Sets attribute key
2498	int r;
2499	struct objc_super spr;
2500	id self = *(id*)args[0];
2501	SEL _meth = *(SEL*)args[1];
2502	id value = *(id*)args[2];
2503	NSString* key = *(NSString**)args[3];
2504
2505#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
2506	// Set up a KVO stack so you only get one notification from this
2507	NS_DURING
2508		if (_KVOHackLevel() == BROKEN_KVO) {
2509			[self willChangeValueForKey:key];
2510		}
2511	NS_HANDLER
2512	NS_ENDHANDLER
2513#endif
2514
2515	NS_DURING
2516		// First check super
2517		objc_superSetClass(spr, (Class)userdata);
2518		objc_superSetReceiver(spr, self);
2519		(void)objc_msgSendSuper(&spr, _meth, value, key);
2520	NS_HANDLER
2521		/* Parent doesn't know the key, try to create in the
2522		 * python side, just like for plain python objects.
2523		 */
2524		if (([[localException name] isEqual:@"NSUnknownKeyException"]
2525			) && [[self class] accessInstanceVariablesDirectly]) {
2526
2527			PyGILState_STATE state = PyGILState_Ensure();
2528			PyObject* val = pythonify_c_value(@encode(id), &value);
2529			if (val == NULL) {
2530				PyErr_Clear();
2531				PyGILState_Release(state);
2532
2533#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
2534				// Pop the KVO stack
2535				if (_KVOHackLevel() == BROKEN_KVO) {
2536				    [self didChangeValueForKey:key];
2537				}
2538#endif
2539
2540				[localException raise];
2541			}
2542			PyObject* res = NULL;
2543			PyObject* selfObj = PyObjCObject_New(self, PyObjCObject_kDEFAULT, YES);
2544			r = -1;
2545			do {
2546				char *rawkey = (char *)[[@"_" stringByAppendingString:key] UTF8String];
2547				res = PyObject_GetAttrString(selfObj, rawkey);
2548				if (res != NULL) {
2549					r = PyObject_SetAttrString(selfObj, rawkey, val);
2550					if (r != -1) {
2551						break;
2552					}
2553				}
2554				PyErr_Clear();
2555				rawkey = (char *)[key UTF8String];
2556				r = PyObject_SetAttrString(selfObj, rawkey, val);
2557			} while (0);
2558			Py_DECREF(selfObj);
2559			Py_DECREF(val);
2560			Py_XDECREF(res);
2561			if (r == -1) {
2562				PyErr_Clear();
2563				PyGILState_Release(state);
2564#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
2565				// Pop the KVO stack
2566				if (_KVOHackLevel() == BROKEN_KVO) {
2567				    [self didChangeValueForKey:key];
2568				}
2569#endif
2570				[localException raise];
2571			}
2572			PyGILState_Release(state);
2573		} else {
2574#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
2575			// Pop the KVO stack
2576			if (_KVOHackLevel() == BROKEN_KVO) {
2577				[self didChangeValueForKey:key];
2578			}
2579#endif
2580			[localException raise];
2581		}
2582	NS_ENDHANDLER
2583
2584#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
2585	// Pop the KVO stack
2586	if (_KVOHackLevel() == BROKEN_KVO) {
2587		[self didChangeValueForKey:key];
2588	}
2589#endif
2590}
2591