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