source: webkit/trunk/JavaScriptCore/runtime/Lookup.h@ 38477

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

2008-11-05 Cameron Zwarich <[email protected]>

Not reviewed.

Fix the build for case-sensitive build systems.

  • API/JSBase.cpp:
  • API/JSObjectRef.cpp:
  • runtime/CommonIdentifiers.h:
  • runtime/Identifier.cpp:
  • runtime/InitializeThreading.cpp:
  • runtime/InternalFunction.h:
  • runtime/JSString.h:
  • runtime/Lookup.h:
  • runtime/PropertyNameArray.h:
  • runtime/PropertySlot.h:
  • runtime/StructureID.cpp:
  • runtime/StructureID.h:
  • runtime/UString.cpp:
  • Property svn:eol-style set to native
File size: 8.6 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21#ifndef KJS_lookup_h
22#define KJS_lookup_h
23
24#include "ExecState.h"
25#include "Identifier.h"
26#include "JSFunction.h"
27#include "JSGlobalObject.h"
28#include "JSObject.h"
29#include "PropertySlot.h"
30#include <stdio.h>
31#include <wtf/Assertions.h>
32
33namespace JSC {
34
35 // Hash table generated by the create_hash_table script.
36 struct HashTableValue {
37 const char* key; // property name
38 unsigned char attributes; // JSObject attributes
39 intptr_t value1;
40 intptr_t value2;
41 };
42
43 // FIXME: There is no reason this get function can't be simpler.
44 // ie. typedef JSValue* (*GetFunction)(ExecState*, JSObject* baseObject)
45 typedef PropertySlot::GetValueFunc GetFunction;
46 typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValue* value);
47
48 class HashEntry {
49 public:
50 void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2)
51 {
52 m_key = key;
53 m_attributes = attributes;
54 m_u.store.value1 = v1;
55 m_u.store.value2 = v2;
56 }
57
58 void setKey(UString::Rep* key) { m_key = key; }
59 UString::Rep* key() const { return m_key; }
60
61 unsigned char attributes() const { return m_attributes; }
62
63 NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }
64 unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); }
65
66 GetFunction propertyGetter() const { ASSERT(!(m_attributes & Function)); return m_u.property.get; }
67 PutFunction propertyPutter() const { ASSERT(!(m_attributes & Function)); return m_u.property.put; }
68
69 intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }
70
71 private:
72 UString::Rep* m_key;
73 unsigned char m_attributes; // JSObject attributes
74
75 union {
76 struct {
77 intptr_t value1;
78 intptr_t value2;
79 } store;
80 struct {
81 NativeFunction functionValue;
82 intptr_t length; // number of arguments for function
83 } function;
84 struct {
85 GetFunction get;
86 PutFunction put;
87 } property;
88 struct {
89 intptr_t value;
90 intptr_t unused;
91 } lexer;
92 } m_u;
93 };
94
95 struct HashTable {
96 int hashSizeMask; // Precomputed size for the hash table (minus 1).
97 const HashTableValue* values; // Fixed values generated by script.
98 mutable const HashEntry* table; // Table allocated at runtime.
99
100 ALWAYS_INLINE void initializeIfNeeded(JSGlobalData* globalData) const
101 {
102 if (!table)
103 createTable(globalData);
104 }
105
106 ALWAYS_INLINE void initializeIfNeeded(ExecState* exec) const
107 {
108 if (!table)
109 createTable(&exec->globalData());
110 }
111
112 void deleteTable() const;
113
114 // Find an entry in the table, and return the entry.
115 ALWAYS_INLINE const HashEntry* entry(JSGlobalData* globalData, const Identifier& identifier) const
116 {
117 initializeIfNeeded(globalData);
118 return entry(identifier);
119 }
120
121 ALWAYS_INLINE const HashEntry* entry(ExecState* exec, const Identifier& identifier) const
122 {
123 initializeIfNeeded(exec);
124 return entry(identifier);
125 }
126
127 private:
128 ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const
129 {
130 ASSERT(table);
131 const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & hashSizeMask];
132 if (entry->key() != identifier.ustring().rep())
133 return 0;
134 return entry;
135 }
136
137 // Convert the hash table keys to identifiers.
138 void createTable(JSGlobalData*) const;
139 };
140
141 void setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject* thisObject, const Identifier& propertyName, PropertySlot&);
142
143 /**
144 * This method does it all (looking in the hashtable, checking for function
145 * overrides, creating the function or retrieving from cache, calling
146 * getValueProperty in case of a non-function property, forwarding to parent if
147 * unknown property).
148 */
149 template <class ThisImp, class ParentImp>
150 inline bool getStaticPropertySlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
151 {
152 const HashEntry* entry = table->entry(exec, propertyName);
153
154 if (!entry) // not found, forward to parent
155 return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
156
157 if (entry->attributes() & Function)
158 setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
159 else
160 slot.setCustom(thisObj, entry->propertyGetter());
161
162 return true;
163 }
164
165 /**
166 * Simplified version of getStaticPropertySlot in case there are only functions.
167 * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing
168 * a dummy getValueProperty.
169 */
170 template <class ParentImp>
171 inline bool getStaticFunctionSlot(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
172 {
173 if (static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertySlot(exec, propertyName, slot))
174 return true;
175
176 const HashEntry* entry = table->entry(exec, propertyName);
177 if (!entry)
178 return false;
179
180 setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
181 return true;
182 }
183
184 /**
185 * Simplified version of getStaticPropertySlot in case there are no functions, only "values".
186 * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.
187 */
188 template <class ThisImp, class ParentImp>
189 inline bool getStaticValueSlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
190 {
191 const HashEntry* entry = table->entry(exec, propertyName);
192
193 if (!entry) // not found, forward to parent
194 return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
195
196 ASSERT(!(entry->attributes() & Function));
197
198 slot.setCustom(thisObj, entry->propertyGetter());
199 return true;
200 }
201
202 /**
203 * This one is for "put".
204 * It looks up a hash entry for the property to be set. If an entry
205 * is found it sets the value and returns true, else it returns false.
206 */
207 template <class ThisImp>
208 inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj)
209 {
210 const HashEntry* entry = table->entry(exec, propertyName);
211
212 if (!entry)
213 return false;
214
215 if (entry->attributes() & Function) // function: put as override property
216 thisObj->putDirect(propertyName, value);
217 else if (!(entry->attributes() & ReadOnly))
218 entry->propertyPutter()(exec, thisObj, value);
219
220 return true;
221 }
222
223 /**
224 * This one is for "put".
225 * It calls lookupPut<ThisImp>() to set the value. If that call
226 * returns false (meaning no entry in the hash table was found),
227 * then it calls put() on the ParentImp class.
228 */
229 template <class ThisImp, class ParentImp>
230 inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
231 {
232 if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
233 thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent
234 }
235
236} // namespace JSC
237
238#endif // KJS_lookup_h
Note: See TracBrowser for help on using the repository browser.