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

Last change on this file since 12908 was 12329, checked in by mjs, 19 years ago

JavaScriptCore:

Reviewed by Eric.

  • renamed PointerHash to PtrHash
  • made PtrHash the default hash function for int and pointer types that aren't further specialized
  • added an AtomicStringImpl class to make it easier and more typesafe to identity hash atomic strings
  • did appropriate consequent cleanup (very few places now need to declare a hash function) http://bugzilla.opendarwin.org/show_bug.cgi?id=6752


  • kjs/array_object.cpp: (ArrayProtoFunc::callAsFunction): no need to mention PointerHash
  • kjs/collector.cpp: ditto
  • kjs/identifier.cpp: (KXMLCore::): declare DefaultHash the new way
  • kjs/internal.cpp: no need to mention PointerHash
  • kjs/ustring.h:
  • kxmlcore/HashCountedSet.h: change how we get the default hash to make it easier to specialize on PtrHash
  • kxmlcore/HashFunctions.h: (KXMLCore::): renamed PointerHash to PtrHash; changed DefaultHash so that it has a Hash typedef rather than being a hash function class itself; declared DefaultHash for int and partializy specialized for pointer types
  • kxmlcore/HashMapPtrSpec.h: (KXMLCore::PtrHashIteratorAdapter::PtrHashIteratorAdapter): Slight tweaks for new way of handling pointer hash (KXMLCore::PtrHashConstIteratorAdapter::PtrHashConstIteratorAdapter): ditto (KXMLCore::): ditto
  • kxmlcore/HashMap.h: ditto
  • kxmlcore/HashSet.h: ditto

WebCore:

Reviewed by Eric.

  • renamed PointerHash to PtrHash
  • made PtrHash the default hash function for int and pointer types that aren't further specialized
  • added an AtomicStringImpl class to make it easier and more typesafe to identity hash atomic strings
  • did appropriate consequent cleanup (very few places now need to declare a hash function) http://bugzilla.opendarwin.org/show_bug.cgi?id=6752


  • bindings/objc/DOM.mm:
  • bridge/mac/WebCoreFrameBridge.mm: (-[WebCoreFrameBridge elementWithName:inForm:]):
  • css/cssstyleselector.cpp: (WebCore::CSSRuleSet::getIDRules): (WebCore::CSSRuleSet::getClassRules): (WebCore::CSSRuleSet::getTagRules): (WebCore::CSSRuleSet::addToRuleSet):
  • khtml/dom/dom_string.h: (KXMLCore::):
  • khtml/ecma/kjs_binding.cpp: (KJS::UString::UString):
  • khtml/ecma/kjs_dom.cpp: (KJS::DOMNode::mark):
  • khtml/ecma/kjs_html.cpp: (KJS::KJS::HTMLElement::classInfo): (KJS::HTMLElement::accessors): (KJS::HTMLElement::selectSetter): (KJS::HTMLElement::inputSetter): (KJS::HTMLElement::textAreaSetter): (KJS::HTMLElement::buttonSetter):
  • khtml/ecma/kjs_window.h:
  • khtml/editing/apply_style_command.cpp: (WebCore::ApplyStyleCommand::applyRelativeFontStyleChange):
  • khtml/html/HTMLCollectionImpl.h:
  • khtml/html/HTMLElementImpl.cpp: (WebCore::HTMLElementImpl::isRecognizedTagName): (WebCore::inlineTagList): (WebCore::blockTagList):
  • khtml/html/HTMLFormCollectionImpl.cpp: (WebCore::HTMLFormCollectionImpl::updateNameCache):
  • khtml/html/HTMLGenericFormElementImpl.cpp: (WebCore::HTMLGenericFormElementImpl::name): (WebCore::HTMLGenericFormElementImpl::setName):
  • khtml/html/HTMLGenericFormElementImpl.h:
  • khtml/html/HTMLInputElementImpl.cpp: (WebCore::HTMLInputElementImpl::name):
  • khtml/html/HTMLInputElementImpl.h:
  • khtml/html/htmlfactory.cpp: (DOM::HTMLElementFactory::createHTMLElement):
  • khtml/html/htmlparser.cpp: (HTMLParser::isHeaderTag): (HTMLParser::isResidualStyleTag): (HTMLParser::isAffectedByResidualStyle):
  • khtml/xml/DocumentImpl.cpp: (WebCore::DocumentImpl::checkedRadioButtonForGroup): (WebCore::DocumentImpl::removeRadioButtonGroup):
  • khtml/xml/DocumentImpl.h:
  • khtml/xml/NodeImpl.h:
  • khtml/xml/dom_atomicstring.h: (DOM::AtomicString::AtomicString): (DOM::AtomicString::impl): (KXMLCore::):
  • khtml/xml/dom_stringimpl.cpp: (DOM::equal):
  • khtml/xml/dom_stringimpl.h: (KXMLCore::):
  • khtml/xml/xml_tokenizer.h:
  • ksvg2/misc/KSVGTimeScheduler.cpp: (KSVG::SVGTimer::notifyAll):
  • kwq/KWQKJobClasses.h:
  • kwq/KWQObject.cpp:
  • loader/CachedObject.h:
  • loader/CachedObjectClientWalker.h:
  • loader/loader.h:
  • page/Frame.cpp: (Frame::endAllLifeSupport):
  • rendering/render_canvas.cpp: (RenderCanvas::selectionRect): (RenderCanvas::setSelection):
  • rendering/render_canvas.h:
  • rendering/render_object.h:
  • xml/xmlhttprequest.h:
  • Property svn:eol-style set to native
