source: webkit/trunk/JavaScriptCore/runtime/Identifier.cpp@ 57879

Last change on this file since 57879 was 57879, checked in by [email protected], 15 years ago

Rubber stamped by Maciej Stachowiak (relanding r57829).
Added missing JS_EXPORTDATA

JavaScriptCore:

  • API/APIShims.h:

(JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
(JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
(JSC::APICallbackShim::APICallbackShim):
(JSC::APICallbackShim::~APICallbackShim):

(JSC::checkSyntax):
(JSC::evaluate):

  • runtime/Identifier.cpp:

(JSC::Identifier::remove):
(JSC::Identifier::checkCurrentIdentifierTable):

  • runtime/Identifier.h:
  • runtime/InitializeThreading.cpp:

(JSC::initializeThreadingOnce):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::create):

  • wtf/WTFThreadData.cpp: Copied from JavaScriptCore/wtf/WTFThreadData.cpp.
  • wtf/WTFThreadData.h: Copied from JavaScriptCore/wtf/WTFThreadData.h.

JavaScriptGlue:

  • ForwardingHeaders/wtf/WTFThreadData.h: Copied from JavaScriptGlue/ForwardingHeaders/wtf/WTFThreadData.h.
  • JSUtils.cpp:

(JSGlueAPIEntry::JSGlueAPIEntry):
(JSGlueAPIEntry::~JSGlueAPIEntry):
(JSGlueAPICallback::JSGlueAPICallback):
(JSGlueAPICallback::~JSGlueAPICallback):

WebCore:

  • ForwardingHeaders/wtf/WTFThreadData.h: Copied from WebCore/ForwardingHeaders/wtf/WTFThreadData.h.
  • platform/ThreadGlobalData.cpp:

(WebCore::ThreadGlobalData::ThreadGlobalData):
(WebCore::ThreadGlobalData::~ThreadGlobalData):

  • platform/ThreadGlobalData.h:

(WebCore::ThreadGlobalData::eventNames):

  • platform/text/AtomicString.cpp:

(WebCore::AtomicStringTable::create):
(WebCore::AtomicStringTable::table):
(WebCore::AtomicStringTable::destroy):
(WebCore::stringTable):

  • Property svn:eol-style set to native
File size: 8.3 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#include "Identifier.h"
23
24#include "CallFrame.h"
25#include "NumericStrings.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#include <wtf/WTFThreadData.h>
32
33using WTF::ThreadSpecific;
34
35namespace JSC {
36
37typedef HashMap<const char*, RefPtr<UString::Rep>, PtrHash<const char*> > LiteralIdentifierTable;
38
39class IdentifierTable : public FastAllocBase {
40public:
41 ~IdentifierTable()
42 {
43 HashSet<UString::Rep*>::iterator end = m_table.end();
44 for (HashSet<UString::Rep*>::iterator iter = m_table.begin(); iter != end; ++iter)
45 (*iter)->setIsIdentifier(false);
46 }
47
48 std::pair<HashSet<UString::Rep*>::iterator, bool> add(UString::Rep* value)
49 {
50 std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add(value);
51 (*result.first)->setIsIdentifier(true);
52 return result;
53 }
54
55 template<typename U, typename V>
56 std::pair<HashSet<UString::Rep*>::iterator, bool> add(U value)
57 {
58 std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add<U, V>(value);
59 (*result.first)->setIsIdentifier(true);
60 return result;
61 }
62
63 void remove(UString::Rep* r) { m_table.remove(r); }
64
65 LiteralIdentifierTable& literalTable() { return m_literalTable; }
66
67private:
68 HashSet<UString::Rep*> m_table;
69 LiteralIdentifierTable m_literalTable;
70};
71
72IdentifierTable* createIdentifierTable()
73{
74 return new IdentifierTable;
75}
76
77void deleteIdentifierTable(IdentifierTable* table)
78{
79 delete table;
80}
81
82bool Identifier::equal(const UString::Rep* r, const char* s)
83{
84 int length = r->length();
85 const UChar* d = r->characters();
86 for (int i = 0; i != length; ++i)
87 if (d[i] != (unsigned char)s[i])
88 return false;
89 return s[length] == 0;
90}
91
92bool Identifier::equal(const UString::Rep* r, const UChar* s, unsigned length)
93{
94 if (r->length() != length)
95 return false;
96 const UChar* d = r->characters();
97 for (unsigned i = 0; i != length; ++i)
98 if (d[i] != s[i])
99 return false;
100 return true;
101}
102
103struct CStringTranslator {
104 static unsigned hash(const char* c)
105 {
106 return UString::Rep::computeHash(c);
107 }
108
109 static bool equal(UString::Rep* r, const char* s)
110 {
111 return Identifier::equal(r, s);
112 }
113
114 static void translate(UString::Rep*& location, const char* c, unsigned hash)
115 {
116 size_t length = strlen(c);
117 UChar* d;
118 UString::Rep* r = UString::Rep::createUninitialized(length, d).releaseRef();
119 for (size_t i = 0; i != length; i++)
120 d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
121 r->setHash(hash);
122 location = r;
123 }
124};
125
126PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
127{
128 if (!c)
129 return UString::null().rep();
130 if (!c[0])
131 return UString::Rep::empty();
132 if (!c[1])
133 return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
134
135 IdentifierTable& identifierTable = *globalData->identifierTable;
136 LiteralIdentifierTable& literalIdentifierTable = identifierTable.literalTable();
137
138 const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c);
139 if (iter != literalIdentifierTable.end())
140 return iter->second;
141
142 pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, CStringTranslator>(c);
143
144 // If the string is newly-translated, then we need to adopt it.
145 // The boolean in the pair tells us if that is so.
146 RefPtr<UString::Rep> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first;
147
148 literalIdentifierTable.add(c, addedString.get());
149
150 return addedString.release();
151}
152
153PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const char* c)
154{
155 return add(&exec->globalData(), c);
156}
157
158struct UCharBuffer {
159 const UChar* s;
160 unsigned int length;
161};
162
163struct UCharBufferTranslator {
164 static unsigned hash(const UCharBuffer& buf)
165 {
166 return UString::Rep::computeHash(buf.s, buf.length);
167 }
168
169 static bool equal(UString::Rep* str, const UCharBuffer& buf)
170 {
171 return Identifier::equal(str, buf.s, buf.length);
172 }
173
174 static void translate(UString::Rep*& location, const UCharBuffer& buf, unsigned hash)
175 {
176 UChar* d;
177 UString::Rep* r = UString::Rep::createUninitialized(buf.length, d).releaseRef();
178 for (unsigned i = 0; i != buf.length; i++)
179 d[i] = buf.s[i];
180 r->setHash(hash);
181 location = r;
182 }
183};
184
185PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar* s, int length)
186{
187 if (length == 1) {
188 UChar c = s[0];
189 if (c <= 0xFF)
190 return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
191 }
192 if (!length)
193 return UString::Rep::empty();
194 UCharBuffer buf = {s, length};
195 pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, UCharBufferTranslator>(buf);
196
197 // If the string is newly-translated, then we need to adopt it.
198 // The boolean in the pair tells us if that is so.
199 return addResult.second ? adoptRef(*addResult.first) : *addResult.first;
200}
201
202PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const UChar* s, int length)
203{
204 return add(&exec->globalData(), s, length);
205}
206
207PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UString::Rep* r)
208{
209 ASSERT(!r->isIdentifier());
210 // The empty & null strings are static singletons, and static strings are handled
211 // in ::add() in the header, so we should never get here with a zero length string.
212 ASSERT(r->length());
213
214 if (r->length() == 1) {
215 UChar c = r->characters()[0];
216 if (c <= 0xFF)
217 r = globalData->smallStrings.singleCharacterStringRep(c);
218 if (r->isIdentifier())
219 return r;
220 }
221
222 return *globalData->identifierTable->add(r).first;
223}
224
225PassRefPtr<UString::Rep> Identifier::addSlowCase(ExecState* exec, UString::Rep* r)
226{
227 return addSlowCase(&exec->globalData(), r);
228}
229
230void Identifier::remove(UString::Rep* r)
231{
232 wtfThreadData().currentIdentifierTable()->remove(r);
233}
234
235Identifier Identifier::from(ExecState* exec, unsigned value)
236{
237 return Identifier(exec, exec->globalData().numericStrings.add(value));
238}
239
240Identifier Identifier::from(ExecState* exec, int value)
241{
242 return Identifier(exec, exec->globalData().numericStrings.add(value));
243}
244
245Identifier Identifier::from(ExecState* exec, double value)
246{
247 return Identifier(exec, exec->globalData().numericStrings.add(value));
248}
249
250#ifndef NDEBUG
251
252void Identifier::checkCurrentIdentifierTable(JSGlobalData* globalData)
253{
254 // Check the identifier table accessible through the threadspecific matches the
255 // globalData's identifier table.
256 ASSERT_UNUSED(globalData, globalData->identifierTable == wtfThreadData().currentIdentifierTable());
257}
258
259void Identifier::checkCurrentIdentifierTable(ExecState* exec)
260{
261 checkCurrentIdentifierTable(&exec->globalData());
262}
263
264#else
265
266// These only exists so that our exports are the same for debug and release builds.
267// This would be an ASSERT_NOT_REACHED(), but we're in NDEBUG only code here!
268void Identifier::checkCurrentIdentifierTable(JSGlobalData*) { CRASH(); }
269void Identifier::checkCurrentIdentifierTable(ExecState*) { CRASH(); }
270
271#endif
272
273} // namespace JSC
Note: See TracBrowser for help on using the repository browser.