]>
Commit | Line | Data |
---|---|---|
7af964d1 | 1 | /* |
7257e56c | 2 | * Copyright (c) 2012 Apple Inc. All Rights Reserved. |
7af964d1 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
7257e56c | 24 | #if __OBJC2__ |
7af964d1 | 25 | |
7af964d1 | 26 | #include "objc-private.h" |
1807f628 | 27 | #include "DenseMapExtras.h" |
7af964d1 | 28 | |
1807f628 | 29 | static objc::ExplicitInitDenseSet<const char *> namedSelectors; |
7257e56c | 30 | static SEL search_builtins(const char *key); |
7af964d1 | 31 | |
7257e56c A |
32 | |
33 | /*********************************************************************** | |
34 | * sel_init | |
35 | * Initialize selector tables and register selectors used internally. | |
36 | **********************************************************************/ | |
c1e772c4 | 37 | void sel_init(size_t selrefCount) |
7af964d1 | 38 | { |
7257e56c | 39 | #if SUPPORT_PREOPT |
bc4fafce | 40 | if (PrintPreopt) { |
1807f628 A |
41 | _objc_inform("PREOPTIMIZATION: using dyld selector opt"); |
42 | } | |
7af964d1 A |
43 | #endif |
44 | ||
bc4fafce A |
45 | namedSelectors.init((unsigned)selrefCount); |
46 | ||
7257e56c | 47 | // Register selectors used by libobjc |
7af964d1 | 48 | |
66799735 | 49 | mutex_locker_t lock(selLock); |
7257e56c | 50 | |
1807f628 A |
51 | SEL_cxx_construct = sel_registerNameNoLock(".cxx_construct", NO); |
52 | SEL_cxx_destruct = sel_registerNameNoLock(".cxx_destruct", NO); | |
7af964d1 A |
53 | } |
54 | ||
55 | ||
7257e56c A |
56 | static SEL sel_alloc(const char *name, bool copy) |
57 | { | |
66799735 | 58 | selLock.assertLocked(); |
c1e772c4 | 59 | return (SEL)(copy ? strdupIfMutable(name) : name); |
7af964d1 A |
60 | } |
61 | ||
62 | ||
7257e56c | 63 | const char *sel_getName(SEL sel) |
7af964d1 | 64 | { |
7257e56c A |
65 | if (!sel) return "<null selector>"; |
66 | return (const char *)(const void*)sel; | |
67 | } | |
7af964d1 | 68 | |
7257e56c | 69 | |
34d5b5e8 A |
70 | unsigned long sel_hash(SEL sel) |
71 | { | |
72 | unsigned long selAddr = (unsigned long)sel; | |
73 | #if CONFIG_USE_PREOPT_CACHES | |
74 | selAddr ^= (selAddr >> 7); | |
75 | #endif | |
76 | return selAddr; | |
77 | } | |
78 | ||
79 | ||
7257e56c A |
80 | BOOL sel_isMapped(SEL sel) |
81 | { | |
82 | if (!sel) return NO; | |
83 | ||
8070259c | 84 | const char *name = (const char *)(void *)sel; |
7257e56c A |
85 | |
86 | if (sel == search_builtins(name)) return YES; | |
7af964d1 | 87 | |
66799735 | 88 | mutex_locker_t lock(selLock); |
1807f628 A |
89 | auto it = namedSelectors.get().find(name); |
90 | return it != namedSelectors.get().end() && (SEL)*it == sel; | |
7257e56c A |
91 | } |
92 | ||
93 | ||
94 | static SEL search_builtins(const char *name) | |
95 | { | |
96 | #if SUPPORT_PREOPT | |
bc4fafce A |
97 | if (SEL result = (SEL)_dyld_get_objc_selector(name)) |
98 | return result; | |
7257e56c A |
99 | #endif |
100 | return nil; | |
7af964d1 A |
101 | } |
102 | ||
7257e56c | 103 | |
66799735 | 104 | static SEL __sel_registerName(const char *name, bool shouldLock, bool copy) |
7af964d1 A |
105 | { |
106 | SEL result = 0; | |
107 | ||
66799735 A |
108 | if (shouldLock) selLock.assertUnlocked(); |
109 | else selLock.assertLocked(); | |
7af964d1 A |
110 | |
111 | if (!name) return (SEL)0; | |
7257e56c A |
112 | |
113 | result = search_builtins(name); | |
7af964d1 A |
114 | if (result) return result; |
115 | ||
66799735 | 116 | conditional_mutex_locker_t lock(selLock, shouldLock); |
1807f628 A |
117 | auto it = namedSelectors.get().insert(name); |
118 | if (it.second) { | |
119 | // No match. Insert. | |
120 | *it.first = (const char *)sel_alloc(name, copy); | |
121 | } | |
122 | return (SEL)*it.first; | |
7af964d1 A |
123 | } |
124 | ||
125 | ||
126 | SEL sel_registerName(const char *name) { | |
127 | return __sel_registerName(name, 1, 1); // YES lock, YES copy | |
128 | } | |
129 | ||
31875a97 | 130 | SEL sel_registerNameNoLock(const char *name, bool copy) { |
7af964d1 A |
131 | return __sel_registerName(name, 0, copy); // NO lock, maybe copy |
132 | } | |
133 | ||
7af964d1 A |
134 | |
135 | // 2001/1/24 | |
136 | // the majority of uses of this function (which used to return NULL if not found) | |
137 | // did not check for NULL, so, in fact, never return NULL | |
138 | // | |
139 | SEL sel_getUid(const char *name) { | |
140 | return __sel_registerName(name, 2, 1); // YES lock, YES copy | |
141 | } | |
142 | ||
143 | ||
144 | BOOL sel_isEqual(SEL lhs, SEL rhs) | |
145 | { | |
31875a97 | 146 | return bool(lhs == rhs); |
7af964d1 A |
147 | } |
148 | ||
149 | ||
7af964d1 | 150 | #endif |