File size: 6.8 KB
Line 
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 2003 Apple Computer, Inc
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22// For JavaScriptCore we need to avoid having static constructors.
23// Our strategy is to declare the global objects with a different type (initialized to 0)
24// and then use placement new to initialize the global objects later. This is not completely
25// portable, and it would be good to figure out a 100% clean way that still avoids code that
26// runs at init time.
27
28#if !defined(WIN32) // can't get this to compile on Visual C++ yet
29#define AVOID_STATIC_CONSTRUCTORS 1
30#endif
31
32#if AVOID_STATIC_CONSTRUCTORS
33#define KJS_IDENTIFIER_HIDE_GLOBALS 1
34#endif
35
36#include "config.h"
37#include "identifier.h"
38
39#include <kxmlcore/FastMalloc.h>
40#include <kxmlcore/HashSet.h>
41#include <string.h> // for strlen
42#include <new> // for placement new
43
44namespace KXMLCore {
45
46 template<typename T> class DefaultHash;
47 template<typename T> class StrHash;
48
49 template<> struct StrHash<KJS::UString::Rep *> {
50 static unsigned hash(const KJS::UString::Rep *key) { return key->hash(); }
51 static bool equal(const KJS::UString::Rep *a, const KJS::UString::Rep *b) { return KJS::Identifier::equal(a, b); }
52 };
53
54 template<> struct DefaultHash<KJS::UString::Rep *> {
55 typedef StrHash<KJS::UString::Rep *> Hash;
56 };
57
58}
59
60namespace KJS {
61
62typedef HashSet<UString::Rep *> IdentifierTable;
63static IdentifierTable *table;
64
65static inline IdentifierTable& identifierTable()
66{
67 if (!table)
68 table = new IdentifierTable;
69 return *table;
70}
71
72
73bool Identifier::equal(const UString::Rep *r, const char *s)
74{
75 int length = r->len;
76 const UChar *d = r->data();
77 for (int i = 0; i != length; ++i)
78 if (d[i].uc != (unsigned char)s[i])
79 return false;
80 return s[length] == 0;
81}
82
83bool Identifier::equal(const UString::Rep *r, const UChar *s, int length)
84{
85 if (r->len != length)
86 return false;
87 const UChar *d = r->data();
88 for (int i = 0; i != length; ++i)
89 if (d[i].uc != s[i].uc)
90 return false;
91 return true;
92}
93
94bool Identifier::equal(const UString::Rep *r, const UString::Rep *b)
95{
96 int length = r->len;
97 if (length != b->len)
98 return false;
99 const UChar *d = r->data();
100 const UChar *s = b->data();
101 for (int i = 0; i != length; ++i)
102 if (d[i].uc != s[i].uc)
103 return false;
104 return true;
105}
106
107struct CStringTranslator
108{
109 static unsigned hash(const char *c)
110 {
111 return UString::Rep::computeHash(c);
112 }
113
114 static bool equal(UString::Rep *r, const char *s)
115 {
116 return Identifier::equal(r, s);
117 }
118
119 static void translate(UString::Rep*& location, const char *c, unsigned hash)
120 {
121 int length = strlen(c);
122 UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * length));
123 for (int i = 0; i != length; i++)
124 d[i] = c[i];
125
126 UString::Rep *r = UString::Rep::create(d, length).release();
127 r->isIdentifier = 1;
128 r->rc = 0;
129 r->_hash = hash;
130
131 location = r;
132 }
133};
134
135PassRefPtr<UString::Rep> Identifier::add(const char *c)
136{
137 if (!c)
138 return &UString::Rep::null;
139 int length = strlen(c);
140 if (length == 0)
141 return &UString::Rep::empty;
142
143 return *identifierTable().add<const char *, CStringTranslator>(c).first;
144}
145
146struct UCharBuffer {
147 const UChar *s;
148 unsigned int length;
149};
150
151struct UCharBufferTranslator
152{
153 static unsigned hash(const UCharBuffer& buf)
154 {
155 return UString::Rep::computeHash(buf.s, buf.length);
156 }
157
158 static bool equal(UString::Rep *str, const UCharBuffer& buf)
159 {
160 return Identifier::equal(str, buf.s, buf.length);
161 }
162
163 static void translate(UString::Rep *& location, const UCharBuffer& buf, unsigned hash)
164 {
165 UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * buf.length));
166 for (unsigned i = 0; i != buf.length; i++)
167 d[i] = buf.s[i];
168
169 UString::Rep *r = UString::Rep::create(d, buf.length).release();
170 r->isIdentifier = 1;
171 r->rc = 0;
172 r->_hash = hash;
173
174 location = r;
175 }
176};
177
178PassRefPtr<UString::Rep> Identifier::add(const UChar *s, int length)
179{
180 if (length == 0)
181 return &UString::Rep::empty;
182
183 UCharBuffer buf = {s, length};
184 return *identifierTable().add<UCharBuffer, UCharBufferTranslator>(buf).first;
185}
186
187PassRefPtr<UString::Rep> Identifier::add(UString::Rep *r)
188{
189 if (r->isIdentifier)
190 return r;
191
192 if (r->len == 0)
193 return &UString::Rep::empty;
194
195 UString::Rep *result = *identifierTable().add(r).first;
196 if (result == r)
197 r->isIdentifier = true;
198 return result;
199}
200
201void Identifier::remove(UString::Rep *r)
202{
203 identifierTable().remove(r);
204}
205
206// Global constants for property name strings.
207
208#if !AVOID_STATIC_CONSTRUCTORS
209 // Define an Identifier in the normal way.
210 #define DEFINE_GLOBAL(name, string) extern const Identifier name(string);
211#else
212 // Define an Identifier-sized array of pointers to avoid static initialization.
213 // Use an array of pointers instead of an array of char in case there is some alignment issue.
214 #define DEFINE_GLOBAL(name, string) \
215 void * name[(sizeof(Identifier) + sizeof(void *) - 1) / sizeof(void *)];
216#endif
217
218const char * const nullCString = 0;
219
220DEFINE_GLOBAL(nullIdentifier, nullCString)
221DEFINE_GLOBAL(specialPrototypePropertyName, "__proto__")
222
223#define DEFINE_PROPERTY_NAME_GLOBAL(name) DEFINE_GLOBAL(name ## PropertyName, #name)
224KJS_IDENTIFIER_EACH_PROPERTY_NAME_GLOBAL(DEFINE_PROPERTY_NAME_GLOBAL)
225
226void Identifier::init()
227{
228#if AVOID_STATIC_CONSTRUCTORS
229 static bool initialized;
230 if (!initialized) {
231 // Use placement new to initialize the globals.
232
233 new (&nullIdentifier) Identifier(nullCString);
234 new (&specialPrototypePropertyName) Identifier("__proto__");
235
236 #define PLACEMENT_NEW_PROPERTY_NAME_GLOBAL(name) new(&name ## PropertyName) Identifier(#name);
237 KJS_IDENTIFIER_EACH_PROPERTY_NAME_GLOBAL(PLACEMENT_NEW_PROPERTY_NAME_GLOBAL)
238
239 initialized = true;
240 }
241#endif
242}
243
244} // namespace KJS
Note: See TracBrowser for help on using the repository browser.