Changeset 36016 in webkit for trunk/JavaScriptCore/kjs/JSObject.h
- Timestamp:
- Sep 1, 2008, 2:22:54 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/JSObject.h
r35830 r36016 32 32 #include "PropertySlot.h" 33 33 #include "ScopeChain.h" 34 #include "StructureID.h" 34 35 35 36 namespace KJS { … … 37 38 class InternalFunction; 38 39 class PropertyNameArray; 40 class StructureID; 39 41 struct HashEntry; 40 42 struct HashTable; … … 48 50 DontDelete = 1 << 3, // property can't be deleted 49 51 Function = 1 << 4, // property is a function - only used by static hashtables 50 IsGetterSetter = 1 << 5 // property is a getter or setter51 52 }; 52 53 53 54 class JSObject : public JSCell { 54 55 public: 55 /** 56 * Creates a new JSObject with the specified prototype 57 * 58 * @param prototype The prototype 59 */ 60 JSObject(JSValue* prototype); 61 62 /** 63 * Creates a new JSObject with a prototype of jsNull() 64 * (that is, the ECMAScript "null" value, not a null object pointer). 65 */ 66 JSObject(); 56 JSObject(PassRefPtr<StructureID>); 57 JSObject(JSObject* prototype); 58 virtual ~JSObject(); 67 59 68 60 virtual void mark(); … … 72 64 JSValue* prototype() const; 73 65 void setPrototype(JSValue* prototype); 66 67 PassRefPtr<StructureID> inheritorID(); 74 68 75 69 virtual UString className() const; … … 84 78 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 85 79 86 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value );80 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&); 87 81 virtual void put(ExecState*, unsigned propertyName, JSValue* value); 88 82 … … 125 119 JSValue** getDirectLocation(const Identifier& propertyName) { return m_propertyMap.getLocation(propertyName); } 126 120 JSValue** getDirectLocation(const Identifier& propertyName, bool& isWriteable) { return m_propertyMap.getLocation(propertyName, isWriteable); } 127 void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0); 128 void putDirect(ExecState*, const Identifier& propertyName, int value, unsigned attr = 0); 121 size_t offsetForLocation(JSValue** location) { return m_propertyMap.offsetForLocation(location); } 129 122 void removeDirect(const Identifier& propertyName); 130 123 bool hasCustomProperties() { return !m_propertyMap.isEmpty(); } 131 132 // convenience to add a function property under the function's own built-in name 133 void putDirectFunction(ExecState*, InternalFunction*, unsigned attr = 0); 124 bool hasGetterSetterProperties() { return m_propertyMap.hasGetterSetterProperties(); } 125 126 void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0); 127 void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 128 void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0); 129 130 // Fast access to known property offsets. 131 JSValue* getDirectOffset(size_t offset) { return m_propertyMap.getOffset(offset); } 132 void putDirectOffset(size_t offset, JSValue* v) { m_propertyMap.putOffset(offset, v); } 134 133 135 134 void fillGetterPropertySlot(PropertySlot&, JSValue** location); … … 143 142 virtual bool isGlobalObject() const { return false; } 144 143 virtual bool isVariableObject() const { return false; } 145 146 144 virtual bool isWatchdogException() const { return false; } 147 148 145 virtual bool isNotAnObjectErrorStub() const { return false; } 149 146 150 147 protected: 151 PropertyMap m_propertyMap;152 148 bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable); 153 149 … … 156 152 157 153 const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const; 158 JSValue* m_prototype; 154 void setStructureID(PassRefPtr<StructureID>); 155 PassRefPtr<StructureID> createInheritorID(); 156 157 PropertyMap m_propertyMap; 158 RefPtr<StructureID> m_inheritorID; 159 159 }; 160 160 161 161 JSObject* constructEmptyObject(ExecState*); 162 162 163 inline JSObject::JSObject(JSValue* prototype) 164 : m_prototype(prototype) 163 inline JSObject::JSObject(JSObject* prototype) 164 : JSCell(prototype->inheritorID().releaseRef()) // ~JSObject balances this ref() 165 { 166 ASSERT(m_structureID); 167 ASSERT(this->prototype()); 168 ASSERT(this->prototype() == jsNull() || Heap::heap(this) == Heap::heap(this->prototype())); 169 } 170 171 inline JSObject::JSObject(PassRefPtr<StructureID> structureID) 172 : JSCell(structureID.releaseRef()) // ~JSObject balances this ref() 173 { 174 ASSERT(m_structureID); 175 } 176 177 inline JSObject::~JSObject() 178 { 179 ASSERT(m_structureID); 180 m_structureID->deref(); 181 } 182 183 inline JSValue* JSObject::prototype() const 184 { 185 return m_structureID->prototype(); 186 } 187 188 inline void JSObject::setPrototype(JSValue* prototype) 165 189 { 166 190 ASSERT(prototype); 167 ASSERT(prototype == jsNull() || Heap::heap(this) == Heap::heap(prototype)); 168 } 169 170 inline JSObject::JSObject() 171 : m_prototype(jsNull()) 172 { 173 } 174 175 inline JSValue* JSObject::prototype() const 176 { 177 return m_prototype; 178 } 179 180 inline void JSObject::setPrototype(JSValue* prototype) 181 { 182 ASSERT(prototype); 183 m_prototype = prototype; 191 RefPtr<StructureID> newStructureID = StructureID::changePrototypeTransition(m_structureID, prototype); 192 setStructureID(newStructureID.release()); 193 } 194 195 inline void JSObject::setStructureID(PassRefPtr<StructureID> structureID) 196 { 197 m_structureID->deref(); 198 m_structureID = structureID.releaseRef(); // ~JSObject balances this ref() 199 } 200 201 inline PassRefPtr<StructureID> JSObject::inheritorID() 202 { 203 if (m_inheritorID) 204 return m_inheritorID.get(); 205 return createInheritorID(); 184 206 } 185 207 … … 226 248 return true; 227 249 228 JSValue* prototype = object-> m_prototype;250 JSValue* prototype = object->prototype(); 229 251 if (!prototype->isObject()) 230 252 return false; … … 242 264 return true; 243 265 244 JSValue* prototype = object-> m_prototype;266 JSValue* prototype = object->prototype(); 245 267 if (!prototype->isObject()) 246 268 break; … … 262 284 fillGetterPropertySlot(slot, location); 263 285 } else 264 slot.setValueSlot( location);286 slot.setValueSlot(this, location, offsetForLocation(location)); 265 287 return true; 266 288 } … … 268 290 // non-standard Netscape extension 269 291 if (propertyName == exec->propertyNames().underscoreProto) { 270 slot.setValue Slot(&m_prototype);292 slot.setValue(prototype()); 271 293 slotIsWriteable = false; 272 294 return true; … … 285 307 fillGetterPropertySlot(slot, location); 286 308 else 287 slot.setValueSlot( location);309 slot.setValueSlot(this, location, offsetForLocation(location)); 288 310 return true; 289 311 } … … 291 313 // non-standard Netscape extension 292 314 if (propertyName == exec->propertyNames().underscoreProto) { 293 slot.setValue Slot(&m_prototype);315 slot.setValue(prototype()); 294 316 return true; 295 317 } … … 300 322 inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attr) 301 323 { 324 PutPropertySlot slot; 325 putDirect(propertyName, value, attr, false, slot); 326 } 327 328 inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot) 329 { 302 330 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 303 304 m_propertyMap.put(propertyName, value, attr);305 } 306 307 inline void JSObject::putDirect(ExecState* exec, const Identifier& propertyName, int value, unsigned attr) 308 { 309 m_propertyMap.put(propertyName, jsNumber(exec, value), attr);331 m_propertyMap.put(propertyName, value, attr, checkReadOnly, this, slot); 332 if (slot.type() == PutPropertySlot::NewProperty) { 333 if (!m_structureID->isDictionary()) { 334 RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName); 335 setStructureID(structureID.release()); 336 } 337 } 310 338 } 311 339 … … 316 344 317 345 inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName) const 346 { 347 PropertySlot slot(const_cast<JSValue*>(this)); 348 return get(exec, propertyName, slot); 349 } 350 351 inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const 318 352 { 319 353 if (UNLIKELY(JSImmediate::isImmediate(this))) { 320 354 JSObject* prototype = JSImmediate::prototype(this, exec); 321 PropertySlot slot(const_cast<JSValue*>(this));322 355 if (!prototype->getPropertySlot(exec, propertyName, slot)) 323 356 return jsUndefined(); … … 325 358 } 326 359 JSCell* cell = static_cast<JSCell*>(const_cast<JSValue*>(this)); 327 PropertySlot slot(cell);328 360 while (true) { 329 361 if (cell->getOwnPropertySlot(exec, propertyName, slot)) … … 339 371 inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName) const 340 372 { 373 PropertySlot slot(const_cast<JSValue*>(this)); 374 return get(exec, propertyName, slot); 375 } 376 377 inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const 378 { 341 379 if (UNLIKELY(JSImmediate::isImmediate(this))) { 342 380 JSObject* prototype = JSImmediate::prototype(this, exec); 343 PropertySlot slot(const_cast<JSValue*>(this));344 381 if (!prototype->getPropertySlot(exec, propertyName, slot)) 345 382 return jsUndefined(); … … 347 384 } 348 385 JSCell* cell = const_cast<JSCell*>(asCell()); 349 PropertySlot slot(cell);350 386 while (true) { 351 387 if (cell->getOwnPropertySlot(exec, propertyName, slot)) … … 359 395 } 360 396 361 inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value) 397 inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 398 { 399 if (UNLIKELY(JSImmediate::isImmediate(this))) { 400 JSImmediate::toObject(this, exec)->put(exec, propertyName, value, slot); 401 return; 402 } 403 asCell()->put(exec, propertyName, value, slot); 404 } 405 406 inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value) 362 407 { 363 408 if (UNLIKELY(JSImmediate::isImmediate(this))) { … … 368 413 } 369 414 370 inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)371 {372 if (UNLIKELY(JSImmediate::isImmediate(this))) {373 JSImmediate::toObject(this, exec)->put(exec, propertyName, value);374 return;375 }376 asCell()->put(exec, propertyName, value);377 }378 379 415 } // namespace KJS 380 416
Note:
See TracChangeset
for help on using the changeset viewer.