Commit | Line | Data |
---|---|---|
9bf86ebb PR |
1 | /* GNU Objective C Runtime selector related functions |
2 | Copyright (C) 1993 Free Software Foundation, Inc. | |
3 | ||
4 | Author: Kresten Krab Thorup | |
5 | ||
6 | This file is part of GNU CC. | |
7 | ||
8 | GNU CC 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 2, or (at your option) any later version. | |
11 | ||
12 | GNU CC 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 | You should have received a copy of the GNU General Public License along with | |
18 | GNU CC; see the file COPYING. If not, write to the Free Software | |
19 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
20 | ||
21 | /* As a special exception, if you link this library with files compiled with | |
22 | GCC to produce an executable, this does not cause the resulting executable | |
23 | to be covered by the GNU General Public License. This exception does not | |
24 | however invalidate any other reasons why the executable file might be | |
25 | covered by the GNU General Public License. */ | |
26 | ||
27 | #include "runtime.h" | |
28 | #include "objc/sarray.h" | |
29 | ||
30 | /* Initial selector hash table size. Value doesnt matter much */ | |
31 | #define SELECTOR_HASH_SIZE 128 | |
32 | ||
33 | /* Tables mapping selector names to uid and opposite */ | |
34 | static struct sarray* __objc_selector_array = 0; /* uid -> name */ | |
35 | static cache_ptr __objc_selector_hash = 0; /* name -> uid */ | |
36 | ||
37 | static void register_selectors_from_list(MethodList_t); | |
38 | ||
39 | /* Number of selectors stored in each of the above tables */ | |
40 | int __objc_selector_max_index = 0; | |
41 | ||
42 | void __objc_init_selector_tables() | |
43 | { | |
44 | __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0); | |
45 | __objc_selector_hash | |
46 | = hash_new (SELECTOR_HASH_SIZE, | |
47 | (hash_func_type) hash_string, | |
48 | (compare_func_type) compare_strings); | |
49 | } | |
50 | ||
51 | /* This routine is given a class and records all of the methods in its class | |
52 | structure in the record table. */ | |
53 | void | |
54 | __objc_register_selectors_from_class (Class* class) | |
55 | { | |
56 | MethodList_t method_list; | |
57 | ||
58 | method_list = class->methods; | |
59 | while (method_list) | |
60 | { | |
61 | register_selectors_from_list (method_list); | |
62 | method_list = method_list->method_next; | |
63 | } | |
64 | } | |
65 | ||
66 | ||
67 | /* This routine is given a list of methods and records each of the methods in | |
68 | the record table. This is the routine that does the actual recording | |
69 | work. | |
70 | ||
71 | This one is only called for Class objects. For categories, | |
72 | class_add_method_list is called. | |
73 | */ | |
74 | static void | |
75 | register_selectors_from_list (MethodList_t method_list) | |
76 | { | |
77 | int i = 0; | |
78 | while (i < method_list->method_count) | |
79 | { | |
80 | Method_t method = &method_list->method_list[i]; | |
81 | method->method_name = sel_register_name ((char*)method->method_name); | |
82 | i += 1; | |
83 | } | |
84 | } | |
85 | ||
86 | /* return selector representing name */ | |
87 | SEL | |
88 | sel_get_uid (const char *name) | |
89 | { | |
90 | return (SEL) hash_value_for_key (__objc_selector_hash, name); | |
91 | } | |
92 | ||
93 | /* Get name of selector. If selector is unknown, the empty string "" | |
94 | is returned */ | |
95 | const char* | |
96 | sel_get_name (SEL selector) | |
97 | { | |
98 | if ((soffset_decode((sidx)selector) > 0) | |
99 | && (soffset_decode((sidx)selector) <= __objc_selector_max_index)) | |
100 | return sarray_get (__objc_selector_array, (sidx) selector); | |
101 | else | |
102 | return NULL; | |
103 | } | |
104 | ||
105 | BOOL | |
106 | sel_is_mapped (SEL selector) | |
107 | { | |
108 | unsigned int idx = soffset_decode ((sidx)selector); | |
109 | return ((idx > 0) && (idx <= __objc_selector_max_index)); | |
110 | } | |
111 | ||
112 | /* The uninstalled dispatch table */ | |
113 | extern struct sarray* __objc_uninstalled_dtable; | |
114 | ||
115 | /* Store the passed selector name in the selector record and return its | |
116 | selector value (value returned by sel_get_uid). */ | |
117 | SEL | |
118 | sel_register_name (const char *sel) | |
119 | { | |
120 | SEL j; | |
121 | sidx i; | |
122 | ||
123 | if ((j = sel_get_uid ((const char *) sel))) | |
124 | return j; | |
125 | ||
126 | /* Save the selector name. */ | |
127 | __objc_selector_max_index += 1; | |
128 | i = soffset_encode(__objc_selector_max_index); | |
129 | ||
130 | DEBUG_PRINTF ("Record selector %s as: %#x\n", sel, i); | |
131 | ||
132 | sarray_at_put_safe (__objc_selector_array, i, (void *) sel); | |
133 | hash_add (&__objc_selector_hash, (void *) sel, (void *) i); | |
134 | ||
135 | sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1); | |
136 | ||
137 | return (SEL) i; | |
138 | } | |
139 |