Annotation of gcc/objc/selector.c, revision 1.1.1.3

1.1       root        1: /* GNU Objective C Runtime selector related functions
1.1.1.3 ! root        2:    Copyright (C) 1993, 1995 Free Software Foundation, Inc.
        !             3:    Contributed by Kresten Krab Thorup
1.1       root        4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify it under the
1.1.1.3 ! root        8: terms of the GNU General Public License as published by the Free Software
        !             9: Foundation; either version 2, or (at your option) any later version.
1.1       root       10: 
                     11: GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
1.1.1.3 ! root       12: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
        !            13: FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
        !            14: details.
1.1       root       15: 
                     16: You should have received a copy of the GNU General Public License along with
1.1.1.3 ! root       17: GNU CC; see the file COPYING.  If not, write to the Free Software
        !            18: Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
1.1       root       19: 
                     20: /* As a special exception, if you link this library with files compiled with
                     21:    GCC to produce an executable, this does not cause the resulting executable
                     22:    to be covered by the GNU General Public License. This exception does not
                     23:    however invalidate any other reasons why the executable file might be
                     24:    covered by the GNU General Public License.  */
                     25: 
                     26: #include "runtime.h"
                     27: #include "objc/sarray.h"
1.1.1.2   root       28: #include "encoding.h"
1.1       root       29: 
1.1.1.3 ! root       30: /* Initial selector hash table size. Value doesn't matter much */
1.1       root       31: #define SELECTOR_HASH_SIZE 128
                     32: 
                     33: /* Tables mapping selector names to uid and opposite */
1.1.1.2   root       34: static struct sarray* __objc_selector_array = 0; /* uid -> sel */
                     35: static struct sarray* __objc_selector_names = 0; /* uid -> name */
1.1       root       36: static cache_ptr      __objc_selector_hash  = 0; /* name -> uid */
                     37: 
                     38: static void register_selectors_from_list(MethodList_t);
                     39: 
                     40: /* Number of selectors stored in each of the above tables */
                     41: int __objc_selector_max_index = 0;
                     42: 
                     43: void __objc_init_selector_tables()
                     44: {
                     45:   __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
1.1.1.2   root       46:   __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
1.1       root       47:   __objc_selector_hash
                     48:     = hash_new (SELECTOR_HASH_SIZE,
                     49:                (hash_func_type) hash_string,
                     50:                (compare_func_type) compare_strings);
                     51: }  
                     52: 
                     53: /* This routine is given a class and records all of the methods in its class
                     54:    structure in the record table.  */
                     55: void
1.1.1.3 ! root       56: __objc_register_selectors_from_class (Class class)
1.1       root       57: {
                     58:   MethodList_t method_list;
                     59: 
                     60:   method_list = class->methods;
                     61:   while (method_list)
                     62:     {
                     63:       register_selectors_from_list (method_list);
                     64:       method_list = method_list->method_next;
                     65:     }
                     66: }
                     67: 
                     68: 
                     69: /* This routine is given a list of methods and records each of the methods in
                     70:    the record table.  This is the routine that does the actual recording
                     71:    work.
                     72: 
                     73:    This one is only called for Class objects.  For categories,
                     74:    class_add_method_list is called.
                     75:    */
                     76: static void
                     77: register_selectors_from_list (MethodList_t method_list)
                     78: {
                     79:   int i = 0;
                     80:   while (i < method_list->method_count)
                     81:     {
                     82:       Method_t method = &method_list->method_list[i];
1.1.1.2   root       83:       method->method_name 
                     84:        = sel_register_typed_name ((const char*)method->method_name, 
                     85:                                     method->method_types);
1.1       root       86:       i += 1;
                     87:     }
                     88: }
                     89: 
