OSDN Git Service

* ja.po: Update.
[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 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.  In the Modern API, you'd
256    normally use sel_registerTypedName() for this, which does the same
257    but would register the selector with the runtime if not registered
258    yet (if you only want to check for selectors without registering,
259    use sel_copyTypedSelectorList()).  */
260 SEL
261 sel_get_typed_uid (const char *name, const char *types)
262 {
263   struct objc_list *l;
264   sidx i;
265
266   objc_mutex_lock (__objc_runtime_mutex);
267
268   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
269   if (i == 0)
270     {
271       objc_mutex_unlock (__objc_runtime_mutex);
272       return 0;
273     }
274
275   for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
276        l; l = l->tail)
277     {
278       SEL s = (SEL) l->head;
279       if (types == 0 || s->sel_types == 0)
280         {
281           if (s->sel_types == types)
282             {
283               objc_mutex_unlock (__objc_runtime_mutex);
284               return s;
285             }
286         }
287       else if (sel_types_match (s->sel_types, types))
288         {
289           objc_mutex_unlock (__objc_runtime_mutex);
290           return s;
291         }
292     }
293
294   objc_mutex_unlock (__objc_runtime_mutex);
295   return 0;
296 }
297
298 /* Return selector representing name; prefer a selector with non-NULL
299    type.  In the Modern API, sel_getTypedSelector() is similar but
300    returns NULL if a typed selector couldn't be found.  */
301 SEL
302 sel_get_any_typed_uid (const char *name)
303 {
304   struct objc_list *l;
305   sidx i;
306   SEL s = NULL;
307
308   objc_mutex_lock (__objc_runtime_mutex);
309
310   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
311   if (i == 0)
312     {
313       objc_mutex_unlock (__objc_runtime_mutex);
314       return 0;
315     }
316
317   for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
318        l; l = l->tail)
319     {
320       s = (SEL) l->head;
321       if (s->sel_types)
322         {
323           objc_mutex_unlock (__objc_runtime_mutex);
324           return s;
325         }
326     }
327
328   objc_mutex_unlock (__objc_runtime_mutex);
329   return s;
330 }
331
332 /* Return selector representing name.  */
333 SEL
334 sel_get_any_uid (const char *name)
335 {
336   struct objc_list *l;
337   sidx i;
338
339   objc_mutex_lock (__objc_runtime_mutex);
340
341   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
342   if (soffset_decode (i) == 0)
343     {
344       objc_mutex_unlock (__objc_runtime_mutex);
345       return 0;
346     }
347
348   l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
349   objc_mutex_unlock (__objc_runtime_mutex);
350
351   if (l == 0)
352     return 0;
353
354   return (SEL) l->head;
355 }
356
357 SEL
358 sel_getTypedSelector (const char *name)
359 {
360   sidx i;
361
362   if (name == NULL)
363     return NULL;
364   
365   objc_mutex_lock (__objc_runtime_mutex);
366   
367   /* Look for a typed selector.  */
368   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
369   if (i != 0)
370     {
371       struct objc_list *l;
372
373       for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
374            l; l = l->tail)
375         {
376           SEL s = (SEL) l->head;
377           if (s->sel_types)
378             {
379               objc_mutex_unlock (__objc_runtime_mutex);
380               return s;
381             }
382         }
383     }
384
385   /* No typed selector found.  Return NULL.  */
386   objc_mutex_unlock (__objc_runtime_mutex);
387   return 0;
388 }
389
390 SEL *
391 sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
392 {
393   unsigned int count = 0;
394   SEL *returnValue = NULL;
395   sidx i;
396   
397   if (name == NULL)
398     {
399       if (numberOfReturnedSelectors)
400         *numberOfReturnedSelectors = 0;
401       return NULL;
402     }
403
404   objc_mutex_lock (__objc_runtime_mutex);
405
406   /* Count how many selectors we have.  */
407   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
408   if (i != 0)
409     {
410       struct objc_list *selector_list = NULL;
411       selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
412
413       /* Count how many selectors we have.  */
414       {
415         struct objc_list *l;
416         for (l = selector_list; l; l = l->tail)
417           count++;
418       }
419
420       if (count != 0)
421         {
422           /* Allocate enough memory to hold them.  */
423           returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
424           
425           /* Copy the selectors.  */
426           {
427             unsigned int j;
428             for (j = 0; j < count; j++)
429               {
430                 returnValue[j] = (SEL)(selector_list->head);
431                 selector_list = selector_list->tail;
432               }
433             returnValue[j] = NULL;
434           }
435         }
436     }      
437
438   objc_mutex_unlock (__objc_runtime_mutex);
439   
440   if (numberOfReturnedSelectors)
441     *numberOfReturnedSelectors = count;
442   
443   return returnValue;
444 }
445
446 /* Get the name of a selector.  If the selector is unknown, the empty
447    string "" is returned.  */ 
448 const char *sel_getName (SEL selector)
449 {
450   const char *ret;
451
452   if (selector == NULL)
453     return "<null selector>";
454   
455   objc_mutex_lock (__objc_runtime_mutex);
456   if ((soffset_decode ((sidx)selector->sel_id) > 0)
457       && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
458     ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
459   else
460     ret = 0;
461   objc_mutex_unlock (__objc_runtime_mutex);
462   return ret;
463 }
464
465 /* Traditional GNU Objective-C Runtime API.  */
466 const char *sel_get_name (SEL selector)
467 {
468   if (selector == NULL)
469     return 0;
470
471   return sel_getName (selector);
472 }
473
474 BOOL
475 sel_is_mapped (SEL selector)
476 {
477   unsigned int idx = soffset_decode ((sidx)selector->sel_id);
478   return ((idx > 0) && (idx <= __objc_selector_max_index));
479 }
480
481 const char *sel_getTypeEncoding (SEL selector)
482 {
483   if (selector)
484     return selector->sel_types;
485   else
486     return 0;
487 }
488
489 /* Traditional GNU Objective-C Runtime API.  */
490 const char *sel_get_type (SEL selector)
491 {
492   return sel_getTypeEncoding (selector);
493 }
494
495 /* The uninstalled dispatch table.  */
496 extern struct sarray *__objc_uninstalled_dtable;
497
498 /* __sel_register_typed_name allocates lots of struct objc_selector:s
499    of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
500    number of malloc calls and memory lost to malloc overhead, we
501    allocate objc_selector:s in blocks here. This is only called from
502    __sel_register_typed_name, and __sel_register_typed_name may only
503    be called when __objc_runtime_mutex is locked.
504
505    Note that the objc_selector:s allocated from
506    __sel_register_typed_name are never freed.
507
508    62 because 62 * sizeof (struct objc_selector) = 496 (992). This
509    should let malloc add some overhead and use a nice, round 512
510    (1024) byte chunk.  */
511 #define SELECTOR_POOL_SIZE 62
512 static struct objc_selector *selector_pool;
513 static int selector_pool_left;
514
515 static struct objc_selector *
516 pool_alloc_selector(void)
517 {
518   if (!selector_pool_left)
519     {
520       selector_pool = objc_malloc (sizeof (struct objc_selector)
521                                    * SELECTOR_POOL_SIZE);
522       selector_pool_left = SELECTOR_POOL_SIZE;
523     }
524   return &selector_pool[--selector_pool_left];
525 }
526
527 /* Store the passed selector name in the selector record and return
528    its selector value (value returned by sel_get_uid).  Assume that
529    the calling function has locked down __objc_runtime_mutex.  The
530    'is_const' parameter tells us if the name and types parameters are
531    really constant or not.  If YES then they are constant and we can
532    just store the pointers.  If NO then we need to copy name and types
533    because the pointers may disappear later on.  If the 'orig'
534    parameter is not NULL, then we are registering a selector from a
535    module, and 'orig' is that selector.  In this case, we can put the
536    selector in the tables if needed, and orig->sel_id is updated with
537    the selector ID of the registered selector, and 'orig' is
538    returned.  */
539 static SEL
540 __sel_register_typed_name (const char *name, const char *types, 
541                            struct objc_selector *orig, BOOL is_const)
542 {
543   struct objc_selector *j;
544   sidx i;
545   struct objc_list *l;
546
547   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
548   if (soffset_decode (i) != 0)
549     {
550       /* There are already selectors with that name.  Examine them to
551          see if the one we're registering already exists.  */
552       for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
553            l; l = l->tail)
554         {
555           SEL s = (SEL)l->head;
556           if (types == 0 || s->sel_types == 0)
557             {
558               if (s->sel_types == types)
559                 {
560                   if (orig)
561                     {
562                       orig->sel_id = (void *)i;
563                       return orig;
564                     }
565                   else
566                     return s;
567                 }
568             }
569           else if (! strcmp (s->sel_types, types))
570             {
571               if (orig)
572                 {
573                   orig->sel_id = (void *)i;
574                   return orig;
575                 }
576               else
577                 return s;
578             }
579         }
580       /* A selector with this specific name/type combination does not
581          exist yet.  We need to register it.  */
582       if (orig)
583         j = orig;
584       else
585         j = pool_alloc_selector ();
586       
587       j->sel_id = (void *)i;
588       /* Can we use the pointer or must we copy types ?  Don't copy if
589          NULL.  */
590       if ((is_const) || (types == 0))
591         j->sel_types = types;
592       else
593         {
594           j->sel_types = (char *)objc_malloc (strlen (types) + 1);
595           strcpy ((char *)j->sel_types, types);
596         }
597       l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
598     }
599   else
600     {
601       /* There are no other selectors with this name registered in the
602          runtime tables.  */
603       const char *new_name;
604
605       /* Determine i.  */
606       __objc_selector_max_index += 1;
607       i = soffset_encode (__objc_selector_max_index);
608
609       /* Prepare the selector.  */
610       if (orig)
611         j = orig;
612       else
613         j = pool_alloc_selector ();
614       
615       j->sel_id = (void *)i;
616       /* Can we use the pointer or must we copy types ?  Don't copy if
617          NULL.  */
618       if (is_const || (types == 0))
619         j->sel_types = types;
620       else
621         {
622           j->sel_types = (char *)objc_malloc (strlen (types) + 1);
623           strcpy ((char *)j->sel_types, types);
624         }
625
626       /* Since this is the first selector with this name, we need to
627          register the correspondence between 'i' (the sel_id) and
628          'name' (the actual string) in __objc_selector_names and
629          __objc_selector_hash.  */
630       
631       /* Can we use the pointer or must we copy name ?  Don't copy if
632          NULL.  (FIXME: Can the name really be NULL here ?)  */
633       if (is_const || (name == 0))
634         new_name = name;
635       else
636         {
637           new_name = (char *)objc_malloc (strlen (name) + 1);
638           strcpy ((char *)new_name, name);
639         }
640       
641       /* This maps the sel_id to the name.  */
642       sarray_at_put_safe (__objc_selector_names, i, (void *)new_name);
643
644       /* This maps the name to the sel_id.  */
645       objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i);
646
647       l = 0;
648     }
649
650   DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 
651                 (long)soffset_decode (i));
652
653   /* Now add the selector to the list of selectors with that id.  */
654   l = list_cons ((void *)j, l);
655   sarray_at_put_safe (__objc_selector_array, i, (void *)l);
656
657   sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
658   
659   return (SEL)j;
660 }
661
662 SEL
663 sel_registerName (const char *name)
664 {
665   SEL ret;
666
667   if (name == NULL)
668     return NULL;
669     
670   objc_mutex_lock (__objc_runtime_mutex);
671   /* Assume that name is not constant static memory and needs to be
672      copied before put into a runtime structure.  is_const == NO.  */
673   ret = __sel_register_typed_name (name, 0, 0, NO);
674   objc_mutex_unlock (__objc_runtime_mutex);
675   
676   return ret;
677 }
678
679 /* Traditional GNU Objective-C Runtime API.  */
680 SEL
681 sel_register_name (const char *name)
682 {
683   return sel_registerName (name);
684 }
685
686 SEL
687 sel_registerTypedName (const char *name, const char *type)
688 {
689   SEL ret;
690
691   if (name == NULL)
692     return NULL;
693
694   objc_mutex_lock (__objc_runtime_mutex);
695   /* Assume that name and type are not constant static memory and need
696      to be copied before put into a runtime structure.  is_const ==
697      NO.  */
698   ret = __sel_register_typed_name (name, type, 0, NO);
699   objc_mutex_unlock (__objc_runtime_mutex);
700   
701   return ret;
702 }
703
704 SEL
705 sel_register_typed_name (const char *name, const char *type)
706 {
707   return sel_registerTypedName (name, type);
708 }
709
710 /* Return the selector representing name.  */
711 SEL
712 sel_getUid (const char *name)
713 {
714   return sel_registerTypedName (name, 0);
715 }
716
717 /* Traditional GNU Objective-C Runtime API.  */
718 SEL
719 sel_get_uid (const char *name)
720 {
721   return sel_getUid (name);
722 }