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