1.1.1.2   root       90: 
                     91: /* Returns YES iff t1 and t2 have same method types, but we ignore
                     92:    the argframe layout */
                     93: BOOL
                     94: sel_types_match (const char* t1, const char* t2)
                     95: {
                     96:   if (!t1 || !t2)
                     97:     return NO;
                     98:   while (*t1 && *t2)
                     99:     {
                    100:       if (*t1 == '+') t1++;
                    101:       if (*t2 == '+') t2++;
                    102:       while (isdigit(*t1)) t1++;
                    103:       while (isdigit(*t2)) t2++;
                    104:       /* xxx Remove these next two lines when qualifiers are put in
                    105:         all selectors, not just Protocol selectors. */
                    106:       t1 = objc_skip_type_qualifiers(t1);
                    107:       t2 = objc_skip_type_qualifiers(t2);
                    108:       if (!*t1 && !*t2)
                    109:        return YES;
                    110:       if (*t1 != *t2)
                    111:        return NO;
                    112:       t1++;
                    113:       t2++;
                    114:     }
                    115:   return NO;
                    116: }
                    117: 
                    118: /* return selector representing name */
                    119: SEL
                    120: sel_get_typed_uid (const char *name, const char *types)
                    121: {
                    122:   struct objc_list *l;
                    123:   sidx i;
                    124: 
                    125:   i = (sidx) hash_value_for_key (__objc_selector_hash, name);
                    126:   if (i == 0)
                    127:     return 0;
                    128: 
                    129:   for (l = (struct objc_list*)sarray_get (__objc_selector_array, i);
                    130:        l; l = l->tail)
                    131:     {
                    132:       SEL s = (SEL)l->head;
                    133:       if (types == 0 || s->sel_types == 0)
                    134:        {
                    135:          if (s->sel_types == types)
                    136:            {
                    137:              return s;
                    138:            }
                    139:        }
                    140:       else if (sel_types_match (s->sel_types, types))
                    141:        {
                    142:          return s;
                    143:        }
                    144:     }
                    145: 
                    146:   return 0;
                    147: }
                    148: 
1.1.1.3 ! root      149: /* Return selector representing name; prefer a selector with non-NULL type */
        !           150: SEL
        !           151: sel_get_any_typed_uid (const char *name)
        !           152: {
        !           153:   struct objc_list *l;
        !           154:   sidx i;
        !           155:   SEL s;
        !           156: 
        !           157:   i = (sidx) hash_value_for_key (__objc_selector_hash, name);
        !           158:   if (i == 0)
        !           159:     return 0;
        !           160: 
        !           161:   for (l = (struct objc_list*)sarray_get (__objc_selector_array, i);
        !           162:        l; l = l->tail)
        !           163:     {
        !           164:       s = (SEL) l->head;
        !           165:       if (s->sel_types)
        !           166:        return s;
        !           167:     }
        !           168: 
        !           169:   return s;
        !           170: }
        !           171: 
1.1.1.2   root      172: /* return selector representing name */
                    173: SEL
                    174: sel_get_any_uid (const char *name)
                    175: {
                    176:   struct objc_list *l;
                    177:   sidx i;
                    178: 
                    179:   i = (sidx) hash_value_for_key (__objc_selector_hash, name);
                    180:   if (soffset_decode (i) == 0)
                    181:     return 0;
                    182: 
                    183:   l = (struct objc_list*)sarray_get (__objc_selector_array, i);
                    184:   if (l == 0)
                    185:     return 0;
                    186: 
                    187:   return (SEL)l->head;
                    188: }
                    189: 
1.1       root      190: /* return selector representing name */
                    191: SEL
                    192: sel_get_uid (const char *name)
                    193: {
1.1.1.2   root      194:   return sel_register_typed_name (name, 0);
1.1       root      195: }
                    196: 
                    197: /* Get name of selector.  If selector is unknown, the empty string "" 
                    198:    is returned */ 
                    199: const char*
                    200: sel_get_name (SEL selector)
                    201: {
1.1.1.2   root      202:   if ((soffset_decode((sidx)selector->sel_id) > 0)
                    203:       && (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index))
                    204:     return sarray_get (__objc_selector_names, (sidx) selector->sel_id);
1.1       root      205:   else
1.1.1.2   root      206:     return 0;
1.1       root      207: }
                    208: 
                    209: BOOL
                    210: sel_is_mapped (SEL selector)
                    211: {
1.1.1.2   root      212:   unsigned int idx = soffset_decode ((sidx)selector->sel_id);
1.1       root      213:   return ((idx > 0) && (idx <= __objc_selector_max_index));
                    214: }
                    215: 
