source: webkit/trunk/JavaScriptCore/kjs/identifier.cpp@ 34372

Last change on this file since 34372 was 34361, checked in by [email protected], 17 years ago

Reviewed by Darin.

Fix JSClassCreate to work with old JSCore API threading model.

No change on SunSpider.

  • API/JSClassRef.cpp: (OpaqueJSClass::OpaqueJSClass): Since JSClass is constructed without a context, there is no way for it to create Identifiers. Also, added initializeThreading(), just for good measure.
  • API/JSCallbackObjectFunctions.h: (KJS::::getPropertyNames): Make an Identifier out of the string here, because propertyNames.add() needs that.
  • kjs/identifier.cpp:
  • kjs/identifier.h: (KJS::Identifier::equal):
  • kjs/ustring.cpp: (KJS::equal): Moved equal() from identifier.h to ustring.h, because it's not really about Identifiers, and to make it possible to use it from StrHash. Include StrHash.h from ustring.h to avoid having the behavior depend on headers that happen to be included.
  • wtf/StrHash.h: Removed.
  • kjs/ustring.h: Made RefPtr<UString::Rep> use the same default hash as UString::Rep* (it used to default to pointer equality). Moved the whole StrHash header into ustring.h.
  • JavaScriptCore.exp: Export equal() for WebCore use (this StrHash is used in c_class.cpp, jni_class.cpp, and npruntime.cpp).
  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
3 *
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.
8 *
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.
13 *
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.
18 *
19 */
20
21#include "config.h"
22
23#include "identifier.h"
24
25#include "JSLock.h"
26#include <new> // for placement new
27#include <string.h> // for strlen
28#include <wtf/Assertions.h>
29#include <wtf/FastMalloc.h>
30#include <wtf/HashSet.h>
31#if USE(MULTIPLE_THREADS)
32#include <wtf/ThreadSpecific.h>
33using namespace WTF;
34#endif
35
36namespace KJS {
37
38class IdentifierTable {
39public:
40 ~IdentifierTable()
41 {
42 HashSet<UString::Rep*>::iterator end = m_table.end();
43 for (HashSet<UString::Rep*>::iterator iter = m_table.begin(); iter != end; ++iter)
44 (*iter)->identifierTable = 0;
45 }
46
47 std::pair<HashSet<UString::Rep*>::iterator, bool> add(UString::Rep* value)
48 {
49 std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add(value);
50 (*result.first)->identifierTable = this;
51 return result;
52 }
53
54 template<typename U, typename V>
55 std::pair<HashSet<UString::Rep*>::iterator, bool> add(U value)
56 {
57 std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add<U, V>(value);
58 (*result.first)->identifierTable = this;
59 return result;
60 }
61
62 void remove(UString::Rep* r) { m_table.remove(r); }
63
64private:
65 HashSet<UString::Rep*> m_table;
66};
67
68typedef HashMap<const char*, RefPtr<UString::Rep>, PtrHash<const char*> > LiteralIdentifierTable;
69
70static inline IdentifierTable& identifierTable()
71{
72#if USE(MULTIPLE_THREADS)
73 static ThreadSpecific<IdentifierTable> table;
74 return *table;
75#else
76 static IdentifierTable table;
77 return table;
78#endif
79}
80
81static inline LiteralIdentifierTable& literalIdentifierTable()
82{
83#if USE(MULTIPLE_THREADS)
84 static ThreadSpecific<LiteralIdentifierTable> table;
85 return *table;
86#else
87 static LiteralIdentifierTable table;
88 return table;
89#endif
90}
91
92void Identifier::initializeIdentifierThreading()
93{
94 identifierTable();
95 literalIdentifierTable();
96}
97
98bool Identifier::equal(const UString::Rep *r, const char *s)
99{
100 int length = r->len;
101 const UChar *d = r->data();
102 for (int i = 0; i != length; ++i)
103 if (d[i] != (unsigned char)s[i])
104 return false;
105 return s[length] == 0;
106}
107
108bool Identifier::equal(const UString::Rep *r, const UChar *s, int length)
109{
110 if (r->len != length)
111 return false;
112 const UChar *d = r->data();
113 for (int i = 0; i != length; ++i)
114 if (d[i] != s[i])
115 return false;
116 return true;
117}
118
119struct CStringTranslator
120{
121 static unsigned hash(const char *c)
122 {
123 return UString::Rep::computeHash(c);
124 }
125
126 static bool equal(UString::Rep *r, const char *s)
127 {
128 return Identifier::equal(r, s);
129 }
130
131 static void translate(UString::Rep*& location, const char *c, unsigned hash)
132 {
133 size_t length = strlen(c);
134 UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * length));
135 for (size_t i = 0; i != length; i++)
136 d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
137
138 UString::Rep *r = UString::Rep::create(d, static_cast<int>(length)).releaseRef();
139 r->rc = 0;
140 r->_hash = hash;
141
142 location = r;
143 }
144};
145
146PassRefPtr<UString::Rep> Identifier::add(const char* c)
147{
148 if (!c) {
149 UString::Rep::null.hash();
150 return &UString::Rep::null;
151 }
152
153 if (!c[0]) {
154 UString::Rep::empty.hash();
155 return &UString::Rep::empty;
156 }
157
158 LiteralIdentifierTable& literalTableLocalRef = literalIdentifierTable();
159
160 const LiteralIdentifierTable::iterator& iter = literalTableLocalRef.find(c);
161 if (iter != literalTableLocalRef.end())
162 return iter->second;
163
164 UString::Rep* addedString = *identifierTable().add<const char*, CStringTranslator>(c).first;
165 literalTableLocalRef.add(c, addedString);
166
167 return addedString;
168}
169
170struct UCharBuffer {
171 const UChar *s;
172 unsigned int length;
173};
174
175struct UCharBufferTranslator
176{
177 static unsigned hash(const UCharBuffer& buf)
178 {
179 return UString::Rep::computeHash(buf.s, buf.length);
180 }
181
182 static bool equal(UString::Rep *str, const UCharBuffer& buf)
183 {
184 return Identifier::equal(str, buf.s, buf.length);
185 }
186
187 static void translate(UString::Rep *& location, const UCharBuffer& buf, unsigned hash)
188 {
189 UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * buf.length));
190 for (unsigned i = 0; i != buf.length; i++)
191 d[i] = buf.s[i];
192
193 UString::Rep *r = UString::Rep::create(d, buf.length).releaseRef();
194 r->rc = 0;
195 r->_hash = hash;
196
197 location = r;
198 }
199};
200
201PassRefPtr<UString::Rep> Identifier::add(const UChar *s, int length)
202{
203 if (!length) {
204 UString::Rep::empty.hash();
205 return &UString::Rep::empty;
206 }
207
208 UCharBuffer buf = {s, length};
209 return *identifierTable().add<UCharBuffer, UCharBufferTranslator>(buf).first;
210}
211
212PassRefPtr<UString::Rep> Identifier::addSlowCase(UString::Rep *r)
213{
214 ASSERT(!r->identifierTable);
215
216 if (r->len == 0) {
217 UString::Rep::empty.hash();
218 return &UString::Rep::empty;
219 }
220
221 return *identifierTable().add(r).first;
222}
223
224void Identifier::remove(UString::Rep *r)
225{
226 r->identifierTable->remove(r);
227}
228
229} // namespace KJS
Note: See TracBrowser for help on using the repository browser.