OSDN Git Service

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