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