OSDN Git Service

Add -lisl to clooglibs.
[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       SEL returnValue = NULL;
373
374       for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
375            l; l = l->tail)
376         {
377           SEL s = (SEL) l->head;
378           if (s->sel_types)
379             {
380               if (returnValue == NULL)
381                 {
382                   /* First typed selector that we find.  Keep it in
383                      returnValue, but keep checking as we want to
384                      detect conflicts.  */
385                   returnValue = s;
386                 }
387               else
388                 {
389                   /* We had already found a typed selectors, so we
390                      have multiple ones.  Double-check that they have
391                      different types, just in case for some reason we
392                      got duplicates with the same types.  If so, it's
393                      OK, we'll ignore the duplicate.  */
394                   if (returnValue->sel_types == s->sel_types)
395                     continue;
396                   else if (sel_types_match (returnValue->sel_types, s->sel_types))
397                     continue;
398                   else
399                     {
400                       /* The types of the two selectors are different;
401                          it's a conflict.  Too bad.  Return NULL.  */
402                       objc_mutex_unlock (__objc_runtime_mutex);
403                       return NULL;
404                     }
405                 }
406             }
407         }
408
409       if (returnValue != NULL)
410         {
411           objc_mutex_unlock (__objc_runtime_mutex);
412           return returnValue;
413         }
414     }
415
416   /* No typed selector found.  Return NULL.  */
417   objc_mutex_unlock (__objc_runtime_mutex);
418   return 0;
419 }
420
421 SEL *
422 sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
423 {
424   unsigned int count = 0;
425   SEL *returnValue = NULL;
426   sidx i;
427   
428   if (name == NULL)
429     {
430       if (numberOfReturnedSelectors)
431         *numberOfReturnedSelectors = 0;
432       return NULL;
433     }
434
435   objc_mutex_lock (__objc_runtime_mutex);
436
437   /* Count how many selectors we have.  */
438   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
439   if (i != 0)
440     {
441       struct objc_list *selector_list = NULL;
442       selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
443
444       /* Count how many selectors we have.  */
445       {
446         struct objc_list *l;
447         for (l = selector_list; l; l = l->tail)
448           count++;
449       }
450
451       if (count != 0)
452         {
453           /* Allocate enough memory to hold them.  */
454           returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
455           
456           /* Copy the selectors.  */
457           {
458             unsigned int j;
459             for (j = 0; j < count; j++)
460               {
461                 returnValue[j] = (SEL)(selector_list->head);
462                 selector_list = selector_list->tail;
463               }
464             returnValue[j] = NULL;
465           }
466         }
467     }      
468
469   objc_mutex_unlock (__objc_runtime_mutex);
470   
471   if (numberOfReturnedSelectors)
472     *numberOfReturnedSelectors = count;
473   
474   return returnValue;
475 }
476
477 /* Get the name of a selector.  If the selector is unknown, the empty
478    string "" is returned.  */ 
479 const char *sel_getName (SEL selector)
480 {
481   const char *ret;
482
483   if (selector == NULL)
484     return "<null selector>";
485   
486   objc_mutex_lock (__objc_runtime_mutex);
487   if ((soffset_decode ((sidx)selector->sel_id) > 0)
488       && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
489     ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
490   else
491     ret = 0;
492   objc_mutex_unlock (__objc_runtime_mutex);
493   return ret;
494 }
495
496 /* Traditional GNU Objective-C Runtime API.  */
497 const char *sel_get_name (SEL selector)
498 {
499   if (selector == NULL)
500     return 0;
501
502   return sel_getName (selector);
503 }
504
505 BOOL
506 sel_is_mapped (SEL selector)
507 {
508   unsigned int idx = soffset_decode ((sidx)selector->sel_id);
509   return ((idx > 0) && (idx <= __objc_selector_max_index));
510 }
511
512 const char *sel_getTypeEncoding (SEL selector)
513 {
514   if (selector)
515     return selector->sel_types;
516   else
517     return 0;
518 }
519
520 /* Traditional GNU Objective-C Runtime API.  */
521 const char *sel_get_type (SEL selector)
522 {
523   return sel_getTypeEncoding (selector);
524 }
525
526 /* The uninstalled dispatch table.  */
527 extern struct sarray *__objc_uninstalled_dtable;
528
529 /* __sel_register_typed_name allocates lots of struct objc_selector:s
530    of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
531    number of malloc calls and memory lost to malloc overhead, we
532    allocate objc_selector:s in blocks here. This is only called from
533    __sel_register_typed_name, and __sel_register_typed_name may only
534    be called when __objc_runtime_mutex is locked.
535
536    Note that the objc_selector:s allocated from
537    __sel_register_typed_name are never freed.
538
539    62 because 62 * sizeof (struct objc_selector) = 496 (992). This
540    should let malloc add some overhead and use a nice, round 512
541    (1024) byte chunk.  */
542 #define SELECTOR_POOL_SIZE 62
543 static struct objc_selector *selector_pool;
544 static int selector_pool_left;
545
546 static struct objc_selector *
547 pool_alloc_selector(void)
548 {
549   if (!selector_pool_left)
550     {
551       selector_pool = objc_malloc (sizeof (struct objc_selector)
552                                    * SELECTOR_POOL_SIZE);
553       selector_pool_left = SELECTOR_POOL_SIZE;
554     }
555   return &selector_pool[--selector_pool_left];
556 }
557
558 /* Store the passed selector name in the selector record and return
559    its selector value (value returned by sel_get_uid).  Assume that
560    the calling function has locked down __objc_runtime_mutex.  The
561    'is_const' parameter tells us if the name and types parameters are
562    really constant or not.  If YES then they are constant and we can
563    just store the pointers.  If NO then we need to copy name and types
564    because the pointers may disappear later on.  If the 'orig'
565    parameter is not NULL, then we are registering a selector from a
566    module, and 'orig' is that selector.  In this case, we can put the
567    selector in the tables if needed, and orig->sel_id is updated with
568    the selector ID of the registered selector, and 'orig' is
569    returned.  */
570 static SEL
571 __sel_register_typed_name (const char *name, const char *types, 
572                            struct objc_selector *orig, BOOL is_const)
573 {
574   struct objc_selector *j;
575   sidx i;
576   struct objc_list *l;
577
578   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
579   if (soffset_decode (i) != 0)
580     {
581       /* There are already selectors with that name.  Examine them to
582          see if the one we're registering already exists.  */
583       for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
584            l; l = l->tail)
585         {
586           SEL s = (SEL)l->head;
587           if (types == 0 || s->sel_types == 0)
588             {
589               if (s->sel_types == types)
590                 {
591                   if (orig)
592                     {
593                       orig->sel_id = (void *)i;
594                       return orig;
595                     }
596                   else
597                     return s;
598                 }
599             }
600           else if (! strcmp (s->sel_types, types))
601             {
602               if (orig)
603                 {
604                   orig->sel_id = (void *)i;
605                   return orig;
606                 }
607               else
608                 return s;
609             }
610         }
611       /* A selector with this specific name/type combination does not
612          exist yet.  We need to register it.  */
613       if (orig)
614         j = orig;
615       else
616         j = pool_alloc_selector ();
617       
618       j->sel_id = (void *)i;
619       /* Can we use the pointer or must we copy types ?  Don't copy if
620          NULL.  */
621       if ((is_const) || (types == 0))
622         j->sel_types = types;
623       else
624         {
625           j->sel_types = (char *)objc_malloc (strlen (types) + 1);
626           strcpy ((char *)j->sel_types, types);
627         }
628       l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
629     }
630   else
631     {
632       /* There are no other selectors with this name registered in the
633          runtime tables.  */
634       const char *new_name;
635
636       /* Determine i.  */
637       __objc_selector_max_index += 1;
638       i = soffset_encode (__objc_selector_max_index);
639
640       /* Prepare the selector.  */
641       if (orig)
642         j = orig;
643       else
644         j = pool_alloc_selector ();
645       
646       j->sel_id = (void *)i;
647       /* Can we use the pointer or must we copy types ?  Don't copy if
648          NULL.  */
649       if (is_const || (types == 0))
650         j->sel_types = types;
651       else
652         {
653           j->sel_types = (char *)objc_malloc (strlen (types) + 1);
654           strcpy ((char *)j->sel_types, types);
655         }
656
657       /* Since this is the first selector with this name, we need to
658          register the correspondence between 'i' (the sel_id) and
659          'name' (the actual string) in __objc_selector_names and
660          __objc_selector_hash.  */
661       
662       /* Can we use the pointer or must we copy name ?  Don't copy if
663          NULL.  (FIXME: Can the name really be NULL here ?)  */
664       if (is_const || (name == 0))
665         new_name = name;
666       else
667         {
668           new_name = (char *)objc_malloc (strlen (name) + 1);
669           strcpy ((char *)new_name, name);
670         }
671       
672       /* This maps the sel_id to the name.  */
673       sarray_at_put_safe (__objc_selector_names, i, (void *)new_name);
674
675       /* This maps the name to the sel_id.  */
676       objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i);
677
678       l = 0;
679     }
680
681   DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 
682                 (long)soffset_decode (i));
683
684   /* Now add the selector to the list of selectors with that id.  */
685   l = list_cons ((void *)j, l);
686   sarray_at_put_safe (__objc_selector_array, i, (void *)l);
687
688   sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
689   
690   return (SEL)j;
691 }
692
693 SEL
694 sel_registerName (const char *name)
695 {
696   SEL ret;
697
698   if (name == NULL)
699     return NULL;
700     
701   objc_mutex_lock (__objc_runtime_mutex);
702   /* Assume that name is not constant static memory and needs to be
703      copied before put into a runtime structure.  is_const == NO.  */
704   ret = __sel_register_typed_name (name, 0, 0, NO);
705   objc_mutex_unlock (__objc_runtime_mutex);
706   
707   return ret;
708 }
709
710 /* Traditional GNU Objective-C Runtime API.  */
711 SEL
712 sel_register_name (const char *name)
713 {
714   return sel_registerName (name);
715 }
716
717 SEL
718 sel_registerTypedName (const char *name, const char *type)
719 {
720   SEL ret;
721
722   if (name == NULL)
723     return NULL;
724
725   objc_mutex_lock (__objc_runtime_mutex);
726   /* Assume that name and type are not constant static memory and need
727      to be copied before put into a runtime structure.  is_const ==
728      NO.  */
729   ret = __sel_register_typed_name (name, type, 0, NO);
730   objc_mutex_unlock (__objc_runtime_mutex);
731   
732   return ret;
733 }
734
735 SEL
736 sel_register_typed_name (const char *name, const char *type)
737 {
738   return sel_registerTypedName (name, type);
739 }
740
741 /* Return the selector representing name.  */
742 SEL
743 sel_getUid (const char *name)
744 {
745   return sel_registerTypedName (name, 0);
746 }
747
748 /* Traditional GNU Objective-C Runtime API.  */
749 SEL
750 sel_get_uid (const char *name)
751 {
752   return sel_getUid (name);
753 }