OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. |
3 * Copyright (C) 2007-2009 Google, Inc. All rights reserved. | 3 * Copyright (C) 2007-2009 Google, Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 30 matching lines...) Expand all Loading... |
41 // Commenting out the locks to avoid dependencies on chrome for now. | 41 // Commenting out the locks to avoid dependencies on chrome for now. |
42 // Need a platform abstraction which we can use. | 42 // Need a platform abstraction which we can use. |
43 // static Lock StringIdentifierMapLock; | 43 // static Lock StringIdentifierMapLock; |
44 | 44 |
45 namespace { | 45 namespace { |
46 | 46 |
47 // We use StringKey here as the key-type to avoid a string copy to | 47 // We use StringKey here as the key-type to avoid a string copy to |
48 // construct the map key and for faster comparisons than strcmp. | 48 // construct the map key and for faster comparisons than strcmp. |
49 class StringKey { | 49 class StringKey { |
50 public: | 50 public: |
51 explicit StringKey(const char* str) : _string(str), _length(strlen(str)) {} | 51 explicit StringKey(const char* str) |
52 StringKey() : _string(0), _length(0) {} | 52 : m_string(str), m_length(strlen(str)) {} |
| 53 StringKey() : m_string(0), m_length(0) {} |
53 explicit StringKey(WTF::HashTableDeletedValueType) | 54 explicit StringKey(WTF::HashTableDeletedValueType) |
54 : _string(hashTableDeletedValue()), _length(0) { } | 55 : m_string(hashTableDeletedValue()), m_length(0) { } |
55 | 56 |
56 StringKey& operator=(const StringKey& other) { | 57 StringKey& operator=(const StringKey& other) { |
57 this->_string = other._string; | 58 this->m_string = other.m_string; |
58 this->_length = other._length; | 59 this->m_length = other.m_length; |
59 return *this; | 60 return *this; |
60 } | 61 } |
61 | 62 |
62 bool isHashTableDeletedValue() const { | 63 bool isHashTableDeletedValue() const { |
63 return _string == hashTableDeletedValue(); | 64 return m_string == hashTableDeletedValue(); |
64 } | 65 } |
65 | 66 |
66 const char* _string; | 67 const char* m_string; |
67 size_t _length; | 68 size_t m_length; |
68 private: | 69 private: |
69 const char* hashTableDeletedValue() const { | 70 const char* hashTableDeletedValue() const { |
70 return reinterpret_cast<const char*>(-1); | 71 return reinterpret_cast<const char*>(-1); |
71 } | 72 } |
72 }; | 73 }; |
73 | 74 |
74 inline bool operator==(const StringKey& x, const StringKey& y) { | 75 inline bool operator==(const StringKey& x, const StringKey& y) { |
75 if (x._length != y._length) { | 76 if (x.m_length != y.m_length) { |
76 return false; | 77 return false; |
77 } else if (x._string == y._string) { | 78 } else if (x.m_string == y.m_string) { |
78 return true; | 79 return true; |
79 } else { | 80 } else { |
80 ASSERT(!x.isHashTableDeletedValue() && !y.isHashTableDeletedValue()); | 81 ASSERT(!x.isHashTableDeletedValue() && !y.isHashTableDeletedValue()); |
81 return memcmp(x._string, y._string, y._length) == 0; | 82 return memcmp(x.m_string, y.m_string, y.m_length) == 0; |
82 } | 83 } |
83 } | 84 } |
84 | 85 |
85 // Implement WTF::DefaultHash<StringKey>::Hash interface. | 86 // Implement WTF::DefaultHash<StringKey>::Hash interface. |
86 struct StringKeyHash { | 87 struct StringKeyHash { |
87 static unsigned hash(const StringKey& key) { | 88 static unsigned hash(const StringKey& key) { |
88 // Use the same string hash function as in V8. | 89 // Compute string hash. |
89 unsigned hash = 0; | 90 unsigned hash = 0; |
90 size_t len = key._length; | 91 size_t len = key.m_length; |
91 const char* str = key._string; | 92 const char* str = key.m_string; |
92 for (size_t i = 0; i < len; i++) { | 93 for (size_t i = 0; i < len; i++) { |
93 char c = str[i]; | 94 char c = str[i]; |
94 hash += c; | 95 hash += c; |
95 hash += (hash << 10); | 96 hash += (hash << 10); |
96 hash ^= (hash >> 6); | 97 hash ^= (hash >> 6); |
97 } | 98 } |
98 hash += (hash << 3); | 99 hash += (hash << 3); |
99 hash ^= (hash >> 11); | 100 hash ^= (hash >> 11); |
100 hash += (hash << 15); | 101 hash += (hash << 15); |
101 if (hash == 0) { | 102 if (hash == 0) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 153 |
153 if (name) { | 154 if (name) { |
154 // AutoLock safeLock(StringIdentifierMapLock); | 155 // AutoLock safeLock(StringIdentifierMapLock); |
155 | 156 |
156 StringKey key(name); | 157 StringKey key(name); |
157 StringIdentifierMap* identMap = getStringIdentifierMap(); | 158 StringIdentifierMap* identMap = getStringIdentifierMap(); |
158 StringIdentifierMap::iterator iter = identMap->find(key); | 159 StringIdentifierMap::iterator iter = identMap->find(key); |
159 if (iter != identMap->end()) | 160 if (iter != identMap->end()) |
160 return static_cast<NPIdentifier>(iter->second); | 161 return static_cast<NPIdentifier>(iter->second); |
161 | 162 |
162 size_t nameLen = key._length; | 163 size_t nameLen = key.m_length; |
163 | 164 |
164 // We never release identifiers, so this dictionary will grow. | 165 // We never release identifiers, so this dictionary will grow. |
165 PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>( | 166 PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>( |
166 malloc(sizeof(PrivateIdentifier) + nameLen + 1)); | 167 malloc(sizeof(PrivateIdentifier) + nameLen + 1)); |
167 char* nameStorage = reinterpret_cast<char*>(identifier + 1); | 168 char* nameStorage = reinterpret_cast<char*>(identifier + 1); |
168 memcpy(nameStorage, name, nameLen + 1); | 169 memcpy(nameStorage, name, nameLen + 1); |
169 identifier->isString = true; | 170 identifier->isString = true; |
170 identifier->value.string = reinterpret_cast<NPUTF8*>(nameStorage); | 171 identifier->value.string = reinterpret_cast<NPUTF8*>(nameStorage); |
171 key._string = nameStorage; | 172 key.m_string = nameStorage; |
172 identMap->set(key, identifier); | 173 identMap->set(key, identifier); |
173 return (NPIdentifier)identifier; | 174 return (NPIdentifier)identifier; |
174 } | 175 } |
175 | 176 |
176 return 0; | 177 return 0; |
177 } | 178 } |
178 | 179 |
179 void NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, | 180 void NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, |
180 NPIdentifier* identifiers) { | 181 NPIdentifier* identifiers) { |
181 ASSERT(names); | 182 ASSERT(names); |
182 ASSERT(identifiers); | 183 ASSERT(identifiers); |
183 | 184 |
184 if (names && identifiers) | 185 if (names && identifiers) |
185 for (int i = 0; i < nameCount; i++) | 186 for (int i = 0; i < nameCount; i++) |
186 identifiers[i] = NPN_GetStringIdentifier(names[i]); | 187 identifiers[i] = NPN_GetStringIdentifier(names[i]); |
187 } | 188 } |
188 | 189 |
189 NPIdentifier NPN_GetIntIdentifier(int32_t intid) { | 190 NPIdentifier NPN_GetIntIdentifier(int32_t intid) { |
190 // AutoLock safeLock(IntIdentifierMapLock); | 191 // AutoLock safeLock(IntIdentifierMapLock); |
| 192 // Special case for -1 and 0, both cannot be used as key in HashMap. |
| 193 if (intid == 0 || intid == -1) { |
| 194 static PrivateIdentifier* minusOneOrZeroIds[2]; |
| 195 PrivateIdentifier* id = minusOneOrZeroIds[intid + 1]; |
| 196 if (!id) { |
| 197 id = reinterpret_cast<PrivateIdentifier*>( |
| 198 malloc(sizeof(PrivateIdentifier))); |
| 199 id->isString = false; |
| 200 id->value.number = intid; |
| 201 minusOneOrZeroIds[intid + 1] = id; |
| 202 } |
| 203 return (NPIdentifier)id; |
| 204 } |
191 | 205 |
192 IntIdentifierMap* identMap = getIntIdentifierMap(); | 206 IntIdentifierMap* identMap = getIntIdentifierMap(); |
193 IntIdentifierMap::iterator iter = identMap->find(intid); | 207 IntIdentifierMap::iterator iter = identMap->find(intid); |
194 if (iter != identMap->end()) | 208 if (iter != identMap->end()) |
195 return static_cast<NPIdentifier>(iter->second); | 209 return static_cast<NPIdentifier>(iter->second); |
196 | 210 |
197 // We never release identifiers, so this dictionary will grow. | 211 // We never release identifiers, so this dictionary will grow. |
198 PrivateIdentifier* identifier = reinterpret_cast<PrivateIdentifier*>( | 212 PrivateIdentifier* identifier = reinterpret_cast<PrivateIdentifier*>( |
199 malloc(sizeof(PrivateIdentifier))); | 213 malloc(sizeof(PrivateIdentifier))); |
200 identifier->isString = false; | 214 identifier->isString = false; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 ForgetV8ObjectForNPObject(obj); | 428 ForgetV8ObjectForNPObject(obj); |
415 | 429 |
416 g_live_objects.remove(obj); | 430 g_live_objects.remove(obj); |
417 } | 431 } |
418 | 432 |
419 bool _NPN_IsAlive(NPObject* obj) { | 433 bool _NPN_IsAlive(NPObject* obj) { |
420 return g_live_objects.find(obj) != g_live_objects.end(); | 434 return g_live_objects.find(obj) != g_live_objects.end(); |
421 } | 435 } |
422 | 436 |
423 } // extern "C" | 437 } // extern "C" |
OLD | NEW |