25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
+
+
-
+
-
-
+
-
-
+
+
-
-
+
-
-
-
-
-
-
+
+
-
-
-
+
-
-
-
+
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
-
+
+
+
+
|
#ifndef OF_SELUID16
# define SEL_MAX 0xFFFFFF
#else
# define SEL_MAX 0xFFFF
#endif
static struct objc_hashtable *selectors = NULL;
static uint32_t selectors_cnt = 0;
static struct objc_sparsearray *selectors = NULL;
static struct objc_sparsearray *selector_names = NULL;
void
objc_register_selector(struct objc_abi_selector *sel)
{
uint32_t hash, last;
struct objc_selector *rsel = (struct objc_selector*)sel;
struct objc_selector *rsel;
const char *name;
if (selectors == NULL)
selectors = objc_sparsearray_new();
selectors = objc_hashtable_new(2);
else if ((rsel = objc_hashtable_get(selectors, sel->name)) != NULL) {
hash = objc_hash_string(sel->name) & SEL_MAX;
((struct objc_selector*)sel)->uid = rsel->uid;
while (hash <= SEL_MAX &&
(name = objc_sparsearray_get(selectors, hash)) != NULL) {
if (!strcmp(name, sel->name)) {
rsel->uid = hash;
return;
}
return;
}
hash++;
}
if (selector_names == NULL)
if (hash > SEL_MAX) {
last = hash;
hash = 0;
selector_names = objc_sparsearray_new();
while (hash < last &&
(name = objc_sparsearray_get(selectors, hash)) != NULL) {
if (!strcmp(name, sel->name)) {
rsel->uid = hash;
name = sel->name;
rsel = (struct objc_selector*)sel;
rsel->uid = selectors_cnt++;
return;
}
if (selectors_cnt > SEL_MAX)
hash++;
}
if (hash >= last)
ERROR("Selector slots exhausted!");
}
objc_sparsearray_set(selectors, hash, (void*)sel->name);
ERROR("Out of selector slots!");
objc_hashtable_set(selectors, name, rsel);
objc_sparsearray_set(selector_names, (uint32_t)rsel->uid, name);
rsel->uid = hash;
}
SEL
sel_registerName(const char *name)
{
const struct objc_abi_selector *rsel;
struct objc_abi_selector *sel;
if ((rsel = objc_hashtable_get(selectors, name)) != NULL)
return (SEL)rsel;
/* FIXME: Free on objc_exit() */
if ((sel = malloc(sizeof(struct objc_abi_selector))) == NULL)
ERROR("Not enough memory to allocate selector!");
if ((sel->name = strdup(name)) == NULL)
ERROR("Not enough memory to allocate selector!");
|
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
-
+
+
-
+
+
+
+
|
const char*
sel_getName(SEL sel)
{
const char *ret;
objc_global_mutex_lock();
ret = objc_sparsearray_get(selectors, (uint32_t)sel->uid);
ret = objc_sparsearray_get(selector_names, (uint32_t)sel->uid);
objc_global_mutex_unlock();
return ret;
}
BOOL
sel_isEqual(SEL sel1, SEL sel2)
{
return sel1->uid == sel2->uid;
}
void
objc_free_all_selectors(void)
{
objc_hashtable_free(selectors);
objc_sparsearray_free(selectors);
objc_sparsearray_free(selector_names);
selectors = NULL;
selectors_cnt = 0;
selector_names = NULL;
}
|