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