1.1.1.2   root      216: 
                    217: const char*
                    218: sel_get_type (SEL selector)
                    219: {
                    220:   if (selector)
                    221:     return selector->sel_types;
                    222:   else
                    223:     return 0;
                    224: }
                    225: 
1.1       root      226: /* The uninstalled dispatch table */
                    227: extern struct sarray* __objc_uninstalled_dtable;
                    228: 
                    229: /* Store the passed selector name in the selector record and return its
                    230:    selector value (value returned by sel_get_uid). */
                    231: SEL
1.1.1.2   root      232: __sel_register_typed_name (const char *name, const char *types, 
                    233:                           struct objc_selector *orig)
1.1       root      234: {
1.1.1.2   root      235:   struct objc_selector* j;
1.1       root      236:   sidx i;
1.1.1.2   root      237:   struct objc_list *l;
1.1       root      238: 
1.1.1.2   root      239:   i = (sidx) hash_value_for_key (__objc_selector_hash, name);
                    240:   if (soffset_decode (i) != 0)
                    241:     {
                    242:       for (l = (struct objc_list*)sarray_get (__objc_selector_array, i);
                    243:           l; l = l->tail)
                    244:        {
                    245:          SEL s = (SEL)l->head;
                    246:          if (types == 0 || s->sel_types == 0)
                    247:            {
                    248:              if (s->sel_types == types)
                    249:                {
                    250:                  if (orig)
                    251:                    {
                    252:                      orig->sel_id = (void*)i;
                    253:                      return orig;
                    254:                    }
                    255:                  else
                    256:                    return s;
                    257:                }
                    258:            }
                    259:          else if (!strcmp (s->sel_types, types))
                    260:            {
                    261:              if (orig)
                    262:                {
                    263:                  orig->sel_id = (void*)i;
                    264:                  return orig;
                    265:                }
                    266:              else
                    267:                return s;
                    268:            }
                    269:        }
                    270:       if (orig)
                    271:        j = orig;
                    272:       else
                    273:        j = __objc_xmalloc (sizeof (struct objc_selector));
                    274: 
                    275:       j->sel_id = (void*)i;
                    276:       j->sel_types = (const char*)types;
                    277:       l = (struct objc_list*)sarray_get (__objc_selector_array, i);
                    278:     }
                    279:   else
                    280:     {
                    281:       __objc_selector_max_index += 1;
                    282:       i = soffset_encode(__objc_selector_max_index);
                    283:       if (orig)
                    284:        j = orig;
                    285:       else
                    286:        j = __objc_xmalloc (sizeof (struct objc_selector));
                    287:        
                    288:       j->sel_id = (void*)i;
                    289:       j->sel_types = (const char*)types;
                    290:       l = 0;
                    291:     }
1.1       root      292: 
1.1.1.2   root      293:   DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 
                    294:                soffset_decode (i));
                    295:   
                    296:   {
                    297:     int is_new = (l == 0);
                    298:     l = list_cons ((void*)j, l);
                    299:     sarray_at_put_safe (__objc_selector_names, i, (void *) name);
                    300:     sarray_at_put_safe (__objc_selector_array, i, (void *) l);
                    301:     if (is_new)
                    302:       hash_add (&__objc_selector_hash, (void *) name, (void *) i);
                    303:   }
1.1       root      304: 
1.1.1.2   root      305:   sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1);
1.1       root      306: 
1.1.1.2   root      307:   return (SEL) j;
                    308: }
1.1       root      309: 
1.1.1.2   root      310: SEL
                    311: sel_register_name (const char *name)
                    312: {
                    313:   return __sel_register_typed_name (name, 0, 0);
                    314: }
1.1       root      315: 
1.1.1.2   root      316: SEL
                    317: sel_register_typed_name (const char *name, const char *type)
                    318: {
                    319:   return __sel_register_typed_name (name, type, 0);
1.1       root      320: }
                    321: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.