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
5 This file is part of GCC.
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.
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
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.
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/>. */
25 #include "objc-private/common.h"
26 #include "objc/runtime.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"
34 /* Initial selector hash table size. Value doesn't matter much. */
35 #define SELECTOR_HASH_SIZE 128
37 /* Tables mapping selector names to uid and opposite. */
38 static struct sarray
*__objc_selector_array
= 0; /* uid -> sel !T:MUTEX */
39 static struct sarray
*__objc_selector_names
= 0; /* uid -> name !T:MUTEX */
40 static cache_ptr __objc_selector_hash
= 0; /* name -> uid !T:MUTEX */
42 /* Number of selectors stored in each of the above tables. */
43 unsigned int __objc_selector_max_index
= 0; /* !T:MUTEX */
45 void __objc_init_selector_tables (void)
47 __objc_selector_array
= sarray_new (SELECTOR_HASH_SIZE
, 0);
48 __objc_selector_names
= sarray_new (SELECTOR_HASH_SIZE
, 0);
50 = objc_hash_new (SELECTOR_HASH_SIZE
,
51 (hash_func_type
) objc_hash_string
,
52 (compare_func_type
) objc_compare_strings
);
55 /* This routine is given a class and records all of the methods in its
56 class structure in the record table. */
58 __objc_register_selectors_from_class (Class
class)
60 struct objc_method_list
* method_list
;
62 method_list
= class->methods
;
65 __objc_register_selectors_from_list (method_list
);
66 method_list
= method_list
->method_next
;
71 /* This routine is given a list of methods and records each of the
72 methods in the record table. This is the routine that does the
73 actual recording work.
75 The name and type pointers in the method list must be permanent and
78 __objc_register_selectors_from_list (struct objc_method_list
*method_list
)
82 objc_mutex_lock (__objc_runtime_mutex
);
83 while (i
< method_list
->method_count
)
85 Method method
= &method_list
->method_list
[i
];
86 if (method
->method_name
)
89 = __sel_register_typed_name ((const char *) method
->method_name
,
90 method
->method_types
, 0, YES
);
94 objc_mutex_unlock (__objc_runtime_mutex
);
97 /* The same as __objc_register_selectors_from_list, but works on a
98 struct objc_method_description_list* instead of a struct
99 objc_method_list*. This is only used for protocols, which have
100 lists of method descriptions, not methods. */
102 __objc_register_selectors_from_description_list
103 (struct objc_method_description_list
*method_list
)
107 objc_mutex_lock (__objc_runtime_mutex
);
108 while (i
< method_list
->count
)
110 struct objc_method_description
*method
= &method_list
->list
[i
];
114 = __sel_register_typed_name ((const char *) method
->name
,
115 method
->types
, 0, YES
);
119 objc_mutex_unlock (__objc_runtime_mutex
);
122 /* Register instance methods as class methods for root classes. */
123 void __objc_register_instance_methods_to_class (Class
class)
125 struct objc_method_list
*method_list
;
126 struct objc_method_list
*class_method_list
;
127 int max_methods_no
= 16;
128 struct objc_method_list
*new_list
;
131 /* Only if a root class. */
132 if (class->super_class
)
135 /* Allocate a method list to hold the new class methods. */
136 new_list
= objc_calloc (sizeof (struct objc_method_list
)
137 + sizeof (struct objc_method
[max_methods_no
]), 1);
138 method_list
= class->methods
;
139 class_method_list
= class->class_pointer
->methods
;
140 curr_method
= &new_list
->method_list
[0];
142 /* Iterate through the method lists for the class. */
147 /* Iterate through the methods from this method list. */
148 for (i
= 0; i
< method_list
->method_count
; i
++)
150 Method mth
= &method_list
->method_list
[i
];
152 && ! search_for_method_in_list (class_method_list
,
155 /* This instance method isn't a class method. Add it
156 into the new_list. */
159 /* Reallocate the method list if necessary. */
160 if (++new_list
->method_count
== max_methods_no
)
162 objc_realloc (new_list
, sizeof (struct objc_method_list
)
164 objc_method
[max_methods_no
+= 16]));
165 curr_method
= &new_list
->method_list
[new_list
->method_count
];
169 method_list
= method_list
->method_next
;
172 /* If we created any new class methods then attach the method list
174 if (new_list
->method_count
)
177 objc_realloc (new_list
, sizeof (struct objc_method_list
)
178 + sizeof (struct objc_method
[new_list
->method_count
]));
179 new_list
->method_next
= class->class_pointer
->methods
;
180 class->class_pointer
->methods
= new_list
;
185 __objc_update_dispatch_table_for_class (class->class_pointer
);
189 sel_isEqual (SEL s1
, SEL s2
)
191 if (s1
== 0 || s2
== 0)
194 return s1
->sel_id
== s2
->sel_id
;
197 /* Return YES iff t1 and t2 have same method types. Ignore the
200 sel_types_match (const char *t1
, const char *t2
)
206 if (*t1
== '+') t1
++;
207 if (*t2
== '+') t2
++;
208 while (isdigit ((unsigned char) *t1
)) t1
++;
209 while (isdigit ((unsigned char) *t2
)) t2
++;
210 /* xxx Remove these next two lines when qualifiers are put in
211 all selectors, not just Protocol selectors. */
212 t1
= objc_skip_type_qualifiers (t1
);
213 t2
= objc_skip_type_qualifiers (t2
);
224 /* Return selector representing name. */
226 sel_get_typed_uid (const char *name
, const char *types
)
231 objc_mutex_lock (__objc_runtime_mutex
);
233 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
236 objc_mutex_unlock (__objc_runtime_mutex
);
240 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
243 SEL s
= (SEL
) l
->head
;
244 if (types
== 0 || s
->sel_types
== 0)
246 if (s
->sel_types
== types
)
248 objc_mutex_unlock (__objc_runtime_mutex
);
252 else if (sel_types_match (s
->sel_types
, types
))
254 objc_mutex_unlock (__objc_runtime_mutex
);
259 objc_mutex_unlock (__objc_runtime_mutex
);
263 /* Return selector representing name; prefer a selector with non-NULL
266 sel_get_any_typed_uid (const char *name
)
272 objc_mutex_lock (__objc_runtime_mutex
);
274 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
277 objc_mutex_unlock (__objc_runtime_mutex
);
281 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
287 objc_mutex_unlock (__objc_runtime_mutex
);
292 objc_mutex_unlock (__objc_runtime_mutex
);
296 /* Return selector representing name. */
298 sel_get_any_uid (const char *name
)
303 objc_mutex_lock (__objc_runtime_mutex
);
305 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
306 if (soffset_decode (i
) == 0)
308 objc_mutex_unlock (__objc_runtime_mutex
);
312 l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
313 objc_mutex_unlock (__objc_runtime_mutex
);
318 return (SEL
) l
->head
;
321 /* Get the name of a selector. If the selector is unknown, the empty
322 string "" is returned. */
323 const char *sel_getName (SEL selector
)
327 if (selector
== NULL
)
328 return "<null selector>";
330 objc_mutex_lock (__objc_runtime_mutex
);
331 if ((soffset_decode ((sidx
)selector
->sel_id
) > 0)
332 && (soffset_decode ((sidx
)selector
->sel_id
) <= __objc_selector_max_index
))
333 ret
= sarray_get_safe (__objc_selector_names
, (sidx
) selector
->sel_id
);
336 objc_mutex_unlock (__objc_runtime_mutex
);
340 /* Traditional GNU Objective-C Runtime API. */
341 const char *sel_get_name (SEL selector
)
343 if (selector
== NULL
)
346 return sel_getName (selector
);
350 sel_is_mapped (SEL selector
)
352 unsigned int idx
= soffset_decode ((sidx
)selector
->sel_id
);
353 return ((idx
> 0) && (idx
<= __objc_selector_max_index
));
356 const char *sel_getType (SEL selector
)
359 return selector
->sel_types
;
364 /* Traditional GNU Objective-C Runtime API. */
365 const char *sel_get_type (SEL selector
)
367 return sel_getType (selector
);
370 /* The uninstalled dispatch table. */
371 extern struct sarray
*__objc_uninstalled_dtable
;
373 /* __sel_register_typed_name allocates lots of struct objc_selector:s
374 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
375 number of malloc calls and memory lost to malloc overhead, we
376 allocate objc_selector:s in blocks here. This is only called from
377 __sel_register_typed_name, and __sel_register_typed_name may only
378 be called when __objc_runtime_mutex is locked.
380 Note that the objc_selector:s allocated from
381 __sel_register_typed_name are never freed.
383 62 because 62 * sizeof (struct objc_selector) = 496 (992). This
384 should let malloc add some overhead and use a nice, round 512
385 (1024) byte chunk. */
386 #define SELECTOR_POOL_SIZE 62
387 static struct objc_selector
*selector_pool
;
388 static int selector_pool_left
;
390 static struct objc_selector
*
391 pool_alloc_selector(void)
393 if (!selector_pool_left
)
395 selector_pool
= objc_malloc (sizeof (struct objc_selector
)
396 * SELECTOR_POOL_SIZE
);
397 selector_pool_left
= SELECTOR_POOL_SIZE
;
399 return &selector_pool
[--selector_pool_left
];
402 /* Store the passed selector name in the selector record and return
403 its selector value (value returned by sel_get_uid). Assume that
404 the calling function has locked down __objc_runtime_mutex. The
405 is_const parameter tells us if the name and types parameters are
406 really constant or not. If YES then they are constant and we can
407 just store the pointers. If NO then we need to copy name and types
408 because the pointers may disappear later on. */
410 __sel_register_typed_name (const char *name
, const char *types
,
411 struct objc_selector
*orig
, BOOL is_const
)
413 struct objc_selector
*j
;
417 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
418 if (soffset_decode (i
) != 0)
420 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
423 SEL s
= (SEL
) l
->head
;
424 if (types
== 0 || s
->sel_types
== 0)
426 if (s
->sel_types
== types
)
430 orig
->sel_id
= (void *) i
;
437 else if (! strcmp (s
->sel_types
, types
))
441 orig
->sel_id
= (void *) i
;
451 j
= pool_alloc_selector ();
453 j
->sel_id
= (void *) i
;
454 /* Can we use the pointer or must copy types? Don't copy if
456 if ((is_const
) || (types
== 0))
457 j
->sel_types
= (const char *) types
;
460 j
->sel_types
= (char *) objc_malloc (strlen (types
) + 1);
461 strcpy ((char *) j
->sel_types
, types
);
463 l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
467 __objc_selector_max_index
+= 1;
468 i
= soffset_encode (__objc_selector_max_index
);
472 j
= pool_alloc_selector ();
474 j
->sel_id
= (void *) i
;
475 /* Can we use the pointer or must copy types? Don't copy if
477 if ((is_const
) || (types
== 0))
478 j
->sel_types
= (const char *) types
;
481 j
->sel_types
= (char *) objc_malloc (strlen (types
) + 1);
482 strcpy ((char *) j
->sel_types
, types
);
487 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name
, types
,
488 (long) soffset_decode (i
));
491 int is_new
= (l
== 0);
492 const char *new_name
;
494 /* Can we use the pointer or must copy name? Don't copy if
496 if ((is_const
) || (name
== 0))
500 new_name
= (char *) objc_malloc (strlen (name
) + 1);
501 strcpy ((char *) new_name
, name
);
504 l
= list_cons ((void *) j
, l
);
505 sarray_at_put_safe (__objc_selector_names
, i
, (void *) new_name
);
506 sarray_at_put_safe (__objc_selector_array
, i
, (void *) l
);
508 objc_hash_add (&__objc_selector_hash
, (void *) new_name
, (void *) i
);
511 sarray_realloc (__objc_uninstalled_dtable
, __objc_selector_max_index
+ 1);
517 sel_registerName (const char *name
)
521 objc_mutex_lock (__objc_runtime_mutex
);
522 /* Assume that name is not constant static memory and needs to be
523 copied before put into a runtime structure. is_const == NO. */
524 ret
= __sel_register_typed_name (name
, 0, 0, NO
);
525 objc_mutex_unlock (__objc_runtime_mutex
);
530 /* Traditional GNU Objective-C Runtime API. */
532 sel_register_name (const char *name
)
534 return sel_registerName (name
);
538 sel_registerTypedName (const char *name
, const char *type
)
542 objc_mutex_lock (__objc_runtime_mutex
);
543 /* Assume that name and type are not constant static memory and need
544 to be copied before put into a runtime structure. is_const ==
546 ret
= __sel_register_typed_name (name
, type
, 0, NO
);
547 objc_mutex_unlock (__objc_runtime_mutex
);
553 sel_register_typed_name (const char *name
, const char *type
)
555 return sel_registerTypedName (name
, type
);
558 /* Return the selector representing name. */
560 sel_getUid (const char *name
)
562 return sel_registerTypedName (name
, 0);
565 /* Traditional GNU Objective-C Runtime API. */
567 sel_get_uid (const char *name
)
569 return sel_getUid (name
);