OSDN Git Service

2011-09-27 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / libobjc / selector.c
1 /* GNU Objective C Runtime selector related functions
2    Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004, 2009, 2010
3    Free Software Foundation, Inc.
4    Contributed by Kresten Krab Thorup
5
6 This file is part of GCC.
7
8 GCC 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 3, or (at your option) any later version.
11
12 GCC 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 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 <http://www.gnu.org/licenses/>.  */
25
26 #include "objc-private/common.h"
27 #include "objc/runtime.h"
28 #include "objc/thr.h"
29 #include "objc-private/hash.h"
30 #include "objc-private/objc-list.h"
31 #include "objc-private/module-abi-8.h"
32 #include "objc-private/runtime.h"
33 #include "objc-private/sarray.h"
34 #include "objc-private/selector.h"
35 #include <stdlib.h>                    /* For malloc.  */
36
37 /* Initial selector hash table size. Value doesn't matter much.  */
38 #define SELECTOR_HASH_SIZE 128
39
40 /* Tables mapping selector names to uid and opposite.  */
41 static struct sarray *__objc_selector_array = 0; /* uid -> sel  !T:MUTEX */
42 static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
43 static cache_ptr      __objc_selector_hash  = 0; /* name -> uid !T:MUTEX */
44
45 /* Number of selectors stored in each of the above tables.  */
46 unsigned int __objc_selector_max_index = 0;     /* !T:MUTEX */
47
48 /* Forward-declare an internal function.  */
49 static SEL
50 __sel_register_typed_name (const char *name, const char *types,
51                            struct objc_selector *orig, BOOL is_const);
52
53 void __objc_init_selector_tables (void)
54 {
55   __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
56   __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
57   __objc_selector_hash
58     = objc_hash_new (SELECTOR_HASH_SIZE,
59                      (hash_func_type) objc_hash_string,
60                      (compare_func_type) objc_compare_strings);
61 }  
62
63 /* Register a bunch of selectors from the table of selectors in a
64    module.  'selectors' should not be NULL.  The list is terminated by
65    a selectors with a NULL sel_id.  The selectors are assumed to
66    contain the 'name' in the sel_id field; this is replaced with the
67    final selector id after they are registered.  */
68 void
69 __objc_register_selectors_from_module (struct objc_selector *selectors)
70 {
71   int i;
72
73   for (i = 0; selectors[i].sel_id; ++i)
74     {
75       const char *name, *type;
76       name = (char *) selectors[i].sel_id;
77       type = (char *) selectors[i].sel_types;
78       /* Constructors are constant static data and we can safely store
79          pointers to them in the runtime structures, so we set
80          is_const == YES.  */
81       __sel_register_typed_name (name, type, (struct objc_selector *) &(selectors[i]),
82                                  /* is_const */ YES);
83     }
84 }
85
86 /* This routine is given a class and records all of the methods in its
87    class structure in the record table.  */
88 void
89 __objc_register_selectors_from_class (Class class)
90 {
91   struct objc_method_list * method_list;
92
93   method_list = class->methods;
94   while (method_list)
95     {
96       __objc_register_selectors_from_list (method_list);
97       method_list = method_list->method_next;
98     }
99 }
100
101
102 /* This routine is given a list of methods and records each of the
103    methods in the record table.  This is the routine that does the
104    actual recording work.
105
106    The name and type pointers in the method list must be permanent and
107    immutable.  */
108 void
109 __objc_register_selectors_from_list (struct objc_method_list *method_list)
110 {
111   int i = 0;
112
113   objc_mutex_lock (__objc_runtime_mutex);
114   while (i < method_list->method_count)
115     {
116       Method method = &method_list->method_list[i];
117       if (method->method_name)
118         {
119           method->method_name
120             = __sel_register_typed_name ((const char *) method->method_name,
121                                          method->method_types, 0, YES);
122         }
123       i += 1;
124     }
125   objc_mutex_unlock (__objc_runtime_mutex);
126 }
127
128 /* The same as __objc_register_selectors_from_list, but works on a
129    struct objc_method_description_list* instead of a struct
130    objc_method_list*.  This is only used for protocols, which have
131    lists of method descriptions, not methods.  */
132 void
133 __objc_register_selectors_from_description_list 
134 (struct objc_method_description_list *method_list)
135 {
136   int i = 0;
137   
138   objc_mutex_lock (__objc_runtime_mutex);
139   while (i < method_list->count)
140     {
141       struct objc_method_description *method = &method_list->list[i];
142       if (method->name)
143         {
144           method->name
145             = __sel_register_typed_name ((const char *) method->name,
146                                          method->types, 0, YES);
147         }
148       i += 1;
149     }
150   objc_mutex_unlock (__objc_runtime_mutex);
151 }
152
153 /* Register instance methods as class methods for root classes.  */
154 void __objc_register_instance_methods_to_class (Class class)
155 {
156   struct objc_method_list *method_list;
157   struct objc_method_list *class_method_list;
158   int max_methods_no = 16;
159   struct objc_method_list *new_list;
160   Method curr_method;
161
162   /* Only if a root class. */
163   if (class->super_class)
164     return;
165
166   /* Allocate a method list to hold the new class methods.  */
167   new_list = objc_calloc (sizeof (struct objc_method_list)
168                           + sizeof (struct objc_method[max_methods_no]), 1);
169   method_list = class->methods;
170   class_method_list = class->class_pointer->methods;
171   curr_method = &new_list->method_list[0];
172   
173   /* Iterate through the method lists for the class.  */
174   while (method_list)
175     {
176       int i;
177       
178       /* Iterate through the methods from this method list.  */
179       for (i = 0; i < method_list->method_count; i++)
180         {
181           Method mth = &method_list->method_list[i];
182           if (mth->method_name
183               && ! search_for_method_in_list (class_method_list,
184                                               mth->method_name))
185             {
186               /* This instance method isn't a class method.  Add it
187                  into the new_list. */
188               *curr_method = *mth;
189               
190               /* Reallocate the method list if necessary.  */
191               if (++new_list->method_count == max_methods_no)
192                 new_list =
193                   objc_realloc (new_list, sizeof (struct objc_method_list)
194                                 + sizeof (struct 
195                                           objc_method[max_methods_no += 16]));
196               curr_method = &new_list->method_list[new_list->method_count];
197             }
198         }
199
200       method_list = method_list->method_next;
201     }
202
203   /* If we created any new class methods then attach the method list
204      to the class.  */
205   if (new_list->method_count)
206     {
207       new_list =
208         objc_realloc (new_list, sizeof (struct objc_method_list)
209                       + sizeof (struct objc_method[new_list->method_count]));
210       new_list->method_next = class->class_pointer->methods;
211       class->class_pointer->methods = new_list;
212     }
213   else
214     objc_free(new_list);
215   
216   __objc_update_dispatch_table_for_class (class->class_pointer);
217 }
218
219 BOOL
220 sel_isEqual (SEL s1, SEL s2)
221 {
222   if (s1 == 0 || s2 == 0)
223     return s1 == s2;
224   else
225     return s1->sel_id == s2->sel_id;
226 }
227
228 /* Return YES iff t1 and t2 have same method types.  Ignore the
229    argframe layout.  */
230 static BOOL
231 sel_types_match (const char *t1, const char *t2)
232 {
233   if (! t1 || ! t2)
234     return NO;
235   while (*t1 && *t2)
236     {
237       if (*t1 == '+') t1++;
238       if (*t2 == '+') t2++;
239       while (isdigit ((unsigned char) *t1)) t1++;
240       while (isdigit ((unsigned char) *t2)) t2++;
241       /* xxx Remove these next two lines when qualifiers are put in
242          all selectors, not just Protocol selectors.  */
243       t1 = objc_skip_type_qualifiers (t1);
244       t2 = objc_skip_type_qualifiers (t2);
245       if (! *t1 && ! *t2)
246         return YES;
247       if (*t1 != *t2)
248         return NO;
249       t1++;
250       t2++;
251     }
252   return NO;
253 }
254
255 /* Return selector representing name.  */
256 SEL
257 sel_get_any_uid (const char *name)
258 {
259   struct objc_list *l;
260   sidx i;
261
262   objc_mutex_lock (__objc_runtime_mutex);
263
264   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
265   if (soffset_decode (i) == 0)
266     {
267       objc_mutex_unlock (__objc_runtime_mutex);
268       return 0;
269     }
270
271   l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
272   objc_mutex_unlock (__objc_runtime_mutex);
273
274   if (l == 0)
275     return 0;
276
277   return (SEL) l->head;
278 }
279
280 SEL
281 sel_getTypedSelector (const char *name)
282 {
283   sidx i;
284
285   if (name == NULL)
286     return NULL;
287   
288   objc_mutex_lock (__objc_runtime_mutex);
289   
290   /* Look for a typed selector.  */
291   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
292   if (i != 0)
293     {
294       struct objc_list *l;
295       SEL returnValue = NULL;
296
297       for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
298            l; l = l->tail)
299         {
300           SEL s = (SEL) l->head;
301           if (s->sel_types)
302             {
303               if (returnValue == NULL)
304                 {
305                   /* First typed selector that we find.  Keep it in
306                      returnValue, but keep checking as we want to
307                      detect conflicts.  */
308                   returnValue = s;
309                 }
310               else
311                 {
312                   /* We had already found a typed selectors, so we
313                      have multiple ones.  Double-check that they have
314                      different types, just in case for some reason we
315                      got duplicates with the same types.  If so, it's
316                      OK, we'll ignore the duplicate.  */
317                   if (returnValue->sel_types == s->sel_types)
318                     continue;
319                   else if (sel_types_match (returnValue->sel_types, s->sel_types))
320                     continue;
321                   else
322                     {
323                       /* The types of the two selectors are different;
324                          it's a conflict.  Too bad.  Return NULL.  */
325                       objc_mutex_unlock (__objc_runtime_mutex);
326                       return NULL;
327                     }
328                 }
329             }
330         }
331
332       if (returnValue != NULL)
333         {
334           objc_mutex_unlock (__objc_runtime_mutex);
335           return returnValue;
336         }
337     }
338
339   /* No typed selector found.  Return NULL.  */
340   objc_mutex_unlock (__objc_runtime_mutex);
341   return 0;
342 }
343
344 SEL *
345 sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
346 {
347   unsigned int count = 0;
348   SEL *returnValue = NULL;
349   sidx i;
350   
351   if (name == NULL)
352     {
353       if (numberOfReturnedSelectors)
354         *numberOfReturnedSelectors = 0;
355       return NULL;
356     }
357
358   objc_mutex_lock (__objc_runtime_mutex);
359
360   /* Count how many selectors we have.  */
361   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
362   if (i != 0)
363     {
364       struct objc_list *selector_list = NULL;
365       selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
366
367       /* Count how many selectors we have.  */
368       {
369         struct objc_list *l;
370         for (l = selector_list; l; l = l->tail)
371           count++;
372       }
373
374       if (count != 0)
375         {
376           /* Allocate enough memory to hold them.  */
377           returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
378           
379           /* Copy the selectors.  */
380           {
381             unsigned int j;
382             for (j = 0; j < count; j++)
383               {
384                 returnValue[j] = (SEL)(selector_list->head);
385                 selector_list = selector_list->tail;
386               }
387             returnValue[j] = NULL;
388           }
389         }
390     }      
391
392   objc_mutex_unlock (__objc_runtime_mutex);
393   
394   if (numberOfReturnedSelectors)
395     *numberOfReturnedSelectors = count;
396   
397   return returnValue;
398 }
399
400 /* Get the name of a selector.  If the selector is unknown, the empty
401    string "" is returned.  */ 
402 const char *sel_getName (SEL selector)
403 {
404   const char *ret;
405
406   if (selector == NULL)
407     return "<null selector>";
408   
409   objc_mutex_lock (__objc_runtime_mutex);
410   if ((soffset_decode ((sidx)selector->sel_id) > 0)
411       && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
412     ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
413   else
414     ret = 0;
415   objc_mutex_unlock (__objc_runtime_mutex);
416   return ret;
417 }
418
419 BOOL
420 sel_is_mapped (SEL selector)
421 {
422   unsigned int idx = soffset_decode ((sidx)selector->sel_id);
423   return ((idx > 0) && (idx <= __objc_selector_max_index));
424 }
425
426 const char *sel_getTypeEncoding (SEL selector)
427 {
428   if (selector)
429     return selector->sel_types;
430   else
431     return 0;
432 }
433
434 /* The uninstalled dispatch table.  */
435 extern struct sarray *__objc_uninstalled_dtable;
436
437 /* __sel_register_typed_name allocates lots of struct objc_selector:s
438    of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
439    number of malloc calls and memory lost to malloc overhead, we
440    allocate objc_selector:s in blocks here. This is only called from
441    __sel_register_typed_name, and __sel_register_typed_name may only
442    be called when __objc_runtime_mutex is locked.
443
444    Note that the objc_selector:s allocated from
445    __sel_register_typed_name are never freed.
446
447    62 because 62 * sizeof (struct objc_selector) = 496 (992). This
448    should let malloc add some overhead and use a nice, round 512
449    (1024) byte chunk.  */
450 #define SELECTOR_POOL_SIZE 62
451 static struct objc_selector *selector_pool;
452 static int selector_pool_left;
453
454 static struct objc_selector *
455 pool_alloc_selector(void)
456 {
457   if (!selector_pool_left)
458     {
459       selector_pool = objc_malloc (sizeof (struct objc_selector)
460                                    * SELECTOR_POOL_SIZE);
461       selector_pool_left = SELECTOR_POOL_SIZE;
462     }
463   return &selector_pool[--selector_pool_left];
464 }
465
466 /* Store the passed selector name in the selector record and return
467    its selector value (value returned by sel_get_uid).  Assume that
468    the calling function has locked down __objc_runtime_mutex.  The
469    'is_const' parameter tells us if the name and types parameters are
470    really constant or not.  If YES then they are constant and we can
471    just store the pointers.  If NO then we need to copy name and types
472    because the pointers may disappear later on.  If the 'orig'
473    parameter is not NULL, then we are registering a selector from a
474    module, and 'orig' is that selector.  In this case, we can put the
475    selector in the tables if needed, and orig->sel_id is updated with
476    the selector ID of the registered selector, and 'orig' is
477    returned.  */
478 static SEL
479 __sel_register_typed_name (const char *name, const char *types, 
480                            struct objc_selector *orig, BOOL is_const)
481 {
482   struct objc_selector *j;
483   sidx i;
484   struct objc_list *l;
485
486   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
487   if (soffset_decode (i) != 0)
488     {
489       /* There are already selectors with that name.  Examine them to
490          see if the one we're registering already exists.  */
491       for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
492            l; l = l->tail)
493         {
494           SEL s = (SEL)l->head;
495           if (types == 0 || s->sel_types == 0)
496             {
497               if (s->sel_types == types)
498                 {
499                   if (orig)
500                     {
501                       orig->sel_id = (void *)i;
502                       return orig;
503                     }
504                   else
505                     return s;
506                 }
507             }
508           else if (sel_types_match (s->sel_types, types))
509             {
510               if (orig)
511                 {
512                   orig->sel_id = (void *)i;
513                   return orig;
514                 }
515               else
516                 return s;
517             }
518         }
519       /* A selector with this specific name/type combination does not
520          exist yet.  We need to register it.  */
521       if (orig)
522         j = orig;
523       else
524         j = pool_alloc_selector ();
525       
526       j->sel_id = (void *)i;
527       /* Can we use the pointer or must we copy types ?  Don't copy if
528          NULL.  */
529       if ((is_const) || (types == 0))
530         j->sel_types = types;
531       else
532         {
533           j->sel_types = (char *)objc_malloc (strlen (types) + 1);
534           strcpy ((char *)j->sel_types, types);
535         }
536       l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
537     }
538   else
539     {
540       /* There are no other selectors with this name registered in the
541          runtime tables.  */
542       const char *new_name;
543
544       /* Determine i.  */
545       __objc_selector_max_index += 1;
546       i = soffset_encode (__objc_selector_max_index);
547
548       /* Prepare the selector.  */
549       if (orig)
550         j = orig;
551       else
552         j = pool_alloc_selector ();
553       
554       j->sel_id = (void *)i;
555       /* Can we use the pointer or must we copy types ?  Don't copy if
556          NULL.  */
557       if (is_const || (types == 0))
558         j->sel_types = types;
559       else
560         {
561           j->sel_types = (char *)objc_malloc (strlen (types) + 1);
562           strcpy ((char *)j->sel_types, types);
563         }
564
565       /* Since this is the first selector with this name, we need to
566          register the correspondence between 'i' (the sel_id) and
567          'name' (the actual string) in __objc_selector_names and
568          __objc_selector_hash.  */
569       
570       /* Can we use the pointer or must we copy name ?  Don't copy if
571          NULL.  (FIXME: Can the name really be NULL here ?)  */
572       if (is_const || (name == 0))
573         new_name = name;
574       else
575         {
576           new_name = (char *)objc_malloc (strlen (name) + 1);
577           strcpy ((char *)new_name, name);
578         }
579       
580       /* This maps the sel_id to the name.  */
581       sarray_at_put_safe (__objc_selector_names, i, (void *)new_name);
582
583       /* This maps the name to the sel_id.  */
584       objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i);
585
586       l = 0;
587     }
588
589   DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 
590                 (long)soffset_decode (i));
591
592   /* Now add the selector to the list of selectors with that id.  */
593   l = list_cons ((void *)j, l);
594   sarray_at_put_safe (__objc_selector_array, i, (void *)l);
595
596   sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
597   
598   return (SEL)j;
599 }
600
601 SEL
602 sel_registerName (const char *name)
603 {
604   SEL ret;
605
606   if (name == NULL)
607     return NULL;
608     
609   objc_mutex_lock (__objc_runtime_mutex);
610   /* Assume that name is not constant static memory and needs to be
611      copied before put into a runtime structure.  is_const == NO.  */
612   ret = __sel_register_typed_name (name, 0, 0, NO);
613   objc_mutex_unlock (__objc_runtime_mutex);
614   
615   return ret;
616 }
617
618 SEL
619 sel_registerTypedName (const char *name, const char *type)
620 {
621   SEL ret;
622
623   if (name == NULL)
624     return NULL;
625
626   objc_mutex_lock (__objc_runtime_mutex);
627   /* Assume that name and type are not constant static memory and need
628      to be copied before put into a runtime structure.  is_const ==
629      NO.  */
630   ret = __sel_register_typed_name (name, type, 0, NO);
631   objc_mutex_unlock (__objc_runtime_mutex);
632   
633   return ret;
634 }
635
636 /* Return the selector representing name.  */
637 SEL
638 sel_getUid (const char *name)
639 {
640   return sel_registerTypedName (name, 0);
641 }