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