2 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
24 #include "JSGlobalData.h"
25 #include "ThreadSpecific.h"
33 friend class Structure
;
37 Identifier(ExecState
* exec
, const char* s
) : _ustring(add(exec
, s
)) { } // Only to be used with string literals.
38 Identifier(ExecState
* exec
, const UChar
* s
, int length
) : _ustring(add(exec
, s
, length
)) { }
39 Identifier(ExecState
* exec
, UString::Rep
* rep
) : _ustring(add(exec
, rep
)) { }
40 Identifier(ExecState
* exec
, const UString
& s
) : _ustring(add(exec
, s
.rep())) { }
42 Identifier(JSGlobalData
* globalData
, const char* s
) : _ustring(add(globalData
, s
)) { } // Only to be used with string literals.
43 Identifier(JSGlobalData
* globalData
, const UChar
* s
, int length
) : _ustring(add(globalData
, s
, length
)) { }
44 Identifier(JSGlobalData
* globalData
, UString::Rep
* rep
) : _ustring(add(globalData
, rep
)) { }
45 Identifier(JSGlobalData
* globalData
, const UString
& s
) : _ustring(add(globalData
, s
.rep())) { }
47 // Special constructor for cases where we overwrite an object in place.
48 Identifier(PlacementNewAdoptType
) : _ustring(PlacementNewAdopt
) { }
50 const UString
& ustring() const { return _ustring
; }
52 const UChar
* data() const { return _ustring
.data(); }
53 int size() const { return _ustring
.size(); }
55 const char* ascii() const { return _ustring
.ascii(); }
57 static Identifier
from(ExecState
* exec
, unsigned y
) { return Identifier(exec
, UString::from(y
)); }
58 static Identifier
from(ExecState
* exec
, int y
) { return Identifier(exec
, UString::from(y
)); }
59 static Identifier
from(ExecState
* exec
, double y
) { return Identifier(exec
, UString::from(y
)); }
61 bool isNull() const { return _ustring
.isNull(); }
62 bool isEmpty() const { return _ustring
.isEmpty(); }
64 uint32_t toUInt32(bool* ok
) const { return _ustring
.toUInt32(ok
); }
65 uint32_t toUInt32(bool* ok
, bool tolerateEmptyString
) const { return _ustring
.toUInt32(ok
, tolerateEmptyString
); };
66 uint32_t toStrictUInt32(bool* ok
) const { return _ustring
.toStrictUInt32(ok
); }
67 unsigned toArrayIndex(bool* ok
) const { return _ustring
.toArrayIndex(ok
); }
68 double toDouble() const { return _ustring
.toDouble(); }
70 friend bool operator==(const Identifier
&, const Identifier
&);
71 friend bool operator!=(const Identifier
&, const Identifier
&);
73 friend bool operator==(const Identifier
&, const char*);
74 friend bool operator!=(const Identifier
&, const char*);
76 static void remove(UString::Rep
*);
78 static bool equal(const UString::Rep
*, const char*);
79 static bool equal(const UString::Rep
*, const UChar
*, int length
);
80 static bool equal(const UString::Rep
* a
, const UString::Rep
* b
) { return JSC::equal(a
, b
); }
82 static PassRefPtr
<UString::Rep
> add(ExecState
*, const char*); // Only to be used with string literals.
83 static PassRefPtr
<UString::Rep
> add(JSGlobalData
*, const char*); // Only to be used with string literals.
88 static bool equal(const Identifier
& a
, const Identifier
& b
) { return a
._ustring
.rep() == b
._ustring
.rep(); }
89 static bool equal(const Identifier
& a
, const char* b
) { return equal(a
._ustring
.rep(), b
); }
91 static PassRefPtr
<UString::Rep
> add(ExecState
*, const UChar
*, int length
);
92 static PassRefPtr
<UString::Rep
> add(JSGlobalData
*, const UChar
*, int length
);
94 static PassRefPtr
<UString::Rep
> add(ExecState
* exec
, UString::Rep
* r
)
96 if (r
->isIdentifier()) {
98 checkSameIdentifierTable(exec
, r
);
102 return addSlowCase(exec
, r
);
104 static PassRefPtr
<UString::Rep
> add(JSGlobalData
* globalData
, UString::Rep
* r
)
106 if (r
->isIdentifier()) {
108 checkSameIdentifierTable(globalData
, r
);
112 return addSlowCase(globalData
, r
);
115 static PassRefPtr
<UString::Rep
> addSlowCase(ExecState
*, UString::Rep
* r
);
116 static PassRefPtr
<UString::Rep
> addSlowCase(JSGlobalData
*, UString::Rep
* r
);
118 static void checkSameIdentifierTable(ExecState
*, UString::Rep
*);
119 static void checkSameIdentifierTable(JSGlobalData
*, UString::Rep
*);
122 inline bool operator==(const Identifier
& a
, const Identifier
& b
)
124 return Identifier::equal(a
, b
);
127 inline bool operator!=(const Identifier
& a
, const Identifier
& b
)
129 return !Identifier::equal(a
, b
);
132 inline bool operator==(const Identifier
& a
, const char* b
)
134 return Identifier::equal(a
, b
);
137 inline bool operator!=(const Identifier
& a
, const char* b
)
139 return !Identifier::equal(a
, b
);
142 IdentifierTable
* createIdentifierTable();
143 void deleteIdentifierTable(IdentifierTable
*);
145 struct ThreadIdentifierTableData
{
146 ThreadIdentifierTableData()
147 : defaultIdentifierTable(0)
148 , currentIdentifierTable(0)
152 IdentifierTable
* defaultIdentifierTable
;
153 IdentifierTable
* currentIdentifierTable
;
156 extern WTF::ThreadSpecific
<ThreadIdentifierTableData
>* g_identifierTableSpecific
;
157 extern ThreadIdentifierTableData
* g_identifierTableMain
;
158 void createIdentifierTableSpecific();
160 inline IdentifierTable
* defaultIdentifierTable()
162 if (isMainThread() || pthread_main_np()) {
163 if (!g_identifierTableMain
)
164 createIdentifierTableSpecific();
165 return g_identifierTableMain
->defaultIdentifierTable
;
167 if (!g_identifierTableSpecific
)
168 createIdentifierTableSpecific();
169 ThreadIdentifierTableData
& data
= **g_identifierTableSpecific
;
171 return data
.defaultIdentifierTable
;
174 inline void setDefaultIdentifierTable(IdentifierTable
* identifierTable
)
176 if (isMainThread() || pthread_main_np()) {
177 if (!g_identifierTableMain
)
178 createIdentifierTableSpecific();
179 g_identifierTableMain
->defaultIdentifierTable
= identifierTable
;
182 if (!g_identifierTableSpecific
)
183 createIdentifierTableSpecific();
184 ThreadIdentifierTableData
& data
= **g_identifierTableSpecific
;
186 data
.defaultIdentifierTable
= identifierTable
;
189 inline IdentifierTable
* currentIdentifierTable()
191 if (isMainThread() || pthread_main_np()) {
192 if (!g_identifierTableMain
)
193 createIdentifierTableSpecific();
194 return g_identifierTableMain
->currentIdentifierTable
;
196 if (!g_identifierTableSpecific
)
197 createIdentifierTableSpecific();
198 ThreadIdentifierTableData
& data
= **g_identifierTableSpecific
;
200 return data
.currentIdentifierTable
;
203 inline IdentifierTable
* setCurrentIdentifierTable(IdentifierTable
* identifierTable
)
205 if (isMainThread() || pthread_main_np()) {
206 if (!g_identifierTableMain
)
207 createIdentifierTableSpecific();
208 IdentifierTable
* oldIdentifierTable
= g_identifierTableMain
->currentIdentifierTable
;
209 g_identifierTableMain
->currentIdentifierTable
= identifierTable
;
210 return oldIdentifierTable
;
212 if (!g_identifierTableSpecific
)
213 createIdentifierTableSpecific();
214 ThreadIdentifierTableData
& data
= **g_identifierTableSpecific
;
216 IdentifierTable
* oldIdentifierTable
= data
.currentIdentifierTable
;
217 data
.currentIdentifierTable
= identifierTable
;
218 return oldIdentifierTable
;
221 inline void resetCurrentIdentifierTable()
223 if (isMainThread() || pthread_main_np()) {
224 if (!g_identifierTableMain
)
225 createIdentifierTableSpecific();
226 g_identifierTableMain
->currentIdentifierTable
= g_identifierTableMain
->defaultIdentifierTable
;
229 if (!g_identifierTableSpecific
)
230 createIdentifierTableSpecific();
231 ThreadIdentifierTableData
& data
= **g_identifierTableSpecific
;
233 data
.currentIdentifierTable
= data
.defaultIdentifierTable
;
238 #endif // Identifier_h