1 /* GNU Objective C Runtime class related functions 2 Copyright (C) 1993, 1995, 1996, 1997, 2001, 2002, 2009, 2010 3 Free Software Foundation, Inc. 4 Contributed by Kresten Krab Thorup and Dennis Glatting. 5 6 Lock-free class table code designed and written from scratch by 7 Nicola Pero, 2001. 8 9 This file is part of GCC. 10 11 GCC is free software; you can redistribute it and/or modify it under the 12 terms of the GNU General Public License as published by the Free Software 13 Foundation; either version 3, or (at your option) any later version. 14 15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 16 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 details. 19 20 Under Section 7 of GPL version 3, you are granted additional 21 permissions described in the GCC Runtime Library Exception, version 22 3.1, as published by the Free Software Foundation. 23 24 You should have received a copy of the GNU General Public License and 25 a copy of the GCC Runtime Library Exception along with this program; 26 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 27 <http://www.gnu.org/licenses/>. */ 28 29 /* The code in this file critically affects class method invocation 30 speed. This long preamble comment explains why, and the issues 31 involved. 32 33 One of the traditional weaknesses of the GNU Objective-C runtime is 34 that class method invocations are slow. The reason is that when you 35 write 36 37 array = [NSArray new]; 38 39 this gets basically compiled into the equivalent of 40 41 array = [(objc_get_class ("NSArray")) new]; 42 43 objc_get_class returns the class pointer corresponding to the string 44 `NSArray'; and because of the lookup, the operation is more 45 complicated and slow than a simple instance method invocation. 46 47 Most high performance Objective-C code (using the GNU Objc runtime) 48 I had the opportunity to read (or write) work around this problem by 49 caching the class pointer: 50 51 Class arrayClass = [NSArray class]; 52 53 ... later on ... 54 55 array = [arrayClass new]; 56 array = [arrayClass new]; 57 array = [arrayClass new]; 58 59 In this case, you always perform a class lookup (the first one), but 60 then all the [arrayClass new] methods run exactly as fast as an 61 instance method invocation. It helps if you have many class method 62 invocations to the same class. 63 64 The long-term solution to this problem would be to modify the 65 compiler to output tables of class pointers corresponding to all the 66 class method invocations, and to add code to the runtime to update 67 these tables - that should in the end allow class method invocations 68 to perform precisely as fast as instance method invocations, because 69 no class lookup would be involved. I think the Apple Objective-C 70 runtime uses this technique. Doing this involves synchronized 71 modifications in the runtime and in the compiler. 72 73 As a first medicine to the problem, I [NP] have redesigned and 74 rewritten the way the runtime is performing class lookup. This 75 doesn't give as much speed as the other (definitive) approach, but 76 at least a class method invocation now takes approximately 4.5 times 77 an instance method invocation on my machine (it would take approx 12 78 times before the rewriting), which is a lot better. 79 80 One of the main reason the new class lookup is so faster is because 81 I implemented it in a way that can safely run multithreaded without 82 using locks - a so-called `lock-free' data structure. The atomic 83 operation is pointer assignment. The reason why in this problem 84 lock-free data structures work so well is that you never remove 85 classes from the table - and the difficult thing with lock-free data 86 structures is freeing data when is removed from the structures. */ 87 88 #include "objc-private/common.h" 89 #include "objc-private/error.h" 90 #include "objc/runtime.h" 91 #include "objc/thr.h" 92 #include "objc-private/module-abi-8.h" /* For CLS_ISCLASS and similar. */ 93 #include "objc-private/runtime.h" /* the kitchen sink */ 94 #include "objc-private/sarray.h" /* For sarray_put_at_safe. */ 95 #include "objc-private/selector.h" /* For sarray_put_at_safe. */ 96 #include <string.h> /* For memset */ 97 98 /* We use a table which maps a class name to the corresponding class 99 pointer. The first part of this file defines this table, and 100 functions to do basic operations on the table. The second part of 101 the file implements some higher level Objective-C functionality for 102 classes by using the functions provided in the first part to manage 103 the table. */ 104 105 /** 106 ** Class Table Internals 107 **/ 108 109 /* A node holding a class */ 110 typedef struct class_node 111 { 112 struct class_node *next; /* Pointer to next entry on the list. 113 NULL indicates end of list. */ 114 115 const char *name; /* The class name string */ 116 int length; /* The class name string length */ 117 Class pointer; /* The Class pointer */ 118 119 } *class_node_ptr; 120 121 /* A table containing classes is a class_node_ptr (pointing to the 122 first entry in the table - if it is NULL, then the table is 123 empty). */ 124 125 /* We have 1024 tables. Each table contains all class names which 126 have the same hash (which is a number between 0 and 1023). To look 127 up a class_name, we compute its hash, and get the corresponding 128 table. Once we have the table, we simply compare strings directly 129 till we find the one which we want (using the length first). The 130 number of tables is quite big on purpose (a normal big application 131 has less than 1000 classes), so that you shouldn't normally get any 132 collisions, and get away with a single comparison (which we can't 133 avoid since we need to know that you have got the right thing). */ 134 #define CLASS_TABLE_SIZE 1024 135 #define CLASS_TABLE_MASK 1023 136 137 static class_node_ptr class_table_array[CLASS_TABLE_SIZE]; 138 139 /* The table writing mutex - we lock on writing to avoid conflicts 140 between different writers, but we read without locks. That is 141 possible because we assume pointer assignment to be an atomic 142 operation. TODO: This is only true under certain circumstances, 143 which should be clarified. */ 144 static objc_mutex_t __class_table_lock = NULL; 145 146 /* CLASS_TABLE_HASH is how we compute the hash of a class name. It is 147 a macro - *not* a function - arguments *are* modified directly. 148 149 INDEX should be a variable holding an int; 150 HASH should be a variable holding an int; 151 CLASS_NAME should be a variable holding a (char *) to the class_name. 152 153 After the macro is executed, INDEX contains the length of the 154 string, and HASH the computed hash of the string; CLASS_NAME is 155 untouched. */ 156 157 #define CLASS_TABLE_HASH(INDEX, HASH, CLASS_NAME) \ 158 HASH = 0; \ 159 for (INDEX = 0; CLASS_NAME[INDEX] != '\0'; INDEX++) \ 160 { \ 161 HASH = (HASH << 4) ^ (HASH >> 28) ^ CLASS_NAME[INDEX]; \ 162 } \ 163 \ 164 HASH = (HASH ^ (HASH >> 10) ^ (HASH >> 20)) & CLASS_TABLE_MASK; 165 166 /* Setup the table. */ 167 static void 168 class_table_setup (void) 169 { 170 /* Start - nothing in the table. */ 171 memset (class_table_array, 0, sizeof (class_node_ptr) * CLASS_TABLE_SIZE); 172 173 /* The table writing mutex. */ 174 __class_table_lock = objc_mutex_allocate (); 175 } 176 177 178 /* Insert a class in the table (used when a new class is 179 registered). */ 180 static void 181 class_table_insert (const char *class_name, Class class_pointer) 182 { 183 int hash, length; 184 class_node_ptr new_node; 185 186 /* Find out the class name's hash and length. */ 187 CLASS_TABLE_HASH (length, hash, class_name); 188 189 /* Prepare the new node holding the class. */ 190 new_node = objc_malloc (sizeof (struct class_node)); 191 new_node->name = class_name; 192 new_node->length = length; 193 new_node->pointer = class_pointer; 194 195 /* Lock the table for modifications. */ 196 objc_mutex_lock (__class_table_lock); 197 198 /* Insert the new node in the table at the beginning of the table at 199 class_table_array[hash]. */ 200 new_node->next = class_table_array[hash]; 201 class_table_array[hash] = new_node; 202 203 objc_mutex_unlock (__class_table_lock); 204 } 205 206 /* Get a class from the table. This does not need mutex protection. 207 Currently, this function is called each time you call a static 208 method, this is why it must be very fast. */ 209 static inline Class 210 class_table_get_safe (const char *class_name) 211 { 212 class_node_ptr node; 213 int length, hash; 214 215 /* Compute length and hash. */ 216 CLASS_TABLE_HASH (length, hash, class_name); 217 218 node = class_table_array[hash]; 219 220 if (node != NULL) 221 { 222 do 223 { 224 if (node->length == length) 225 { 226 /* Compare the class names. */ 227 int i; 228 229 for (i = 0; i < length; i++) 230 { 231 if ((node->name)[i] != class_name[i]) 232 break; 233 } 234 235 if (i == length) 236 { 237 /* They are equal! */ 238 return node->pointer; 239 } 240 } 241 } 242 while ((node = node->next) != NULL); 243 } 244 245 return Nil; 246 } 247 248 /* Enumerate over the class table. */ 249 struct class_table_enumerator 250 { 251 int hash; 252 class_node_ptr node; 253 }; 254 255 256 static Class 257 class_table_next (struct class_table_enumerator **e) 258 { 259 struct class_table_enumerator *enumerator = *e; 260 class_node_ptr next; 261 262 if (enumerator == NULL) 263 { 264 *e = objc_malloc (sizeof (struct class_table_enumerator)); 265 enumerator = *e; 266 enumerator->hash = 0; 267 enumerator->node = NULL; 268 269 next = class_table_array[enumerator->hash]; 270 } 271 else 272 next = enumerator->node->next; 273 274 if (next != NULL) 275 { 276 enumerator->node = next; 277 return enumerator->node->pointer; 278 } 279 else 280 { 281 enumerator->hash++; 282 283 while (enumerator->hash < CLASS_TABLE_SIZE) 284 { 285 next = class_table_array[enumerator->hash]; 286 if (next != NULL) 287 { 288 enumerator->node = next; 289 return enumerator->node->pointer; 290 } 291 enumerator->hash++; 292 } 293 294 /* Ok - table finished - done. */ 295 objc_free (enumerator); 296 return Nil; 297 } 298 } 299 300 #if 0 /* DEBUGGING FUNCTIONS */ 301 /* Debugging function - print the class table. */ 302 void 303 class_table_print (void) 304 { 305 int i; 306 307 for (i = 0; i < CLASS_TABLE_SIZE; i++) 308 { 309 class_node_ptr node; 310 311 printf ("%d:\n", i); 312 node = class_table_array[i]; 313 314 while (node != NULL) 315 { 316 printf ("\t%s\n", node->name); 317 node = node->next; 318 } 319 } 320 } 321 322 /* Debugging function - print an histogram of number of classes in 323 function of hash key values. Useful to evaluate the hash function 324 in real cases. */ 325 void 326 class_table_print_histogram (void) 327 { 328 int i, j; 329 int counter = 0; 330 331 for (i = 0; i < CLASS_TABLE_SIZE; i++) 332 { 333 class_node_ptr node; 334 335 node = class_table_array[i]; 336 337 while (node != NULL) 338 { 339 counter++; 340 node = node->next; 341 } 342 if (((i + 1) % 50) == 0) 343 { 344 printf ("%4d:", i + 1); 345 for (j = 0; j < counter; j++) 346 printf ("X"); 347 348 printf ("\n"); 349 counter = 0; 350 } 351 } 352 printf ("%4d:", i + 1); 353 for (j = 0; j < counter; j++) 354 printf ("X"); 355 356 printf ("\n"); 357 } 358 #endif /* DEBUGGING FUNCTIONS */ 359 360 /** 361 ** Objective-C runtime functions 362 **/ 363 364 /* From now on, the only access to the class table data structure 365 should be via the class_table_* functions. */ 366 367 /* This is a hook which is called by objc_get_class and 368 objc_lookup_class if the runtime is not able to find the class. 369 This may e.g. try to load in the class using dynamic loading. 370 371 This hook was a public, global variable in the Traditional GNU 372 Objective-C Runtime API (objc/objc-api.h). The modern GNU 373 Objective-C Runtime API (objc/runtime.h) provides the 374 objc_setGetUnknownClassHandler() function instead. 375 */ 376 Class (*_objc_lookup_class) (const char *name) = 0; /* !T:SAFE */ 377 378 /* The handler currently in use. PS: if both 379 __obj_get_unknown_class_handler and _objc_lookup_class are defined, 380 __objc_get_unknown_class_handler is called first. */ 381 static objc_get_unknown_class_handler 382 __objc_get_unknown_class_handler = NULL; 383 384 objc_get_unknown_class_handler 385 objc_setGetUnknownClassHandler (objc_get_unknown_class_handler 386 new_handler) 387 { 388 objc_get_unknown_class_handler old_handler 389 = __objc_get_unknown_class_handler; 390 __objc_get_unknown_class_handler = new_handler; 391 return old_handler; 392 } 393 394 395 /* True when class links has been resolved. */ 396 BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */ 397 398 399 void 400 __objc_init_class_tables (void) 401 { 402 /* Allocate the class hash table. */ 403 404 if (__class_table_lock) 405 return; 406 407 objc_mutex_lock (__objc_runtime_mutex); 408 409 class_table_setup (); 410 411 objc_mutex_unlock (__objc_runtime_mutex); 412 } 413 414 /* This function adds a class to the class hash table, and assigns the 415 class a number, unless it's already known. Return 'YES' if the 416 class was added. Return 'NO' if the class was already known. */ 417 BOOL 418 __objc_add_class_to_hash (Class class) 419 { 420 Class existing_class; 421 422 objc_mutex_lock (__objc_runtime_mutex); 423 424 /* Make sure the table is there. */ 425 assert (__class_table_lock); 426 427 /* Make sure it's not a meta class. */ 428 assert (CLS_ISCLASS (class)); 429 430 /* Check to see if the class is already in the hash table. */ 431 existing_class = class_table_get_safe (class->name); 432 433 if (existing_class) 434 { 435 objc_mutex_unlock (__objc_runtime_mutex); 436 return NO; 437 } 438 else 439 { 440 /* The class isn't in the hash table. Add the class and assign 441 a class number. */ 442 static unsigned int class_number = 1; 443 444 CLS_SETNUMBER (class, class_number); 445 CLS_SETNUMBER (class->class_pointer, class_number); 446 447 ++class_number; 448 class_table_insert (class->name, class); 449 450 objc_mutex_unlock (__objc_runtime_mutex); 451 return YES; 452 } 453 } 454 455 Class 456 objc_getClass (const char *name) 457 { 458 Class class; 459 460 if (name == NULL) 461 return Nil; 462 463 class = class_table_get_safe (name); 464 465 if (class) 466 return class; 467 468 if (__objc_get_unknown_class_handler) 469 return (*__objc_get_unknown_class_handler) (name); 470 471 if (_objc_lookup_class) 472 return (*_objc_lookup_class) (name); 473 474 return Nil; 475 } 476 477 Class 478 objc_lookUpClass (const char *name) 479 { 480 if (name == NULL) 481 return Nil; 482 else 483 return class_table_get_safe (name); 484 } 485 486 Class 487 objc_getMetaClass (const char *name) 488 { 489 Class class = objc_getClass (name); 490 491 if (class) 492 return class->class_pointer; 493 else 494 return Nil; 495 } 496 497 Class 498 objc_getRequiredClass (const char *name) 499 { 500 Class class = objc_getClass (name); 501 502 if (class) 503 return class; 504 else 505 _objc_abort ("objc_getRequiredClass ('%s') failed: class not found\n", name); 506 } 507 508 int 509 objc_getClassList (Class *returnValue, int maxNumberOfClassesToReturn) 510 { 511 /* Iterate over all entries in the table. */ 512 int hash, count = 0; 513 514 for (hash = 0; hash < CLASS_TABLE_SIZE; hash++) 515 { 516 class_node_ptr node = class_table_array[hash]; 517 518 while (node != NULL) 519 { 520 if (returnValue) 521 { 522 if (count < maxNumberOfClassesToReturn) 523 returnValue[count] = node->pointer; 524 else 525 return count; 526 } 527 count++; 528 node = node->next; 529 } 530 } 531 532 return count; 533 } 534 535 Class 536 objc_allocateClassPair (Class super_class, const char *class_name, size_t extraBytes) 537 { 538 Class new_class; 539 Class new_meta_class; 540 541 if (class_name == NULL) 542 return Nil; 543 544 if (objc_getClass (class_name)) 545 return Nil; 546 547 if (super_class) 548 { 549 /* If you want to build a hierarchy of classes, you need to 550 build and register them one at a time. The risk is that you 551 are able to cause confusion by registering a subclass before 552 the superclass or similar. */ 553 if (CLS_IS_IN_CONSTRUCTION (super_class)) 554 return Nil; 555 } 556 557 /* Technically, we should create the metaclass first, then use 558 class_createInstance() to create the class. That complication 559 would be relevant if we had class variables, but we don't, so we 560 just ignore it and create everything directly and assume all 561 classes have the same size. */ 562 new_class = objc_calloc (1, sizeof (struct objc_class) + extraBytes); 563 new_meta_class = objc_calloc (1, sizeof (struct objc_class) + extraBytes); 564 565 /* We create an unresolved class, similar to one generated by the 566 compiler. It will be resolved later when we register it. 567 568 Note how the metaclass details are not that important; when the 569 class is resolved, the ones that matter will be fixed up. */ 570 new_class->class_pointer = new_meta_class; 571 new_meta_class->class_pointer = 0; 572 573 if (super_class) 574 { 575 /* Force the name of the superclass in place of the link to the 576 actual superclass, which will be put there when the class is 577 resolved. */ 578 const char *super_class_name = class_getName (super_class); 579 new_class->super_class = (void *)super_class_name; 580 new_meta_class->super_class = (void *)super_class_name; 581 } 582 else 583 { 584 new_class->super_class = (void *)0; 585 new_meta_class->super_class = (void *)0; 586 } 587 588 new_class->name = objc_malloc (strlen (class_name) + 1); 589 strcpy ((char*)new_class->name, class_name); 590 new_meta_class->name = new_class->name; 591 592 new_class->version = 0; 593 new_meta_class->version = 0; 594 595 new_class->info = _CLS_CLASS | _CLS_IN_CONSTRUCTION; 596 new_meta_class->info = _CLS_META | _CLS_IN_CONSTRUCTION; 597 598 if (super_class) 599 new_class->instance_size = super_class->instance_size; 600 else 601 new_class->instance_size = 0; 602 new_meta_class->instance_size = sizeof (struct objc_class); 603 604 return new_class; 605 } 606 607 void 608 objc_registerClassPair (Class class_) 609 { 610 if (class_ == Nil) 611 return; 612 613 if ((! CLS_ISCLASS (class_)) || (! CLS_IS_IN_CONSTRUCTION (class_))) 614 return; 615 616 if ((! CLS_ISMETA (class_->class_pointer)) || (! CLS_IS_IN_CONSTRUCTION (class_->class_pointer))) 617 return; 618 619 objc_mutex_lock (__objc_runtime_mutex); 620 621 if (objc_getClass (class_->name)) 622 { 623 objc_mutex_unlock (__objc_runtime_mutex); 624 return; 625 } 626 627 CLS_SET_NOT_IN_CONSTRUCTION (class_); 628 CLS_SET_NOT_IN_CONSTRUCTION (class_->class_pointer); 629 630 __objc_init_class (class_); 631 632 /* Resolve class links immediately. No point in waiting. */ 633 __objc_resolve_class_links (); 634 635 objc_mutex_unlock (__objc_runtime_mutex); 636 } 637 638 void 639 objc_disposeClassPair (Class class_) 640 { 641 if (class_ == Nil) 642 return; 643 644 if ((! CLS_ISCLASS (class_)) || (! CLS_IS_IN_CONSTRUCTION (class_))) 645 return; 646 647 if ((! CLS_ISMETA (class_->class_pointer)) || (! CLS_IS_IN_CONSTRUCTION (class_->class_pointer))) 648 return; 649 650 /* Undo any class_addIvar(). */ 651 if (class_->ivars) 652 { 653 int i; 654 for (i = 0; i < class_->ivars->ivar_count; i++) 655 { 656 struct objc_ivar *ivar = &(class_->ivars->ivar_list[i]); 657 658 objc_free ((char *)ivar->ivar_name); 659 objc_free ((char *)ivar->ivar_type); 660 } 661 662 objc_free (class_->ivars); 663 } 664 665 /* Undo any class_addMethod(). */ 666 if (class_->methods) 667 { 668 struct objc_method_list *list = class_->methods; 669 while (list) 670 { 671 int i; 672 struct objc_method_list *next = list->method_next; 673 674 for (i = 0; i < list->method_count; i++) 675 { 676 struct objc_method *method = &(list->method_list[i]); 677 678 objc_free ((char *)method->method_name); 679 objc_free ((char *)method->method_types); 680 } 681 682 objc_free (list); 683 list = next; 684 } 685 } 686 687 /* Undo any class_addProtocol(). */ 688 if (class_->protocols) 689 { 690 struct objc_protocol_list *list = class_->protocols; 691 while (list) 692 { 693 struct objc_protocol_list *next = list->next; 694 695 objc_free (list); 696 list = next; 697 } 698 } 699 700 /* Undo any class_addMethod() on the meta-class. */ 701 if (class_->class_pointer->methods) 702 { 703 struct objc_method_list *list = class_->class_pointer->methods; 704 while (list) 705 { 706 int i; 707 struct objc_method_list *next = list->method_next; 708 709 for (i = 0; i < list->method_count; i++) 710 { 711 struct objc_method *method = &(list->method_list[i]); 712 713 objc_free ((char *)method->method_name); 714 objc_free ((char *)method->method_types); 715 } 716 717 objc_free (list); 718 list = next; 719 } 720 } 721 722 /* Undo objc_allocateClassPair(). */ 723 objc_free ((char *)(class_->name)); 724 objc_free (class_->class_pointer); 725 objc_free (class_); 726 } 727 728 /* Traditional GNU Objective-C Runtime API. Important: this method is 729 called automatically by the compiler while messaging (if using the 730 traditional ABI), so it is worth keeping it fast; don't make it 731 just a wrapper around objc_getClass(). */ 732 /* Note that this is roughly equivalent to objc_getRequiredClass(). */ 733 /* Get the class object for the class named NAME. If NAME does not 734 identify a known class, the hook _objc_lookup_class is called. If 735 this fails, an error message is issued and the system aborts. */ 736 Class 737 objc_get_class (const char *name) 738 { 739 Class class; 740 741 class = class_table_get_safe (name); 742 743 if (class) 744 return class; 745 746 if (__objc_get_unknown_class_handler) 747 class = (*__objc_get_unknown_class_handler) (name); 748 749 if ((!class) && _objc_lookup_class) 750 class = (*_objc_lookup_class) (name); 751 752 if (class) 753 return class; 754 755 _objc_abort ("objc runtime: cannot find class %s\n", name); 756 757 return 0; 758 } 759 760 /* This is used by the compiler too. */ 761 Class 762 objc_get_meta_class (const char *name) 763 { 764 return objc_get_class (name)->class_pointer; 765 } 766 767 /* This is not used by GCC, but the clang compiler seems to use it 768 when targetting the GNU runtime. That's wrong, but we have it to 769 be compatible. */ 770 Class 771 objc_lookup_class (const char *name) 772 { 773 return objc_getClass (name); 774 } 775 776 /* This is used when the implementation of a method changes. It goes 777 through all classes, looking for the ones that have these methods 778 (either method_a or method_b; method_b can be NULL), and reloads 779 the implementation for these. You should call this with the 780 runtime mutex already locked. */ 781 void 782 __objc_update_classes_with_methods (struct objc_method *method_a, struct objc_method *method_b) 783 { 784 int hash; 785 786 /* Iterate over all classes. */ 787 for (hash = 0; hash < CLASS_TABLE_SIZE; hash++) 788 { 789 class_node_ptr node = class_table_array[hash]; 790 791 while (node != NULL) 792 { 793 /* We execute this loop twice: the first time, we iterate 794 over all methods in the class (instance methods), while 795 the second time we iterate over all methods in the meta 796 class (class methods). */ 797 Class class = Nil; 798 BOOL done = NO; 799 800 while (done == NO) 801 { 802 struct objc_method_list * method_list; 803 804 if (class == Nil) 805 { 806 /* The first time, we work on the class. */ 807 class = node->pointer; 808 } 809 else 810 { 811 /* The second time, we work on the meta class. */ 812 class = class->class_pointer; 813 done = YES; 814 } 815 816 method_list = class->methods; 817 818 while (method_list) 819 { 820 int i; 821 822 for (i = 0; i < method_list->method_count; ++i) 823 { 824 struct objc_method *method = &method_list->method_list[i]; 825 826 /* If the method is one of the ones we are 827 looking for, update the implementation. */ 828 if (method == method_a) 829 sarray_at_put_safe (class->dtable, 830 (sidx) method_a->method_name->sel_id, 831 method_a->method_imp); 832 833 if (method == method_b) 834 { 835 if (method_b != NULL) 836 sarray_at_put_safe (class->dtable, 837 (sidx) method_b->method_name->sel_id, 838 method_b->method_imp); 839 } 840 } 841 842 method_list = method_list->method_next; 843 } 844 } 845 node = node->next; 846 } 847 } 848 } 849 850 /* Resolve super/subclass links for all classes. The only thing we 851 can be sure of is that the class_pointer for class objects point to 852 the right meta class objects. */ 853 void 854 __objc_resolve_class_links (void) 855 { 856 struct class_table_enumerator *es = NULL; 857 Class object_class = objc_get_class ("Object"); 858 Class class1; 859 860 assert (object_class); 861 862 objc_mutex_lock (__objc_runtime_mutex); 863 864 /* Assign subclass links. */ 865 while ((class1 = class_table_next (&es))) 866 { 867 /* Make sure we have what we think we have. */ 868 assert (CLS_ISCLASS (class1)); 869 assert (CLS_ISMETA (class1->class_pointer)); 870 871 /* The class_pointer of all meta classes point to Object's meta 872 class. */ 873 class1->class_pointer->class_pointer = object_class->class_pointer; 874 875 if (! CLS_ISRESOLV (class1)) 876 { 877 CLS_SETRESOLV (class1); 878 CLS_SETRESOLV (class1->class_pointer); 879 880 if (class1->super_class) 881 { 882 Class a_super_class 883 = objc_get_class ((char *) class1->super_class); 884 885 assert (a_super_class); 886 887 DEBUG_PRINTF ("making class connections for: %s\n", 888 class1->name); 889 890 /* Assign subclass links for superclass. */ 891 class1->sibling_class = a_super_class->subclass_list; 892 a_super_class->subclass_list = class1; 893 894 /* Assign subclass links for meta class of superclass. */ 895 if (a_super_class->class_pointer) 896 { 897 class1->class_pointer->sibling_class 898 = a_super_class->class_pointer->subclass_list; 899 a_super_class->class_pointer->subclass_list 900 = class1->class_pointer; 901 } 902 } 903 else /* A root class, make its meta object be a subclass of 904 Object. */ 905 { 906 class1->class_pointer->sibling_class 907 = object_class->subclass_list; 908 object_class->subclass_list = class1->class_pointer; 909 } 910 } 911 } 912 913 /* Assign superclass links. */ 914 es = NULL; 915 while ((class1 = class_table_next (&es))) 916 { 917 Class sub_class; 918 for (sub_class = class1->subclass_list; sub_class; 919 sub_class = sub_class->sibling_class) 920 { 921 sub_class->super_class = class1; 922 if (CLS_ISCLASS (sub_class)) 923 sub_class->class_pointer->super_class = class1->class_pointer; 924 } 925 } 926 927 objc_mutex_unlock (__objc_runtime_mutex); 928 } 929 930 const char * 931 class_getName (Class class_) 932 { 933 if (class_ == Nil) 934 return "nil"; 935 936 return class_->name; 937 } 938 939 BOOL 940 class_isMetaClass (Class class_) 941 { 942 /* CLS_ISMETA includes the check for Nil class_. */ 943 return CLS_ISMETA (class_); 944 } 945 946 /* Even inside libobjc it may be worth using class_getSuperclass 947 instead of accessing class_->super_class directly because it 948 resolves the class links if needed. If you access 949 class_->super_class directly, make sure to deal with the situation 950 where the class is not resolved yet! */ 951 Class 952 class_getSuperclass (Class class_) 953 { 954 if (class_ == Nil) 955 return Nil; 956 957 /* Classes that are in construction are not resolved, and still have 958 the class name (instead of a class pointer) in the 959 class_->super_class field. In that case we need to lookup the 960 superclass name to return the superclass. We can not resolve the 961 class until it is registered. */ 962 if (CLS_IS_IN_CONSTRUCTION (class_)) 963 { 964 if (CLS_ISMETA (class_)) 965 return object_getClass ((id)objc_lookUpClass ((const char *)(class_->super_class))); 966 else 967 return objc_lookUpClass ((const char *)(class_->super_class)); 968 } 969 970 /* If the class is not resolved yet, super_class would point to a 971 string (the name of the super class) as opposed to the actual 972 super class. In that case, we need to resolve the class links 973 before we can return super_class. */ 974 if (! CLS_ISRESOLV (class_)) 975 __objc_resolve_class_links (); 976 977 return class_->super_class; 978 } 979 980 int 981 class_getVersion (Class class_) 982 { 983 if (class_ == Nil) 984 return 0; 985 986 return (int)(class_->version); 987 } 988 989 void 990 class_setVersion (Class class_, int version) 991 { 992 if (class_ == Nil) 993 return; 994 995 class_->version = version; 996 } 997 998 size_t 999 class_getInstanceSize (Class class_) 1000 { 1001 if (class_ == Nil) 1002 return 0; 1003 1004 return class_->instance_size; 1005 } 1006 1007