1/*
2 * Support for libffi (http://sources.redhat.com/libffi)
3 *
4 * libffi is a library that makes it possible to dynamicly create calls
5 * to C functions (without knowing the signature at compile-time). It also
6 * provides a way to create closures, that is dynamicly create functions with
7 * a runtime specified interface.
8 *
9 * This file contains functions to dynamicly call objc_msgSendSuper and to
10 * dynamicly create IMPs for use in Objective-C method dispatch tables. The
11 * file 'register.m' contains compile-time generated equivalents of these.
12 *
13 * FIXME: There's way to much duplicated code in here, please refactor me.
14 */
15#include "pyobjc.h"
16
17#import <Foundation/NSHost.h>
18#import <CoreFoundation/CoreFoundation.h>
19
20#ifdef __ppc64__
21extern bool ffi64_stret_needs_ptr(const ffi_type* inType,
22		        unsigned short*, unsigned short*);
23#endif
24
25/*
26 * Define SMALL_STRUCT_LIMIT as the largest struct that will be returned
27 * in registers instead of with a hidden pointer argument.
28 */
29
30static const char gCharEncoding[] = { _C_CHR, 0 };
31static const char gCFRangeEncoding[1024] = { 0 };
32
33#if defined(__ppc__)
34
35#   define SMALL_STRUCT_LIMIT	4
36
37#elif defined(__ppc64__)
38
39#   define SMALL_STRUCT_LIMIT	8
40
41#elif defined(__i386__)
42
43#   define SMALL_STRUCT_LIMIT 	8
44
45#elif defined(__x86_64__)
46
47#   define SMALL_STRUCT_LIMIT	16
48
49#else
50
51#   error "Unsupported MACOSX platform"
52
53#endif
54
55
56#ifndef FFI_CLOSURES
57#    error "Need FFI_CLOSURES!"
58#endif
59
60#if 1 /* These are only usefull from the debugger, leaving them enabled is harmless */
61static void describe_ffitype(ffi_type* type)
62{
63	switch (type->type) {
64	case FFI_TYPE_VOID: printf("%s", "void"); break;
65	case FFI_TYPE_INT: printf("%s", "int"); break;
66	case FFI_TYPE_FLOAT: printf("%s", "float"); break;
67	case FFI_TYPE_DOUBLE: printf("%s", "double"); break;
68	case FFI_TYPE_UINT8: printf("%s", "uint8"); break;
69	case FFI_TYPE_SINT8: printf("%s", "sint8"); break;
70	case FFI_TYPE_UINT16: printf("%s", "uint16"); break;
71	case FFI_TYPE_SINT16: printf("%s", "sint16"); break;
72	case FFI_TYPE_UINT32: printf("%s", "uint32"); break;
73	case FFI_TYPE_SINT32: printf("%s", "sint32"); break;
74	case FFI_TYPE_UINT64: printf("%s", "uint64"); break;
75	case FFI_TYPE_SINT64: printf("%s", "sint64"); break;
76	case FFI_TYPE_POINTER: printf("%s", "*"); break;
77	case FFI_TYPE_STRUCT: {
78			ffi_type** elems = type->elements;
79
80			printf("%s", "struct { ");
81			if (elems) {
82				while (*elems) {
83					describe_ffitype(*(elems++));
84					printf("%s", "; ");
85				}
86			}
87			printf("%s", "}");
88		}
89	       break;
90
91	default:
92	       // Don't abort, this is called from the debugger
93	       printf("?(%d)", type->type);
94	}
95}
96
97static void describe_cif(ffi_cif* cif) __attribute__((__unused__));
98static void describe_cif(ffi_cif* cif)
99{
100	size_t i;
101
102	printf("<ffi_cif abi=%d nargs=%d  bytes=%d flags=%#x args=[",
103		cif->abi, cif->nargs, cif->bytes, cif->flags);
104	for  (i = 0; i < cif->nargs; i++) {
105		describe_ffitype(cif->arg_types[i]);
106		printf("%s", ", ");
107	}
108	printf("%s", "] rettype=");
109	describe_ffitype(cif->rtype);
110	printf("%s", ">\n");
111}
112
113#endif
114
115
116
117static inline Py_ssize_t align(Py_ssize_t offset, Py_ssize_t alignment)
118{
119	Py_ssize_t rest = offset % alignment;
120	if (rest == 0) return offset;
121	return offset + (alignment - rest);
122}
123
124static Py_ssize_t
125num_struct_fields(const char* argtype)
126{
127	Py_ssize_t res = 0;
128
129	if (*argtype != _C_STRUCT_B) return -1;
130	while (*argtype != _C_STRUCT_E && *argtype != '=') argtype++;
131	if (*argtype == _C_STRUCT_E) return 0;
132
133	argtype++;
134	while (*argtype != _C_STRUCT_E) {
135		if (*argtype == '"') {
136			/* Skip field name */
137			argtype++;
138			while (*argtype++ != '"') {}
139		}
140
141		argtype = PyObjCRT_SkipTypeSpec(argtype);
142		if (argtype == NULL) return -1;
143		res ++;
144	}
145	return res;
146}
147
148
149static void
150free_type(void *obj)
151{
152	PyMem_Free(((ffi_type*)obj)->elements);
153	PyMem_Free(obj);
154}
155
156static ffi_type* signature_to_ffi_type(const char* argtype);
157
158#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 6
159static void cleanup_ffitype_capsule(void* ptr)
160{
161	free_type(ptr);
162}
163#else
164static void cleanup_ffitype_capsule(PyObject* ptr)
165{
166	free_type(PyCapsule_GetPointer(ptr, "objc.__ffi_type__"));
167}
168#endif
169
170static ffi_type*
171array_to_ffi_type(const char* argtype)
172{
173static  PyObject* array_types = NULL; /* XXX: Use NSMap  */
174	PyObject* v;
175	ffi_type* type;
176	Py_ssize_t field_count;
177	Py_ssize_t i;
178	const char* key = argtype;
179
180	if (array_types == NULL) {
181		array_types = PyDict_New();
182		if (array_types == NULL) return NULL;
183	}
184
185	v = PyDict_GetItemString(array_types, (char*)argtype);
186	if (v != NULL) {
187		return (ffi_type*)PyCapsule_GetPointer(v, "objc.__ffi_type__");
188	}
189
190	/* We don't have a type description yet, dynamicly
191	 * create it.
192	 */
193	field_count = atoi(argtype+1);
194
195	type = PyMem_Malloc(sizeof(*type));
196	if (type == NULL) {
197		PyErr_NoMemory();
198		return NULL;
199	}
200	type->size = PyObjCRT_SizeOfType(argtype);
201	type->alignment = PyObjCRT_AlignOfType(argtype);
202
203	/* Libffi doesn't really know about arrays as part of larger
204	 * data-structures (e.g. struct foo { int field[3]; };). We fake it
205	 * by treating the nested array as a struct. These seems to work
206	 * fine on MacOS X.
207	 */
208	type->type = FFI_TYPE_STRUCT;
209	type->elements = PyMem_Malloc((1+field_count) * sizeof(ffi_type*));
210	if (type->elements == NULL) {
211		PyMem_Free(type);
212		PyErr_NoMemory();
213		return NULL;
214	}
215
216	while (isdigit(*++argtype));
217	type->elements[0] = signature_to_ffi_type(argtype);
218	for (i = 1; i < field_count; i++) {
219		type->elements[i] = type->elements[0];
220	}
221	type->elements[field_count] = 0;
222
223	v = PyCapsule_New(type, "objc.__ffi_type__", cleanup_ffitype_capsule);
224	if (v == NULL) {
225		free_type(type);
226		return NULL;
227	}
228
229	PyDict_SetItemString(array_types, (char*)key, v);
230	if (PyErr_Occurred()) {
231		Py_DECREF(v);
232		return NULL;
233	}
234	Py_DECREF(v);
235	return type;
236}
237
238static ffi_type*
239struct_to_ffi_type(const char* argtype)
240{
241	static  PyObject* struct_types = NULL; /* XXX: Use NSMap  */
242	PyObject* v;
243	ffi_type* type;
244	Py_ssize_t field_count;
245	const char* curtype;
246
247	if (struct_types == NULL) {
248		struct_types = PyDict_New();
249		if (struct_types == NULL) return NULL;
250	}
251
252	v = PyDict_GetItemString(struct_types, (char*)argtype);
253	if (v != NULL) {
254		return (ffi_type*)PyCapsule_GetPointer(v, "objc.__ffi_type__");
255	}
256
257	/* We don't have a type description yet, dynamicly
258	 * create it.
259	 */
260	field_count = num_struct_fields(argtype);
261	if (field_count == -1) {
262		PyErr_Format(PyObjCExc_InternalError,
263			"Cannot determine layout of %s", argtype);
264		return NULL;
265	}
266
267	type = PyMem_Malloc(sizeof(*type));
268	if (type == NULL) {
269		PyErr_NoMemory();
270		return NULL;
271	}
272	type->size = PyObjCRT_SizeOfType(argtype);
273	type->alignment = PyObjCRT_AlignOfType(argtype);
274	type->type = FFI_TYPE_STRUCT;
275	type->elements = PyMem_Malloc((1+field_count) * sizeof(ffi_type*));
276	if (type->elements == NULL) {
277		PyMem_Free(type);
278		PyErr_NoMemory();
279		return NULL;
280	}
281
282	field_count = 0;
283	curtype = argtype+1;
284	while (*curtype != _C_STRUCT_E && *curtype != '=') curtype++;
285	if (*curtype == '=') {
286		curtype ++;
287		while (*curtype != _C_STRUCT_E) {
288			if (*curtype == '"') {
289				/* Skip field name */
290				curtype++;
291				while (*curtype++ != '"') {}
292			}
293			type->elements[field_count] =
294				signature_to_ffi_type(curtype);
295			if (type->elements[field_count] == NULL) {
296				PyMem_Free(type->elements);
297				return NULL;
298			}
299			field_count++;
300			curtype = PyObjCRT_SkipTypeSpec(curtype);
301			if (curtype == NULL) {
302				PyMem_Free(type->elements);
303				return NULL;
304			}
305		}
306	}
307	type->elements[field_count] = NULL;
308
309	v = PyCapsule_New(type, "objc.__ffi_type__", cleanup_ffitype_capsule);
310	if (v == NULL) {
311		free_type(type);
312		return NULL;
313	}
314
315	PyDict_SetItemString(struct_types, (char*)argtype, v);
316	if (PyErr_Occurred()) {
317		Py_DECREF(v);
318		return NULL;
319	}
320	Py_DECREF(v);
321	return type;
322}
323
324ffi_type*
325signature_to_ffi_return_type(const char* argtype)
326{
327#ifdef __ppc__
328static const char long_type[] = { _C_LNG, 0 };
329static const char ulong_type[] = { _C_ULNG, 0 };
330
331	switch (*argtype) {
332	case _C_CHR: case _C_SHT: case _C_UNICHAR:
333		return signature_to_ffi_type(long_type);
334	case _C_UCHR: case _C_USHT:
335		return signature_to_ffi_type(ulong_type);
336#ifdef _C_BOOL
337	case _C_BOOL: return signature_to_ffi_type(long_type);
338#endif
339	case _C_NSBOOL:
340		      return signature_to_ffi_type(long_type);
341	default:
342		return signature_to_ffi_type(argtype);
343	}
344#else
345	return signature_to_ffi_type(argtype);
346#endif
347}
348
349
350static ffi_type*
351signature_to_ffi_type(const char* argtype)
352{
353	argtype = PyObjCRT_SkipTypeQualifiers(argtype);
354	switch (*argtype) {
355	case _C_VOID: return &ffi_type_void;
356	case _C_ID: return &ffi_type_pointer;
357	case _C_CLASS: return &ffi_type_pointer;
358	case _C_SEL: return &ffi_type_pointer;
359	case _C_CHR: return &ffi_type_schar;
360	case _C_CHAR_AS_INT: return &ffi_type_schar;
361	case _C_CHAR_AS_TEXT: return &ffi_type_schar;
362#ifdef _C_BOOL
363	case _C_BOOL:
364	     /* sizeof(bool) == 4 on PPC32, and 1 on all others */
365#if defined(__ppc__) && !defined(__LP__)
366	     return &ffi_type_sint;
367#else
368	     return &ffi_type_schar;
369#endif
370
371#endif
372	case _C_NSBOOL: return &ffi_type_schar;
373	case _C_UCHR: return &ffi_type_uchar;
374	case _C_SHT: return &ffi_type_sshort;
375	case _C_UNICHAR: return &ffi_type_ushort;
376	case _C_USHT: return &ffi_type_ushort;
377	case _C_INT: return &ffi_type_sint;
378	case _C_UINT: return &ffi_type_uint;
379
380	 /* The next to defintions are incorrect, but the correct definitions
381	  * don't work (e.g. give testsuite failures).
382	  */
383#ifdef __LP64__
384	case _C_LNG: return &ffi_type_sint64;  /* ffi_type_slong */
385	case _C_ULNG: return &ffi_type_uint64;  /* ffi_type_ulong */
386#else
387	case _C_LNG: return &ffi_type_sint;  /* ffi_type_slong */
388	case _C_ULNG: return &ffi_type_uint;  /* ffi_type_ulong */
389#endif
390	case _C_LNG_LNG: return &ffi_type_sint64;
391	case _C_ULNG_LNG: return &ffi_type_uint64;
392	case _C_FLT: return &ffi_type_float;
393	case _C_DBL: return &ffi_type_double;
394	case _C_CHARPTR: return &ffi_type_pointer;
395	case _C_PTR: return &ffi_type_pointer;
396	case _C_ARY_B:
397		return array_to_ffi_type(argtype);
398	case _C_IN: case _C_OUT: case _C_INOUT: case _C_CONST:
399#if 0	/* 'O' is used by remote objects ??? */
400	  case 'O':
401#endif
402		return signature_to_ffi_type(argtype+1);
403	case _C_STRUCT_B:
404		return struct_to_ffi_type(argtype);
405	case _C_UNDEF:
406		return &ffi_type_pointer;
407	default:
408		PyErr_Format(PyExc_NotImplementedError,
409			"Type '%#x' (%c) not supported", *argtype, *argtype);
410		return NULL;
411	}
412}
413
414/*
415 * arg_signature_to_ffi_type: Make the ffi_type for the call to the method IMP.
416 */
417
418#ifdef __ppc__
419#define arg_signature_to_ffi_type signature_to_ffi_type
420
421#else
422static inline ffi_type*
423arg_signature_to_ffi_type(const char* argtype)
424{
425	/* NOTE: This is the minimal change to pass the unittests, it is not
426	 * based on analysis of the calling conventions.
427	 */
428	switch (*argtype) {
429	default: return signature_to_ffi_type(argtype);
430	}
431}
432#endif
433
434static Py_ssize_t extract_count(const char* type, void* pvalue)
435{
436	type = PyObjCRT_SkipTypeQualifiers(type);
437	switch (*type) {
438	case _C_ID:
439		{
440			NSArray* value = *(id*)pvalue;
441			if (!value) {
442				return 0;
443			} else if ([value respondsToSelector:@selector(count)]) {
444				return [value count];
445			} else {
446				/* Fall through to error case */
447			}
448		}
449		break;
450	case _C_CHR: return *(char*)pvalue;
451	case _C_CHAR_AS_INT: return *(char*)pvalue;
452	case _C_UCHR: return *(unsigned char*)pvalue;
453	case _C_SHT: return *(short*)pvalue;
454	case _C_USHT: return *(unsigned short*)pvalue;
455	case _C_INT: return *(int*)pvalue;
456	case _C_UINT: return *(unsigned int*)pvalue;
457	case _C_LNG: return *(long*)pvalue;
458	case _C_ULNG: return *(unsigned long*)pvalue;
459	case _C_LNG_LNG: return *(long long*)pvalue;
460	case _C_ULNG_LNG: return *(unsigned long long*)pvalue;
461	case _C_PTR:
462		switch(type[1]) {
463		case _C_CHR: return **(char**)pvalue;
464		case _C_CHAR_AS_INT: return **(char**)pvalue;
465		case _C_UCHR: return **(unsigned char**)pvalue;
466		case _C_SHT: return **(short**)pvalue;
467		case _C_USHT: return **(unsigned short**)pvalue;
468		case _C_INT: return **(int**)pvalue;
469		case _C_UINT: return **(unsigned int**)pvalue;
470		case _C_LNG: return **(long**)pvalue;
471		case _C_ULNG: return **(unsigned long**)pvalue;
472		case _C_LNG_LNG: return **(long long**)pvalue;
473		case _C_ULNG_LNG: return **(unsigned long long**)pvalue;
474		}
475
476		if (strncmp(type+1, @encode(NSRange), sizeof(@encode(NSRange)) - 1) == 0) {
477			return (*(NSRange**)pvalue)->length;
478		}
479
480		/* Fall through: */
481	}
482	if (strncmp(type, @encode(NSRange), sizeof(@encode(NSRange)) - 1) == 0) {
483		return ((NSRange*)pvalue)->length;
484	}
485	if (strncmp(type, @encode(CFRange), sizeof(@encode(CFRange)) - 1) == 0) {
486		return ((CFRange*)pvalue)->length;
487	}
488#ifdef __LP64__
489	if (strncmp(type, "{_CFRange=qq}", sizeof("{_CFRange=qq}") - 1) == 0) {
490		return ((CFRange*)pvalue)->length;
491	}
492#else
493	if (strncmp(type, "{_CFRange=ii}", sizeof("{_CFRange=ii}") - 1) == 0) {
494		return ((CFRange*)pvalue)->length;
495	}
496#endif
497	if (strncmp(type, "{_CFRange=ll}", sizeof("{_CFRange=ll}") - 1) == 0) {
498		return ((CFRange*)pvalue)->length;
499	}
500
501	if (strncmp(type, @encode(CFArrayRef), sizeof(@encode(CFArrayRef))-1) == 0 ||
502		strncmp(type, @encode(CFMutableArrayRef), sizeof(@encode(CFMutableArrayRef))-1) == 0) {
503
504		return CFArrayGetCount(*(CFArrayRef*)pvalue);
505	}
506	PyErr_Format(PyExc_TypeError,
507			"Don't know how to convert to extract count: %s", type);
508	return -1;
509}
510
511/* Support for printf format strings */
512static int
513parse_printf_args(
514	PyObject* py_format,
515	PyObject* argtuple, Py_ssize_t argoffset,
516	void** byref, struct byref_attr* byref_attr,
517	ffi_type** arglist, void** values,
518	Py_ssize_t curarg)
519{
520	/* Walk the format string as a UTF-8 encoded ASCII value. This isn't
521	 * perfect but keeps the code simple.
522	 */
523	Py_ssize_t maxarg = PyTuple_Size(argtuple);
524
525	PyObject* encoded;
526	PyObject* v;
527
528	if (PyBytes_Check(py_format)) {
529		encoded = py_format;
530		Py_INCREF(encoded);
531
532	} else if (PyUnicode_Check(py_format)) {
533		encoded = PyUnicode_AsEncodedString(py_format, "utf-8", NULL);
534		if (encoded == NULL) {
535			return -1;
536		}
537
538	} else {
539		PyErr_SetString(PyExc_TypeError, "Unsupported format string type");
540		return -1;
541	}
542
543	const char* format = PyBytes_AsString(encoded);
544	if (format == NULL) {
545		if (!PyErr_Occurred()) {
546			PyErr_SetString(PyExc_ValueError, "Empty format string");
547		}
548		Py_DECREF(encoded);
549		return -1;
550	}
551
552	format = strchr(format, '%');
553	while (format && *format != '\0') {
554		char typecode;
555
556		/* Skip '%' */
557		format ++;
558
559		/* Check for '%%' escape */
560		if (*format == '%') {
561			format++;
562			format = strchr(format, '%');
563			continue;
564		}
565
566		/* Skip flags */
567		while (1) {
568		   if (!*format)  break;
569		   if (
570			   (*format == '#')
571			|| (*format == '0')
572			|| (*format == '-')
573			|| (*format == ' ')
574			|| (*format == '+')
575			|| (*format == '\'')) {
576
577			format++;
578		   } else {
579			break;
580		   }
581		}
582
583		/* Field width */
584		if (*format == '*') {
585			if (argoffset >= maxarg) {
586				PyErr_Format(PyExc_ValueError, "Too few arguments for format string [cur:%"PY_FORMAT_SIZE_T"d/len:%"PY_FORMAT_SIZE_T"d]", argoffset, maxarg);
587				Py_DECREF(encoded);
588				return -1;
589			}
590			format++;
591			byref[curarg] = PyMem_Malloc(sizeof(int));
592			if (byref[curarg] == NULL) {
593				Py_DECREF(encoded);
594				return -1;
595			}
596
597			if (depythonify_c_value(@encode(int), PyTuple_GET_ITEM(argtuple, argoffset), byref[curarg]) < 0) {
598				Py_DECREF(encoded);
599				return -1;
600			}
601			values[curarg] = byref[curarg];
602			arglist[curarg] = signature_to_ffi_type(@encode(int));
603
604			argoffset++;
605			curarg++;
606
607		} else {
608			while (isdigit(*format)) format++;
609		}
610
611		/* Precision */
612		if (*format == '.') {
613			format++;
614			if (*format == '*') {
615				format++;
616				if (argoffset >= maxarg) {
617					PyErr_Format(PyExc_ValueError, "Too few arguments for format string [cur:%"PY_FORMAT_SIZE_T"d/len:%"PY_FORMAT_SIZE_T"d]", argoffset, maxarg);
618					Py_DECREF(encoded);
619					return -1;
620				}
621				byref[curarg] = PyMem_Malloc(sizeof(long long));
622				if (byref[curarg] == NULL) {
623					Py_DECREF(encoded);
624					return -1;
625				}
626
627
628				if (depythonify_c_value(@encode(int), PyTuple_GET_ITEM(argtuple, argoffset), byref[curarg]) < 0) {
629					Py_DECREF(encoded);
630					return -1;
631				}
632				values[curarg] = byref[curarg];
633				arglist[curarg] = signature_to_ffi_type(@encode(int));
634				argoffset++;
635				curarg++;
636			} else {
637				while (isdigit(*format)) format++;
638			}
639		}
640
641		/* length modifier */
642		typecode = 0;
643
644		if (*format == 'h') {
645			format++;
646
647			if (*format == 'h') {
648				format++;
649			}
650
651		} else if (*format == 'l') {
652			format++;
653			typecode = _C_LNG;
654			if (*format == 'l') {
655				typecode = _C_LNG_LNG;
656				format++;
657			}
658
659		} else if (*format == 'q') {
660			format++;
661			typecode = _C_LNG_LNG;
662
663		} else if (*format == 'j') {
664			typecode = _C_LNG_LNG;
665			format++;
666
667		} else if (*format == 'z') {
668			typecode = *@encode(size_t);
669			format++;
670
671		} else if (*format == 't') {
672			typecode = *@encode(ptrdiff_t);
673			format++;
674
675		} else if (*format == 'L') {
676			/* typecode = _C_LNGDBL, that's odd: no type encoding for long double! */
677			format++;
678
679		}
680
681		if (argoffset >= maxarg) {
682			PyErr_Format(PyExc_ValueError, "Too few arguments for format string [cur:%"PY_FORMAT_SIZE_T"d/len:%"PY_FORMAT_SIZE_T"d]", argoffset, maxarg);
683			Py_DECREF(encoded);
684			return -1;
685		}
686
687		/* And finally the info we're after: the actual format character */
688		switch (*format) {
689		case 'c': case 'C':
690#if SIZEOF_WCHAR_T != 4
691#	error "Unexpected wchar_t size"
692#endif
693
694			byref[curarg] = PyMem_Malloc(sizeof(int));
695			arglist[curarg] = signature_to_ffi_type(@encode(int));
696			v = PyTuple_GET_ITEM(argtuple, argoffset);
697#if PY_MAJOR_VERSION == 2
698			if (PyString_Check(v)) {
699				if (PyString_Size(v) != 1) {
700					PyErr_SetString(PyExc_ValueError, "Expecting string of length 1");
701					Py_DECREF(encoded);
702					return -1;
703				}
704				*(int*)byref[curarg] = (wchar_t)*PyString_AsString(v);
705			} else
706#endif
707			if (PyUnicode_Check(v)) {
708
709				if (PyUnicode_GetSize(v) != 1) {
710					PyErr_SetString(PyExc_ValueError, "Expecting string of length 1");
711					Py_DECREF(encoded);
712					return -1;
713				}
714				*(int*)byref[curarg] = (wchar_t)*PyUnicode_AsUnicode(v);
715			} else if (depythonify_c_value(@encode(int), v, byref[curarg]) < 0) {
716				Py_DECREF(encoded);
717				return -1;
718			}
719
720			values[curarg] = byref[curarg];
721
722			argoffset++;
723			curarg++;
724			break;
725
726		case 'd': case 'i': case 'D':
727			/* INT */
728			if (*format == 'D') {
729				typecode = _C_LNG;
730			}
731
732			if (typecode == _C_LNG_LNG) {
733				byref[curarg] = PyMem_Malloc(sizeof(long long));
734
735			} else if (typecode == _C_LNG) {
736				byref[curarg] = PyMem_Malloc(sizeof(long));
737
738			} else {
739				typecode = _C_INT;
740				byref[curarg] = PyMem_Malloc(sizeof(int));
741			}
742			if (byref[curarg] == NULL) {
743				PyErr_NoMemory();
744				return -1;
745			}
746			if (depythonify_c_value(&typecode, PyTuple_GET_ITEM(argtuple, argoffset), byref[curarg]) < 0) {
747				Py_DECREF(encoded);
748				return -1;
749			}
750			values[curarg] = byref[curarg];
751			arglist[curarg] = signature_to_ffi_type(&typecode);
752
753			argoffset++;
754			curarg++;
755			break;
756
757		case 'o': case 'u': case 'x':
758		case 'X': case 'U': case 'O':
759			/* UNSIGNED */
760			if (*format == 'U' || *format == 'X') {
761				typecode = _C_LNG;
762			}
763
764			if (typecode == _C_LNG_LNG) {
765				byref[curarg] = PyMem_Malloc(sizeof(long long));
766				typecode = _C_ULNG_LNG;
767
768			} else if (typecode == _C_LNG) {
769				byref[curarg] = PyMem_Malloc(sizeof(long));
770				typecode = _C_ULNG;
771
772			} else {
773				byref[curarg] = PyMem_Malloc(sizeof(int));
774				typecode = _C_UINT;
775			}
776			if (byref[curarg] == NULL) {
777				PyErr_NoMemory();
778				Py_DECREF(encoded);
779				return -1;
780			}
781			if (depythonify_c_value(&typecode, PyTuple_GET_ITEM(argtuple, argoffset), byref[curarg]) < 0) {
782				Py_DECREF(encoded);
783				return -1;
784			}
785			values[curarg] = byref[curarg];
786			arglist[curarg] = signature_to_ffi_type(&typecode);
787
788			argoffset++;
789			curarg++;
790			break;
791
792		case 'f': case 'F': case 'e': case 'E':
793		case 'g': case 'G': case 'a': case 'A':
794			/* double */
795			typecode = _C_DBL;
796			byref[curarg] = PyMem_Malloc(sizeof(double));
797			if (byref[curarg] == NULL) {
798				PyErr_NoMemory();
799				Py_DECREF(encoded);
800				return -1;
801			}
802
803			if (depythonify_c_value(&typecode, PyTuple_GET_ITEM(argtuple, argoffset), byref[curarg]) < 0) {
804				Py_DECREF(encoded);
805				return -1;
806			}
807			values[curarg] = byref[curarg];
808#if defined(__ppc__)
809			/* Passing floats to variadic functions on darwin/ppc
810			 * is slightly convoluted. Lying to libffi about the
811			 * type of the argument seems to trick it into doing
812			 * what the callee expects.
813			 * XXX: need to test if this is still needed.
814			 */
815			arglist[curarg] = &ffi_type_uint64;
816#else
817			arglist[curarg] = signature_to_ffi_type(&typecode);
818#endif
819
820			argoffset++;
821			curarg++;
822			break;
823
824
825		case 's': case 'S':
826			/* string */
827			if (*format == 'S' || typecode == _C_LNG) {
828				/* whar_t */
829				v = byref_attr[curarg].buffer = PyUnicode_FromObject( PyTuple_GET_ITEM(argtuple, argoffset));
830				if (byref_attr[curarg].buffer == NULL) {
831					Py_DECREF(encoded);
832					return -1;
833				}
834
835				Py_ssize_t sz = PyUnicode_GetSize(v);
836				byref[curarg] = PyMem_Malloc(sizeof(wchar_t)*(sz+1));
837				if (byref[curarg] == NULL) {
838					Py_DECREF(encoded);
839					return -1;
840				}
841
842				if (PyUnicode_AsWideChar(UNICODE_CAST(v), (wchar_t*)byref[curarg], sz)<0) {
843					Py_DECREF(encoded);
844					return -1;
845				}
846				((wchar_t*)byref[curarg])[sz] = 0;
847				arglist[curarg] = signature_to_ffi_type(@encode(wchar_t*));
848				values[curarg] = byref + curarg;
849			} else {
850				/* char */
851				typecode = _C_CHARPTR;
852				byref[curarg] = PyMem_Malloc(sizeof(char*));
853				if (byref[curarg] == NULL) {
854					PyErr_NoMemory();
855					Py_DECREF(encoded);
856					return -1;
857				}
858				if (depythonify_c_value(&typecode, PyTuple_GET_ITEM(argtuple, argoffset), byref[curarg]) < 0) {
859					Py_DECREF(encoded);
860					return -1;
861				}
862				arglist[curarg] = signature_to_ffi_type(&typecode);
863				values[curarg] = byref[curarg];
864			}
865
866			argoffset++;
867			curarg++;
868			break;
869
870		case '@': case 'K':
871			/* object (%K is only used by NSPredicate */
872			typecode = _C_ID;
873			byref[curarg] = PyMem_Malloc(sizeof(char*));
874			if (byref[curarg] == NULL) {
875				PyErr_NoMemory();
876				Py_DECREF(encoded);
877				return -1;
878			}
879			if (depythonify_c_value(&typecode, PyTuple_GET_ITEM(argtuple, argoffset), byref[curarg]) < 0) {
880				Py_DECREF(encoded);
881				return -1;
882			}
883			values[curarg] = byref[curarg];
884			arglist[curarg] = signature_to_ffi_type(&typecode);
885
886			argoffset++;
887			curarg++;
888			break;
889
890		case 'p':
891			/* pointer */
892			byref[curarg] = PyMem_Malloc(sizeof(char*));
893			if (byref[curarg] == NULL) {
894				PyErr_NoMemory();
895				Py_DECREF(encoded);
896				return -1;
897			}
898			*((char**)byref[curarg]) = (char*)PyTuple_GET_ITEM(argtuple, argoffset);
899			values[curarg] = byref[curarg];
900			arglist[curarg] = signature_to_ffi_type(@encode(void*));
901
902			argoffset++;
903			curarg++;
904			break;
905
906		case 'n':
907			/* pointer-to-int */
908			byref[curarg] = PyMem_Malloc(sizeof(long long));
909			if (byref[curarg] == NULL) {
910				PyErr_NoMemory();
911				Py_DECREF(encoded);
912				return -1;
913			}
914			values[curarg] = byref[curarg];
915			arglist[curarg] = signature_to_ffi_type(&typecode);
916
917			argoffset++;
918			break;
919
920		default:
921			PyErr_SetString(PyExc_ValueError, "Invalid format string");
922			Py_DECREF(encoded);
923			return -1;
924		}
925
926
927		format = strchr(format+1, '%');
928	}
929
930	Py_DECREF(encoded);
931
932	if (argoffset != maxarg) {
933		PyErr_Format(PyExc_ValueError, "Too many values for format [%"PY_FORMAT_SIZE_T"d/%"PY_FORMAT_SIZE_T"d]", argoffset, maxarg);
934		return -1;
935	}
936	return curarg;
937}
938
939static int parse_varargs_array(
940	PyObjCMethodSignature* methinfo,
941	PyObject* argtuple, Py_ssize_t argoffset,
942	void** byref,
943	ffi_type** arglist, void** values, Py_ssize_t count)
944{
945	Py_ssize_t curarg = Py_SIZE(methinfo)-1;
946	Py_ssize_t maxarg = PyTuple_Size(argtuple);
947	Py_ssize_t argSize;
948
949	if (count != -1) {
950		if (maxarg - curarg != count) {
951			PyErr_Format(PyExc_ValueError, "Wrong number of variadic arguments, need %" PY_FORMAT_SIZE_T "d, got %" PY_FORMAT_SIZE_T "d",
952					count, (maxarg - curarg));
953			return -1;
954		}
955	}
956
957	struct _PyObjC_ArgDescr* argType = (
958			methinfo->argtype + Py_SIZE(methinfo) - 1);
959
960	argSize = PyObjCRT_SizeOfType(argType->type);
961
962	if (count == -1) {
963		if (argType->type[0] != _C_ID) {
964			PyErr_Format(PyExc_TypeError,
965				"variadic null-terminated arrays only supported for type '%c', not '%s' || %s", _C_ID, argType->type, PyObject_REPR((PyObject*)methinfo));
966			return -1;
967		}
968	}
969
970	for (;argoffset < maxarg; curarg++, argoffset++) {
971		byref[curarg]  = PyMem_Malloc(argSize);
972		if (byref[curarg] == NULL) {
973			return -1;
974		}
975		if (depythonify_c_value(argType->type,
976			PyTuple_GET_ITEM(argtuple, argoffset),
977			byref[curarg]) < 0) {
978
979			return -1;
980		}
981
982		values[curarg] = byref[curarg];
983		arglist[curarg] = &ffi_type_pointer;
984	}
985	byref[curarg]  = NULL;
986	values[curarg] = &byref[curarg];
987	arglist[curarg] = &ffi_type_pointer;
988	return curarg+1;
989}
990
991/* This function decodes its arguments into Python values, then
992 * calls the python method and finally encodes the return value
993 */
994
995enum closureType {
996	PyObjC_Function,
997	PyObjC_Method,
998	PyObjC_Block,
999};
1000
1001typedef struct {
1002	PyObject* callable;
1003	int       argCount;
1004	PyObjCMethodSignature* methinfo;
1005	enum closureType	  closureType;
1006} _method_stub_userdata;
1007
1008static void
1009method_stub(ffi_cif* cif __attribute__((__unused__)), void* resp, void** args, void* _userdata)
1010{
1011	int err;
1012	PyObject*  seq;
1013	_method_stub_userdata* userdata = (_method_stub_userdata*)_userdata;
1014	PyObject* callable = userdata->callable;
1015	PyObjCMethodSignature* methinfo = userdata->methinfo;
1016	Py_ssize_t         i, startArg;
1017	PyObject*          arglist;
1018	PyObject*          res;
1019	PyObject*          v = NULL;
1020	int                have_output = 0;
1021	const char*        rettype;
1022	PyObject* 	   pyself;
1023	int		   cookie;
1024	Py_ssize_t	   count;
1025	BOOL		   haveCountArg;
1026
1027	PyGILState_STATE   state = PyGILState_Ensure();
1028
1029	rettype = methinfo->rettype.type;
1030
1031	arglist = PyList_New(0);
1032
1033	/* First translate from Objective-C to python */
1034	if (userdata->closureType == PyObjC_Method) {
1035		pyself = PyObjCObject_NewTransient(*(id*)args[0], &cookie);
1036		if (pyself == NULL) {
1037			goto error;
1038		}
1039		pyself = PyObjC_AdjustSelf(pyself);
1040		if (pyself == NULL) {
1041			goto error;
1042		}
1043		if (PyList_Append(arglist, pyself) == -1) {
1044			goto error;
1045		}
1046		startArg = 2;
1047	} else if (userdata->closureType == PyObjC_Block) {
1048		startArg = 1;
1049		pyself = NULL;
1050	} else {
1051		startArg = 0;
1052		pyself = NULL;
1053	}
1054
1055	for (i = startArg; i < Py_SIZE(methinfo); i++) {
1056
1057		const char* argtype = methinfo->argtype[i].type;
1058
1059#if 0
1060		if (argtype[0] == 'O') {
1061			argtype ++;
1062		}
1063#endif
1064
1065		switch (*argtype) {
1066		case _C_INOUT:
1067			if (argtype[1] == _C_PTR) {
1068				have_output ++;
1069			}
1070			/* FALL THROUGH */
1071		case _C_IN: case _C_CONST:
1072			if (argtype[1] == _C_PTR && argtype[2] == _C_VOID && methinfo->argtype[i].ptrType == PyObjC_kPointerPlain) {
1073				/* A plain 'void*' that was marked up.
1074				 * This is wrong, but happens in the official metadata included
1075				 * with 10.5.x
1076				 */
1077				v = pythonify_c_value(argtype, args[i]);
1078			} else if (argtype[1] == _C_PTR || argtype[1] == _C_CHARPTR) {
1079				const char* resttype;
1080
1081				if (argtype[1] == _C_PTR) {
1082					resttype = argtype + 2;
1083				} else {
1084					resttype = gCharEncoding;
1085				}
1086
1087				if (*(void**)args[i] == NULL) {
1088					v = PyObjC_NULL;
1089					Py_INCREF(v);
1090				} else {
1091					switch (methinfo->argtype[i].ptrType) {
1092					case PyObjC_kPointerPlain:
1093						v = pythonify_c_value(resttype,
1094							*(void**)args[i]);
1095						break;
1096
1097					case PyObjC_kNullTerminatedArray:
1098						v = pythonify_c_array_nullterminated(resttype, *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1099						break;
1100
1101					case PyObjC_kArrayCountInArg:
1102						count = extract_count(
1103							methinfo->argtype[methinfo->argtype[i].arrayArg].type,
1104							args[methinfo->argtype[i].arrayArg]);
1105						if (count == -1 && PyErr_Occurred()) {
1106							v = NULL;
1107						} else {
1108							v = PyObjC_CArrayToPython2(resttype, *(void**)args[i], count, methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1109						}
1110						break;
1111
1112					case PyObjC_kFixedLengthArray:
1113						count = methinfo->argtype[i].arrayArg;
1114						v = PyObjC_CArrayToPython2(resttype, *(void**)args[i], count, methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1115						break;
1116
1117					case PyObjC_kVariableLengthArray:
1118						v = PyObjC_VarList_New(resttype, *(void**)args[i]);
1119						break;
1120					}
1121				}
1122
1123			} else {
1124				if (argtype[1] == _C_ARY_B) {
1125					v = pythonify_c_value(argtype+1, *(void**)(args[i]));
1126				} else {
1127					v = pythonify_c_value(argtype+1, args[i]);
1128				}
1129
1130			}
1131			break;
1132
1133		case _C_OUT:
1134			if (argtype[1] == _C_PTR) {
1135				have_output ++;
1136			}
1137
1138			if (userdata->argCount == Py_SIZE(methinfo)-1) {
1139				/* Python method has parameters for the output
1140				 * arguments as well, pass a placeholder value.
1141				 *
1142				 * XXX: For some types of arguments we could
1143				 * well pass in a buffer/array.array-style object!
1144				 */
1145				if (*(void**)args[i] == NULL) {
1146					v = PyObjC_NULL;
1147				} else {
1148					v = Py_None;
1149				}
1150				Py_INCREF(v);
1151			} else {
1152				/* Skip output parameter */
1153				continue;
1154			}
1155			break;
1156
1157		case _C_CHARPTR:
1158			 /* XXX: Not quite happy about this, why special case 'char*' but not 'int*' (both without in/out/inout markup) */
1159			if (*(void**)args[i] == NULL) {
1160				v = PyObjC_NULL;
1161				Py_INCREF(v);
1162			} else {
1163				switch (methinfo->argtype[i].ptrType) {
1164				case PyObjC_kPointerPlain:
1165					v = pythonify_c_value(argtype, args[i]);
1166					break;
1167
1168				case PyObjC_kNullTerminatedArray:
1169					v = pythonify_c_array_nullterminated(argtype, args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1170					break;
1171
1172				case PyObjC_kArrayCountInArg:
1173					count = extract_count(
1174						methinfo->argtype[methinfo->argtype[i].arrayArg].type,
1175						args[methinfo->argtype[i].arrayArg]);
1176					if (count == -1 && PyErr_Occurred()) {
1177						v = NULL;
1178					} else {
1179						v = PyBytes_FromStringAndSize(args[i], count);
1180					}
1181					break;
1182
1183				case PyObjC_kFixedLengthArray:
1184					count = methinfo->argtype[i].arrayArg;
1185					v = PyBytes_FromStringAndSize(args[i], count);
1186					break;
1187
1188				case PyObjC_kVariableLengthArray:
1189					v = PyObjC_VarList_New(gCharEncoding,
1190						args[i]);
1191					break;
1192				}
1193			}
1194			break;
1195
1196		case _C_ARY_B:
1197			/* An array is actually a pointer to the first
1198			 * element of the array. Libffi passes a pointer to
1199			 * that pointer, we need to strip one level of
1200			 * indirection to ensure that pythonify_c_value works
1201			 * correctly.
1202			 */
1203			v = pythonify_c_value(argtype, *(void**)args[i]);
1204			break;
1205
1206		default:
1207			v = pythonify_c_value(argtype, args[i]);
1208		}
1209		if (v == NULL) {
1210			Py_DECREF(arglist);
1211			goto error;
1212		}
1213		if (PyList_Append(arglist, v) == -1) {
1214			Py_DECREF(v);
1215			Py_DECREF(arglist);
1216			goto error;
1217		}
1218		Py_DECREF(v);
1219	}
1220
1221	v = PyList_AsTuple(arglist);
1222	if (v == NULL) {
1223		Py_DECREF(arglist);
1224		if (pyself) {
1225			PyObjCObject_ReleaseTransient(pyself, cookie);
1226		}
1227		goto error;
1228	}
1229	Py_DECREF(arglist);
1230	arglist = v;
1231
1232	if (!callable) {
1233		abort();
1234	}
1235
1236	/* Avoid calling a PyObjCPythonSelector directory, it does
1237	 * additional work that we don't need.
1238	 */
1239	if (PyObjCPythonSelector_Check(callable)) {
1240		callable = ((PyObjCPythonSelector*)callable)->callable;
1241	}
1242
1243	res = PyObject_Call(callable, arglist, NULL);
1244	Py_DECREF(arglist);
1245
1246	if (res == NULL) {
1247		goto error;
1248	}
1249
1250	if (!have_output) {
1251		if (*rettype != _C_VOID) {
1252			const char* unqualified_type = PyObjCRT_SkipTypeQualifiers(rettype);
1253			if (unqualified_type[0] == _C_PTR || unqualified_type[0] == _C_CHARPTR) {
1254				const char* rest = unqualified_type + 1;
1255				if (*unqualified_type == _C_CHARPTR) {
1256					rest = gCharEncoding;
1257				}
1258
1259				if (res == PyObjC_NULL) {
1260					*(void**)resp = NULL;
1261				} else {
1262					switch (methinfo->rettype.ptrType) {
1263					case PyObjC_kPointerPlain:
1264						err = depythonify_c_return_value(unqualified_type, res, resp);
1265						if (err == -1) {
1266							Py_DECREF(res);
1267							goto error;
1268						}
1269						break;
1270
1271					case PyObjC_kFixedLengthArray:
1272						count = methinfo->rettype.arrayArg;
1273						err = depythonify_c_return_array_count(rest, count, res, resp, methinfo->rettype.alreadyRetained, methinfo->rettype.alreadyCFRetained);
1274						if (err == -1) {
1275							Py_DECREF(res);
1276							goto error;
1277						}
1278						break;
1279
1280					case PyObjC_kVariableLengthArray:
1281						err = depythonify_c_return_array_count(rest, -1, res, resp, methinfo->rettype.alreadyRetained, methinfo->rettype.alreadyCFRetained);
1282						if (err == -1) {
1283							Py_DECREF(res);
1284							goto error;
1285						}
1286						break;
1287
1288					case PyObjC_kNullTerminatedArray:
1289						err = depythonify_c_return_array_nullterminated(rest, res, resp, methinfo->rettype.alreadyRetained, methinfo->rettype.alreadyCFRetained);
1290						if (err == -1) {
1291							Py_DECREF(res);
1292							goto error;
1293						}
1294						break;
1295
1296					case PyObjC_kArrayCountInArg:
1297						/* We don't have output arguments, thus can calculate the response immediately */
1298						count = extract_count(
1299							methinfo->argtype[methinfo->rettype.arrayArg].type,
1300							args[methinfo->rettype.arrayArg]);
1301						if (count == -1 && PyErr_Occurred()) {
1302							goto error;
1303						}
1304						err = depythonify_c_return_array_count(rest, count, res, resp, methinfo->rettype.alreadyRetained, methinfo->rettype.alreadyCFRetained);
1305						if (err == -1) {
1306							Py_DECREF(res);
1307							goto error;
1308						}
1309					}
1310				}
1311
1312			} else {
1313				err = depythonify_c_return_value(rettype,
1314					res, resp);
1315
1316				if (methinfo->rettype.alreadyRetained) {
1317				   /* Must return a 'new' instead of a borrowed
1318				    * reference.
1319				    */
1320				   [(*(id*)resp) retain];
1321
1322				} else if (methinfo->rettype.alreadyCFRetained) {
1323				   /* Must return a 'new' instead of a borrowed
1324				    * reference.
1325				    */
1326				   CFRetain((*(id*)resp));
1327
1328				} else if (*rettype == _C_ID && Py_REFCNT(res) == 1) {
1329					/* make sure return value doesn't die before
1330					 * the caller can get its hands on it.
1331					 */
1332				    [[(*(id*)resp) retain] autorelease];
1333				}
1334
1335				if (err == -1) {
1336					if (res == Py_None) {
1337						if (userdata->closureType == PyObjC_Method) {
1338							PyErr_Format(PyExc_ValueError,
1339							   "%s: returned None, expecting "
1340							   "a value",
1341							   sel_getName(*(SEL*)args[1]));
1342						} else {
1343							PyErr_Format(PyExc_ValueError,
1344							   "%R: returned None, expecting "
1345							   "a value",
1346							   userdata->callable);
1347						}
1348
1349					}
1350					Py_DECREF(res);
1351					goto error;
1352				}
1353			}
1354		} else {
1355			if (res != Py_None) {
1356				if (userdata->closureType == PyObjC_Method) {
1357					PyErr_Format(PyExc_ValueError,
1358						"%s: did not return None, expecting "
1359						"void return value",
1360						sel_getName(*(SEL*)args[1]));
1361				} else {
1362					PyErr_Format(PyExc_ValueError,
1363					   "%R: returned None, expecting "
1364					   "a value",
1365					   userdata->callable);
1366				}
1367				goto error;
1368			}
1369			//*((int*)resp) = 0;
1370		}
1371
1372	} else {
1373		/* We have some output parameters, locate them and encode
1374		 * their values
1375		 */
1376		Py_ssize_t idx;
1377		PyObject* real_res;
1378
1379		if (*rettype == _C_VOID && have_output == 1) {
1380			/* Special case: the python method returned only
1381			 * the return value, not a tuple.
1382			 */
1383
1384			for (i = startArg; i < Py_SIZE(methinfo); i++) {
1385				const char* argtype = methinfo->argtype[i].type;
1386
1387				switch (*argtype) {
1388				case _C_INOUT: case _C_OUT:
1389					if (argtype[1] == _C_PTR) {
1390						argtype += 2;
1391					} else if (argtype[1] == _C_CHARPTR) {
1392						argtype = gCharEncoding;
1393					} else {
1394						continue;
1395					}
1396					break;
1397				default: continue;
1398				}
1399
1400				if (*(void**)args[i] == NULL) {
1401					break;
1402				}
1403
1404				switch (methinfo->argtype[i].ptrType) {
1405				case PyObjC_kPointerPlain:
1406					err = depythonify_c_value(argtype, res, *(void**)args[i]);
1407					if (err == -1) {
1408						goto error;
1409					}
1410					if (argtype[0] == _C_ID && methinfo->argtype[i].alreadyRetained) {
1411						[**(id**)args[i] retain];
1412
1413					} else if (argtype[0] == _C_ID && methinfo->argtype[i].alreadyCFRetained) {
1414						CFRetain(**(id**)args[i]);
1415
1416					} else if (Py_REFCNT(res) == 1 && argtype[0] == _C_ID) {
1417						/* make sure return value doesn't die before
1418						 * the caller can get its hands on it.
1419						 */
1420						[[**(id**)args[i] retain] autorelease];
1421					}
1422					break;
1423
1424				case PyObjC_kNullTerminatedArray:
1425					count = c_array_nullterminated_size(res, &seq);
1426					if (count == -1) {
1427						goto error;
1428					}
1429					err = depythonify_c_array_nullterminated(argtype, count, seq, *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1430					Py_DECREF(seq);
1431					if (err == -1) {
1432						goto error;
1433					}
1434					break;
1435
1436				case PyObjC_kArrayCountInArg:
1437					count = extract_count(
1438							methinfo->argtype[methinfo->argtype[i].arrayArg].type,
1439							args[methinfo->argtype[i].arrayArg]);
1440					if (count == -1 && PyErr_Occurred()) {
1441						goto error;
1442					}
1443					err = depythonify_c_array_count(argtype, count, NO, res, *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1444					if (err == -1) {
1445						goto error;
1446					}
1447					break;
1448
1449				case PyObjC_kFixedLengthArray:
1450					count = methinfo->argtype[i].arrayArg;
1451					err = depythonify_c_array_count(argtype, count, YES, res, *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1452					if (err == -1) {
1453						goto error;
1454					}
1455					break;
1456
1457				case PyObjC_kVariableLengthArray:
1458					err = depythonify_c_array_count(argtype, -1, YES, res, *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1459					if (err == -1) {
1460						goto error;
1461					}
1462					break;
1463				}
1464
1465				break;
1466			}
1467
1468			PyGILState_Release(state);
1469			return;
1470		}
1471
1472		if (*rettype != _C_VOID) {
1473			if (!PyTuple_Check(res) || PyTuple_Size(res) != have_output+1) {
1474				PyErr_Format(PyExc_TypeError,
1475					"%s: Need tuple of %d arguments as result",
1476					sel_getName(*(SEL*)args[1]), have_output+1);
1477				Py_DECREF(res);
1478				goto error;
1479			}
1480
1481			real_res = PyTuple_GET_ITEM(res, 0);
1482			idx = 1;
1483
1484			const char* unqualified_type = PyObjCRT_SkipTypeQualifiers(rettype);
1485			if (unqualified_type[0] == _C_PTR || unqualified_type[0] == _C_CHARPTR) {
1486				const char* resttype = rettype + 1;
1487				if (unqualified_type[0] == _C_CHARPTR) {
1488					resttype = gCharEncoding;
1489				}
1490
1491				if (real_res == PyObjC_NULL) {
1492					*(void**)resp = NULL;
1493				} else {
1494					switch (methinfo->rettype.ptrType) {
1495					case PyObjC_kPointerPlain:
1496						err = depythonify_c_return_value(unqualified_type,
1497							real_res, resp);
1498						if (err == -1) {
1499							Py_DECREF(res);
1500							goto error;
1501						}
1502						break;
1503
1504					case PyObjC_kFixedLengthArray:
1505						count = methinfo->rettype.arrayArg;
1506						err = depythonify_c_return_array_count(resttype, count, real_res, resp, methinfo->rettype.alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1507						if (err == -1) {
1508							Py_DECREF(res);
1509							goto error;
1510						}
1511						break;
1512
1513					case PyObjC_kVariableLengthArray:
1514						err = depythonify_c_return_array_count(resttype, -1, real_res, resp, methinfo->rettype.alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1515						if (err == -1) {
1516							Py_DECREF(res);
1517							goto error;
1518						}
1519						break;
1520
1521					case PyObjC_kNullTerminatedArray:
1522						err = depythonify_c_return_array_nullterminated(resttype, real_res, resp, methinfo->rettype.alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1523						if (err == -1) {
1524							Py_DECREF(res);
1525							goto error;
1526						}
1527						break;
1528
1529					case PyObjC_kArrayCountInArg:
1530						if (*PyObjCRT_SkipTypeQualifiers(methinfo->argtype[methinfo->rettype.arrayArg].type) != _C_PTR) {
1531							count = extract_count(
1532								methinfo->argtype[methinfo->rettype.arrayArg].type,
1533								args[methinfo->rettype.arrayArg]);
1534							if (count == -1 && PyErr_Occurred()) {
1535								goto error;
1536							}
1537							err = depythonify_c_return_array_count(resttype, count, real_res, resp, methinfo->rettype.alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1538							if (err == -1) {
1539								Py_DECREF(res);
1540								goto error;
1541							}
1542						} else {
1543							/* Wait until after the arguments have been depythonified */
1544							*(void**)resp = NULL;
1545							break;
1546						}
1547
1548					}
1549				}
1550
1551			} else {
1552				err = depythonify_c_return_value(rettype,
1553					real_res, resp);
1554
1555				if (methinfo->rettype.alreadyRetained) {
1556				   /* Must return a 'new' instead of a borrowed
1557				    * reference.
1558				    */
1559				   [(*(id*)resp) retain];
1560
1561				} else if (methinfo->rettype.alreadyCFRetained) {
1562					CFRetain(*(id*)resp);
1563
1564				} else if (*rettype == _C_ID && Py_REFCNT(real_res) == 1) {
1565					/* make sure return value doesn't die before
1566					 * the caller can get its hands on it.
1567					 */
1568				    [[(*(id*)resp) retain] autorelease];
1569				}
1570				if (err == -1) {
1571					if (real_res == Py_None) {
1572						PyErr_Format(PyExc_ValueError,
1573						   "%s: returned None, expecting "
1574						   "a value",
1575						   sel_getName(*(SEL*)args[1]));
1576					}
1577					Py_DECREF(res);
1578					goto error;
1579				}
1580			}
1581		} else {
1582			if (!PyTuple_Check(res) || PyTuple_Size(res) != have_output) {
1583				PyErr_Format(PyExc_TypeError,
1584					"%s: Need tuple of %d arguments as result",
1585					sel_getName(*(SEL*)args[1]), have_output);
1586				Py_DECREF(res);
1587				goto error;
1588			}
1589			real_res = NULL;
1590			idx = 0;
1591		}
1592
1593		haveCountArg = NO;
1594		for (i = startArg; i < Py_SIZE(methinfo); i++) {
1595			const char* argtype = methinfo->argtype[i].type;
1596
1597			switch (*argtype) {
1598			case _C_INOUT: case _C_OUT:
1599				if (argtype[1] == _C_PTR) {
1600					argtype += 2;
1601				} else if (argtype[1] == _C_CHARPTR) {
1602					argtype ++;
1603				} else {
1604					continue;
1605				}
1606				break;
1607			default: continue;
1608			}
1609
1610			if (*(void**)args[i] == NULL) {
1611				idx++;
1612				continue;
1613			}
1614
1615			switch (methinfo->argtype[i].ptrType) {
1616			case PyObjC_kPointerPlain:
1617				err = depythonify_c_value(argtype, PyTuple_GET_ITEM(res, idx++), *(void**)args[i]);
1618				if (err == -1) {
1619					goto error;
1620				}
1621
1622				if (argtype[0] == _C_ID && methinfo->argtype[i].alreadyRetained) {
1623					[**(id**)args[i] retain];
1624
1625				} else if (argtype[0] == _C_ID && methinfo->argtype[i].alreadyCFRetained) {
1626					CFRetain(**(id**)args[i]);
1627
1628				} else if (Py_REFCNT(res) == 1 && argtype[0] == _C_ID) {
1629					/* make sure return value doesn't die before
1630					 * the caller can get its hands on it.
1631					 */
1632					[[**(id**)args[i] retain] autorelease];
1633				}
1634				break;
1635
1636			case PyObjC_kNullTerminatedArray:
1637				count = c_array_nullterminated_size(PyTuple_GET_ITEM(res, idx++), &seq);
1638				if (count == -1) {
1639					goto error;
1640				}
1641
1642				err = depythonify_c_array_nullterminated(argtype, count, seq, *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1643				Py_DECREF(seq);
1644				if (err == -1) {
1645					goto error;
1646				}
1647				break;
1648
1649			case PyObjC_kArrayCountInArg:
1650				if (methinfo->argtype[i].arraySizeInRetval) {
1651					count = extract_count(methinfo->rettype.type, resp);
1652					if (count == -1 && PyErr_Occurred()) goto error;
1653
1654					err = depythonify_c_array_count(argtype, count, NO, PyTuple_GET_ITEM(res, idx++), *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1655					if (err == -1) {
1656						goto error;
1657					}
1658
1659				} else {
1660					haveCountArg = YES;
1661				}
1662				break;
1663
1664			case PyObjC_kFixedLengthArray:
1665				if (methinfo->argtype[i].arraySizeInRetval) {
1666					count = extract_count(methinfo->rettype.type, resp);
1667					if (count == -1 && PyErr_Occurred()) goto error;
1668
1669				} else {
1670					count = methinfo->argtype[i].arrayArg;
1671				}
1672				err = depythonify_c_array_count(argtype, count, YES, PyTuple_GET_ITEM(res, idx++), *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1673				if (err == -1) {
1674					goto error;
1675				}
1676				break;
1677
1678			case PyObjC_kVariableLengthArray:
1679				if (methinfo->argtype[i].arraySizeInRetval) {
1680					count = extract_count(methinfo->rettype.type, resp);
1681					if (count == -1 && PyErr_Occurred()) goto error;
1682
1683				} else {
1684					count = -1;
1685				}
1686				err = depythonify_c_array_count(argtype, count, YES, PyTuple_GET_ITEM(res, idx++), *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1687				if (err == -1) {
1688					goto error;
1689				}
1690				break;
1691
1692			}
1693		}
1694
1695		if (haveCountArg) {
1696			if (real_res == NULL) {
1697				idx = 0;
1698			} else {
1699				idx = 1;
1700			}
1701			for (i = 2; i < Py_SIZE(methinfo); i++) {
1702				const char* argtype = methinfo->argtype[i].type;
1703
1704				switch (*argtype) {
1705				case _C_INOUT: case _C_OUT:
1706					if (argtype[1] == _C_PTR) {
1707						argtype += 2;
1708					} else if (argtype[1] == _C_CHARPTR) {
1709						argtype ++;
1710					} else {
1711						continue;
1712					}
1713					break;
1714				default: continue;
1715				}
1716
1717				if (*(void**)args[i] == NULL) {
1718					idx++;
1719					continue;
1720				}
1721
1722				switch (methinfo->argtype[i].ptrType) {
1723				case PyObjC_kPointerPlain:
1724				case PyObjC_kNullTerminatedArray:
1725				case PyObjC_kFixedLengthArray:
1726				case PyObjC_kVariableLengthArray:
1727					idx++;
1728					break;
1729
1730				case PyObjC_kArrayCountInArg:
1731					count = extract_count(
1732							methinfo->argtype[methinfo->argtype[i].arrayArg].type,
1733							args[methinfo->argtype[i].arrayArg]);
1734					if (count == -1 && PyErr_Occurred()) {
1735						goto error;
1736					}
1737					err = depythonify_c_array_count(argtype, count, NO, PyTuple_GET_ITEM(res, idx++), *(void**)args[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1738					if (err == -1) {
1739						goto error;
1740					}
1741					break;
1742				}
1743			}
1744		}
1745
1746		if (*rettype != _C_VOID) {
1747			const char* unqualified = PyObjCRT_SkipTypeQualifiers(rettype);
1748			if (unqualified[0] == _C_PTR || unqualified[0] == _C_CHARPTR) {
1749				if (methinfo->rettype.ptrType == PyObjC_kArrayCountInArg) {
1750					const char* rest = unqualified + 1;
1751					if (unqualified[0] == _C_CHARPTR) {
1752						rest = gCharEncoding;
1753					}
1754
1755					count = extract_count(
1756						methinfo->argtype[methinfo->rettype.arrayArg].type,
1757						args[methinfo->rettype.arrayArg]);
1758					if (count == -1 && PyErr_Occurred()) {
1759						goto error;
1760					}
1761					err = depythonify_c_return_array_count(rest, count, real_res, resp, methinfo->rettype.alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
1762					if (err == -1) {
1763						Py_DECREF(res);
1764						goto error;
1765					}
1766				}
1767			}
1768		}
1769
1770	}
1771	Py_DECREF(res);
1772
1773	/* Do this at the end to ensure we work correctly when
1774	 * 'res' is 'pyself' and 'pyself' those are the only
1775	 * references from Python (that is, 'pyself' is a
1776	 * "transient" reference.
1777	 */
1778	if (pyself) {
1779		PyObjCObject_ReleaseTransient(pyself, cookie);
1780	}
1781
1782	PyGILState_Release(state);
1783
1784	return;
1785
1786error:
1787	if (pyself) {
1788		PyObjCObject_ReleaseTransient(pyself, cookie);
1789	}
1790	PyObjCErr_ToObjCWithGILState(&state);
1791}
1792
1793/*
1794 * Return an IMP that is suitable for forwarding a method with the specified
1795 * signature from Objective-C to Python.
1796 */
1797
1798static int _argcount(PyObject* callable, BOOL* haveVarArgs, BOOL* haveVarKwds)
1799{
1800	PyCodeObject *func_code;
1801
1802	if (PyFunction_Check(callable)) {
1803		func_code = (PyCodeObject *)PyFunction_GetCode(callable);
1804		*haveVarArgs = (func_code->co_flags & CO_VARARGS) != 0;
1805		*haveVarKwds = (func_code->co_flags & CO_VARKEYWORDS) != 0;
1806		return func_code->co_argcount;
1807	} else if (PyMethod_Check(callable)) {
1808		func_code = (PyCodeObject *)PyFunction_GetCode(
1809			PyMethod_Function (callable));
1810		*haveVarArgs = (func_code->co_flags & CO_VARARGS) != 0;
1811		*haveVarKwds = (func_code->co_flags & CO_VARKEYWORDS) != 0;
1812		if (PyMethod_Self(callable) == NULL) {
1813			return func_code->co_argcount;
1814		} else {
1815			return func_code->co_argcount - 1;
1816		}
1817	} else if (PyObjCPythonSelector_Check(callable)) {
1818		return _argcount(((PyObjCPythonSelector*)callable)->callable, haveVarArgs, haveVarKwds);
1819
1820
1821	} else if (PyObjCNativeSelector_Check(callable)) {
1822		PyObjCMethodSignature* sig = PyObjCSelector_GetMetadata(callable);
1823		 int result = Py_SIZE(sig) - 1;
1824
1825		 Py_DECREF(sig);
1826		 return result;
1827
1828
1829	} else {
1830		PyErr_Format(PyExc_TypeError,
1831			"Sorry, cannot create IMP for instances of type %s",
1832			Py_TYPE(callable)->tp_name);
1833		return -1;
1834	}
1835}
1836
1837
1838PyObjC_callback_function
1839PyObjCFFI_MakeFunctionClosure(PyObjCMethodSignature* methinfo, PyObject* callable)
1840{
1841	_method_stub_userdata* stubUserdata;
1842	PyObjC_callback_function closure;
1843
1844	stubUserdata = PyMem_Malloc(sizeof(*stubUserdata));
1845	if (stubUserdata == NULL) {
1846		return NULL;
1847	}
1848
1849	stubUserdata->methinfo = methinfo;
1850	Py_INCREF(methinfo);
1851	stubUserdata->closureType = PyObjC_Function;
1852
1853	if (callable) {
1854		BOOL haveVarArgs = NO;
1855		BOOL haveVarKwds = NO;
1856		stubUserdata->argCount = _argcount(callable, &haveVarArgs, &haveVarKwds);
1857		if (stubUserdata->argCount == -1) {
1858			Py_DECREF(methinfo);
1859			PyMem_Free(stubUserdata);
1860			return NULL;
1861		}
1862
1863
1864		if (stubUserdata->argCount == Py_SIZE(methinfo) && !haveVarArgs && !haveVarKwds) {
1865			/* OK */
1866		} else if ((stubUserdata->argCount <= 1) && (haveVarArgs || haveVarKwds)) {
1867			/* OK:
1868			 *    def m(self, *args, **kwds), or
1869			 *    def m(*args, **kwds)
1870			 */
1871		} else {
1872			/* Wrong number of arguments, raise an error */
1873			PyErr_Format(PyObjCExc_BadPrototypeError,
1874				"Objective-C expects %"PY_FORMAT_SIZE_T"d arguments, Python argument has %d arguments for %R",
1875				Py_SIZE(methinfo), stubUserdata->argCount,
1876				callable);
1877			Py_DECREF(methinfo);
1878			PyMem_Free(stubUserdata);
1879			return NULL;
1880		}
1881
1882		stubUserdata->callable = callable;
1883		Py_INCREF(stubUserdata->callable);
1884	} else {
1885		stubUserdata->callable = NULL;
1886		stubUserdata->argCount = 0;
1887	}
1888
1889
1890	closure = (PyObjC_callback_function)PyObjCFFI_MakeClosure(methinfo, method_stub, stubUserdata);
1891	if (closure == NULL) {
1892		Py_DECREF(methinfo);
1893		if (stubUserdata->callable) {
1894			Py_DECREF(stubUserdata->callable);
1895		}
1896		PyMem_Free(stubUserdata);
1897		return NULL;
1898	}
1899
1900	return closure;
1901}
1902
1903
1904static int _coloncount(SEL sel)
1905{
1906	const char* selname = sel_getName(sel);
1907	int result = 0;
1908	while (*selname != 0) {
1909		if (*selname++ == ':') {
1910			result ++;
1911		}
1912	}
1913	return result;
1914}
1915
1916IMP
1917PyObjCFFI_MakeIMPForSignature(PyObjCMethodSignature* methinfo, SEL sel, PyObject* callable)
1918{
1919	_method_stub_userdata* stubUserdata;
1920	IMP closure;
1921
1922	stubUserdata = PyMem_Malloc(sizeof(*stubUserdata));
1923	if (stubUserdata == NULL) {
1924		return NULL;
1925	}
1926
1927	stubUserdata->methinfo = methinfo;
1928	Py_INCREF(methinfo);
1929	stubUserdata->closureType = PyObjC_Method;
1930
1931	if (callable) {
1932		BOOL haveVarArgs = NO;
1933		BOOL haveVarKwds = NO;
1934		stubUserdata->argCount = _argcount(callable, &haveVarArgs, &haveVarKwds);
1935		if (stubUserdata->argCount == -1) {
1936			Py_DECREF(methinfo);
1937			PyMem_Free(stubUserdata);
1938			return NULL;
1939		}
1940
1941		if (stubUserdata->argCount == Py_SIZE(methinfo) - 1&& !haveVarArgs && !haveVarKwds) {
1942			/* OK */
1943		} else if ((stubUserdata->argCount <= 1) && haveVarArgs && haveVarKwds) {
1944			/* OK */
1945		} else {
1946			/* Wrong number of arguments, raise an error */
1947			PyErr_Format(PyObjCExc_BadPrototypeError,
1948				"Objective-C expects %"PY_FORMAT_SIZE_T"d arguments, Python argument has %d arguments for %R",
1949				Py_SIZE(methinfo) - 1, stubUserdata->argCount,
1950				callable);
1951			Py_DECREF(methinfo);
1952			PyMem_Free(stubUserdata);
1953			return NULL;
1954		}
1955
1956		if (!haveVarArgs && !haveVarKwds) {
1957			/* Check if the number of colons is correct */
1958			int cc= _coloncount(sel);
1959
1960			if (cc != 0 && stubUserdata->argCount - 1 != cc) {
1961				PyErr_Format(PyObjCExc_BadPrototypeError,
1962					"Python signature doesn't match implied Objective-C signature for %R",
1963					callable);
1964				Py_DECREF(methinfo);
1965				PyMem_Free(stubUserdata);
1966				return NULL;
1967			}
1968		}
1969
1970		stubUserdata->callable = callable;
1971		Py_INCREF(stubUserdata->callable);
1972	} else {
1973		stubUserdata->callable = NULL;
1974		stubUserdata->argCount = 0;
1975	}
1976
1977
1978
1979	closure = PyObjCFFI_MakeClosure(methinfo, method_stub, stubUserdata);
1980	if (closure == NULL) {
1981		Py_DECREF(methinfo);
1982		if (stubUserdata->callable) {
1983			Py_DECREF(stubUserdata->callable);
1984		}
1985		PyMem_Free(stubUserdata);
1986		return NULL;
1987	}
1988
1989	return closure;
1990}
1991
1992void
1993PyObjCFFI_FreeIMP(IMP imp)
1994{
1995	_method_stub_userdata* userdata = PyObjCFFI_FreeClosure(imp);
1996
1997	if (userdata) {
1998		Py_XDECREF(userdata->methinfo);
1999		Py_DECREF(userdata->callable);
2000		PyMem_Free(userdata);
2001	}
2002}
2003
2004IMP
2005PyObjCFFI_MakeIMPForPyObjCSelector(PyObjCSelector *aSelector)
2006{
2007	if (PyObjCNativeSelector_Check(aSelector)) {
2008		PyObjCNativeSelector *nativeSelector =
2009			(PyObjCNativeSelector *) aSelector;
2010		Method aMeth;
2011
2012		if (nativeSelector->sel_flags & PyObjCSelector_kCLASS_METHOD) {
2013			aMeth = class_getClassMethod(nativeSelector->sel_class, nativeSelector->sel_selector);
2014		} else {
2015			aMeth = class_getInstanceMethod(nativeSelector->sel_class, nativeSelector->sel_selector);
2016		}
2017		return method_getImplementation(aMeth);
2018	} else {
2019		IMP result;
2020
2021		PyObjCPythonSelector *pythonSelector = (PyObjCPythonSelector *) aSelector;
2022		PyObjCMethodSignature* methinfo = PyObjCMethodSignature_ForSelector(
2023				pythonSelector->sel_class,
2024				(pythonSelector->sel_flags & PyObjCSelector_kCLASS_METHOD) != 0,
2025				pythonSelector->sel_selector,
2026				pythonSelector->sel_python_signature,
2027				PyObjCNativeSelector_Check(pythonSelector));
2028
2029		result = PyObjCFFI_MakeIMPForSignature(methinfo, pythonSelector->sel_selector, pythonSelector->callable);
2030		Py_DECREF(methinfo);
2031		return result;
2032	}
2033}
2034
2035
2036PyObjCBlockFunction
2037PyObjCFFI_MakeBlockFunction(PyObjCMethodSignature* methinfo, PyObject* callable)
2038{
2039	_method_stub_userdata* stubUserdata;
2040	PyObjCBlockFunction closure;
2041
2042	stubUserdata = PyMem_Malloc(sizeof(*stubUserdata));
2043	if (stubUserdata == NULL) {
2044		return NULL;
2045	}
2046
2047	stubUserdata->methinfo = methinfo;
2048	Py_INCREF(methinfo);
2049	stubUserdata->closureType = PyObjC_Block;
2050
2051	if (callable) {
2052		BOOL haveVarArgs = NO;
2053		BOOL haveVarKwds = NO;
2054		stubUserdata->argCount = _argcount(callable, &haveVarArgs, &haveVarKwds);
2055		if (stubUserdata->argCount == -1) {
2056			Py_DECREF(methinfo);
2057			PyMem_Free(stubUserdata);
2058			return NULL;
2059		}
2060
2061		if (stubUserdata->argCount == Py_SIZE(methinfo) -1 && !haveVarArgs && !haveVarKwds) {
2062			/* OK */
2063		} else if ((stubUserdata->argCount <= 1) && haveVarArgs && haveVarKwds) {
2064			/* OK */
2065		} else {
2066			/* Wrong number of arguments, raise an error */
2067			PyErr_Format(PyObjCExc_BadPrototypeError,
2068				"Objective-C expects %"PY_FORMAT_SIZE_T"d arguments, Python argument has %d arguments for %R",
2069				Py_SIZE(methinfo) - 1, stubUserdata->argCount,
2070				callable);
2071			Py_DECREF(methinfo);
2072			PyMem_Free(stubUserdata);
2073			return NULL;
2074		}
2075
2076		stubUserdata->callable = callable;
2077		Py_INCREF(stubUserdata->callable);
2078	} else {
2079		stubUserdata->callable = NULL;
2080		stubUserdata->argCount = 0;
2081	}
2082
2083	closure = (PyObjCBlockFunction)PyObjCFFI_MakeClosure(methinfo, method_stub, stubUserdata);
2084	if (closure == NULL) {
2085		Py_DECREF(methinfo);
2086		if (stubUserdata->callable) {
2087			Py_DECREF(stubUserdata->callable);
2088		}
2089		PyMem_Free(stubUserdata);
2090		return NULL;
2091	}
2092
2093	return closure;
2094}
2095
2096void
2097PyObjCFFI_FreeBlockFunction(PyObjCBlockFunction imp)
2098{
2099	_method_stub_userdata* userdata = PyObjCFFI_FreeClosure((IMP)imp);
2100
2101	if (userdata) {
2102		Py_XDECREF(userdata->methinfo);
2103		Py_DECREF(userdata->callable);
2104		PyMem_Free(userdata);
2105	}
2106}
2107
2108/* Count the number of arguments and their total size */
2109/* argument_size is not cleared and should be initialized to the amount of
2110 * bufferspace that will be allocated just before the argument array
2111 */
2112int PyObjCFFI_CountArguments(
2113		PyObjCMethodSignature* methinfo, Py_ssize_t argOffset,
2114		Py_ssize_t* byref_in_count,
2115		Py_ssize_t* byref_out_count,
2116		Py_ssize_t* plain_count,
2117		Py_ssize_t* argbuf_len,
2118		BOOL* variadicAllArgs)
2119{
2120	Py_ssize_t i;
2121	Py_ssize_t itemAlign;
2122	Py_ssize_t itemSize;
2123
2124	*byref_in_count = *byref_out_count = *plain_count = 0;
2125
2126	for (i = argOffset; i < Py_SIZE(methinfo); i++) {
2127		const char *argtype = methinfo->argtype[i].type;
2128#if 0
2129		if (argtype[0] == 'O') {
2130			argtype++;
2131		}
2132#endif
2133
2134		switch (*argtype) {
2135		case _C_INOUT:
2136			if (argtype[1] == _C_PTR && PyObjCPointerWrapper_HaveWrapper(argtype+1)) {
2137				itemAlign = PyObjCRT_AlignOfType(argtype+1);
2138				itemSize = PyObjCRT_SizeOfType(argtype+1);
2139
2140			} else if (argtype[1] == _C_PTR) {
2141				(*byref_out_count) ++;
2142				(*byref_in_count) ++;
2143				itemAlign = PyObjCRT_AlignOfType(argtype+2);
2144				itemSize = PyObjCRT_SizeOfType(argtype+2);
2145				if (itemSize == -1) {
2146					return -1;
2147				}
2148			} else if (argtype[1] == _C_CHARPTR) {
2149				(*byref_out_count) ++;
2150				(*byref_in_count) ++;
2151				itemAlign = PyObjCRT_AlignOfType(gCharEncoding);
2152				itemSize = PyObjCRT_SizeOfType(gCharEncoding);
2153				if (itemSize == -1) {
2154					return -1;
2155				}
2156			} else {
2157				itemSize = PyObjCRT_SizeOfType(argtype+1);
2158				itemAlign = PyObjCRT_AlignOfType(argtype+1);
2159				if (itemSize == -1) {
2160					return -1;
2161				}
2162			}
2163			*argbuf_len = align(*argbuf_len, itemAlign);
2164			(*argbuf_len) += itemSize;
2165			break;
2166
2167		case _C_IN: case _C_CONST:
2168			if (argtype[1] == _C_PTR && argtype[2] == _C_VOID && methinfo->argtype[i].ptrType == PyObjC_kPointerPlain) {
2169				itemSize = PyObjCRT_SizeOfType(argtype);
2170				itemAlign = PyObjCRT_AlignOfType(argtype);
2171				if (itemSize == -1) {
2172					return -1;
2173				}
2174				*argbuf_len = align(*argbuf_len, itemAlign);
2175				(*argbuf_len) += itemSize;
2176				(*plain_count)++;
2177			} else if (argtype[1] == _C_PTR) {
2178				(*byref_in_count) ++;
2179				itemSize = PyObjCRT_SizeOfType(argtype+2);
2180				itemAlign = PyObjCRT_AlignOfType(argtype+2);
2181				if (itemSize == -1) {
2182					return -1;
2183				}
2184			} else if (argtype[1] == _C_CHARPTR) {
2185				(*byref_in_count) ++;
2186				itemAlign = PyObjCRT_AlignOfType(gCharEncoding);
2187				itemSize = PyObjCRT_SizeOfType(gCharEncoding);
2188				if (itemSize == -1) {
2189					return -1;
2190				}
2191			} else {
2192				(*plain_count) ++;
2193				itemSize = PyObjCRT_SizeOfType(argtype+1);
2194				itemAlign = PyObjCRT_AlignOfType(argtype+1);
2195				if (itemSize == -1) {
2196					return -1;
2197				}
2198			}
2199			*argbuf_len = align(*argbuf_len, itemAlign);
2200			(*argbuf_len) += itemSize;
2201			break;
2202
2203		case _C_OUT:
2204			if (argtype[1] == _C_PTR) {
2205				(*byref_out_count) ++;
2206				itemSize = PyObjCRT_SizeOfType(argtype+2);
2207				itemAlign = PyObjCRT_AlignOfType(argtype+2);
2208				if (itemSize == -1) {
2209					return -1;
2210				}
2211			} else if (argtype[1] == _C_CHARPTR) {
2212				(*byref_out_count) ++;
2213				itemAlign = PyObjCRT_AlignOfType(gCharEncoding);
2214				itemSize = PyObjCRT_SizeOfType(gCharEncoding);
2215				if (itemSize == -1) {
2216					return -1;
2217				}
2218			} else {
2219				(*plain_count)++;
2220				itemSize = PyObjCRT_SizeOfType(argtype+1);
2221				itemAlign = PyObjCRT_AlignOfType(argtype+1);
2222				if (itemSize == -1) {
2223					return -1;
2224				}
2225			}
2226			*argbuf_len = align(*argbuf_len, itemAlign);
2227			(*argbuf_len) += itemSize;
2228			break;
2229
2230		case _C_STRUCT_B: case _C_UNION_B: case _C_ARY_B:
2231			(*plain_count)++;
2232			itemSize = PyObjCRT_SizeOfType(argtype);
2233			itemAlign = PyObjCRT_AlignOfType(argtype);
2234			if (itemSize == -1) {
2235				return -1;
2236			}
2237			*argbuf_len = align(*argbuf_len, itemAlign);
2238			(*argbuf_len) += itemSize;
2239			break;
2240
2241#if 0
2242		case _C_UNDEF:
2243			*argbuf_len = align(*argbuf_len, __alignof__(PyObjC_callback_function));
2244			(*argbuf_len) += sizeof(PyObjC_callback_function);
2245			break;
2246#endif
2247
2248		default:
2249			if (methinfo->argtype[i].printfFormat) {
2250				/* XXX: is this still needed? */
2251				*variadicAllArgs = YES;
2252				*argbuf_len += sizeof(NSObject*) * 2;
2253			}
2254			itemSize = PyObjCRT_SizeOfType(argtype);
2255			itemAlign = PyObjCRT_AlignOfType(argtype);
2256			if (itemSize == -1) {
2257				return -1;
2258			}
2259			*argbuf_len = align(*argbuf_len, itemAlign);
2260			(*argbuf_len) += itemSize;
2261			(*plain_count)++;
2262			break;
2263		}
2264	}
2265	return 0;
2266}
2267
2268
2269#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
2270static void imp_capsule_cleanup(void* ptr)
2271{
2272	PyObjCFFI_FreeIMP(ptr);
2273}
2274static void block_capsule_cleanup(void* ptr)
2275{
2276	PyObjCBlock_Release(ptr);
2277}
2278#else
2279static void imp_capsule_cleanup(PyObject* ptr)
2280{
2281	PyObjCFFI_FreeIMP(PyCapsule_GetPointer(ptr, "objc.__imp__"));
2282}
2283static void block_capsule_cleanup(PyObject* ptr)
2284{
2285	PyObjCBlock_Release(PyCapsule_GetPointer(ptr, "objc.__imp__"));
2286}
2287#endif
2288
2289
2290int PyObjCFFI_ParseArguments(
2291		PyObjCMethodSignature* methinfo, Py_ssize_t argOffset,
2292		PyObject* args,
2293		Py_ssize_t argbuf_cur, unsigned char* argbuf,
2294		Py_ssize_t argbuf_len __attribute__((__unused__)), // only used in debug builds
2295		void** byref,
2296		struct byref_attr* byref_attr,
2297		ffi_type** arglist, void** values)
2298{
2299	Py_ssize_t py_arg = 0;
2300	Py_ssize_t i;
2301	void* arg;
2302	Py_ssize_t count;
2303	PyObject* seq;
2304	BOOL have_counted_array = NO;
2305	PyObject* printf_format = NULL;
2306	Py_ssize_t sz;
2307	void* buffer = NULL;
2308	Py_ssize_t bufferlen = 0;
2309
2310	/* We have to do two passes over the argument array: the first to deal
2311	 * with plain arguments, the second deals with arrays whose size is
2312	 * the value of another argument.
2313	 */
2314
2315	Py_ssize_t meth_arg_count;
2316	if (methinfo->variadic && (methinfo->null_terminated_array || (methinfo->arrayArg != -1))) {
2317		meth_arg_count = Py_SIZE(methinfo) - 1;
2318	}  else {
2319		meth_arg_count = Py_SIZE(methinfo);
2320	}
2321
2322
2323	for (i = argOffset; i < meth_arg_count; i++) {
2324
2325		int error = 0;
2326		PyObject *argument = NULL;
2327		const char *argtype = methinfo->argtype[i].type;
2328
2329		if (argtype[0] == _C_OUT && (
2330				(argtype[1] == _C_PTR && !PyObjCPointerWrapper_HaveWrapper(argtype + 1))
2331			     || (argtype[1] == _C_CHARPTR)
2332			)) {
2333			/* Just allocate room in argbuf and set that*/
2334			const char* resttype = argtype+2;
2335			if (argtype[1] == _C_CHARPTR) {
2336				resttype = gCharEncoding;
2337			}
2338
2339			argument = PyTuple_GET_ITEM (args, py_arg);
2340			py_arg ++;
2341
2342			if (argument == Py_None) {
2343				/* Fall through to the default
2344				 * behaviour
2345				 */
2346				error = 1; /* misuse of this flag ... */
2347
2348			} else if (argument == PyObjC_NULL) {
2349				if (methinfo->argtype[i].allowNULL) {
2350
2351					byref[i] = NULL;
2352					arglist[i] = &ffi_type_pointer;
2353					values[i] = byref + i;
2354
2355					error = 0;
2356				} else {
2357					PyErr_Format(
2358						PyExc_ValueError,
2359						"argument %" PY_FORMAT_SIZE_T "d isn't allowed to be NULL",
2360						i - argOffset);
2361					error = -1;
2362				}
2363			} else {
2364
2365				switch (methinfo->argtype[i].ptrType) {
2366				case PyObjC_kFixedLengthArray:
2367				case PyObjC_kVariableLengthArray:
2368				case PyObjC_kArrayCountInArg:
2369					if (PyObject_AsWriteBuffer(argument, &buffer, &bufferlen) != -1) {
2370						error = 1;
2371						break;
2372
2373					} else {
2374						PyErr_Clear();
2375						/* FALL THROUGH */
2376					}
2377
2378				default:
2379					PyErr_Format(
2380						PyExc_ValueError,
2381						"argument %" PY_FORMAT_SIZE_T "d must be None or objc.NULL",
2382						i - argOffset);
2383					error = -1;
2384				}
2385			}
2386
2387			if (error == -1) {
2388				return -1;
2389
2390			}  else if (error == 0) {
2391				continue;
2392
2393			}
2394
2395			switch (methinfo->argtype[i].ptrType) {
2396			case PyObjC_kPointerPlain:
2397				argbuf_cur = align(argbuf_cur,
2398					PyObjCRT_AlignOfType(resttype));
2399				sz = PyObjCRT_SizeOfType(resttype);
2400				byref[i] = PyMem_Malloc(sz);
2401				arg = NULL;
2402
2403				arglist[i] = &ffi_type_pointer;
2404				values[i] = byref+i;
2405
2406				/* Clear the output buffer, just in case the called
2407				 * function doesn't write anything into the buffer.
2408				 */
2409				memset(byref[i], 0, sz);
2410				break;
2411
2412			case PyObjC_kNullTerminatedArray:
2413				PyErr_SetString(PyExc_TypeError,
2414					"NULL-terminated 'out' arguments are not supported");
2415				return -1;
2416
2417			case PyObjC_kFixedLengthArray:
2418				if (PyObject_AsWriteBuffer(argument, &buffer, &bufferlen) != -1) {
2419
2420					count = methinfo->argtype[i].arrayArg;
2421					byref_attr[i].token = PyObjC_PythonToCArray(
2422						YES, YES,
2423						resttype,
2424						argument,
2425						byref + i,
2426						&count,
2427						&byref_attr[i].buffer);
2428					if (byref_attr[i].token == -1) {
2429						return -1;
2430					}
2431
2432
2433				} else {
2434					PyErr_Clear();
2435
2436					sz = PyObjCRT_SizeOfType(resttype) * methinfo->argtype[i].arrayArg;
2437					byref[i] = PyMem_Malloc(sz);
2438					if (byref[i] == NULL) {
2439						PyErr_NoMemory();
2440						return -1;
2441					}
2442					memset(byref[i], 0, sz);
2443				}
2444
2445				arglist[i] = &ffi_type_pointer;
2446				values[i] = byref+i;
2447				break;
2448
2449			case PyObjC_kVariableLengthArray:
2450				if (PyObject_AsWriteBuffer(argument, &buffer, &bufferlen) != -1) {
2451
2452					count = methinfo->argtype[i].arrayArg;
2453					byref_attr[i].token = PyObjC_PythonToCArray(
2454						YES, YES,
2455						resttype,
2456						argument,
2457						byref + i,
2458						NULL,
2459						&byref_attr[i].buffer);
2460					if (byref_attr[i].token == -1) {
2461						return -1;
2462					}
2463
2464
2465				} else {
2466					PyErr_Format(PyExc_TypeError,
2467						"Need explict buffer for variable-length array argument");
2468					return -1;
2469				}
2470
2471				arglist[i] = &ffi_type_pointer;
2472				values[i] = byref+i;
2473				break;
2474
2475			case PyObjC_kArrayCountInArg:
2476				have_counted_array = YES;
2477				break;
2478			}
2479
2480		} else {
2481			/* Encode argument, maybe after allocating space */
2482
2483			if (argtype[0] == _C_OUT) argtype ++; /* XXX: is this correct ???? */
2484
2485			argument = PyTuple_GET_ITEM (args, py_arg);
2486			switch (*argtype) {
2487			case _C_STRUCT_B: case _C_ARY_B: case _C_UNION_B:
2488				/* Allocate space and encode */
2489
2490				sz = PyObjCRT_SizeOfType(argtype);
2491				byref[i] = PyMem_Malloc(sz);
2492				if (byref[i] == NULL) {
2493					PyErr_NoMemory();
2494					return -1;
2495				}
2496				error = depythonify_c_value (
2497					argtype,
2498					argument,
2499					byref[i]);
2500
2501				arglist[i] = signature_to_ffi_type(argtype);
2502
2503				if (*argtype == _C_ARY_B) {
2504					values[i] = &byref[i];
2505				} else {
2506					values[i] = byref[i];
2507				}
2508				break;
2509
2510			case _C_INOUT:
2511			case _C_IN:
2512			case _C_CONST:
2513				if (argtype[1] == _C_PTR && argtype[2] == _C_VOID && methinfo->argtype[i].ptrType == PyObjC_kPointerPlain) {
2514					argbuf_cur = align(argbuf_cur, PyObjCRT_AlignOfType(argtype));
2515					arg = argbuf + argbuf_cur;
2516					argbuf_cur += PyObjCRT_SizeOfType(argtype);
2517					PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
2518
2519					if (methinfo->argtype[i].printfFormat) {
2520						printf_format = argument;
2521						Py_INCREF(argument);
2522					}
2523
2524					error = depythonify_c_value (
2525						argtype,
2526						argument,
2527						arg);
2528
2529					arglist[i] = signature_to_ffi_type(argtype);
2530					values[i] = arg;
2531
2532				} else if (argtype[1] == _C_CHARPTR || (argtype[1] == _C_PTR && !PyObjCPointerWrapper_HaveWrapper(argtype+1))) {
2533					/* Allocate space and encode */
2534					const char* resttype = argtype + 2;
2535					if (argtype[1] == _C_CHARPTR) {
2536						resttype = gCharEncoding;
2537					} else if (argtype[2] == _C_UNDEF) {
2538						/* This better be a function argument, other types of 'undefined' arguments
2539						 * aren't supported.
2540						 */
2541						if (methinfo->argtype[i].callable == NULL) {
2542							PyErr_SetString(PyExc_ValueError, "calling method/function with 'undefined' argument");
2543							return -1;
2544						}
2545						argbuf_cur = align(argbuf_cur, __alignof__(PyObjC_callback_function));
2546						arg = argbuf + argbuf_cur;
2547						argbuf_cur += sizeof(PyObjC_callback_function);
2548						PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
2549						arglist[i] = signature_to_ffi_type(argtype);
2550						values[i] = arg;
2551
2552						if (argument == Py_None) {
2553							*(PyObjC_callback_function*)arg = NULL;
2554
2555						} else {
2556							PyObjC_callback_function closure;
2557							PyObject* v = PyObject_GetAttrString(argument, "pyobjc_closure");
2558							if (v == NULL) {
2559								if (!methinfo->argtype[i].callableRetained) {
2560									/* The callback isn't retained by the called function,
2561									 * therefore we can safely synthesize a closure and
2562									 * clean it up after the call.
2563									 */
2564									PyErr_Clear();
2565
2566									closure = PyObjCFFI_MakeFunctionClosure(
2567											methinfo->argtype[i].callable,
2568											argument
2569										);
2570									if (closure == NULL) {
2571										return -1;
2572									}
2573									byref_attr[i].buffer = PyCapsule_New(
2574										closure,
2575										"objc.__imp__",
2576										imp_capsule_cleanup);
2577								} else {
2578									PyErr_SetString(PyExc_TypeError,
2579										"Callable argument is not a PyObjC closure");
2580									return -1;
2581								}
2582
2583							} else {
2584								if (!PyCapsule_CheckExact(v)) {
2585									PyErr_SetString(PyExc_TypeError,
2586										"Invalid pyobjc_closure attribute");
2587								}
2588								closure = PyCapsule_GetPointer(v, "objc.__imp__");
2589								if (closure == NULL) {
2590									PyErr_SetString(PyExc_TypeError,
2591										"Invalid pyobjc_closure attribute");
2592								}
2593							}
2594							*(PyObjC_callback_function*)arg = closure;
2595						}
2596						break;
2597					}
2598
2599					if (argument == PyObjC_NULL || argument == Py_None) {
2600						if (methinfo->argtype[i].allowNULL) {
2601
2602							byref[i] = NULL;
2603							error = 0;
2604						} else {
2605							PyErr_Format(
2606								PyExc_ValueError,
2607								"argument %" PY_FORMAT_SIZE_T "d isn't allowed to be NULL", i - argOffset);
2608							error = -1;
2609						}
2610
2611					} else {
2612						switch (methinfo->argtype[i].ptrType) {
2613						case PyObjC_kPointerPlain:
2614							byref[i] = PyMem_Malloc(PyObjCRT_SizeOfType(resttype));
2615							error = depythonify_c_value (
2616								resttype,
2617								argument,
2618								byref[i]);
2619							break;
2620
2621
2622						case PyObjC_kFixedLengthArray:
2623							count = methinfo->argtype[i].arrayArg;
2624
2625							byref_attr[i].token = PyObjC_PythonToCArray(
2626								argtype[0] == _C_INOUT, YES,
2627								resttype,
2628								argument,
2629								byref + i,
2630								&count,
2631								&byref_attr[i].buffer);
2632							if (byref_attr[i].token == -1) {
2633								error = -1;
2634							} else {
2635								error = 0;
2636							}
2637							break;
2638
2639						case PyObjC_kVariableLengthArray:
2640							 /* TODO: add explicit support for UniChar arrays */
2641							byref_attr[i].token = PyObjC_PythonToCArray(
2642									argtype[0] == _C_INOUT, YES,
2643									resttype,
2644									argument,
2645									byref + i,
2646									NULL,
2647									&byref_attr[i].buffer);
2648							if (byref_attr[i].token == -1) {
2649								error = -1;
2650							} else {
2651								error = 0;
2652							}
2653							break;
2654
2655						case PyObjC_kNullTerminatedArray:
2656							 /* TODO: add explicit support for UniChar arrays */
2657							if (*resttype == _C_CHAR_AS_TEXT && PyBytes_Check(argument)) {
2658								byref[i] = PyMem_Malloc(PyBytes_Size(argument) + 1);
2659								memcpy(byref[i], PyBytes_AsString(argument), PyBytes_Size(argument));
2660								((char*)(byref[i]))[PyBytes_Size(argument)] = '\0';
2661
2662							} else {
2663								seq = NULL;
2664								count = c_array_nullterminated_size(argument, &seq);
2665								if (seq == NULL) {
2666									error = -1;
2667								} else {
2668									byref[i] = PyMem_Malloc(count * PyObjCRT_SizeOfType(resttype));
2669									if (byref[i] == NULL) {
2670										PyErr_NoMemory();
2671										error = -1;
2672									} else {
2673										error = depythonify_c_array_nullterminated(resttype,
2674											count,
2675											seq,
2676											byref[i], methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
2677									}
2678									Py_DECREF(seq);
2679								}
2680							}
2681							break;
2682
2683						case PyObjC_kArrayCountInArg:
2684							have_counted_array = YES;
2685							error = 0;
2686							break;
2687
2688
2689						default:
2690							Py_FatalError("Corrupt metadata!");
2691						}
2692					}
2693
2694					arglist[i] = &ffi_type_pointer;
2695					values[i] = byref + i;
2696
2697				} else {
2698					/* just encode */
2699					argbuf_cur = align(argbuf_cur, PyObjCRT_AlignOfType(argtype+1));
2700					arg = argbuf + argbuf_cur;
2701					argbuf_cur += PyObjCRT_SizeOfType(argtype+1);
2702					PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
2703
2704					if (methinfo->argtype[i].printfFormat) {
2705						printf_format = argument;
2706						Py_INCREF(argument);
2707					}
2708					error = depythonify_c_value (
2709						argtype+1,
2710						argument,
2711						arg);
2712
2713					arglist[i] = signature_to_ffi_type(
2714						argtype+1);
2715					values[i] = arg;
2716
2717				}
2718				break;
2719
2720			case _C_CHARPTR:
2721
2722				arglist[i] = NULL;
2723				if (argument == PyObjC_NULL) {
2724					if (methinfo->argtype[i].allowNULL) {
2725
2726						byref[i] = NULL;
2727						error = 0;
2728					} else {
2729						PyErr_Format(
2730							PyExc_ValueError,
2731							"argument %" PY_FORMAT_SIZE_T "d isn't allowed to be NULL", i - argOffset);
2732						error = -1;
2733					}
2734
2735				} else {
2736					switch (methinfo->argtype[i].ptrType) {
2737					case PyObjC_kPointerPlain:
2738						argbuf_cur = align(argbuf_cur, PyObjCRT_AlignOfType(argtype));
2739						arg = argbuf + argbuf_cur;
2740						argbuf_cur += PyObjCRT_SizeOfType(argtype);
2741						PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
2742
2743						if (methinfo->argtype[i].printfFormat) {
2744							printf_format = argument;
2745							Py_INCREF(argument);
2746
2747						}
2748						error = depythonify_c_value (
2749							argtype,
2750							argument,
2751							arg);
2752
2753						arglist[i] = signature_to_ffi_type(argtype);
2754						values[i] = arg;
2755						break;
2756
2757
2758					case PyObjC_kFixedLengthArray:
2759						{
2760						char resttype[] = {  _C_CHR, 0 };
2761						count = methinfo->argtype[i].arrayArg;
2762						byref_attr[i].token = PyObjC_PythonToCArray(
2763							NO, YES,
2764							resttype,
2765							argument,
2766							byref + i,
2767							&count,
2768							&byref_attr[i].buffer);
2769						}
2770						if (byref_attr[i].token == -1) {
2771							error = -1;
2772						}
2773						break;
2774
2775					case PyObjC_kVariableLengthArray:
2776						{
2777							const char* buf;
2778							Py_ssize_t len;
2779
2780							error = PyObject_AsCharBuffer(argument, &buf, &len);
2781							if (error != -1) {
2782								byref[i] = PyMem_Malloc(len);
2783								if (byref[i] == NULL) {
2784									PyErr_NoMemory();
2785									error = -1;
2786								} else {
2787									memcpy(byref[i], buf, len);
2788									error = 0;
2789								}
2790							} else {
2791								/* XXX */
2792								error = -1;
2793							}
2794
2795						}
2796
2797						break;
2798
2799					case PyObjC_kNullTerminatedArray:
2800						{
2801							const char* buf;
2802							Py_ssize_t len;
2803
2804							error = PyObject_AsCharBuffer(argument, &buf, &len);
2805							if (error != -1) {
2806								byref[i] = PyMem_Malloc(len+1);
2807								if (byref[i] == NULL) {
2808									PyErr_NoMemory();
2809									error = -1;
2810								} else {
2811									memcpy(byref[i], buf, len);
2812									((char*)byref[i])[len] = '\0';
2813								}
2814							} else {
2815								error = -1;
2816							}
2817						}
2818						break;
2819
2820					case PyObjC_kArrayCountInArg:
2821						have_counted_array = YES;
2822						error = 0;
2823						break;
2824
2825
2826					default:
2827						Py_FatalError("Corrupt metadata!");
2828					}
2829				}
2830
2831				if (arglist[i] == NULL) {
2832					arglist[i] = &ffi_type_pointer;
2833					values[i] = byref + i;
2834				}
2835				break;
2836
2837			case _C_PTR:
2838				if (argtype[1] == _C_UNDEF) {
2839					/* This better be a function argument, other types of 'undefined' arguments
2840					 * aren't supported.
2841					 */
2842					if (methinfo->argtype[i].callable == NULL) {
2843						PyErr_SetString(PyExc_ValueError, "calling method/function with 'undefined' argument");
2844						return -1;
2845					}
2846					argbuf_cur = align(argbuf_cur, __alignof__(PyObjC_callback_function));
2847					arg = argbuf + argbuf_cur;
2848					argbuf_cur += sizeof(PyObjC_callback_function);
2849					PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
2850					arglist[i] = signature_to_ffi_type(argtype);
2851					values[i] = arg;
2852
2853					if (argument == Py_None) {
2854						*(PyObjC_callback_function*)arg = NULL;
2855
2856					} else {
2857						PyObjC_callback_function closure;
2858						PyObject* v = PyObject_GetAttrString(argument, "pyobjc_closure");
2859						if (v == NULL) {
2860							if (!methinfo->argtype[i].callableRetained) {
2861								/* The callback isn't retained by the called function,
2862								 * therefore we can safely synthesize a closure and
2863								 * clean it up after the call.
2864								 */
2865								PyErr_Clear();
2866
2867								closure = PyObjCFFI_MakeFunctionClosure(
2868										methinfo->argtype[i].callable,
2869										argument
2870									);
2871								if (closure == NULL) {
2872									return -1;
2873								}
2874								byref_attr[i].buffer = PyCapsule_New(
2875									closure,
2876									"objc.__imp__",
2877									imp_capsule_cleanup);
2878							} else {
2879								PyErr_SetString(PyExc_TypeError,
2880									"Callable argument is not a PyObjC closure");
2881								return -1;
2882							}
2883
2884						} else {
2885							if (!PyCapsule_CheckExact(v)) {
2886								PyErr_SetString(PyExc_TypeError,
2887									"Invalid pyobjc_closure attribute");
2888							}
2889							closure = PyCapsule_GetPointer(v, "objc.__imp__");
2890							if (closure == NULL) {
2891								PyErr_SetString(PyExc_TypeError,
2892									"Invalid pyobjc_closure attribute");
2893							}
2894						}
2895						*(PyObjC_callback_function*)arg = closure;
2896					}
2897					break;
2898				} else {
2899					/* FALL THROUGH */
2900				}
2901
2902
2903			case _C_ID:
2904				if (argtype[1] == '?') {
2905					/* Argument is a block */
2906					if (methinfo->argtype[i].callable == NULL) {
2907						PyErr_Format(PyExc_TypeError, "Argument %"PY_FORMAT_SIZE_T"d is a block, but no signature available", i);
2908						return -1;
2909					}
2910					argbuf_cur = align(argbuf_cur, PyObjCRT_AlignOfType(argtype));
2911					arg = argbuf + argbuf_cur;
2912					argbuf_cur += PyObjCRT_SizeOfType(argtype);
2913					PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
2914					*(void**)arg = PyObjCBlock_Create(
2915						methinfo->argtype[i].callable, argument);
2916					if (*(void**)arg == NULL) {
2917						return -1;
2918					}
2919					byref_attr[i].buffer = PyCapsule_New(
2920						*(void**)arg,
2921						"objc.__block__",
2922						block_capsule_cleanup);
2923					arglist[i] = signature_to_ffi_type(argtype);
2924					values[i] = arg;
2925
2926					break;
2927				}
2928				/* else: fallthrough */
2929
2930			default:
2931				argbuf_cur = align(argbuf_cur, PyObjCRT_AlignOfType(argtype));
2932				arg = argbuf + argbuf_cur;
2933				argbuf_cur += PyObjCRT_SizeOfType(argtype);
2934				PyObjC_Assert(argbuf_cur <= argbuf_len, -1);
2935
2936				if (methinfo->argtype[i].printfFormat) {
2937					printf_format = argument;
2938					Py_INCREF(argument);
2939				}
2940
2941				error = depythonify_c_value (
2942					argtype,
2943					argument,
2944					arg);
2945
2946				arglist[i] = signature_to_ffi_type(argtype);
2947				values[i] = arg;
2948			}
2949
2950			if (error == -1) {
2951				return -1;
2952			}
2953			py_arg++;
2954		}
2955	}
2956
2957	if (have_counted_array) {
2958		py_arg = 0;
2959
2960		for (i = argOffset; i < meth_arg_count; i++) {
2961			PyObject *argument = NULL;
2962			const char *argtype = methinfo->argtype[i].type;
2963
2964			if (argtype[0] == _C_OUT && (argtype[1] == _C_PTR || argtype[1] == _C_CHARPTR)) {
2965				argument = PyTuple_GET_ITEM (args, py_arg);
2966				py_arg ++;
2967
2968				const char* resttype = argtype+2;
2969				if (argtype[1] == _C_CHARPTR) {
2970					resttype = gCharEncoding;
2971				}
2972
2973				if (methinfo->argtype[i].ptrType == PyObjC_kArrayCountInArg) {
2974					count = extract_count(
2975							methinfo->argtype[methinfo->argtype[i].arrayArg].type,
2976							values[methinfo->argtype[i].arrayArg]);
2977					if (count == -1 && PyErr_Occurred()) {
2978						return -1;
2979					}
2980					if (argument && (PyObject_AsWriteBuffer(argument, &buffer, &bufferlen) != -1)) {
2981						byref_attr[i].token = PyObjC_PythonToCArray(
2982							YES, YES,
2983							resttype,
2984							argument,
2985							byref + i,
2986							&count,
2987							&byref_attr[i].buffer);
2988						if (byref_attr[i].token == -1) {
2989							return -1;
2990						}
2991					} else {
2992						PyErr_Clear();
2993
2994						byref[i] = PyMem_Malloc(count * PyObjCRT_SizeOfType(resttype));
2995						if (byref[i] == NULL) {
2996							PyErr_NoMemory();
2997							return -1;
2998						} else {
2999							memset(byref[i], 0, count * PyObjCRT_SizeOfType(resttype));
3000						}
3001					}
3002				}
3003
3004				arglist[i] = &ffi_type_pointer;
3005				values[i] = byref + i;
3006
3007			} else {
3008				/* Encode argument, maybe after allocating space */
3009				if (argtype[0] == _C_OUT) argtype ++;
3010
3011				argument = PyTuple_GET_ITEM (args, py_arg);
3012				py_arg ++;
3013
3014				switch (*argtype) {
3015				case _C_INOUT:
3016				case _C_IN:
3017				case _C_CONST:
3018					if (argtype[1] == _C_PTR || argtype[1] == _C_CHARPTR) {
3019						/* Allocate space and encode */
3020						const char* resttype = argtype+2;
3021						if (argtype[1] == _C_CHARPTR) {
3022							resttype = gCharEncoding;
3023						}
3024
3025						if (argument != PyObjC_NULL) {
3026							switch (methinfo->argtype[i].ptrType) {
3027							case PyObjC_kPointerPlain:
3028							case PyObjC_kNullTerminatedArray:
3029							case PyObjC_kFixedLengthArray:
3030							case PyObjC_kVariableLengthArray:
3031								/* To keep the compiler happy */
3032								break;
3033
3034							case PyObjC_kArrayCountInArg:
3035								count = extract_count(
3036										methinfo->argtype[methinfo->argtype[i].arrayArg].type,
3037										values[methinfo->argtype[i].arrayArg]);
3038								if (count == -1 && PyErr_Occurred()) {
3039									return -1;
3040								}
3041
3042								byref_attr[i].token = PyObjC_PythonToCArray(
3043									argtype[0] == _C_INOUT, NO,
3044									resttype,
3045									argument,
3046									byref + i,
3047									&count,
3048									&byref_attr[i].buffer);
3049								if (byref_attr[i].token == -1) {
3050									return -1;
3051								}
3052
3053								arglist[i] = &ffi_type_pointer;
3054								values[i] = byref + i;
3055								break;
3056							}
3057						}
3058					}
3059					break;
3060
3061				case _C_CHARPTR:
3062					if (argument != PyObjC_NULL) {
3063						switch (methinfo->argtype[i].ptrType) {
3064						case PyObjC_kPointerPlain:
3065						case PyObjC_kNullTerminatedArray:
3066						case PyObjC_kFixedLengthArray:
3067						case PyObjC_kVariableLengthArray:
3068							/* To keep the compiler happy */
3069							break;
3070
3071						case PyObjC_kArrayCountInArg:
3072							count = extract_count(
3073									methinfo->argtype[methinfo->argtype[i].arrayArg].type,
3074									values[methinfo->argtype[i].arrayArg]);
3075							if (count == -1 && PyErr_Occurred()) {
3076								return -1;
3077							}
3078							byref_attr[i].token = PyObjC_PythonToCArray(
3079									NO, NO,
3080									gCharEncoding,
3081									argument,
3082									byref + i,
3083									&count,
3084									&byref_attr[i].buffer);
3085							if (byref_attr[i].token == -1) {
3086								return -1;
3087							}
3088							arglist[i] = &ffi_type_pointer;
3089							values[i] = byref + i;
3090						}
3091					}
3092				}
3093			}
3094		}
3095	}
3096
3097	if (printf_format) {
3098		int r;
3099
3100		r = parse_printf_args(
3101			printf_format,
3102			args, py_arg,
3103			byref, byref_attr,
3104			arglist, values,
3105			Py_SIZE(methinfo));
3106		if (r == -1) {
3107			return -1;
3108		}
3109		Py_DECREF(printf_format);
3110		printf_format = NULL;
3111
3112		return r;
3113	} else if (methinfo->variadic && methinfo->null_terminated_array) {
3114		int r;
3115
3116		r = parse_varargs_array(
3117				methinfo,
3118				args, py_arg, byref,
3119				arglist, values, -1);
3120		if (r == -1) {
3121			return -1;
3122		}
3123		return r;
3124	} else if (methinfo->variadic && methinfo->arrayArg != -1) {
3125		int r;
3126		Py_ssize_t cnt = extract_count(
3127			methinfo->argtype[methinfo->arrayArg].type,
3128			values[methinfo->arrayArg]);
3129		if (cnt == -1) {
3130			return -1;
3131		}
3132
3133		r = parse_varargs_array(
3134				methinfo,
3135				args, py_arg, byref,
3136				arglist, values, cnt);
3137		if (r == -1) {
3138			return -1;
3139		}
3140		return r;
3141	}
3142
3143	return Py_SIZE(methinfo);
3144}
3145
3146
3147PyObject*
3148PyObjCFFI_BuildResult(
3149	PyObjCMethodSignature* methinfo, Py_ssize_t argOffset,
3150	void* pRetval, void** byref, struct byref_attr* byref_attr,
3151	Py_ssize_t byref_out_count, PyObject* self, int flags,
3152	void** argvalues)
3153{
3154	PyObject* objc_result = NULL;
3155	PyObject* result = NULL;
3156	int py_arg;
3157	void* arg;
3158	Py_ssize_t i;
3159	Py_ssize_t count;
3160
3161	if ( (*methinfo->rettype.type != _C_VOID) /* && (![methinfo isOneway]) */ ) {
3162		const char* tp = methinfo->rettype.type;
3163		BOOL isOut = NO;
3164
3165		if (tp[0] == _C_CONST) {
3166			tp++;
3167		}
3168
3169		if (tp[0] == _C_OUT) {
3170			isOut = YES;
3171			tp++;
3172		}
3173
3174		/* Pointer values: */
3175		if (tp[0] == _C_PTR && tp[1] == _C_UNDEF && methinfo->rettype.callable) {
3176			if (*(void**)pRetval == NULL) {
3177				objc_result = Py_None;
3178				Py_INCREF(Py_None);
3179			} else {
3180				objc_result = PyObjCFunc_WithMethodSignature(NULL, *(void**)pRetval, methinfo->rettype.callable);
3181				if (objc_result == NULL) {
3182					return NULL;
3183				}
3184			}
3185
3186		} else if (*tp == _C_CHARPTR || (*tp == _C_PTR && !PyObjCPointerWrapper_HaveWrapper(tp))) {
3187			const char* resttype = tp + 1;
3188			if (*tp == _C_CHARPTR) {
3189				resttype = gCharEncoding;
3190			}
3191
3192			if (isOut) {
3193				objc_result = pythonify_c_return_value (resttype, *(void**)pRetval);
3194				if (objc_result == NULL) {
3195					return NULL;
3196				}
3197
3198				if (methinfo->rettype.alreadyRetained) {
3199					if (PyObjCObject_Check(objc_result)) {
3200						/* pythonify_c_return_value has retained the object, but we already
3201						 * own a reference, therefore give the ref away again
3202						 */
3203						[PyObjCObject_GetObject(objc_result) release];
3204					}
3205				}
3206				if (methinfo->rettype.alreadyCFRetained) {
3207					if (PyObjCObject_Check(objc_result)) {
3208						/* pythonify_c_return_value has retained the object, but we already
3209						 * own a reference, therefore give the ref away again
3210						 */
3211						CFRelease(PyObjCObject_GetObject(objc_result));
3212					}
3213				}
3214
3215
3216			} else {
3217
3218				switch (methinfo->rettype.ptrType) {
3219				case PyObjC_kPointerPlain:
3220					/* Fall through to default behaviour */
3221					break;
3222				case PyObjC_kNullTerminatedArray:
3223					if (*(void**)pRetval == NULL) {
3224						Py_INCREF(PyObjC_NULL);
3225						objc_result = PyObjC_NULL;
3226					} else {
3227						objc_result = pythonify_c_array_nullterminated(resttype, *(void**)pRetval, methinfo->rettype.alreadyRetained, methinfo->rettype.alreadyCFRetained);
3228						if (objc_result == NULL) {
3229							return NULL;
3230						}
3231					}
3232					break;
3233
3234				case PyObjC_kFixedLengthArray:
3235					if (*(void**)pRetval == NULL) {
3236						Py_INCREF(PyObjC_NULL);
3237						objc_result = PyObjC_NULL;
3238
3239					} else {
3240						objc_result = PyObjC_CArrayToPython2(
3241							resttype,
3242							*(void**)pRetval,
3243							methinfo->rettype.arrayArg, methinfo->rettype.alreadyRetained, methinfo->rettype.alreadyCFRetained);
3244						if (objc_result == NULL) {
3245							return NULL;
3246						}
3247					}
3248					break;
3249
3250				case PyObjC_kVariableLengthArray:
3251					/* FIXME: explict support for UniChar buffers */
3252					if (*(void**)pRetval == NULL) {
3253						Py_INCREF(PyObjC_NULL);
3254						objc_result = PyObjC_NULL;
3255					} else {
3256						objc_result = PyObjC_VarList_New(resttype, *(void**)pRetval);
3257					}
3258					break;
3259
3260				case PyObjC_kArrayCountInArg:
3261
3262					if (*(void**)pRetval == NULL) {
3263						Py_INCREF(PyObjC_NULL);
3264						objc_result = PyObjC_NULL;
3265					} else {
3266						count = extract_count(methinfo->argtype[methinfo->rettype.arrayArg].type, argvalues[methinfo->rettype.arrayArg]);
3267						if (count == -1 && PyErr_Occurred()) {
3268								return NULL;
3269						}
3270
3271						objc_result = PyObjC_CArrayToPython2(
3272							resttype,
3273							*(void**)pRetval,
3274							count, methinfo->rettype.alreadyRetained, methinfo->rettype.alreadyCFRetained);
3275
3276						if (objc_result == NULL) {
3277							return NULL;
3278						}
3279					}
3280					break;
3281
3282				default:
3283					PyErr_Format(PyExc_SystemError,
3284						"Unhandled pointer type: %d",
3285						methinfo->rettype.ptrType);
3286					return NULL;
3287				}
3288
3289				if (methinfo->free_result) {
3290					free(*(void**)pRetval);
3291				}
3292
3293			}
3294	 	}
3295
3296		/* default behaviour: */
3297		if (objc_result == NULL) {
3298			if (tp[0] == _C_ID && tp[1] == '?') {
3299				/* The value is a block, those values are
3300				 * treated slightly differently than normal:
3301				 * - always use -copy on them to ensure we
3302				 *   can safely store them.
3303				 * - try to attach the calling signature to the
3304				 *   block.
3305				 */
3306				id v = [*(id*)pRetval copy];
3307				objc_result = pythonify_c_return_value (tp, &v);
3308				[v release];
3309				if (objc_result == NULL) {
3310					return NULL;
3311				}
3312
3313				if (PyObjCObject_IsBlock(objc_result) && PyObjCObject_GetBlock(objc_result) == NULL) {
3314					/* Result is an (Objective-)C block for which we don't have a Python signature
3315					 *
3316					 * 1) Try to extract from the metadata system
3317					 * 2) Try to extract from the ObjC runtime
3318					 *
3319					 * Both systems may not have the required information.
3320					 */
3321
3322					if (methinfo->rettype.callable != NULL) {
3323						PyObjCObject_SET_BLOCK(objc_result, methinfo->rettype.callable);
3324						Py_INCREF(methinfo->rettype.callable);
3325					} else {
3326						const char* signature = PyObjCBlock_GetSignature(objc_result);
3327						if (signature != NULL) {
3328							PyObjCMethodSignature* sig = PyObjCMethodSignature_WithMetaData(signature, NULL, YES);
3329							if (sig == NULL) {
3330								Py_DECREF(objc_result);
3331								return NULL;
3332							}
3333							PyObjCObject_SET_BLOCK(objc_result, sig);
3334							sig = NULL;
3335						}
3336					}
3337				}
3338			} else {
3339
3340				objc_result = pythonify_c_return_value (tp, pRetval);
3341				if (objc_result == NULL) {
3342					return NULL;
3343				}
3344
3345			}
3346
3347			if (methinfo->rettype.alreadyRetained) {
3348				if (PyObjCObject_Check(objc_result)) {
3349					/* pythonify_c_return_value has retained the object, but we already
3350					 * own a reference, therefore give the ref away again
3351					 */
3352					[PyObjCObject_GetObject(objc_result) release];
3353				}
3354			}
3355			if (methinfo->rettype.alreadyCFRetained) {
3356				if (PyObjCObject_Check(objc_result)) {
3357					/* pythonify_c_return_value has retained the object, but we already
3358					 * own a reference, therefore give the ref away again
3359					 */
3360					CFRelease(PyObjCObject_GetObject(objc_result));
3361				}
3362			}
3363		}
3364	} else {
3365		Py_INCREF(Py_None);
3366		objc_result =  Py_None;
3367	}
3368
3369	/* XXX: This is for selectors only, need to change this !!!! */
3370
3371	if (self != NULL && objc_result != self
3372		&& PyObjCObject_Check(self) && PyObjCObject_Check(objc_result)
3373		&& !(flags & PyObjCSelector_kRETURNS_UNINITIALIZED)
3374		&& (((PyObjCObject*)self)->flags & PyObjCObject_kUNINITIALIZED)) {
3375		[PyObjCObject_GetObject(objc_result) release];
3376		PyObjCObject_ClearObject(self);
3377	}
3378
3379	if (byref_out_count == 0) {
3380		return objc_result;
3381
3382	} else {
3383
3384		if (*methinfo->rettype.type == _C_VOID) {
3385			if (byref_out_count > 1) {
3386				result = PyTuple_New(byref_out_count);
3387				if (result == NULL) {
3388					return NULL;
3389				}
3390			} else {
3391				result = NULL;
3392			}
3393			Py_DECREF(objc_result);
3394			py_arg = 0;
3395		} else {
3396			result = PyTuple_New(byref_out_count+1);
3397			if (result == NULL) {
3398				return NULL;
3399			}
3400			PyTuple_SET_ITEM(result, 0, objc_result);
3401			py_arg = 1;
3402		}
3403		objc_result = NULL;
3404
3405		for (i = argOffset; i < Py_SIZE(methinfo); i++) {
3406			const char *argtype = methinfo->argtype[i].type;
3407			PyObject*   v = NULL;
3408
3409			switch (*argtype) {
3410			case _C_INOUT:
3411			case _C_OUT:
3412				if (argtype[1] == _C_CHARPTR || (argtype[1] == _C_PTR && !PyObjCPointerWrapper_HaveWrapper(argtype+1))) {
3413					const char* resttype = argtype+2;
3414					if (argtype[1] == _C_CHARPTR) {
3415						resttype = gCharEncoding;
3416					}
3417
3418					arg = byref[i];
3419
3420					if (arg == NULL) {
3421						v = PyObjC_NULL;
3422						Py_INCREF(v);
3423
3424					} else if (byref_attr[i].buffer != NULL) {
3425						v = byref_attr[i].buffer;
3426						Py_INCREF(v);
3427
3428					} else {
3429						switch (methinfo->argtype[i].ptrType) {
3430						case PyObjC_kPointerPlain:
3431
3432							if (resttype[0] == _C_ID && resttype[1] == '?') {
3433								id tmp = [*(id*)arg copy];
3434								v = pythonify_c_value(resttype, &tmp);
3435								[tmp release];
3436
3437								if (methinfo->argtype[i].callable != NULL) {
3438									if (PyObjCObject_IsBlock(v) && PyObjCObject_GetBlock(v) == NULL) {
3439										PyObjCObject_SET_BLOCK(v, methinfo->argtype[i].callable);
3440										Py_INCREF(methinfo->argtype[i].callable);
3441									}
3442								}
3443							} else {
3444								v = pythonify_c_value(resttype, arg);
3445							}
3446							if (methinfo->argtype[i].alreadyRetained && PyObjCObject_Check(v)) {
3447								[PyObjCObject_GetObject(v) release];
3448							}
3449							if (methinfo->argtype[i].alreadyCFRetained && PyObjCObject_Check(v)) {
3450								CFRelease(PyObjCObject_GetObject(v));
3451							}
3452							if (!v) goto error_cleanup;
3453							break;
3454
3455						case PyObjC_kFixedLengthArray:
3456							if (methinfo->argtype[i].arraySizeInRetval) {
3457								count = extract_count(methinfo->rettype.type, pRetval);
3458								if (count == -1 && PyErr_Occurred()) goto error_cleanup;
3459
3460							} else {
3461								count = methinfo->argtype[i].arrayArg;
3462							}
3463
3464							if (*resttype == _C_UNICHAR) {
3465
3466								int byteorder = 0;
3467								v = PyUnicode_DecodeUTF16(
3468									arg, count*2, NULL, &byteorder);
3469								if (!v) goto error_cleanup;
3470
3471							} else {
3472								v = PyObjC_CArrayToPython2(resttype,
3473									arg,
3474									count, methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
3475								if (!v) goto error_cleanup;
3476							}
3477							break;
3478
3479						case PyObjC_kVariableLengthArray:
3480							 /* TODO: add support for UniChar arrays */
3481							if (methinfo->argtype[i].arraySizeInRetval) {
3482								count = extract_count(methinfo->rettype.type, pRetval);
3483								if (count == -1 && PyErr_Occurred()) goto error_cleanup;
3484
3485								v = PyObjC_CArrayToPython2(resttype,
3486									arg,
3487									count, methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
3488								if (!v) goto error_cleanup;
3489
3490							} else {
3491								v = PyObjC_VarList_New(methinfo->rettype.type, pRetval);
3492								if (!v) goto error_cleanup;
3493							}
3494
3495							break;
3496
3497						case PyObjC_kNullTerminatedArray:
3498							 /* TODO: add support for UniChar arrays */
3499							v = pythonify_c_array_nullterminated(
3500								resttype, arg, methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
3501							if (!v) goto error_cleanup;
3502							break;
3503
3504						case PyObjC_kArrayCountInArg:
3505							if (methinfo->argtype[i].arraySizeInRetval) {
3506								count = extract_count(methinfo->rettype.type, pRetval);
3507
3508							} else {
3509								count = extract_count(
3510									methinfo->argtype[methinfo->argtype[i].arrayArgOut].type,
3511									argvalues[methinfo->argtype[i].arrayArgOut]);
3512							}
3513							if (count == -1 && PyErr_Occurred()) goto error_cleanup;
3514
3515							if (*resttype == _C_UNICHAR) {
3516								int byteorder = 0;
3517								v = PyUnicode_DecodeUTF16(
3518									arg, count*2, NULL, &byteorder);
3519								if (!v) goto error_cleanup;
3520
3521							} else {
3522								v = PyObjC_CArrayToPython2(
3523									resttype,
3524									arg,
3525									count, methinfo->argtype[i].alreadyRetained, methinfo->argtype[i].alreadyCFRetained);
3526							}
3527
3528							if (v == NULL) goto error_cleanup;
3529							break;
3530						}
3531					}
3532
3533					if (result != NULL) {
3534						if (PyTuple_SetItem(result,
3535							py_arg++, v) < 0) {
3536
3537							Py_DECREF(v);
3538							goto error_cleanup;
3539						}
3540					} else {
3541						result = v;
3542					}
3543
3544				}
3545				break;
3546			}
3547		}
3548	}
3549
3550	return result;
3551
3552error_cleanup:
3553	Py_XDECREF(result);
3554	return NULL;
3555}
3556
3557int PyObjCFFI_AllocByRef(int argcount, void*** byref, struct byref_attr** byref_attr)
3558{
3559	*byref = NULL; *byref_attr = NULL;
3560
3561	*byref = PyMem_Malloc(sizeof(void*) * argcount);
3562	if (*byref == NULL) {
3563		PyErr_NoMemory();
3564		return -1;
3565	}
3566	memset(*byref, 0, sizeof(void*) * argcount);
3567
3568	*byref_attr = PyMem_Malloc(sizeof(struct byref_attr) * argcount);
3569	if (*byref_attr == NULL) {
3570		free(*byref);
3571		*byref = NULL;
3572
3573		PyErr_NoMemory();
3574		return -1;
3575	}
3576	memset(*byref_attr, 0, sizeof(struct byref_attr) * argcount);
3577
3578	return 0;
3579}
3580
3581int PyObjCFFI_FreeByRef(int argcount, void** byref, struct byref_attr* byref_attr)
3582{
3583	Py_ssize_t i;
3584	if (byref) {
3585		for (i = 0; i < argcount; i++) {
3586			if (byref[i] == NULL) continue;
3587
3588			if (byref_attr[i].token != 0) {
3589				PyObjC_FreeCArray(byref_attr[i].token, byref[i]);
3590				byref[i] = NULL;
3591
3592				Py_XDECREF(byref_attr[i].buffer); byref_attr[i].buffer = NULL;
3593
3594			} else {
3595				PyMem_Free(byref[i]); byref[i] = NULL;
3596			}
3597		}
3598		PyMem_Free(byref);
3599	}
3600
3601	if (byref_attr) {
3602		PyMem_Free(byref_attr);
3603	}
3604
3605	return 0;
3606}
3607
3608
3609PyObject *
3610PyObjCFFI_Caller(PyObject *aMeth, PyObject* self, PyObject *args)
3611{
3612	Py_ssize_t argbuf_len = 0;
3613	Py_ssize_t argbuf_cur = 0;
3614	unsigned char* volatile argbuf = NULL;
3615	Py_ssize_t byref_in_count = 0;
3616	Py_ssize_t byref_out_count = 0;
3617	Py_ssize_t plain_count = 0;
3618	void** byref = NULL; /* offset for arguments in argbuf */
3619	struct byref_attr* byref_attr = NULL;
3620	const char* 	  rettype;
3621	PyObjCMethodSignature*  volatile methinfo;
3622	PyObjCNativeSelector* meth = (PyObjCNativeSelector*)aMeth;
3623	PyObject* objc_result = NULL;
3624	PyObject* volatile result = NULL;
3625	id		  self_obj = nil;
3626	struct objc_super super;
3627	struct objc_super* superPtr;
3628	ffi_cif		  cif;
3629	ffi_type*	  arglist[128]; /* XX: Magic constant */
3630	void*             values[128];
3631	int               r;
3632	void* volatile	  msgResult;
3633	Py_ssize_t        resultSize;
3634	volatile int      useStret;
3635	volatile int      flags;
3636	SEL		  theSel;
3637	volatile int		  isUninitialized;
3638	BOOL		  variadicAllArgs = NO;
3639
3640	if (PyObjCIMP_Check(aMeth)) {
3641		methinfo = PyObjCIMP_GetSignature(aMeth);
3642		flags = PyObjCIMP_GetFlags(aMeth);
3643	} else {
3644		methinfo = PyObjCSelector_GetMetadata(aMeth);
3645		if (methinfo == NULL) {
3646			return NULL;
3647		}
3648		flags = meth->sel_flags;
3649	}
3650	rettype = methinfo->rettype.type;
3651	variadicAllArgs = methinfo->variadic && (methinfo->null_terminated_array || methinfo->arrayArg != -1);
3652
3653	if (methinfo->suggestion != NULL) {
3654		PyErr_SetObject(PyExc_TypeError, methinfo->suggestion);
3655		return NULL;
3656	}
3657
3658	if (Py_SIZE(methinfo) >= 127) {
3659		 PyErr_Format(PyObjCExc_Error,
3660			 "wrapping a function with %"PY_FORMAT_SIZE_T"d arguments, at most 64 "
3661			 "are supported", Py_SIZE(methinfo));
3662		 return NULL;
3663	}
3664
3665
3666	resultSize = PyObjCRT_SizeOfReturnType(rettype);
3667	if (resultSize == -1) {
3668		return NULL;
3669	}
3670
3671
3672	/* First count the number of by reference parameters, and the number
3673	 * of bytes of storage needed for them. Note that arguments 0 and 1
3674	 * are self and the selector, no need to count those.
3675	 */
3676	argbuf_len = align(resultSize, sizeof(void*));
3677	r = PyObjCFFI_CountArguments(
3678		methinfo, 2,
3679		&byref_in_count,
3680		&byref_out_count,
3681		&plain_count,
3682		&argbuf_len,
3683		&variadicAllArgs);
3684	if (r == -1) {
3685		return NULL;
3686	}
3687
3688
3689	/*
3690	 * We need input arguments for every normal argument and for every
3691	 * input argument that is passed by reference.
3692	 */
3693	if (variadicAllArgs) {
3694		if (byref_in_count != 0 || byref_out_count != 0) {
3695			PyErr_Format(PyExc_TypeError, "Sorry, printf format with by-ref args not supported");
3696			goto error_cleanup;
3697		}
3698		if (methinfo->null_terminated_array) {
3699			if (PyTuple_Size(args) < Py_SIZE(methinfo) - 3) {
3700				PyErr_Format(PyExc_TypeError,
3701					"Need %"PY_FORMAT_SIZE_T"d arguments, got %"PY_FORMAT_SIZE_T"d",
3702					Py_SIZE(methinfo) - 3,
3703					PyTuple_Size(args));
3704				goto error_cleanup;
3705			}
3706		} else if (PyTuple_Size(args) < Py_SIZE(methinfo) - 2) {
3707			PyErr_Format(PyExc_TypeError, "Need %"PY_FORMAT_SIZE_T"d arguments, got %"PY_FORMAT_SIZE_T"d",
3708			Py_SIZE(methinfo) - 2, PyTuple_Size(args));
3709			goto error_cleanup;
3710		}
3711
3712		if (PyTuple_Size(args) > 127) {
3713			PyErr_Format(PyExc_TypeError, "At most %d arguments are supported, got %" PY_FORMAT_SIZE_T "d arguments", 127, PyTuple_Size(args));
3714			goto error_cleanup;
3715		}
3716
3717	} else if (PyTuple_Size(args) != Py_SIZE(methinfo) - 2) {
3718
3719		PyErr_Format(PyExc_TypeError, "Need %"PY_FORMAT_SIZE_T"d arguments, got %"PY_FORMAT_SIZE_T"d",
3720			Py_SIZE(methinfo) - 2, PyTuple_Size(args));
3721		goto error_cleanup;
3722	}
3723
3724
3725	argbuf = PyMem_Malloc(argbuf_len);
3726	if (argbuf == 0) {
3727		PyErr_NoMemory();
3728		goto error_cleanup;
3729	}
3730
3731	if (variadicAllArgs) {
3732		if (PyObjCFFI_AllocByRef(Py_SIZE(methinfo)+PyTuple_Size(args),
3733					&byref, &byref_attr) < 0) {
3734			goto error_cleanup;
3735		}
3736	} else {
3737		if (PyObjCFFI_AllocByRef(Py_SIZE(methinfo), &byref, &byref_attr) < 0) {
3738			goto error_cleanup;
3739		}
3740	}
3741
3742	/* Set 'self' argument, for class methods we use the class */
3743	if (flags & PyObjCSelector_kCLASS_METHOD) {
3744		if (PyObjCObject_Check(self)) {
3745			self_obj = PyObjCObject_GetObject(self);
3746			if (self_obj != NULL) {
3747				self_obj = object_getClass(self_obj);
3748			}
3749		} else if (PyObjCClass_Check(self)) {
3750			self_obj = PyObjCClass_GetClass(self);
3751
3752
3753		} else if (PyType_Check(self) && PyType_IsSubtype((PyTypeObject*)self, &PyType_Type)) {
3754			PyObject* c = PyObjCClass_ClassForMetaClass(self);
3755			if (c == NULL) {
3756				self_obj = nil;
3757
3758			} else {
3759				self_obj = PyObjCClass_GetClass(c);
3760			}
3761
3762		} else {
3763			PyErr_Format(PyExc_TypeError,
3764				"Need objective-C object or class as self, not an instance of '%s'",
3765					Py_TYPE(self)->tp_name);
3766			goto error_cleanup;
3767		}
3768	} else {
3769		int err;
3770		if (PyObjCObject_Check(self)) {
3771			self_obj = PyObjCObject_GetObject(self);
3772		} else {
3773			err = depythonify_c_value(@encode(id), self, &self_obj);
3774			if (err == -1) {
3775				goto error_cleanup;
3776			}
3777		}
3778	}
3779	/* XXX: Ronald: why the XXX? */
3780
3781	useStret = 0;
3782
3783	if (PyObjCIMP_Check(aMeth)) {
3784		useStret = 0;
3785		theSel = PyObjCIMP_GetSelector(aMeth);
3786		arglist[0] = &ffi_type_pointer;
3787		values[0] = &self_obj;
3788		arglist[1] = &ffi_type_pointer;
3789		values[1] = &theSel;
3790		msgResult = argbuf;
3791		argbuf_cur = align(resultSize, sizeof(void*));
3792
3793	} else {
3794		objc_superSetReceiver(super, self_obj);
3795		if (meth->sel_flags & PyObjCSelector_kCLASS_METHOD) {
3796			objc_superSetClass(super,
3797					object_getClass(meth->sel_class));
3798		} else {
3799			objc_superSetClass(super,  meth->sel_class);
3800		}
3801
3802		useStret = 0;
3803		if (*rettype == _C_STRUCT_B &&
3804#ifdef  __ppc64__
3805			ffi64_stret_needs_ptr(signature_to_ffi_return_type(rettype), NULL, NULL)
3806
3807#else /* !__ppc64__ */
3808			(resultSize > SMALL_STRUCT_LIMIT
3809#ifdef __i386__
3810			 /* darwin/x86 ABI is slightly odd ;-) */
3811			 || (resultSize != 1
3812				&& resultSize != 2
3813				&& resultSize != 4
3814				&& resultSize != 8)
3815#endif
3816#ifdef __x86_64__
3817			 /* darwin/x86-64 ABI is slightly odd ;-) */
3818			 || (resultSize != 1
3819				&& resultSize != 2
3820				&& resultSize != 4
3821				&& resultSize != 8
3822				&& resultSize != 16
3823				)
3824#endif
3825			)
3826#endif /* !__ppc64__ */
3827			) {
3828
3829			useStret = 1;
3830		}
3831		superPtr = &super;
3832		arglist[ 0] = &ffi_type_pointer;
3833		values[ 0] = &superPtr;
3834		arglist[ 1] = &ffi_type_pointer;
3835		values[ 1] = &meth->sel_selector;
3836		theSel = meth->sel_selector;
3837		msgResult = argbuf;
3838		argbuf_cur = align(resultSize, sizeof(void*));
3839	}
3840
3841	r = PyObjCFFI_ParseArguments(methinfo, 2, args,
3842		argbuf_cur, argbuf, argbuf_len, byref, byref_attr,
3843		arglist, values);
3844	if (r == -1) {
3845		goto error_cleanup;
3846	}
3847
3848
3849	PyErr_Clear();
3850	ffi_type* retsig = signature_to_ffi_return_type(rettype);
3851	if (retsig == NULL) goto error_cleanup;
3852	r = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, r, retsig, arglist);
3853	if (r != FFI_OK) {
3854		PyErr_Format(PyExc_RuntimeError,
3855			"Cannot setup FFI CIF [%d]", r);
3856		goto error_cleanup;
3857	}
3858
3859	if (PyObjCObject_Check(self)) {
3860		isUninitialized = ((PyObjCObject*)self)->flags  & PyObjCObject_kUNINITIALIZED;
3861		((PyObjCObject*)self)->flags  &= ~PyObjCObject_kUNINITIALIZED;
3862	} else {
3863		isUninitialized = NO;
3864        }
3865
3866	if (Py_SIZE(methinfo) >= 3) {
3867	}
3868
3869	PyObjC_DURING
3870		if (PyObjCIMP_Check(aMeth)) {
3871			ffi_call(&cif, FFI_FN(PyObjCIMP_GetIMP(aMeth)),
3872				msgResult, values);
3873
3874		} else {
3875			if (useStret) {
3876				ffi_call(&cif, FFI_FN(objc_msgSendSuper_stret),
3877					msgResult, values);
3878			} else {
3879				ffi_call(&cif, FFI_FN(objc_msgSendSuper),
3880					msgResult, values);
3881
3882			}
3883		}
3884
3885	PyObjC_HANDLER
3886		PyObjCErr_FromObjC(localException);
3887
3888	PyObjC_ENDHANDLER
3889#if 1
3890	if (isUninitialized && PyObjCObject_Check(self)) {
3891		((PyObjCObject*)self)->flags  |= PyObjCObject_kUNINITIALIZED;
3892	}
3893#endif
3894
3895	if (PyErr_Occurred()) goto error_cleanup;
3896
3897	if (Py_SIZE(methinfo) >= 3) {
3898	}
3899
3900	result = PyObjCFFI_BuildResult(methinfo, 2, msgResult, byref,
3901			byref_attr, byref_out_count,
3902			self, flags, values);
3903
3904	if (variadicAllArgs) {
3905		if (PyObjCFFI_FreeByRef(Py_SIZE(methinfo)+PyTuple_Size(args), byref, byref_attr) < 0) {
3906			byref = NULL; byref_attr = NULL;
3907			goto error_cleanup;
3908		}
3909	} else {
3910		if (PyObjCFFI_FreeByRef(Py_SIZE(methinfo), byref, byref_attr) < 0) {
3911			byref = NULL; byref_attr = NULL;
3912			goto error_cleanup;
3913		}
3914	}
3915	PyMem_Free(argbuf); argbuf = NULL;
3916	methinfo = NULL;
3917
3918	return result;
3919
3920error_cleanup:
3921
3922	if (objc_result) {
3923		Py_DECREF(objc_result);
3924		objc_result = NULL;
3925	}
3926	if (result) {
3927		Py_DECREF(result);
3928		result = NULL;
3929	}
3930	if (variadicAllArgs) {
3931		if (PyObjCFFI_FreeByRef(PyTuple_Size(args), byref, byref_attr) < 0) {
3932			byref = NULL; byref_attr = NULL;
3933			goto error_cleanup;
3934		}
3935	} else {
3936		if (PyObjCFFI_FreeByRef(Py_SIZE(methinfo), byref, byref_attr) < 0) {
3937			byref = NULL; byref_attr = NULL;
3938			goto error_cleanup;
3939		}
3940	}
3941	if (argbuf) {
3942		PyMem_Free(argbuf);
3943		argbuf = NULL;
3944	}
3945	return NULL;
3946}
3947
3948/*
3949 * PyObjCFFI_CIFForSignature - Create CIF for a method signature
3950 *
3951 * return the CIF, return NULL on error. pArgOffset is set to 1 if the method
3952 * should be called using objc_sendMsg_sret (using a pointer to the return value
3953 * as an initial argument), and is set to 0 otherwise.
3954 */
3955ffi_cif*
3956PyObjCFFI_CIFForSignature(PyObjCMethodSignature* methinfo)
3957{
3958	ffi_cif* cif;
3959	ffi_type** cl_arg_types;
3960	ffi_type* cl_ret_type;
3961	const char* rettype;
3962	ffi_status rv;
3963	int i;
3964
3965	rettype = methinfo->rettype.type;
3966
3967	cl_ret_type = signature_to_ffi_return_type(rettype);
3968	if (cl_ret_type == NULL) {
3969		return NULL;
3970	}
3971
3972	/* Build FFI argumentlist description */
3973	cl_arg_types = PyMem_Malloc(sizeof(ffi_type*) * (2 + Py_SIZE(methinfo)));
3974	if (cl_arg_types == NULL) {
3975		PyMem_Free(cl_ret_type);
3976		PyErr_NoMemory();
3977		return NULL;
3978	}
3979
3980	for (i = 0; i < Py_SIZE(methinfo); i++) {
3981		cl_arg_types[i] = arg_signature_to_ffi_type(
3982			methinfo->argtype[i].type);
3983		if (cl_arg_types[i] == NULL) {
3984			PyMem_Free(cl_arg_types);
3985			return NULL;
3986		}
3987	}
3988
3989	/* Create the invocation description */
3990	cif = PyMem_Malloc(sizeof(*cif));
3991	if (cif == NULL) {
3992		PyMem_Free(cl_arg_types);
3993		PyErr_NoMemory();
3994		return NULL;
3995	}
3996
3997	rv = ffi_prep_cif(cif, FFI_DEFAULT_ABI, Py_SIZE(methinfo),
3998		cl_ret_type, cl_arg_types);
3999
4000	if (rv != FFI_OK) {
4001		PyMem_Free(cif);
4002		PyMem_Free(cl_arg_types);
4003		PyErr_Format(PyExc_RuntimeError,
4004			"Cannot create FFI CIF: err=%d", rv);
4005		return NULL;
4006	}
4007
4008	return cif;
4009}
4010
4011/*
4012 * PyObjCFFI_FreeCIF - Free the CIF created by PyObjCFFI_CIFForSignature
4013 */
4014void
4015PyObjCFFI_FreeCIF(ffi_cif* cif)
4016{
4017	if (cif->arg_types) PyMem_Free(cif->arg_types);
4018	PyMem_Free(cif);
4019}
4020
4021/*
4022 * PyObjCFFI_MakeClosure - Create a closure for an Objective-C method
4023 *
4024 * Return the closure, or NULL. The 'func' will be called with a CIF object,
4025 * a pointer to the return value, the argument array and the 'userdata'.
4026 */
4027IMP
4028PyObjCFFI_MakeClosure(
4029	PyObjCMethodSignature* methinfo,
4030	PyObjCFFI_ClosureFunc func,
4031	void* userdata)
4032{
4033	ffi_cif *cif;
4034	ffi_closure *cl;
4035	ffi_status rv;
4036
4037	cif = PyObjCFFI_CIFForSignature(methinfo);
4038	if (cif == NULL) {
4039		return NULL;
4040	}
4041
4042	/* And finally create the actual closure */
4043	/*cl = PyMem_Malloc(sizeof(*cl));*/
4044	cl = PyObjC_malloc_closure();
4045	if (cl == NULL) {
4046		PyObjCFFI_FreeCIF(cif);
4047		/*PyErr_NoMemory();*/
4048		return NULL;
4049	}
4050
4051	/*printf("create closure for cif\n");
4052	describe_cif(cif);
4053	printf("\n\n");*/
4054
4055	rv = ffi_prep_closure(cl, cif, func, userdata);
4056	if (rv != FFI_OK) {
4057		PyObjCFFI_FreeCIF(cif);
4058		PyErr_Format(PyExc_RuntimeError,
4059			"Cannot create FFI closure: %d", rv);
4060		return NULL;
4061	}
4062
4063	return (IMP)cl;
4064}
4065
4066/*
4067 * PyObjCFFI_FreeClosure - Free the closure created by PyObjCFFI_MakeClosure
4068 *
4069 * Returns the userdata.
4070 */
4071void*
4072PyObjCFFI_FreeClosure(IMP closure)
4073{
4074	void* retval;
4075	ffi_closure* cl;
4076
4077	cl = (ffi_closure*)closure;
4078	retval = cl->user_data;
4079	PyObjCFFI_FreeCIF(cl->cif);
4080	PyObjC_free_closure(cl); /* XXX: error handling */
4081
4082	return retval;
4083}
4084