X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libobjc%2Fselector.c;h=55ca7064bd2c80c3fc62de282464fc63a2673faf;hb=45f3982640ef8034c09b1f99806122525801e62d;hp=83c70e4ae0f17579e29c7ed3663069da3b87394a;hpb=8a7d0ecc89848fa1b5bd4af83609f07ee93d11e3;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libobjc/selector.c b/libobjc/selector.c index 83c70e4ae0f..55ca7064bd2 100644 --- a/libobjc/selector.c +++ b/libobjc/selector.c @@ -1,136 +1,198 @@ /* GNU Objective C Runtime selector related functions - Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004, 2009, 2010 + Free Software Foundation, Inc. Contributed by Kresten Krab Thorup -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify it under the +GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. +Foundation; either version 3, or (at your option) any later version. -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY +GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "runtime.h" -#include "objc/sarray.h" -#include "encoding.h" - -/* Initial selector hash table size. Value doesn't matter much */ +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "objc-private/common.h" +#include "objc/runtime.h" +#include "objc/thr.h" +#include "objc-private/hash.h" +#include "objc-private/objc-list.h" +#include "objc-private/module-abi-8.h" +#include "objc-private/runtime.h" +#include "objc-private/sarray.h" +#include "objc-private/selector.h" +#include /* For malloc. */ + +/* Initial selector hash table size. Value doesn't matter much. */ #define SELECTOR_HASH_SIZE 128 -/* Tables mapping selector names to uid and opposite */ -static struct sarray* __objc_selector_array = 0; /* uid -> sel !T:MUTEX */ -static struct sarray* __objc_selector_names = 0; /* uid -> name !T:MUTEX */ +/* Tables mapping selector names to uid and opposite. */ +static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */ +static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */ static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */ -static void register_selectors_from_list(MethodList_t); +/* Number of selectors stored in each of the above tables. */ +unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */ -/* Number of selectors stored in each of the above tables */ -int __objc_selector_max_index = 0; /* !T:MUTEX */ +/* Forward-declare an internal function. */ +static SEL +__sel_register_typed_name (const char *name, const char *types, + struct objc_selector *orig, BOOL is_const); -void __objc_init_selector_tables() +void __objc_init_selector_tables (void) { __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0); __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0); __objc_selector_hash - = hash_new (SELECTOR_HASH_SIZE, - (hash_func_type) hash_string, - (compare_func_type) compare_strings); + = objc_hash_new (SELECTOR_HASH_SIZE, + (hash_func_type) objc_hash_string, + (compare_func_type) objc_compare_strings); } -/* This routine is given a class and records all of the methods in its class - structure in the record table. */ +/* Register a bunch of selectors from the table of selectors in a + module. 'selectors' should not be NULL. The list is terminated by + a selectors with a NULL sel_id. The selectors are assumed to + contain the 'name' in the sel_id field; this is replaced with the + final selector id after they are registered. */ +void +__objc_register_selectors_from_module (struct objc_selector *selectors) +{ + int i; + + for (i = 0; selectors[i].sel_id; ++i) + { + const char *name, *type; + name = (char *) selectors[i].sel_id; + type = (char *) selectors[i].sel_types; + /* Constructors are constant static data and we can safely store + pointers to them in the runtime structures, so we set + is_const == YES. */ + __sel_register_typed_name (name, type, (struct objc_selector *) &(selectors[i]), + /* is_const */ YES); + } +} + +/* This routine is given a class and records all of the methods in its + class structure in the record table. */ void __objc_register_selectors_from_class (Class class) { - MethodList_t method_list; + struct objc_method_list * method_list; method_list = class->methods; while (method_list) { - register_selectors_from_list (method_list); + __objc_register_selectors_from_list (method_list); method_list = method_list->method_next; } } -/* This routine is given a list of methods and records each of the methods in - the record table. This is the routine that does the actual recording - work. +/* This routine is given a list of methods and records each of the + methods in the record table. This is the routine that does the + actual recording work. - This one is only called for Class objects. For categories, - class_add_method_list is called. - */ -static void -register_selectors_from_list (MethodList_t method_list) + The name and type pointers in the method list must be permanent and + immutable. */ +void +__objc_register_selectors_from_list (struct objc_method_list *method_list) { int i = 0; + + objc_mutex_lock (__objc_runtime_mutex); while (i < method_list->method_count) { - Method_t method = &method_list->method_list[i]; - method->method_name - = sel_register_typed_name ((const char*)method->method_name, - method->method_types); + Method method = &method_list->method_list[i]; + if (method->method_name) + { + method->method_name + = __sel_register_typed_name ((const char *) method->method_name, + method->method_types, 0, YES); + } i += 1; } + objc_mutex_unlock (__objc_runtime_mutex); } +/* The same as __objc_register_selectors_from_list, but works on a + struct objc_method_description_list* instead of a struct + objc_method_list*. This is only used for protocols, which have + lists of method descriptions, not methods. */ +void +__objc_register_selectors_from_description_list +(struct objc_method_description_list *method_list) +{ + int i = 0; + + objc_mutex_lock (__objc_runtime_mutex); + while (i < method_list->count) + { + struct objc_method_description *method = &method_list->list[i]; + if (method->name) + { + method->name + = __sel_register_typed_name ((const char *) method->name, + method->types, 0, YES); + } + i += 1; + } + objc_mutex_unlock (__objc_runtime_mutex); +} -/* Register instance methods as class methods for root classes */ -void __objc_register_instance_methods_to_class(Class class) +/* Register instance methods as class methods for root classes. */ +void __objc_register_instance_methods_to_class (Class class) { - MethodList_t method_list; - MethodList_t class_method_list; + struct objc_method_list *method_list; + struct objc_method_list *class_method_list; int max_methods_no = 16; - MethodList_t new_list; - Method_t curr_method; + struct objc_method_list *new_list; + Method curr_method; /* Only if a root class. */ - if(class->super_class) + if (class->super_class) return; - /* Allocate a method list to hold the new class methods */ - new_list = objc_calloc(sizeof(struct objc_method_list) - + sizeof(struct objc_method[max_methods_no]), 1); + /* Allocate a method list to hold the new class methods. */ + new_list = objc_calloc (sizeof (struct objc_method_list) + + sizeof (struct objc_method[max_methods_no]), 1); method_list = class->methods; class_method_list = class->class_pointer->methods; curr_method = &new_list->method_list[0]; - - /* Iterate through the method lists for the class */ + + /* Iterate through the method lists for the class. */ while (method_list) { int i; - - /* Iterate through the methods from this method list */ + + /* Iterate through the methods from this method list. */ for (i = 0; i < method_list->method_count; i++) { - Method_t mth = &method_list->method_list[i]; + Method mth = &method_list->method_list[i]; if (mth->method_name - && !search_for_method_in_list (class_method_list, + && ! search_for_method_in_list (class_method_list, mth->method_name)) { - /* This instance method isn't a class method. - Add it into the new_list. */ + /* This instance method isn't a class method. Add it + into the new_list. */ *curr_method = *mth; - - /* Reallocate the method list if necessary */ - if(++new_list->method_count == max_methods_no) + + /* Reallocate the method list if necessary. */ + if (++new_list->method_count == max_methods_no) new_list = - objc_realloc(new_list, sizeof(struct objc_method_list) - + sizeof(struct - objc_method[max_methods_no += 16])); + objc_realloc (new_list, sizeof (struct objc_method_list) + + sizeof (struct + objc_method[max_methods_no += 16])); curr_method = &new_list->method_list[new_list->method_count]; } } @@ -138,39 +200,49 @@ void __objc_register_instance_methods_to_class(Class class) method_list = method_list->method_next; } - /* If we created any new class methods - then attach the method list to the class */ + /* If we created any new class methods then attach the method list + to the class. */ if (new_list->method_count) { new_list = - objc_realloc(new_list, sizeof(struct objc_method_list) - + sizeof(struct objc_method[new_list->method_count])); + objc_realloc (new_list, sizeof (struct objc_method_list) + + sizeof (struct objc_method[new_list->method_count])); new_list->method_next = class->class_pointer->methods; class->class_pointer->methods = new_list; } - - __objc_update_dispatch_table_for_class (class->class_pointer); + else + objc_free(new_list); + + __objc_update_dispatch_table_for_class (class->class_pointer); } - -/* Returns YES iff t1 and t2 have same method types, but we ignore - the argframe layout */ BOOL -sel_types_match (const char* t1, const char* t2) +sel_isEqual (SEL s1, SEL s2) +{ + if (s1 == 0 || s2 == 0) + return s1 == s2; + else + return s1->sel_id == s2->sel_id; +} + +/* Return YES iff t1 and t2 have same method types. Ignore the + argframe layout. */ +static BOOL +sel_types_match (const char *t1, const char *t2) { - if (!t1 || !t2) + if (! t1 || ! t2) return NO; while (*t1 && *t2) { if (*t1 == '+') t1++; if (*t2 == '+') t2++; - while (isdigit(*t1)) t1++; - while (isdigit(*t2)) t2++; + while (isdigit ((unsigned char) *t1)) t1++; + while (isdigit ((unsigned char) *t2)) t2++; /* xxx Remove these next two lines when qualifiers are put in - all selectors, not just Protocol selectors. */ - t1 = objc_skip_type_qualifiers(t1); - t2 = objc_skip_type_qualifiers(t2); - if (!*t1 && !*t2) + all selectors, not just Protocol selectors. */ + t1 = objc_skip_type_qualifiers (t1); + t2 = objc_skip_type_qualifiers (t2); + if (! *t1 && ! *t2) return YES; if (*t1 != *t2) return NO; @@ -180,123 +252,167 @@ sel_types_match (const char* t1, const char* t2) return NO; } -/* return selector representing name */ +/* Return selector representing name. */ SEL -sel_get_typed_uid (const char *name, const char *types) +sel_get_any_uid (const char *name) { struct objc_list *l; sidx i; - objc_mutex_lock(__objc_runtime_mutex); + objc_mutex_lock (__objc_runtime_mutex); - i = (sidx) hash_value_for_key (__objc_selector_hash, name); - if (i == 0) + i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); + if (soffset_decode (i) == 0) { - objc_mutex_unlock(__objc_runtime_mutex); + objc_mutex_unlock (__objc_runtime_mutex); return 0; } - for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - l; l = l->tail) - { - SEL s = (SEL)l->head; - if (types == 0 || s->sel_types == 0) - { - if (s->sel_types == types) - { - objc_mutex_unlock(__objc_runtime_mutex); - return s; - } - } - else if (sel_types_match (s->sel_types, types)) - { - objc_mutex_unlock(__objc_runtime_mutex); - return s; - } - } + l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i); + objc_mutex_unlock (__objc_runtime_mutex); - objc_mutex_unlock(__objc_runtime_mutex); - return 0; + if (l == 0) + return 0; + + return (SEL) l->head; } -/* Return selector representing name; prefer a selector with non-NULL type */ SEL -sel_get_any_typed_uid (const char *name) +sel_getTypedSelector (const char *name) { - struct objc_list *l; sidx i; - SEL s = NULL; - - objc_mutex_lock(__objc_runtime_mutex); - i = (sidx) hash_value_for_key (__objc_selector_hash, name); - if (i == 0) + if (name == NULL) + return NULL; + + objc_mutex_lock (__objc_runtime_mutex); + + /* Look for a typed selector. */ + i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); + if (i != 0) { - objc_mutex_unlock(__objc_runtime_mutex); - return 0; - } + struct objc_list *l; + SEL returnValue = NULL; - for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - l; l = l->tail) - { - s = (SEL) l->head; - if (s->sel_types) + for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i); + l; l = l->tail) { - objc_mutex_unlock(__objc_runtime_mutex); - return s; + SEL s = (SEL) l->head; + if (s->sel_types) + { + if (returnValue == NULL) + { + /* First typed selector that we find. Keep it in + returnValue, but keep checking as we want to + detect conflicts. */ + returnValue = s; + } + else + { + /* We had already found a typed selectors, so we + have multiple ones. Double-check that they have + different types, just in case for some reason we + got duplicates with the same types. If so, it's + OK, we'll ignore the duplicate. */ + if (returnValue->sel_types == s->sel_types) + continue; + else if (sel_types_match (returnValue->sel_types, s->sel_types)) + continue; + else + { + /* The types of the two selectors are different; + it's a conflict. Too bad. Return NULL. */ + objc_mutex_unlock (__objc_runtime_mutex); + return NULL; + } + } + } + } + + if (returnValue != NULL) + { + objc_mutex_unlock (__objc_runtime_mutex); + return returnValue; } } - objc_mutex_unlock(__objc_runtime_mutex); - return s; + /* No typed selector found. Return NULL. */ + objc_mutex_unlock (__objc_runtime_mutex); + return 0; } -/* return selector representing name */ -SEL -sel_get_any_uid (const char *name) +SEL * +sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors) { - struct objc_list *l; + unsigned int count = 0; + SEL *returnValue = NULL; sidx i; - - objc_mutex_lock(__objc_runtime_mutex); - - i = (sidx) hash_value_for_key (__objc_selector_hash, name); - if (soffset_decode (i) == 0) + + if (name == NULL) { - objc_mutex_unlock(__objc_runtime_mutex); - return 0; + if (numberOfReturnedSelectors) + *numberOfReturnedSelectors = 0; + return NULL; } - l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - objc_mutex_unlock(__objc_runtime_mutex); + objc_mutex_lock (__objc_runtime_mutex); - if (l == 0) - return 0; + /* Count how many selectors we have. */ + i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); + if (i != 0) + { + struct objc_list *selector_list = NULL; + selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i); + + /* Count how many selectors we have. */ + { + struct objc_list *l; + for (l = selector_list; l; l = l->tail) + count++; + } - return (SEL)l->head; -} + if (count != 0) + { + /* Allocate enough memory to hold them. */ + returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1))); + + /* Copy the selectors. */ + { + unsigned int j; + for (j = 0; j < count; j++) + { + returnValue[j] = (SEL)(selector_list->head); + selector_list = selector_list->tail; + } + returnValue[j] = NULL; + } + } + } -/* return selector representing name */ -SEL -sel_get_uid (const char *name) -{ - return sel_register_typed_name (name, 0); + objc_mutex_unlock (__objc_runtime_mutex); + + if (numberOfReturnedSelectors) + *numberOfReturnedSelectors = count; + + return returnValue; } -/* Get name of selector. If selector is unknown, the empty string "" - is returned */ -const char* -sel_get_name (SEL selector) +/* Get the name of a selector. If the selector is unknown, the empty + string "" is returned. */ +const char *sel_getName (SEL selector) { const char *ret; - objc_mutex_lock(__objc_runtime_mutex); - if ((soffset_decode((sidx)selector->sel_id) > 0) - && (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index)) + if (selector == NULL) + return ""; + + objc_mutex_lock (__objc_runtime_mutex); + if ((soffset_decode ((sidx)selector->sel_id) > 0) + && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index)) ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id); else ret = 0; - objc_mutex_unlock(__objc_runtime_mutex); + objc_mutex_unlock (__objc_runtime_mutex); return ret; } @@ -307,9 +423,7 @@ sel_is_mapped (SEL selector) return ((idx > 0) && (idx <= __objc_selector_max_index)); } - -const char* -sel_get_type (SEL selector) +const char *sel_getTypeEncoding (SEL selector) { if (selector) return selector->sel_types; @@ -317,28 +431,64 @@ sel_get_type (SEL selector) return 0; } -/* The uninstalled dispatch table */ -extern struct sarray* __objc_uninstalled_dtable; +/* The uninstalled dispatch table. */ +extern struct sarray *__objc_uninstalled_dtable; -/* Store the passed selector name in the selector record and return its - selector value (value returned by sel_get_uid). - Assumes that the calling function has locked down __objc_runtime_mutex. */ -/* is_const parameter tells us if the name and types parameters - are really constant or not. If YES then they are constant and - we can just store the pointers. If NO then we need to copy - name and types because the pointers may disappear later on. */ -SEL +/* __sel_register_typed_name allocates lots of struct objc_selector:s + of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the + number of malloc calls and memory lost to malloc overhead, we + allocate objc_selector:s in blocks here. This is only called from + __sel_register_typed_name, and __sel_register_typed_name may only + be called when __objc_runtime_mutex is locked. + + Note that the objc_selector:s allocated from + __sel_register_typed_name are never freed. + + 62 because 62 * sizeof (struct objc_selector) = 496 (992). This + should let malloc add some overhead and use a nice, round 512 + (1024) byte chunk. */ +#define SELECTOR_POOL_SIZE 62 +static struct objc_selector *selector_pool; +static int selector_pool_left; + +static struct objc_selector * +pool_alloc_selector(void) +{ + if (!selector_pool_left) + { + selector_pool = objc_malloc (sizeof (struct objc_selector) + * SELECTOR_POOL_SIZE); + selector_pool_left = SELECTOR_POOL_SIZE; + } + return &selector_pool[--selector_pool_left]; +} + +/* Store the passed selector name in the selector record and return + its selector value (value returned by sel_get_uid). Assume that + the calling function has locked down __objc_runtime_mutex. The + 'is_const' parameter tells us if the name and types parameters are + really constant or not. If YES then they are constant and we can + just store the pointers. If NO then we need to copy name and types + because the pointers may disappear later on. If the 'orig' + parameter is not NULL, then we are registering a selector from a + module, and 'orig' is that selector. In this case, we can put the + selector in the tables if needed, and orig->sel_id is updated with + the selector ID of the registered selector, and 'orig' is + returned. */ +static SEL __sel_register_typed_name (const char *name, const char *types, struct objc_selector *orig, BOOL is_const) { - struct objc_selector* j; + struct objc_selector *j; sidx i; struct objc_list *l; - i = (sidx) hash_value_for_key (__objc_selector_hash, name); + i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); if (soffset_decode (i) != 0) { - for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); + /* There are already selectors with that name. Examine them to + see if the one we're registering already exists. */ + for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i); l; l = l->tail) { SEL s = (SEL)l->head; @@ -348,111 +498,144 @@ __sel_register_typed_name (const char *name, const char *types, { if (orig) { - orig->sel_id = (void*)i; + orig->sel_id = (void *)i; return orig; } else return s; } } - else if (!strcmp (s->sel_types, types)) + else if (sel_types_match (s->sel_types, types)) { if (orig) { - orig->sel_id = (void*)i; + orig->sel_id = (void *)i; return orig; } else return s; } } + /* A selector with this specific name/type combination does not + exist yet. We need to register it. */ if (orig) j = orig; else - j = objc_malloc (sizeof (struct objc_selector)); - - j->sel_id = (void*)i; - /* Can we use the pointer or must copy types? Don't copy if NULL */ + j = pool_alloc_selector (); + + j->sel_id = (void *)i; + /* Can we use the pointer or must we copy types ? Don't copy if + NULL. */ if ((is_const) || (types == 0)) - j->sel_types = (const char*)types; - else { - j->sel_types = (char *) objc_malloc(strlen(types)+1); - strcpy((char *)j->sel_types, types); - } - l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); + j->sel_types = types; + else + { + j->sel_types = (char *)objc_malloc (strlen (types) + 1); + strcpy ((char *)j->sel_types, types); + } + l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i); } else { + /* There are no other selectors with this name registered in the + runtime tables. */ + const char *new_name; + + /* Determine i. */ __objc_selector_max_index += 1; - i = soffset_encode(__objc_selector_max_index); + i = soffset_encode (__objc_selector_max_index); + + /* Prepare the selector. */ if (orig) j = orig; else - j = objc_malloc (sizeof (struct objc_selector)); - - j->sel_id = (void*)i; - /* Can we use the pointer or must copy types? Don't copy if NULL */ - if ((is_const) || (types == 0)) - j->sel_types = (const char*)types; - else { - j->sel_types = (char *) objc_malloc(strlen(types)+1); - strcpy((char *)j->sel_types, types); - } + j = pool_alloc_selector (); + + j->sel_id = (void *)i; + /* Can we use the pointer or must we copy types ? Don't copy if + NULL. */ + if (is_const || (types == 0)) + j->sel_types = types; + else + { + j->sel_types = (char *)objc_malloc (strlen (types) + 1); + strcpy ((char *)j->sel_types, types); + } + + /* Since this is the first selector with this name, we need to + register the correspondence between 'i' (the sel_id) and + 'name' (the actual string) in __objc_selector_names and + __objc_selector_hash. */ + + /* Can we use the pointer or must we copy name ? Don't copy if + NULL. (FIXME: Can the name really be NULL here ?) */ + if (is_const || (name == 0)) + new_name = name; + else + { + new_name = (char *)objc_malloc (strlen (name) + 1); + strcpy ((char *)new_name, name); + } + + /* This maps the sel_id to the name. */ + sarray_at_put_safe (__objc_selector_names, i, (void *)new_name); + + /* This maps the name to the sel_id. */ + objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i); + l = 0; } DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, - soffset_decode (i)); - - { - int is_new = (l == 0); - const char *new_name; - - /* Can we use the pointer or must copy name? Don't copy if NULL */ - if ((is_const) || (name == 0)) - new_name = name; - else { - new_name = (char *) objc_malloc(strlen(name)+1); - strcpy((char *)new_name, name); - } - - l = list_cons ((void*)j, l); - sarray_at_put_safe (__objc_selector_names, i, (void *) new_name); - sarray_at_put_safe (__objc_selector_array, i, (void *) l); - if (is_new) - hash_add (&__objc_selector_hash, (void *) new_name, (void *) i); - } + (long)soffset_decode (i)); - sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1); + /* Now add the selector to the list of selectors with that id. */ + l = list_cons ((void *)j, l); + sarray_at_put_safe (__objc_selector_array, i, (void *)l); - return (SEL) j; + sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1); + + return (SEL)j; } SEL -sel_register_name (const char *name) +sel_registerName (const char *name) { SEL ret; + + if (name == NULL) + return NULL; - objc_mutex_lock(__objc_runtime_mutex); + objc_mutex_lock (__objc_runtime_mutex); /* Assume that name is not constant static memory and needs to be - copied before put into a runtime structure. is_const == NO */ + copied before put into a runtime structure. is_const == NO. */ ret = __sel_register_typed_name (name, 0, 0, NO); - objc_mutex_unlock(__objc_runtime_mutex); + objc_mutex_unlock (__objc_runtime_mutex); return ret; } SEL -sel_register_typed_name (const char *name, const char *type) +sel_registerTypedName (const char *name, const char *type) { SEL ret; - - objc_mutex_lock(__objc_runtime_mutex); - /* Assume that name and type are not constant static memory and need to - be copied before put into a runtime structure. is_const == NO */ + + if (name == NULL) + return NULL; + + objc_mutex_lock (__objc_runtime_mutex); + /* Assume that name and type are not constant static memory and need + to be copied before put into a runtime structure. is_const == + NO. */ ret = __sel_register_typed_name (name, type, 0, NO); - objc_mutex_unlock(__objc_runtime_mutex); + objc_mutex_unlock (__objc_runtime_mutex); return ret; } +/* Return the selector representing name. */ +SEL +sel_getUid (const char *name) +{ + return sel_registerTypedName (name, 0); +}