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/objc-api.h"
28 #include "objc-private/hash.h"
29 #include "objc-private/objc-list.h"
30 #include "objc-private/runtime.h"
31 #include "objc-private/sarray.h"
32 #include "objc/encoding.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 MethodList_t 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 (MethodList_t method_list
)
82 objc_mutex_lock (__objc_runtime_mutex
);
83 while (i
< method_list
->method_count
)
85 Method_t 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 /* Temporary definition while we include objc/objc-api.h instead of
98 objc-private/module-abi-8.h. It should go away once we include
100 struct objc_method_description_list
103 struct objc_method_description list
[1];
106 /* The same as __objc_register_selectors_from_list, but works on a
107 struct objc_method_description_list* instead of a struct
108 objc_method_list*. This is only used for protocols, which have
109 lists of method descriptions, not methods. */
111 __objc_register_selectors_from_description_list
112 (struct objc_method_description_list
*method_list
)
116 objc_mutex_lock (__objc_runtime_mutex
);
117 while (i
< method_list
->count
)
119 struct objc_method_description
*method
= &method_list
->list
[i
];
123 = __sel_register_typed_name ((const char *) method
->name
,
124 method
->types
, 0, YES
);
128 objc_mutex_unlock (__objc_runtime_mutex
);
131 /* Register instance methods as class methods for root classes. */
132 void __objc_register_instance_methods_to_class (Class
class)
134 MethodList_t method_list
;
135 MethodList_t class_method_list
;
136 int max_methods_no
= 16;
137 MethodList_t new_list
;
138 Method_t curr_method
;
140 /* Only if a root class. */
141 if (class->super_class
)
144 /* Allocate a method list to hold the new class methods. */
145 new_list
= objc_calloc (sizeof (struct objc_method_list
)
146 + sizeof (struct objc_method
[max_methods_no
]), 1);
147 method_list
= class->methods
;
148 class_method_list
= class->class_pointer
->methods
;
149 curr_method
= &new_list
->method_list
[0];
151 /* Iterate through the method lists for the class. */
156 /* Iterate through the methods from this method list. */
157 for (i
= 0; i
< method_list
->method_count
; i
++)
159 Method_t mth
= &method_list
->method_list
[i
];
161 && ! search_for_method_in_list (class_method_list
,
164 /* This instance method isn't a class method. Add it
165 into the new_list. */
168 /* Reallocate the method list if necessary. */
169 if (++new_list
->method_count
== max_methods_no
)
171 objc_realloc (new_list
, sizeof (struct objc_method_list
)
173 objc_method
[max_methods_no
+= 16]));
174 curr_method
= &new_list
->method_list
[new_list
->method_count
];
178 method_list
= method_list
->method_next
;
181 /* If we created any new class methods then attach the method list
183 if (new_list
->method_count
)
186 objc_realloc (new_list
, sizeof (struct objc_method_list
)
187 + sizeof (struct objc_method
[new_list
->method_count
]));
188 new_list
->method_next
= class->class_pointer
->methods
;
189 class->class_pointer
->methods
= new_list
;
194 __objc_update_dispatch_table_for_class (class->class_pointer
);
198 sel_isEqual (SEL s1
, SEL s2
)
200 if (s1
== 0 || s2
== 0)
203 return s1
->sel_id
== s2
->sel_id
;
206 /* Return YES iff t1 and t2 have same method types. Ignore the
209 sel_types_match (const char *t1
, const char *t2
)
215 if (*t1
== '+') t1
++;
216 if (*t2
== '+') t2
++;
217 while (isdigit ((unsigned char) *t1
)) t1
++;
218 while (isdigit ((unsigned char) *t2
)) t2
++;
219 /* xxx Remove these next two lines when qualifiers are put in
220 all selectors, not just Protocol selectors. */
221 t1
= objc_skip_type_qualifiers (t1
);
222 t2
= objc_skip_type_qualifiers (t2
);
233 /* Return selector representing name. */
235 sel_get_typed_uid (const char *name
, const char *types
)
240 objc_mutex_lock (__objc_runtime_mutex
);
242 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
245 objc_mutex_unlock (__objc_runtime_mutex
);
249 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
252 SEL s
= (SEL
) l
->head
;
253 if (types
== 0 || s
->sel_types
== 0)
255 if (s
->sel_types
== types
)
257 objc_mutex_unlock (__objc_runtime_mutex
);
261 else if (sel_types_match (s
->sel_types
, types
))
263 objc_mutex_unlock (__objc_runtime_mutex
);
268 objc_mutex_unlock (__objc_runtime_mutex
);
272 /* Return selector representing name; prefer a selector with non-NULL
275 sel_get_any_typed_uid (const char *name
)
281 objc_mutex_lock (__objc_runtime_mutex
);
283 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
286 objc_mutex_unlock (__objc_runtime_mutex
);
290 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
296 objc_mutex_unlock (__objc_runtime_mutex
);
301 objc_mutex_unlock (__objc_runtime_mutex
);
305 /* Return selector representing name. */
307 sel_get_any_uid (const char *name
)
312 objc_mutex_lock (__objc_runtime_mutex
);
314 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
315 if (soffset_decode (i
) == 0)
317 objc_mutex_unlock (__objc_runtime_mutex
);
321 l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
322 objc_mutex_unlock (__objc_runtime_mutex
);
327 return (SEL
) l
->head
;
330 /* Get the name of a selector. If the selector is unknown, the empty
331 string "" is returned. */
332 const char *sel_getName (SEL selector
)
336 if (selector
== NULL
)
337 return "<null selector>";
339 objc_mutex_lock (__objc_runtime_mutex
);
340 if ((soffset_decode ((sidx
)selector
->sel_id
) > 0)
341 && (soffset_decode ((sidx
)selector
->sel_id
) <= __objc_selector_max_index
))
342 ret
= sarray_get_safe (__objc_selector_names
, (sidx
) selector
->sel_id
);
345 objc_mutex_unlock (__objc_runtime_mutex
);
349 /* Traditional GNU Objective-C Runtime API. */
350 const char *sel_get_name (SEL selector
)
352 if (selector
== NULL
)
355 return sel_getName (selector
);
359 sel_is_mapped (SEL selector
)
361 unsigned int idx
= soffset_decode ((sidx
)selector
->sel_id
);
362 return ((idx
> 0) && (idx
<= __objc_selector_max_index
));
365 const char *sel_getType (SEL selector
)
368 return selector
->sel_types
;
373 /* Traditional GNU Objective-C Runtime API. */
374 const char *sel_get_type (SEL selector
)
376 return sel_getType (selector
);
379 /* The uninstalled dispatch table. */
380 extern struct sarray
*__objc_uninstalled_dtable
;
382 /* __sel_register_typed_name allocates lots of struct objc_selector:s
383 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
384 number of malloc calls and memory lost to malloc overhead, we
385 allocate objc_selector:s in blocks here. This is only called from
386 __sel_register_typed_name, and __sel_register_typed_name may only
387 be called when __objc_runtime_mutex is locked.
389 Note that the objc_selector:s allocated from
390 __sel_register_typed_name are never freed.
392 62 because 62 * sizeof (struct objc_selector) = 496 (992). This
393 should let malloc add some overhead and use a nice, round 512
394 (1024) byte chunk. */
395 #define SELECTOR_POOL_SIZE 62
396 static struct objc_selector
*selector_pool
;
397 static int selector_pool_left
;
399 static struct objc_selector
*
400 pool_alloc_selector(void)
402 if (!selector_pool_left
)
404 selector_pool
= objc_malloc (sizeof (struct objc_selector
)
405 * SELECTOR_POOL_SIZE
);
406 selector_pool_left
= SELECTOR_POOL_SIZE
;
408 return &selector_pool
[--selector_pool_left
];
411 /* Store the passed selector name in the selector record and return
412 its selector value (value returned by sel_get_uid). Assume that
413 the calling function has locked down __objc_runtime_mutex. The
414 is_const parameter tells us if the name and types parameters are
415 really constant or not. If YES then they are constant and we can
416 just store the pointers. If NO then we need to copy name and types
417 because the pointers may disappear later on. */
419 __sel_register_typed_name (const char *name
, const char *types
,
420 struct objc_selector
*orig
, BOOL is_const
)
422 struct objc_selector
*j
;
426 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
427 if (soffset_decode (i
) != 0)
429 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
432 SEL s
= (SEL
) l
->head
;
433 if (types
== 0 || s
->sel_types
== 0)
435 if (s
->sel_types
== types
)
439 orig
->sel_id
= (void *) i
;
446 else if (! strcmp (s
->sel_types
, types
))
450 orig
->sel_id
= (void *) i
;
460 j
= pool_alloc_selector ();
462 j
->sel_id
= (void *) i
;
463 /* Can we use the pointer or must copy types? Don't copy if
465 if ((is_const
) || (types
== 0))
466 j
->sel_types
= (const char *) types
;
469 j
->sel_types
= (char *) objc_malloc (strlen (types
) + 1);
470 strcpy ((char *) j
->sel_types
, types
);
472 l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
476 __objc_selector_max_index
+= 1;
477 i
= soffset_encode (__objc_selector_max_index
);
481 j
= pool_alloc_selector ();
483 j
->sel_id
= (void *) i
;
484 /* Can we use the pointer or must copy types? Don't copy if
486 if ((is_const
) || (types
== 0))
487 j
->sel_types
= (const char *) types
;
490 j
->sel_types
= (char *) objc_malloc (strlen (types
) + 1);
491 strcpy ((char *) j
->sel_types
, types
);
496 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name
, types
,
497 (long) soffset_decode (i
));
500 int is_new
= (l
== 0);
501 const char *new_name
;
503 /* Can we use the pointer or must copy name? Don't copy if
505 if ((is_const
) || (name
== 0))
509 new_name
= (char *) objc_malloc (strlen (name
) + 1);
510 strcpy ((char *) new_name
, name
);
513 l
= list_cons ((void *) j
, l
);
514 sarray_at_put_safe (__objc_selector_names
, i
, (void *) new_name
);
515 sarray_at_put_safe (__objc_selector_array
, i
, (void *) l
);
517 objc_hash_add (&__objc_selector_hash
, (void *) new_name
, (void *) i
);
520 sarray_realloc (__objc_uninstalled_dtable
, __objc_selector_max_index
+ 1);
526 sel_registerName (const char *name
)
530 objc_mutex_lock (__objc_runtime_mutex
);
531 /* Assume that name is not constant static memory and needs to be
532 copied before put into a runtime structure. is_const == NO. */
533 ret
= __sel_register_typed_name (name
, 0, 0, NO
);
534 objc_mutex_unlock (__objc_runtime_mutex
);
539 /* Traditional GNU Objective-C Runtime API. */
541 sel_register_name (const char *name
)
543 return sel_registerName (name
);
547 sel_registerTypedName (const char *name
, const char *type
)
551 objc_mutex_lock (__objc_runtime_mutex
);
552 /* Assume that name and type are not constant static memory and need
553 to be copied before put into a runtime structure. is_const ==
555 ret
= __sel_register_typed_name (name
, type
, 0, NO
);
556 objc_mutex_unlock (__objc_runtime_mutex
);
562 sel_register_typed_name (const char *name
, const char *type
)
564 return sel_registerTypedName (name
, type
);
567 /* Return the selector representing name. */
569 sel_getUid (const char *name
)
571 return sel_registerTypedName (name
, 0);
574 /* Traditional GNU Objective-C Runtime API. */
576 sel_get_uid (const char *name
)
578 return sel_getUid (name
);