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

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

unix.superglobalmegacorp.com

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