Changeset 36016 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Sep 1, 2008, 2:22:54 PM (17 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 2 added
- 43 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/Arguments.cpp
r35807 r36016 45 45 46 46 putDirect(exec->propertyNames().callee, function, DontEnum); 47 putDirect(exec , exec->propertyNames().length, args.size(), DontEnum);47 putDirect(exec->propertyNames().length, jsNumber(exec, args.size()), DontEnum); 48 48 49 49 int i = 0; … … 79 79 } 80 80 81 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value )81 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 82 82 { 83 83 if (d->indexToNameMap.isMapped(propertyName)) 84 d->activation->put(exec, d->indexToNameMap[propertyName], value );84 d->activation->put(exec, d->indexToNameMap[propertyName], value, slot); 85 85 else 86 JSObject::put(exec, propertyName, value );86 JSObject::put(exec, propertyName, value, slot); 87 87 } 88 88 -
trunk/JavaScriptCore/kjs/Arguments.h
r35807 r36016 39 39 40 40 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 41 virtual void put(ExecState*, const Identifier& propertyName, JSValue* );41 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 42 42 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); 43 43 -
trunk/JavaScriptCore/kjs/ArrayPrototype.cpp
r36006 r36016 114 114 } 115 115 116 static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue* value) 117 { 118 PutPropertySlot slot; 119 obj->put(exec, propertyName, value, slot); 120 } 121 116 122 JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&) 117 123 { … … 290 296 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 291 297 if (length == 0) { 292 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));298 putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length)); 293 299 result = jsUndefined(); 294 300 } else { 295 301 result = thisObj->get(exec, length - 1); 296 302 thisObj->deleteProperty(exec, length - 1); 297 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));303 putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1)); 298 304 } 299 305 return result; … … 307 313 thisObj->put(exec, length + n, args.at(exec, n)); 308 314 length += args.size(); 309 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));315 putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length)); 310 316 return jsNumber(exec, length); 311 317 } … … 342 348 unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec); 343 349 if (length == 0) { 344 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));350 putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length)); 345 351 result = jsUndefined(); 346 352 } else { … … 353 359 } 354 360 thisObj->deleteProperty(exec, length - 1); 355 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));361 putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1)); 356 362 } 357 363 return result; … … 510 516 thisObj->put(exec, k + begin, args.at(exec, k + 2)); 511 517 512 thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));518 putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs)); 513 519 return result; 514 520 } … … 532 538 thisObj->put(exec, k, args.at(exec, k)); 533 539 JSValue* result = jsNumber(exec, length + nrArgs); 534 thisObj->put(exec, exec->propertyNames().length, result);540 putProperty(exec, thisObj, exec->propertyNames().length, result); 535 541 return result; 536 542 } -
trunk/JavaScriptCore/kjs/DateConstructor.cpp
r36006 r36016 61 61 putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().now, dateNow), DontEnum); 62 62 63 putDirect(exec , exec->propertyNames().length, 7, ReadOnly | DontEnum | DontDelete);63 putDirect(exec->propertyNames().length, jsNumber(exec, 7), ReadOnly | DontEnum | DontDelete); 64 64 } 65 65 -
trunk/JavaScriptCore/kjs/InternalFunction.cpp
r35807 r36016 34 34 35 35 InternalFunction::InternalFunction(ExecState* exec) 36 : JSObject(exec->globalData().nullProtoStructureID) 36 37 { 37 38 putDirect(exec->propertyNames().name, jsString(exec, exec->propertyNames().nullIdentifier.ustring()), DontDelete | ReadOnly | DontEnum); -
trunk/JavaScriptCore/kjs/JSActivation.cpp
r35807 r36016 42 42 const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 }; 43 43 44 JSActivation::JSActivation( PassRefPtr<FunctionBodyNode> functionBody, Register* registers)45 : Base( new JSActivationData(functionBody, registers))44 JSActivation::JSActivation(ExecState* exec, PassRefPtr<FunctionBodyNode> functionBody, Register* registers) 45 : Base(exec->globalData().nullProtoStructureID, new JSActivationData(functionBody, registers)) 46 46 { 47 47 } … … 79 79 // We don't call through to JSObject because there's no way to give an 80 80 // activation object getter properties or a prototype. 81 ASSERT(! m_propertyMap.hasGetterSetterProperties());81 ASSERT(!hasGetterSetterProperties()); 82 82 ASSERT(prototype() == jsNull()); 83 83 return false; 84 84 } 85 85 86 void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value )86 void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 87 87 { 88 88 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); … … 94 94 // properties are non-standard extensions that other implementations do not 95 95 // expose in the activation object. 96 ASSERT(! m_propertyMap.hasGetterSetterProperties());97 m_propertyMap.put(propertyName, value, 0, true);96 ASSERT(!hasGetterSetterProperties()); 97 putDirect(propertyName, value, 0, true, slot); 98 98 } 99 99 … … 109 109 // properties are non-standard extensions that other implementations do not 110 110 // expose in the activation object. 111 ASSERT(!m_propertyMap.hasGetterSetterProperties()); 112 m_propertyMap.put(propertyName, value, attributes, true); 111 ASSERT(!hasGetterSetterProperties()); 112 PutPropertySlot slot; 113 putDirect(propertyName, value, attributes, true, slot); 113 114 } 114 115 -
trunk/JavaScriptCore/kjs/JSActivation.h
r35022 r36016 41 41 typedef JSVariableObject Base; 42 42 public: 43 JSActivation( PassRefPtr<FunctionBodyNode>, Register*);43 JSActivation(ExecState* exec, PassRefPtr<FunctionBodyNode>, Register*); 44 44 virtual ~JSActivation(); 45 45 … … 49 49 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 50 50 51 virtual void put(ExecState*, const Identifier&, JSValue* );51 virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&); 52 52 virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes); 53 53 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); -
trunk/JavaScriptCore/kjs/JSArray.cpp
r35807 r36016 126 126 #endif 127 127 128 JSArray::JSArray(JSValue* prototype, unsigned initialLength) 128 JSArray::JSArray(DummyConstructTag) 129 : JSObject(StructureID::create(jsNull())) 130 { 131 unsigned initialCapacity = 0; 132 133 m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); 134 m_fastAccessCutoff = 0; 135 m_storage->m_vectorLength = initialCapacity; 136 m_storage->m_length = 0; 137 138 checkConsistency(); 139 } 140 141 JSArray::JSArray(JSObject* prototype, unsigned initialLength) 129 142 : JSObject(prototype) 130 143 { … … 221 234 222 235 // ECMA 15.4.5.1 223 void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* value )236 void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 224 237 { 225 238 bool isArrayIndex; … … 240 253 } 241 254 242 JSObject::put(exec, propertyName, value );255 JSObject::put(exec, propertyName, value, slot); 243 256 } 244 257 … … 277 290 if (i >= MIN_SPARSE_ARRAY_INDEX) { 278 291 if (i > MAX_ARRAY_INDEX) { 279 put(exec, Identifier::from(exec, i), value); 292 PutPropertySlot slot; 293 put(exec, Identifier::from(exec, i), value, slot); 280 294 return; 281 295 } -
trunk/JavaScriptCore/kjs/JSArray.h
r35900 r36016 39 39 class JSArray : public JSObject { 40 40 public: 41 JSArray(JSValue* prototype, unsigned initialLength); 41 enum DummyConstructTag { DummyConstruct }; 42 JSArray(DummyConstructTag); 43 JSArray(JSObject* prototype, unsigned initialLength); 42 44 JSArray(ExecState* exec, JSObject* prototype, const ArgList& initialValues); 43 45 virtual ~JSArray(); … … 70 72 71 73 protected: 72 virtual void put(ExecState*, const Identifier& propertyName, JSValue* );74 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 73 75 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); 74 76 virtual bool deleteProperty(ExecState*, unsigned propertyName); -
trunk/JavaScriptCore/kjs/JSCell.cpp
r35830 r36016 171 171 } 172 172 173 void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value) 173 void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value, PutPropertySlot& slot) 174 { 175 toObject(exec)->put(exec, identifier, value, slot); 176 } 177 178 void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value) 174 179 { 175 180 toObject(exec)->put(exec, identifier, value); 176 181 } 177 182 178 void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value)179 {180 toObject(exec)->put(exec, identifier, value);181 }182 183 183 bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier) 184 184 { -
trunk/JavaScriptCore/kjs/JSCell.h
r35830 r36016 24 24 #define JSCell_h 25 25 26 #include "StructureID.h" 26 27 #include "JSValue.h" 27 28 #include "collector.h" … … 40 41 private: 41 42 JSCell(); 43 JSCell(StructureID*); 42 44 virtual ~JSCell(); 43 45 … … 49 51 virtual bool isObject() const; 50 52 virtual bool isObject(const ClassInfo*) const; 53 54 StructureID* structureID() const; 51 55 52 56 // Extracting the value. … … 82 86 // Object operations, with the toObject operation included. 83 87 virtual const ClassInfo* classInfo() const; 84 virtual void put(ExecState*, const Identifier& propertyName, JSValue* );88 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 85 89 virtual void put(ExecState*, unsigned propertyName, JSValue*); 86 90 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); … … 98 102 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 99 103 100 intptr_t reserved; // Reserved for work in progress.104 StructureID* m_structureID; 101 105 }; 102 106 103 107 inline JSCell::JSCell() 108 : m_structureID(0) 109 { 110 } 111 112 inline JSCell::JSCell(StructureID* structureID) 113 : m_structureID(structureID) 104 114 { 105 115 } … … 112 122 { 113 123 return Heap::isNumber(const_cast<JSCell*>(this)); 124 } 125 126 inline StructureID* JSCell::structureID() const 127 { 128 return m_structureID; 114 129 } 115 130 -
trunk/JavaScriptCore/kjs/JSFunction.cpp
r35807 r36016 109 109 } 110 110 111 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value )111 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 112 112 { 113 113 if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length) 114 114 return; 115 Base::put(exec, propertyName, value );115 Base::put(exec, propertyName, value, slot); 116 116 } 117 117 -
trunk/JavaScriptCore/kjs/JSFunction.h
r35807 r36016 44 44 45 45 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 46 virtual void put(ExecState*, const Identifier& propertyName, JSValue* );46 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 47 47 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); 48 48 -
trunk/JavaScriptCore/kjs/JSGlobalData.cpp
r35853 r36016 77 77 , stringTable(&KJS::stringTable) 78 78 #endif 79 , stringStructureID(StructureID::create(jsNull())) 80 , numberStructureID(StructureID::create(jsNull())) 81 , nullProtoStructureID(StructureID::create(jsNull())) 79 82 , identifierTable(createIdentifierTable()) 80 83 , propertyNames(new CommonIdentifiers(this)) -
trunk/JavaScriptCore/kjs/JSGlobalData.h
r36006 r36016 51 51 class Parser; 52 52 class ParserRefCounted; 53 class StructureID; 53 54 class UString; 54 55 struct HashTable; … … 72 73 const HashTable* regExpConstructorTable; 73 74 const HashTable* stringTable; 75 76 RefPtr<StructureID> stringStructureID; 77 RefPtr<StructureID> numberStructureID; 78 RefPtr<StructureID> nullProtoStructureID; 74 79 75 80 IdentifierTable* identifierTable; -
trunk/JavaScriptCore/kjs/JSGlobalObject.cpp
r35853 r36016 136 136 } 137 137 138 void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value )138 void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 139 139 { 140 140 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); … … 142 142 if (symbolTablePut(propertyName, value)) 143 143 return; 144 return JSVariableObject::put(exec, propertyName, value);144 JSVariableObject::put(exec, propertyName, value, slot); 145 145 } 146 146 … … 153 153 154 154 JSValue* valueBefore = getDirect(propertyName); 155 JSVariableObject::put(exec, propertyName, value); 155 PutPropertySlot slot; 156 JSVariableObject::put(exec, propertyName, value, slot); 156 157 if (!valueBefore) { 157 158 if (JSValue* valueAfter = getDirect(propertyName)) … … 188 189 // dangerous. (The allocations below may cause a GC.) 189 190 190 m_propertyMap.clear();191 ASSERT(!hasCustomProperties()); 191 192 symbolTable().clear(); 192 193 setRegisterArray(0, 0); … … 334 335 #endif 335 336 336 // Set prototype, and also insert the object prototype at the end of the chain. 337 337 resetPrototype(prototype); 338 } 339 340 // Set prototype, and also insert the object prototype at the end of the chain. 341 void JSGlobalObject::resetPrototype(JSValue* prototype) 342 { 338 343 setPrototype(prototype); 339 344 lastInPrototypeChain(this)->setPrototype(d()->objectPrototype); -
trunk/JavaScriptCore/kjs/JSGlobalObject.h
r35807 r36016 131 131 132 132 public: 133 JSGlobalObject() 134 : JSVariableObject(new JSGlobalObjectData(this, this)) 133 void* operator new(size_t, JSGlobalData*); 134 135 JSGlobalObject(JSGlobalData* globalData) 136 : JSVariableObject(globalData->nullProtoStructureID, new JSGlobalObjectData(this, this)) 135 137 { 136 138 init(this); … … 138 140 139 141 protected: 140 JSGlobalObject(JS Value* prototype, JSGlobalObjectData* d, JSObject* globalThisValue)142 JSGlobalObject(JSObject* prototype, JSGlobalObjectData* d, JSObject* globalThisValue) 141 143 : JSVariableObject(prototype, d) 142 144 { … … 149 151 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 150 152 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable); 151 virtual void put(ExecState*, const Identifier&, JSValue* );153 virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&); 152 154 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes); 153 155 … … 158 160 JSGlobalObject*& head() { return d()->globalData->head; } 159 161 JSGlobalObject* next() { return d()->next; } 160 161 // Resets the global object to contain only built-in properties, sets162 // the global object's prototype to "prototype," then adds the163 // default object prototype to the tail of the global object's164 // prototype chain.165 void reset(JSValue* prototype);166 162 167 163 // The following accessors return pristine values, even if a script … … 231 227 void copyGlobalsFrom(RegisterFile&); 232 228 void copyGlobalsTo(RegisterFile&); 233 234 // Per-JSGlobalData hash tables, cached on the global object for faster access. 229 230 void resetPrototype(JSValue* prototype); 231 235 232 JSGlobalData* globalData() { return d()->globalData.get(); } 236 237 void* operator new(size_t, JSGlobalData*);238 239 void init(JSObject* thisValue);240 241 233 JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); } 242 234 … … 257 249 258 250 private: 251 // FIXME: Fold these functions into the constructor. 252 void init(JSObject* thisValue); 253 void reset(JSValue* prototype); 254 259 255 void* operator new(size_t); // can only be allocated with JSGlobalData 260 256 }; -
trunk/JavaScriptCore/kjs/JSImmediate.cpp
r35245 r36016 43 43 JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v == jsNull()); 44 44 exec->setException(exception); 45 return new (exec) JSNotAnObject(ex ception);45 return new (exec) JSNotAnObject(exec, exception); 46 46 } 47 47 … … 56 56 JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v == jsNull()); 57 57 exec->setException(exception); 58 return new (exec) JSNotAnObject(ex ception);58 return new (exec) JSNotAnObject(exec, exception); 59 59 } 60 60 -
trunk/JavaScriptCore/kjs/JSNotAnObject.cpp
r35830 r36016 103 103 } 104 104 105 void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue* )105 void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*, PutPropertySlot&) 106 106 { 107 107 UNUSED_PARAM(exec); -
trunk/JavaScriptCore/kjs/JSNotAnObject.h
r35830 r36016 36 36 class JSNotAnObjectErrorStub : public JSObject { 37 37 public: 38 JSNotAnObjectErrorStub(bool isNull) 39 : m_isNull(isNull) 38 JSNotAnObjectErrorStub(ExecState* exec, bool isNull) 39 : JSObject(exec->globalData().nullProtoStructureID) 40 , m_isNull(isNull) 40 41 { 41 42 } … … 51 52 class JSNotAnObject : public JSObject { 52 53 public: 53 JSNotAnObject(JSNotAnObjectErrorStub* exception) 54 : m_exception(exception) 54 JSNotAnObject(ExecState* exec, JSNotAnObjectErrorStub* exception) 55 : JSObject(exec->globalData().nullProtoStructureID) 56 , m_exception(exception) 55 57 { 56 58 } … … 72 74 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 73 75 74 virtual void put(ExecState*, const Identifier& propertyName, JSValue* );76 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 75 77 virtual void put(ExecState*, unsigned propertyName, JSValue*); 76 78 -
trunk/JavaScriptCore/kjs/JSObject.cpp
r35830 r36016 57 57 #endif 58 58 59 JSValue* prototype = m_prototype; 60 if (!prototype->marked()) 61 prototype->mark(); 62 59 m_structureID->mark(); 63 60 m_propertyMap.mark(); 64 61 … … 87 84 88 85 // ECMA 8.6.2.2 89 void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value )86 void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 90 87 { 91 88 ASSERT(value); … … 114 111 JSValue* prototype; 115 112 for (JSObject* obj = this; !obj->m_propertyMap.hasGetterSetterProperties(); obj = static_cast<JSObject*>(prototype)) { 116 prototype = obj-> m_prototype;113 prototype = obj->prototype(); 117 114 if (prototype == jsNull()) { 118 m_propertyMap.put(propertyName, value, 0, true);115 putDirect(propertyName, value, 0, true, slot); 119 116 return; 120 117 } … … 126 123 127 124 for (JSObject* obj = this; ; obj = static_cast<JSObject*>(prototype)) { 128 if (JSValue* gs = obj->m_propertyMap.get(propertyName , attributes)) {129 if ( attributes & IsGetterSetter) {125 if (JSValue* gs = obj->m_propertyMap.get(propertyName)) { 126 if (gs->isGetterSetter()) { 130 127 JSObject* setterFunc = static_cast<GetterSetter*>(gs)->setter(); 131 128 if (!setterFunc) { … … 147 144 } 148 145 149 prototype = obj-> m_prototype;146 prototype = obj->prototype(); 150 147 if (prototype == jsNull()) 151 148 break; 152 149 } 153 154 m_propertyMap.put(propertyName, value, 0, true); 150 151 putDirect(propertyName, value, 0, true, slot); 152 return; 155 153 } 156 154 157 155 void JSObject::put(ExecState* exec, unsigned propertyName, JSValue* value) 158 156 { 159 put(exec, Identifier::from(exec, propertyName), value); 157 PutPropertySlot slot; 158 put(exec, Identifier::from(exec, propertyName), value, slot); 160 159 } 161 160 … … 190 189 if ((attributes & DontDelete)) 191 190 return false; 192 m_propertyMap.remove(propertyName); 193 if (attributes & IsGetterSetter) 194 m_propertyMap.setHasGetterSetterProperties(m_propertyMap.containsGettersOrSetters()); 191 removeDirect(propertyName); 195 192 return true; 196 193 } 197 194 198 195 // Look in the static hashtable of properties 199 196 const HashEntry* entry = findPropertyHashEntry(exec, propertyName); … … 249 246 { 250 247 // Must call toString first for Date objects. 251 if ((hint == PreferString) || (hint != PreferNumber && m_prototype== exec->lexicalGlobalObject()->datePrototype())) {248 if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) { 252 249 if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString)) 253 250 return value; … … 279 276 void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction) 280 277 { 278 GetterSetter* getterSetter; 279 PutPropertySlot slot; 280 281 281 JSValue* object = getDirect(propertyName); 282 GetterSetter* getterSetter;283 282 if (object && object->isGetterSetter()) 284 283 getterSetter = static_cast<GetterSetter*>(object); 285 284 else { 286 285 getterSetter = new (exec) GetterSetter; 287 putDirect(propertyName, getterSetter, IsGetterSetter); 286 putDirect(propertyName, getterSetter, None, true, slot); 287 } 288 289 // putDirect will change our StructureID if we add a new property. For 290 // getters and setters, though, we also need to change our StructureID 291 // if we override an existing non-getter or non-setter. 292 if (slot.type() != PutPropertySlot::NewProperty) { 293 if (!m_structureID->isDictionary()) { 294 RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID); 295 setStructureID(structureID.release()); 296 } 288 297 } 289 298 … … 294 303 void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction) 295 304 { 305 GetterSetter* getterSetter; 306 PutPropertySlot slot; 307 296 308 JSValue* object = getDirect(propertyName); 297 GetterSetter* getterSetter;298 309 if (object && object->isGetterSetter()) 299 310 getterSetter = static_cast<GetterSetter*>(object); 300 311 else { 301 312 getterSetter = new (exec) GetterSetter; 302 putDirect(propertyName, getterSetter, IsGetterSetter); 303 } 304 313 putDirect(propertyName, getterSetter, None, true, slot); 314 } 315 316 // putDirect will change our StructureID if we add a new property. For 317 // getters and setters, though, we also need to change our StructureID 318 // if we override an existing non-getter or non-setter. 319 if (slot.type() != PutPropertySlot::NewProperty) { 320 if (!m_structureID->isDictionary()) { 321 RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID); 322 setStructureID(structureID.release()); 323 } 324 } 325 305 326 m_propertyMap.setHasGetterSetterProperties(true); 306 327 getterSetter->setSetter(setterFunction); … … 413 434 } 414 435 415 if ( m_prototype->isObject())416 static_cast<JSObject*>( m_prototype)->getPropertyNames(exec, propertyNames);436 if (prototype()->isObject()) 437 static_cast<JSObject*>(prototype())->getPropertyNames(exec, propertyNames); 417 438 } 418 439 … … 456 477 { 457 478 m_propertyMap.remove(propertyName); 479 if (!m_structureID->isDictionary()) { 480 RefPtr<StructureID> structureID = StructureID::dictionaryTransition(m_structureID); 481 setStructureID(structureID.release()); 482 } 458 483 } 459 484 … … 471 496 } 472 497 498 PassRefPtr<StructureID> JSObject::createInheritorID() 499 { 500 m_inheritorID = StructureID::create(this); 501 return m_inheritorID; 502 } 503 473 504 bool JSObject::isObject() const 474 505 { -
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 -
trunk/JavaScriptCore/kjs/JSStaticScopeObject.cpp
r35807 r36016 37 37 } 38 38 39 void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue* value )39 void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&) 40 40 { 41 41 if (symbolTablePut(propertyName, value)) -
trunk/JavaScriptCore/kjs/JSStaticScopeObject.h
r35533 r36016 45 45 46 46 public: 47 JSStaticScopeObject( const Identifier& ident, JSValue* value, unsigned attributes)48 : JSVariableObject( new JSStaticScopeObjectData())47 JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue* value, unsigned attributes) 48 : JSVariableObject(exec->globalData().nullProtoStructureID, new JSStaticScopeObjectData()) 49 49 { 50 50 JSStaticScopeObjectData* data = static_cast<JSStaticScopeObjectData*>(d); … … 57 57 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 58 58 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable); 59 virtual void put(ExecState*, const Identifier&, JSValue* );59 virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&); 60 60 void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes); 61 61 }; -
trunk/JavaScriptCore/kjs/JSValue.h
r35830 r36016 38 38 class JSString; 39 39 class PropertySlot; 40 class PutPropertySlot; 41 class StructureID; 40 42 struct ClassInfo; 41 43 struct Instruction; … … 68 70 bool isObject() const; 69 71 bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits. 70 72 71 73 // Extracting the value. 72 74 bool getBoolean(bool&) const; … … 126 128 // Object operations, with the toObject operation included. 127 129 JSValue* get(ExecState*, const Identifier& propertyName) const; 130 JSValue* get(ExecState*, const Identifier& propertyName, PropertySlot&) const; 128 131 JSValue* get(ExecState*, unsigned propertyName) const; 129 void put(ExecState*, const Identifier& propertyName, JSValue*); 132 JSValue* get(ExecState*, unsigned propertyName, PropertySlot&) const; 133 void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 130 134 void put(ExecState*, unsigned propertyName, JSValue*); 131 135 bool deleteProperty(ExecState*, const Identifier& propertyName); -
trunk/JavaScriptCore/kjs/JSVariableObject.h
r35657 r36016 81 81 }; 82 82 83 JSVariableObject(JSVariableObjectData* data) 84 : d(data) // Subclass owns this pointer. 83 JSVariableObject(PassRefPtr<StructureID> structureID, JSVariableObjectData* data) 84 : JSObject(structureID) 85 , d(data) // Subclass owns this pointer. 85 86 { 86 87 } 87 88 88 JSVariableObject(JS Value* prototype, JSVariableObjectData* data)89 JSVariableObject(JSObject* prototype, JSVariableObjectData* data) 89 90 : JSObject(prototype) 90 91 , d(data) // Subclass owns this pointer. -
trunk/JavaScriptCore/kjs/JSWrapperObject.h
r35027 r36016 35 35 class JSWrapperObject : public JSObject { 36 36 public: 37 JSWrapperObject(JS Value* proto);37 JSWrapperObject(JSObject* prototype); 38 38 39 39 JSValue* internalValue() const; … … 46 46 }; 47 47 48 inline JSWrapperObject::JSWrapperObject(JS Value* proto)49 : JSObject(proto )48 inline JSWrapperObject::JSWrapperObject(JSObject* prototype) 49 : JSObject(prototype) 50 50 , m_internalValue(0) 51 51 { -
trunk/JavaScriptCore/kjs/ObjectPrototype.cpp
r36006 r36016 42 42 43 43 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype) 44 : JSObject( ) // [[Prototype]] is null44 : JSObject(exec->globalData().nullProtoStructureID) 45 45 { 46 46 putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum); -
trunk/JavaScriptCore/kjs/PropertyMap.cpp
r35027 r36016 22 22 #include "PropertyMap.h" 23 23 24 #include "JSObject.h"25 24 #include "protect.h" 26 25 #include "PropertyNameArray.h" … … 44 43 #define USE_SINGLE_ENTRY 1 45 44 46 // 2/28/2006 ggaren: command-line JS iBench says that USE_SINGLE_ENTRY is a47 // 3.2% performance boost.48 49 45 namespace KJS { 50 46 … … 81 77 #endif 82 78 83 struct PropertyMapEntry {84 UString::Rep* key;85 JSValue* value;86 unsigned attributes;87 unsigned index;88 89 PropertyMapEntry(UString::Rep* k, JSValue* v, int a)90 : key(k)91 , value(v)92 , attributes(a)93 , index(0)94 {95 }96 };97 98 // lastIndexUsed is an ever-increasing index used to identify the order items99 // were inserted into the property map. It's required that getEnumerablePropertyNames100 // return the properties in the order they were added for compatibility with other101 // browsers' JavaScript implementations.102 struct PropertyMapHashTable {103 unsigned sizeMask;104 unsigned size;105 unsigned keyCount;106 unsigned deletedSentinelCount;107 unsigned lastIndexUsed;108 unsigned entryIndicies[1];109 110 PropertyMapEntry* entries()111 {112 // The entries vector comes after the indices vector.113 // The 0th item in the entries vector is not really used; it has to114 // have a 0 in its key to allow the hash table lookup to handle deleted115 // sentinels without any special-case code, but the other fields are unused.116 return reinterpret_cast<PropertyMapEntry*>(&entryIndicies[size]);117 }118 119 static size_t allocationSize(unsigned size)120 {121 // We never let a hash table get more than half full,122 // So the number of indices we need is the size of the hash table.123 // But the number of entries is half that (plus one for the deleted sentinel).124 return sizeof(PropertyMapHashTable)125 + (size - 1) * sizeof(unsigned)126 + (1 + size / 2) * sizeof(PropertyMapEntry);127 }128 };129 130 79 static const unsigned emptyEntryIndex = 0; 131 80 static const unsigned deletedSentinelIndex = 1; … … 157 106 } 158 107 159 void PropertyMap::clear()160 {161 if (!m_usingTable) {162 #if USE_SINGLE_ENTRY163 if (m_singleEntryKey) {164 m_singleEntryKey->deref();165 m_singleEntryKey = 0;166 }167 #endif168 return;169 }170 171 unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;172 for (unsigned i = 1; i <= entryCount; i++) {173 if (UString::Rep* key = m_u.table->entries()[i].key)174 key->deref();175 }176 for (unsigned i = 0; i < m_u.table->size; i++)177 m_u.table->entryIndicies[i] = emptyEntryIndex;178 m_u.table->keyCount = 0;179 m_u.table->deletedSentinelCount = 0;180 }181 182 108 JSValue* PropertyMap::get(const Identifier& propertyName, unsigned& attributes) const 183 109 { … … 388 314 } 389 315 390 void PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly )316 void PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot) 391 317 { 392 318 ASSERT(!propertyName.isNull()); … … 405 331 m_singleEntryAttributes = static_cast<short>(attributes); 406 332 checkConsistency(); 333 slot.setNewProperty(slotBase, KJS_INVALID_OFFSET); 407 334 return; 408 335 } … … 414 341 #endif 415 342 416 if (!m_usingTable || (m_u.table->keyCount + m_u.table->deletedSentinelCount) * 2 >= m_u.table->size)343 if (!m_usingTable) 417 344 expand(); 418 345 … … 439 366 m_u.table->entries()[entryIndex - 1].value = value; 440 367 // Attributes are intentionally not updated. 368 slot.setExistingProperty(slotBase, offsetForTableLocation(&m_u.table->entries()[entryIndex - 1].value)); 441 369 return; 442 370 } else if (entryIndex == deletedSentinelIndex) { … … 486 414 ++m_u.table->keyCount; 487 415 416 if ((m_u.table->keyCount + m_u.table->deletedSentinelCount) * 2 >= m_u.table->size) 417 expand(); 418 488 419 checkConsistency(); 420 slot.setNewProperty(slotBase, offsetForTableLocation(&m_u.table->entries()[entryIndex - 1].value)); 489 421 } 490 422 … … 696 628 return +1; 697 629 return 0; 698 }699 700 bool PropertyMap::containsGettersOrSetters() const701 {702 if (!m_usingTable) {703 #if USE_SINGLE_ENTRY704 return !!(m_singleEntryAttributes & IsGetterSetter);705 #else706 return false;707 #endif708 }709 710 unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;711 for (unsigned i = 1; i <= entryCount; i++) {712 if (m_u.table->entries()[i].attributes & IsGetterSetter)713 return true;714 }715 716 return false;717 630 } 718 631 -
trunk/JavaScriptCore/kjs/PropertyMap.h
r35068 r36016 22 22 #define PropertyMap_h 23 23 24 #include "PropertySlot.h" 24 25 #include "identifier.h" 25 26 … … 32 33 struct PropertyMapHashTable; 33 34 35 struct PropertyMapEntry { 36 UString::Rep* key; 37 JSValue* value; 38 unsigned attributes; 39 unsigned index; 40 41 PropertyMapEntry(UString::Rep* k, JSValue* v, int a) 42 : key(k) 43 , value(v) 44 , attributes(a) 45 , index(0) 46 { 47 } 48 }; 49 50 // lastIndexUsed is an ever-increasing index used to identify the order items 51 // were inserted into the property map. It's required that getEnumerablePropertyNames 52 // return the properties in the order they were added for compatibility with other 53 // browsers' JavaScript implementations. 54 struct PropertyMapHashTable { 55 unsigned sizeMask; 56 unsigned size; 57 unsigned keyCount; 58 unsigned deletedSentinelCount; 59 unsigned lastIndexUsed; 60 unsigned entryIndicies[1]; 61 62 PropertyMapEntry* entries() 63 { 64 // The entries vector comes after the indices vector. 65 // The 0th item in the entries vector is not really used; it has to 66 // have a 0 in its key to allow the hash table lookup to handle deleted 67 // sentinels without any special-case code, but the other fields are unused. 68 return reinterpret_cast<PropertyMapEntry*>(&entryIndicies[size]); 69 } 70 71 static size_t allocationSize(unsigned size) 72 { 73 // We never let a hash table get more than half full, 74 // So the number of indices we need is the size of the hash table. 75 // But the number of entries is half that (plus one for the deleted sentinel). 76 return sizeof(PropertyMapHashTable) 77 + (size - 1) * sizeof(unsigned) 78 + (1 + size / 2) * sizeof(PropertyMapEntry); 79 } 80 }; 81 34 82 class PropertyMap : Noncopyable { 35 83 public: … … 37 85 ~PropertyMap(); 38 86 39 void clear();40 87 bool isEmpty() { return !m_usingTable & !m_singleEntryKey; } 41 88 42 void put(const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly = false);89 void put(const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot&); 43 90 void remove(const Identifier& propertyName); 44 91 JSValue* get(const Identifier& propertyName) const; … … 46 93 JSValue** getLocation(const Identifier& propertyName); 47 94 JSValue** getLocation(const Identifier& propertyName, bool& isWriteable); 95 96 JSValue* getOffset(size_t offset) 97 { 98 ASSERT(m_usingTable); 99 return reinterpret_cast<JSValue**>(m_u.table->entryIndicies)[offset]; 100 } 101 void putOffset(size_t offset, JSValue* v) 102 { 103 ASSERT(m_usingTable); 104 reinterpret_cast<JSValue**>(m_u.table->entryIndicies)[offset] = v; 105 } 106 107 size_t offsetForLocation(JSValue** location) { return m_usingTable ? offsetForTableLocation(location) : KJS_INVALID_OFFSET; } 48 108 49 109 void mark() const; … … 52 112 bool hasGetterSetterProperties() const { return m_getterSetterFlag; } 53 113 void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; } 54 55 bool containsGettersOrSetters() const;56 114 57 115 private: … … 67 125 void insert(const Entry&); 68 126 127 size_t offsetForTableLocation(JSValue** location) 128 { 129 ASSERT(m_usingTable); 130 return location - reinterpret_cast<JSValue**>(m_u.table->entryIndicies); 131 } 132 69 133 void checkConsistency(); 70 134 -
trunk/JavaScriptCore/kjs/PropertySlot.h
r35806 r36016 35 35 #define KJS_VALUE_SLOT_MARKER 0 36 36 #define KJS_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1) 37 #define KJS_INVALID_OFFSET static_cast<size_t>(-1) 37 38 38 39 class PropertySlot { 39 40 public: 40 41 PropertySlot() 42 : m_offset(KJS_INVALID_OFFSET) 41 43 { 42 44 clearBase(); … … 46 48 explicit PropertySlot(JSValue* base) 47 49 : m_slotBase(base) 50 , m_offset(KJS_INVALID_OFFSET) 48 51 { 49 52 clearValue(); … … 68 71 return (*m_data.registerSlot).jsValue(exec); 69 72 return m_getValue(exec, Identifier::from(exec, propertyName), *this); 73 } 74 75 bool isCacheable() const { return m_offset != KJS_INVALID_OFFSET; } 76 size_t cachedOffset() const 77 { 78 ASSERT(isCacheable()); 79 return m_offset; 70 80 } 71 81 … … 88 98 } 89 99 100 void setValueSlot(JSValue* slotBase, JSValue** valueSlot) 101 { 102 ASSERT(valueSlot); 103 m_getValue = KJS_VALUE_SLOT_MARKER; 104 m_slotBase = slotBase; 105 m_data.valueSlot = valueSlot; 106 } 107 108 void setValueSlot(JSValue* slotBase, JSValue** valueSlot, size_t offset) 109 { 110 ASSERT(valueSlot); 111 m_getValue = KJS_VALUE_SLOT_MARKER; 112 m_slotBase = slotBase; 113 m_data.valueSlot = valueSlot; 114 m_offset = offset; 115 } 116 90 117 void setValue(JSValue* value) 91 118 { … … 180 207 GetValueFunc m_getValue; 181 208 182 JSValue* m_value;183 184 209 JSValue* m_slotBase; 185 210 union { … … 190 215 unsigned index; 191 216 } m_data; 217 218 JSValue* m_value; 219 220 size_t m_offset; 192 221 }; 222 223 class PutPropertySlot { 224 public: 225 enum SlotType { 226 Invalid, 227 ExistingProperty, 228 NewProperty, 229 }; 230 231 PutPropertySlot() 232 : m_type(Invalid) 233 , m_base(0) 234 { 235 } 236 237 void setExistingProperty(JSObject* base, size_t offset) 238 { 239 m_type = ExistingProperty; 240 m_base = base; 241 m_offset = offset; 242 } 243 244 void setNewProperty(JSObject* base, size_t offset) 245 { 246 m_type = NewProperty; 247 m_base = base; 248 m_offset = offset; 249 } 250 251 SlotType type() const { return m_type; } 252 JSObject* slotBase() const { return m_base; } 253 254 bool isCacheable() const { return m_type != Invalid; } 255 size_t cachedOffset() const { 256 ASSERT(isCacheable()); 257 return m_offset; 258 } 259 260 private: 261 SlotType m_type; 262 JSObject* m_base; 263 size_t m_offset; 264 }; 193 265 194 266 } // namespace KJS -
trunk/JavaScriptCore/kjs/RegExpConstructor.cpp
r36006 r36016 123 123 virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::getOwnPropertySlot(exec, propertyName, slot); } 124 124 virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::getOwnPropertySlot(exec, propertyName, slot); } 125 virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* v ) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::put(exec, propertyName, v); }125 virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* v, PutPropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::put(exec, propertyName, v, slot); } 126 126 virtual void put(ExecState* exec, unsigned propertyName, JSValue* v) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::put(exec, propertyName, v); } 127 127 virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::deleteProperty(exec, propertyName); } … … 164 164 JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start)); 165 165 } 166 JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0])); 167 JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input)); 166 167 PutPropertySlot slot; 168 JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]), slot); 169 JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot); 168 170 169 171 delete d; … … 257 259 } 258 260 259 void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue* value )260 { 261 lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this );261 void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 262 { 263 lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this, slot); 262 264 } 263 265 -
trunk/JavaScriptCore/kjs/RegExpConstructor.h
r35027 r36016 54 54 RegExpConstructor(ExecState*, FunctionPrototype*, RegExpPrototype*); 55 55 56 virtual void put(ExecState*, const Identifier& propertyName, JSValue* );56 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 57 57 void putValueProperty(ExecState*, int token, JSValue*); 58 58 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); -
trunk/JavaScriptCore/kjs/RegExpObject.cpp
r35807 r36016 79 79 } 80 80 81 void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value )81 void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 82 82 { 83 lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this );83 lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot); 84 84 } 85 85 -
trunk/JavaScriptCore/kjs/RegExpObject.h
r35807 r36016 44 44 bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 45 45 JSValue* getValueProperty(ExecState*, int token) const; 46 void put(ExecState*, const Identifier& propertyName, JSValue* );46 void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&); 47 47 void putValueProperty(ExecState*, int token, JSValue*); 48 48 -
trunk/JavaScriptCore/kjs/Shell.cpp
r35911 r36016 163 163 class GlobalObject : public JSGlobalObject { 164 164 public: 165 GlobalObject( Vector<UString>& arguments);165 GlobalObject(JSGlobalData*, const Vector<UString>& arguments); 166 166 virtual UString className() const { return "global"; } 167 167 }; … … 169 169 ASSERT_CLASS_FITS_IN_CELL(GlobalObject); 170 170 171 GlobalObject::GlobalObject(Vector<UString>& arguments) 171 GlobalObject::GlobalObject(JSGlobalData* globalData, const Vector<UString>& arguments) 172 : JSGlobalObject(globalData) 172 173 { 173 174 putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "debug"), functionDebug)); … … 332 333 CodeGenerator::setDumpsGeneratedCode(true); 333 334 335 #if ENABLE(SAMPLING_TOOL) 336 Machine* machine = globalObject->globalData()->machine; 337 machine->m_sampler = new SamplingTool(); 338 machine->m_sampler->start(); 339 #endif 340 334 341 bool success = true; 335 342 for (size_t i = 0; i < fileNames.size(); i++) { … … 342 349 prettyPrintScript(globalObject->globalExec(), fileName, script); 343 350 else { 344 #if ENABLE(SAMPLING_TOOL)345 Machine* machine = globalObject->globalData()->machine;346 machine->m_sampler = new SamplingTool();347 machine->m_sampler->start();348 #endif349 350 351 Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data()); 351 352 success = success && completion.complType() != Throw; … … 358 359 359 360 globalObject->globalExec()->clearException(); 361 } 362 } 360 363 361 364 #if ENABLE(SAMPLING_TOOL) … … 364 367 delete machine->m_sampler; 365 368 #endif 366 }367 }368 369 return success; 369 370 } … … 473 474 parseArguments(argc, argv, options); 474 475 475 GlobalObject* globalObject = new (globalData) GlobalObject( options.arguments);476 GlobalObject* globalObject = new (globalData) GlobalObject(globalData, options.arguments); 476 477 bool success = runWithScripts(globalObject, options.fileNames, options.prettyPrint, options.dump); 477 478 if (options.interactive && success) -
trunk/JavaScriptCore/kjs/StringObject.cpp
r36006 r36016 62 62 } 63 63 64 void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value )64 void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot) 65 65 { 66 66 if (propertyName == exec->propertyNames().length) 67 67 return; 68 JSObject::put(exec, propertyName, value );68 JSObject::put(exec, propertyName, value, slot); 69 69 } 70 70 -
trunk/JavaScriptCore/kjs/StringObject.h
r35027 r36016 37 37 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 38 38 39 virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* );39 virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*, PutPropertySlot&); 40 40 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); 41 41 virtual void getPropertyNames(ExecState*, PropertyNameArray&); -
trunk/JavaScriptCore/kjs/SymbolTable.h
r34610 r36016 35 35 36 36 namespace KJS { 37 38 struct IdentifierRepHash : PtrHash<RefPtr<UString::Rep> > {39 static unsigned hash(const RefPtr<UString::Rep>& key) { return key->computedHash(); }40 static unsigned hash(UString::Rep* key) { return key->computedHash(); }41 };42 37 43 38 static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); } … … 124 119 }; 125 120 126 typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable;121 typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, WTF::IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable; 127 122 128 123 } // namespace KJS -
trunk/JavaScriptCore/kjs/lookup.cpp
r35195 r36016 75 75 PrototypeFunction* function = new (exec) PrototypeFunction(exec, entry->length, propertyName, entry->functionValue); 76 76 thisObj->putDirect(propertyName, function, entry->attributes); 77 slot.setValueSlot(thisObj->getDirectLocation(propertyName)); 77 78 JSValue** location = thisObj->getDirectLocation(propertyName); 79 slot.setValueSlot(thisObj, location, thisObj->offsetForLocation(location)); 78 80 } 79 81 -
trunk/JavaScriptCore/kjs/lookup.h
r35900 r36016 218 218 */ 219 219 template <class ThisImp, class ParentImp> 220 inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj )220 inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot) 221 221 { 222 222 if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj)) 223 thisObj->ParentImp::put(exec, propertyName, value ); // not found: forward to parent223 thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent 224 224 } 225 225 -
trunk/JavaScriptCore/kjs/nodes.cpp
r35986 r36016 1843 1843 1844 1844 if (!m_ident.isNull()) { 1845 JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject( m_ident, func, ReadOnly | DontDelete);1845 JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete); 1846 1846 func->scope().push(functionScopeObject); 1847 1847 } -
trunk/JavaScriptCore/kjs/ustring.h
r36007 r36016 367 367 template<> struct DefaultHash<RefPtr<KJS::UString::Rep> > { 368 368 typedef StrHash<RefPtr<KJS::UString::Rep> > Hash; 369 }; 369 370 }; 371 372 struct IdentifierRepHash : PtrHash<RefPtr<KJS::UString::Rep> > { 373 static unsigned hash(const RefPtr<KJS::UString::Rep>& key) { return key->computedHash(); } 374 static unsigned hash(KJS::UString::Rep* key) { return key->computedHash(); } 375 }; 376 370 377 } // namespace WTF 371 378
Note:
See TracChangeset
for help on using the changeset viewer.