Changeset 47780 in webkit
- Timestamp:
- Aug 26, 2009 9:52:15 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 69 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r47775 r47780 1 2009-08-25 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 [ES5] Implement getOwnPropertyDescriptor 6 https://bugs.webkit.org/show_bug.cgi?id=28724 7 8 Implement the core runtime support for getOwnPropertyDescriptor. 9 This adds a virtual getOwnPropertyDescriptor method to every class 10 that implements getOwnPropertySlot that shadows the behaviour of 11 getOwnPropertySlot. The alternative would be to make getOwnPropertySlot 12 (or PropertySlots in general) provide property attribute information, 13 but quick testing showed this to be a regression. 14 15 * JavaScriptCore.exp: 16 * JavaScriptCore.xcodeproj/project.pbxproj: 17 * runtime/Arguments.cpp: 18 (JSC::Arguments::getOwnPropertyDescriptor): 19 * runtime/Arguments.h: 20 * runtime/ArrayPrototype.cpp: 21 (JSC::ArrayPrototype::getOwnPropertyDescriptor): 22 * runtime/ArrayPrototype.h: 23 * runtime/CommonIdentifiers.h: 24 * runtime/DatePrototype.cpp: 25 (JSC::DatePrototype::getOwnPropertyDescriptor): 26 * runtime/DatePrototype.h: 27 * runtime/JSArray.cpp: 28 (JSC::JSArray::getOwnPropertyDescriptor): 29 * runtime/JSArray.h: 30 * runtime/JSByteArray.cpp: 31 (JSC::JSByteArray::getOwnPropertyDescriptor): 32 * runtime/JSByteArray.h: 33 * runtime/JSFunction.cpp: 34 (JSC::JSFunction::getOwnPropertyDescriptor): 35 * runtime/JSFunction.h: 36 * runtime/JSGlobalObject.h: 37 (JSC::JSGlobalObject::getOwnPropertyDescriptor): 38 * runtime/JSNotAnObject.cpp: 39 (JSC::JSNotAnObject::getOwnPropertyDescriptor): 40 * runtime/JSNotAnObject.h: 41 * runtime/JSONObject.cpp: 42 (JSC::JSONObject::getOwnPropertySlot): 43 (JSC::JSONObject::getOwnPropertyDescriptor): 44 * runtime/JSONObject.h: 45 * runtime/JSObject.cpp: 46 (JSC::JSObject::getOwnPropertyDescriptor): 47 (JSC::JSObject::getPropertyDescriptor): 48 * runtime/JSObject.h: 49 * runtime/JSString.cpp: 50 (JSC::JSString::getStringPropertyDescriptor): 51 (JSC::JSString::getOwnPropertyDescriptor): 52 * runtime/JSString.h: 53 * runtime/JSVariableObject.cpp: 54 (JSC::JSVariableObject::symbolTableGet): 55 * runtime/JSVariableObject.h: 56 * runtime/Lookup.h: 57 (JSC::getStaticPropertyDescriptor): 58 (JSC::getStaticFunctionDescriptor): 59 (JSC::getStaticValueDescriptor): 60 Add property descriptor equivalents of the lookup 61 table access functions 62 63 * runtime/MathObject.cpp: 64 (JSC::MathObject::getOwnPropertySlot): 65 (JSC::MathObject::getOwnPropertyDescriptor): 66 * runtime/MathObject.h: 67 * runtime/NumberConstructor.cpp: 68 (JSC::NumberConstructor::getOwnPropertyDescriptor): 69 * runtime/NumberConstructor.h: 70 * runtime/ObjectConstructor.cpp: 71 (JSC::ObjectConstructor::ObjectConstructor): 72 (JSC::objectConstructorGetOwnPropertyDescriptor): 73 * runtime/PropertyDescriptor.cpp: Added. 74 (JSC::PropertyDescriptor::writable): 75 (JSC::PropertyDescriptor::enumerable): 76 (JSC::PropertyDescriptor::configurable): 77 (JSC::PropertyDescriptor::hasAccessors): 78 (JSC::PropertyDescriptor::setUndefined): 79 (JSC::PropertyDescriptor::getter): 80 (JSC::PropertyDescriptor::setter): 81 (JSC::PropertyDescriptor::setDescriptor): 82 (JSC::PropertyDescriptor::setAccessorDescriptor): 83 * runtime/PropertyDescriptor.h: Added. 84 (JSC::PropertyDescriptor::PropertyDescriptor): 85 (JSC::PropertyDescriptor::attributes): 86 (JSC::PropertyDescriptor::isValid): 87 (JSC::PropertyDescriptor::value): 88 * runtime/RegExpConstructor.cpp: 89 (JSC::RegExpConstructor::getOwnPropertyDescriptor): 90 * runtime/RegExpConstructor.h: 91 * runtime/RegExpMatchesArray.h: 92 (JSC::RegExpMatchesArray::getOwnPropertyDescriptor): 93 * runtime/RegExpObject.cpp: 94 (JSC::RegExpObject::getOwnPropertyDescriptor): 95 * runtime/RegExpObject.h: 96 * runtime/StringObject.cpp: 97 (JSC::StringObject::getOwnPropertyDescriptor): 98 * runtime/StringObject.h: 99 * runtime/StringPrototype.cpp: 100 (JSC::StringPrototype::getOwnPropertyDescriptor): 101 * runtime/StringPrototype.h: 102 1 103 2009-08-24 Gavin Barraclough <barraclough@apple.com> 2 104 -
trunk/JavaScriptCore/JavaScriptCore.exp
r47752 r47780 118 118 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE 119 119 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE 120 __ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE 120 121 __ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE 121 122 __ZN3JSC12StringObject4infoE … … 147 148 __ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_9StructureEEERKNS_10IdentifierE 148 149 __ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE 150 __ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE 149 151 __ZN3JSC16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE 150 152 __ZN3JSC16toUInt32SlowCaseEdRb … … 155 157 __ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi 156 158 __ZN3JSC18DebuggerActivationC1EPNS_8JSObjectE 159 __ZN3JSC18PropertyDescriptor12setUndefinedEv 160 __ZN3JSC18PropertyDescriptor13setDescriptorENS_7JSValueEj 161 __ZN3JSC18PropertyDescriptor21setAccessorDescriptorENS_7JSValueES1_j 162 __ZNK3JSC18PropertyDescriptor6setterEv 163 __ZNK3JSC18PropertyDescriptor6getterEv 157 164 __ZN3JSC19constructEmptyArrayEPNS_9ExecStateE 158 165 __ZN3JSC19initializeThreadingEv … … 245 252 __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE 246 253 __ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE 254 __ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE 247 255 __ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE 248 256 __ZN3JSC8JSObject23allocatePropertyStorageEmm 257 __ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE 249 258 __ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE 250 259 __ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE … … 338 347 __ZNK3JSC17DebuggerCallFrame4typeEv 339 348 __ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_7JSValueE 349 __ZNK3JSC18PropertyDescriptor12hasAccessorsEv 340 350 __ZNK3JSC4Heap10statisticsEv 341 351 __ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r47665 r47780 216 216 A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; }; 217 217 A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; }; 218 A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; }; 219 A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; }; 218 220 BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9050E1839DB000F9297 /* ErrorConstructor.h */; }; 219 221 BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9070E1839DB000F9297 /* ErrorPrototype.h */; }; … … 769 771 A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONObject.cpp; sourceTree = "<group>"; }; 770 772 A7F9949A0FD746A300A0B2D0 /* JSONObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSONObject.lut.h; path = /Users/oliver/builds/Debug/DerivedSources/JavaScriptCore/JSONObject.lut.h; sourceTree = "<absolute>"; }; 773 A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyDescriptor.h; sourceTree = "<group>"; }; 774 A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyDescriptor.cpp; sourceTree = "<group>"; }; 771 775 A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; }; 772 776 A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; }; … … 1339 1343 isa = PBXGroup; 1340 1344 children = ( 1345 A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */, 1341 1346 BCF605110E203EF800B9A64D /* ArgList.cpp */, 1342 1347 BCF605120E203EF800B9A64D /* ArgList.h */, … … 1511 1516 A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */, 1512 1517 A74B3498102A5F8E0032AB98 /* MarkStack.cpp */, 1518 A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */, 1513 1519 ); 1514 1520 path = runtime; … … 1916 1922 86CAFEE31035DDE60028A609 /* Executable.h in Headers */, 1917 1923 142D3939103E4560007DCB52 /* NumericStrings.h in Headers */, 1924 A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */, 1918 1925 ); 1919 1926 runOnlyForDeploymentPostprocessing = 0; … … 2285 2292 A74B3499102A5F8E0032AB98 /* MarkStack.cpp in Sources */, 2286 2293 86CA032E1038E8440028A609 /* Executable.cpp in Sources */, 2294 A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */, 2287 2295 ); 2288 2296 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/runtime/Arguments.cpp
r47022 r47780 180 180 } 181 181 182 bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 183 { 184 bool isArrayIndex; 185 unsigned i = propertyName.toArrayIndex(&isArrayIndex); 186 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { 187 if (i < d->numParameters) { 188 descriptor.setDescriptor(d->registers[d->firstParameterIndex + i].jsValue(), DontEnum); 189 } else 190 descriptor.setDescriptor(d->extraArguments[i - d->numParameters].jsValue(), DontEnum); 191 return true; 192 } 193 194 if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) { 195 descriptor.setDescriptor(jsNumber(exec, d->numArguments), DontEnum); 196 return true; 197 } 198 199 if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { 200 descriptor.setDescriptor(d->callee, DontEnum); 201 return true; 202 } 203 204 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 205 } 206 182 207 void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot) 183 208 { -
trunk/JavaScriptCore/runtime/Arguments.h
r47641 r47780 93 93 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 94 94 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 95 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 95 96 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 96 97 virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&); -
trunk/JavaScriptCore/runtime/ArrayPrototype.cpp
r47738 r47780 126 126 } 127 127 128 bool ArrayPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 129 { 130 return getStaticFunctionDescriptor<JSArray>(exec, ExecState::arrayTable(exec), this, propertyName, descriptor); 131 } 132 128 133 // ------------------------------ Array Functions ---------------------------- 129 134 -
trunk/JavaScriptCore/runtime/ArrayPrototype.h
r38440 r47780 32 32 33 33 bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 34 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 34 35 35 36 virtual const ClassInfo* classInfo() const { return &info; } -
trunk/JavaScriptCore/runtime/CommonIdentifiers.h
r47271 r47780 38 38 macro(caller) \ 39 39 macro(compile) \ 40 macro(configurable) \ 40 41 macro(constructor) \ 42 macro(enumerable) \ 41 43 macro(eval) \ 42 44 macro(exec) \ 43 45 macro(fromCharCode) \ 44 46 macro(global) \ 47 macro(get) \ 45 48 macro(getPrototypeOf) \ 49 macro(getOwnPropertyDescriptor) \ 46 50 macro(hasOwnProperty) \ 47 51 macro(ignoreCase) \ … … 58 62 macro(propertyIsEnumerable) \ 59 63 macro(prototype) \ 64 macro(set) \ 60 65 macro(source) \ 61 66 macro(test) \ … … 68 73 macro(toString) \ 69 74 macro(UTC) \ 75 macro(value) \ 70 76 macro(valueOf) \ 77 macro(writable) \ 71 78 macro(displayName) 72 79 -
trunk/JavaScriptCore/runtime/DatePrototype.cpp
r47288 r47780 408 408 } 409 409 410 411 bool DatePrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 412 { 413 return getStaticFunctionDescriptor<JSObject>(exec, ExecState::dateTable(exec), this, propertyName, descriptor); 414 } 415 410 416 // Functions 411 417 -
trunk/JavaScriptCore/runtime/DatePrototype.h
r43122 r47780 33 33 34 34 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 35 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 35 36 36 37 virtual const ClassInfo* classInfo() const { return &info; } -
trunk/JavaScriptCore/runtime/JSArray.cpp
r47653 r47780 240 240 241 241 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 242 } 243 244 bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 245 { 246 if (propertyName == exec->propertyNames().length) { 247 descriptor.setDescriptor(jsNumber(exec, length()), DontDelete | DontEnum); 248 return true; 249 } 250 251 bool isArrayIndex; 252 unsigned i = propertyName.toArrayIndex(&isArrayIndex); 253 if (isArrayIndex) { 254 if (i >= m_storage->m_length) 255 return false; 256 if (i < m_storage->m_vectorLength) { 257 JSValue value = m_storage->m_vector[i]; 258 if (value) { 259 descriptor.setDescriptor(value, 0); 260 return true; 261 } 262 } else if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) { 263 if (i >= MIN_SPARSE_ARRAY_INDEX) { 264 SparseArrayValueMap::iterator it = map->find(i); 265 if (it != map->end()) { 266 descriptor.setDescriptor(it->second, 0); 267 return true; 268 } 269 } 270 } 271 } 272 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 242 273 } 243 274 -
trunk/JavaScriptCore/runtime/JSArray.h
r47269 r47780 48 48 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 49 49 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 50 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 50 51 virtual void put(ExecState*, unsigned propertyName, JSValue); // FIXME: Make protected and add setItem. 51 52 -
trunk/JavaScriptCore/runtime/JSByteArray.cpp
r47267 r47780 60 60 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 61 61 } 62 62 63 bool JSByteArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 64 { 65 bool ok; 66 unsigned index = propertyName.toUInt32(&ok, false); 67 if (ok && canAccessIndex(index)) { 68 descriptor.setDescriptor(getIndex(exec, index), DontDelete); 69 return true; 70 } 71 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 72 } 73 63 74 bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 64 75 { -
trunk/JavaScriptCore/runtime/JSByteArray.h
r46528 r47780 79 79 virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); 80 80 virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&); 81 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 81 82 virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); 82 83 virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue); -
trunk/JavaScriptCore/runtime/JSFunction.cpp
r47686 r47780 178 178 } 179 179 180 bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 181 { 182 if (isHostFunction()) 183 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 184 185 if (propertyName == exec->propertyNames().prototype) { 186 PropertySlot slot; 187 getOwnPropertySlot(exec, propertyName, slot); 188 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 189 } 190 191 if (propertyName == exec->propertyNames().arguments) { 192 descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete); 193 return true; 194 } 195 196 if (propertyName == exec->propertyNames().length) { 197 descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); 198 return true; 199 } 200 201 if (propertyName == exec->propertyNames().caller) { 202 descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete); 203 return true; 204 } 205 206 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 207 } 208 180 209 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 181 210 { -
trunk/JavaScriptCore/runtime/JSFunction.h
r47664 r47780 79 79 80 80 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 81 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 81 82 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 82 83 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); -
trunk/JavaScriptCore/runtime/JSGlobalObject.h
r47404 r47780 171 171 172 172 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 173 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 173 174 virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&); 174 175 virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); … … 327 328 } 328 329 330 inline bool JSGlobalObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 331 { 332 if (symbolTableGet(propertyName, descriptor)) 333 return true; 334 return JSVariableObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 335 } 336 329 337 inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName) 330 338 { -
trunk/JavaScriptCore/runtime/JSNotAnObject.cpp
r47022 r47780 94 94 } 95 95 96 bool JSNotAnObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier&, PropertyDescriptor&) 97 { 98 ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception); 99 return false; 100 } 101 96 102 void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue, PutPropertySlot&) 97 103 { -
trunk/JavaScriptCore/runtime/JSNotAnObject.h
r47022 r47780 81 81 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 82 82 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 83 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 83 84 84 85 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); -
trunk/JavaScriptCore/runtime/JSONObject.cpp
r47086 r47780 582 582 bool JSONObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 583 583 { 584 const HashEntry* entry = ExecState::jsonTable(exec)->entry(exec, propertyName); 585 if (!entry) 586 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 587 588 ASSERT(entry->attributes() & Function); 589 setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); 590 return true; 584 return getStaticFunctionSlot<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, slot); 585 } 586 587 bool JSONObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 588 { 589 return getStaticFunctionDescriptor<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, descriptor); 591 590 } 592 591 -
trunk/JavaScriptCore/runtime/JSONObject.h
r47267 r47780 49 49 private: 50 50 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 51 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 51 52 52 53 virtual const ClassInfo* classInfo() const { return &info; } -
trunk/JavaScriptCore/runtime/JSObject.cpp
r47267 r47780 31 31 #include "NativeErrorConstructor.h" 32 32 #include "ObjectPrototype.h" 33 #include "PropertyDescriptor.h" 33 34 #include "PropertyNameArray.h" 34 35 #include "Lookup.h" … … 505 506 } 506 507 508 bool JSObject::getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor& descriptor) 509 { 510 unsigned attributes = 0; 511 JSCell* cell = 0; 512 size_t offset = m_structure->get(propertyName, attributes, cell); 513 if (offset == WTF::notFound) 514 return false; 515 descriptor.setDescriptor(getDirectOffset(offset), attributes); 516 return true; 517 } 518 519 bool JSObject::getPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 520 { 521 JSObject* object = this; 522 while (true) { 523 if (object->getOwnPropertyDescriptor(exec, propertyName, descriptor)) 524 return true; 525 JSValue prototype = object->prototype(); 526 if (!prototype.isObject()) 527 return false; 528 object = asObject(prototype); 529 } 530 } 507 531 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSObject.h
r47601 r47780 49 49 class HashEntry; 50 50 class InternalFunction; 51 class PropertyDescriptor; 51 52 class PropertyNameArray; 52 53 class Structure; … … 96 97 bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 97 98 bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 99 bool getPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); 98 100 99 101 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 100 102 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 103 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 101 104 102 105 virtual void put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&); -
trunk/JavaScriptCore/runtime/JSString.cpp
r43506 r47780 104 104 } 105 105 106 bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 107 { 108 if (propertyName == exec->propertyNames().length) { 109 descriptor.setDescriptor(jsNumber(exec, m_value.size()), DontEnum | DontDelete | ReadOnly); 110 return true; 111 } 112 113 bool isStrictUInt32; 114 unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); 115 if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) { 116 descriptor.setDescriptor(jsSingleCharacterSubstring(exec, m_value, i), DontDelete | ReadOnly); 117 return true; 118 } 119 120 return false; 121 } 122 123 bool JSString::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 124 { 125 if (getStringPropertyDescriptor(exec, propertyName, descriptor)) 126 return true; 127 if (propertyName != exec->propertyNames().underscoreProto) 128 return false; 129 descriptor.setDescriptor(exec->lexicalGlobalObject()->stringPrototype(), DontEnum); 130 return true; 131 } 132 106 133 bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) 107 134 { -
trunk/JavaScriptCore/runtime/JSString.h
r47622 r47780 28 28 #include "Identifier.h" 29 29 #include "JSNumberCell.h" 30 #include "PropertyDescriptor.h" 30 31 #include "PropertySlot.h" 31 32 … … 87 88 bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 88 89 bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 90 bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); 89 91 90 92 bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); } … … 114 116 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 115 117 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 118 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 116 119 117 120 UString m_value; -
trunk/JavaScriptCore/runtime/JSVariableObject.cpp
r37989 r47780 31 31 32 32 #include "PropertyNameArray.h" 33 #include "PropertyDescriptor.h" 33 34 34 35 namespace JSC { … … 68 69 } 69 70 71 bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertyDescriptor& descriptor) 72 { 73 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 74 if (!entry.isNull()) { 75 descriptor.setDescriptor(registerAt(entry.getIndex()).jsValue(), entry.getAttributes() | DontDelete); 76 return true; 77 } 78 return false; 79 } 80 70 81 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSVariableObject.h
r43122 r47780 90 90 91 91 bool symbolTableGet(const Identifier&, PropertySlot&); 92 bool symbolTableGet(const Identifier&, PropertyDescriptor&); 92 93 bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable); 93 94 bool symbolTablePut(const Identifier&, JSValue); -
trunk/JavaScriptCore/runtime/Lookup.h
r45553 r47780 187 187 } 188 188 189 template <class ThisImp, class ParentImp> 190 inline bool getStaticPropertyDescriptor(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) 191 { 192 const HashEntry* entry = table->entry(exec, propertyName); 193 194 if (!entry) // not found, forward to parent 195 return thisObj->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor); 196 197 PropertySlot slot; 198 if (entry->attributes() & Function) 199 setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); 200 else 201 slot.setCustom(thisObj, entry->propertyGetter()); 202 203 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 204 return true; 205 } 206 189 207 /** 190 208 * Simplified version of getStaticPropertySlot in case there are only functions. … … 205 223 return true; 206 224 } 225 226 /** 227 * Simplified version of getStaticPropertyDescriptor in case there are only functions. 228 * Using this instead of getStaticPropertyDescriptor allows 'this' to avoid implementing 229 * a dummy getValueProperty. 230 */ 231 template <class ParentImp> 232 inline bool getStaticFunctionDescriptor(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) 233 { 234 if (static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor)) 235 return true; 236 237 const HashEntry* entry = table->entry(exec, propertyName); 238 if (!entry) 239 return false; 240 241 PropertySlot slot; 242 setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); 243 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 244 return true; 245 } 207 246 208 247 /** … … 221 260 222 261 slot.setCustom(thisObj, entry->propertyGetter()); 262 return true; 263 } 264 265 /** 266 * Simplified version of getStaticPropertyDescriptor in case there are no functions, only "values". 267 * Using this instead of getStaticPropertyDescriptor removes the need for a FuncImp class. 268 */ 269 template <class ThisImp, class ParentImp> 270 inline bool getStaticValueDescriptor(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) 271 { 272 const HashEntry* entry = table->entry(exec, propertyName); 273 274 if (!entry) // not found, forward to parent 275 return thisObj->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor); 276 277 ASSERT(!(entry->attributes() & Function)); 278 PropertySlot slot; 279 slot.setCustom(thisObj, entry->propertyGetter()); 280 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 223 281 return true; 224 282 } -
trunk/JavaScriptCore/runtime/MathObject.cpp
r43372 r47780 104 104 bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot) 105 105 { 106 const HashEntry* entry = ExecState::mathTable(exec)->entry(exec, propertyName); 107 108 if (!entry) 109 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 110 111 ASSERT(entry->attributes() & Function); 112 setUpStaticFunctionSlot(exec, entry, this, propertyName, slot); 113 return true; 106 return getStaticFunctionSlot<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, slot); 107 } 108 109 bool MathObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 110 { 111 return getStaticFunctionDescriptor<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, descriptor); 114 112 } 115 113 -
trunk/JavaScriptCore/runtime/MathObject.h
r47267 r47780 31 31 32 32 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 33 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 33 34 34 35 virtual const ClassInfo* classInfo() const { return &info; } -
trunk/JavaScriptCore/runtime/NumberConstructor.cpp
r43372 r47780 69 69 } 70 70 71 bool NumberConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 72 { 73 return getStaticValueDescriptor<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, descriptor); 74 } 75 71 76 static JSValue numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&) 72 77 { -
trunk/JavaScriptCore/runtime/NumberConstructor.h
r47267 r47780 33 33 34 34 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 35 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 35 36 JSValue getValueProperty(ExecState*, int token) const; 36 37 -
trunk/JavaScriptCore/runtime/ObjectConstructor.cpp
r47239 r47780 26 26 #include "JSGlobalObject.h" 27 27 #include "ObjectPrototype.h" 28 #include "PropertyDescriptor.h" 28 29 #include "PrototypeFunction.h" 29 30 … … 33 34 34 35 static JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&); 36 static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&); 35 37 36 38 ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure) 37 39 : InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object")) 38 40 { 39 41 // ECMA 15.2.3.1 40 42 putDirectWithoutTransition(exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly); 41 43 42 44 // no. of arguments for constructor 43 45 putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete); 44 46 45 47 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum); 48 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum); 46 49 } 47 50 … … 84 87 } 85 88 89 JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, JSObject*, JSValue, const ArgList& args) 90 { 91 if (!args.at(0).isObject()) 92 return throwError(exec, TypeError, "Requested property descriptor of a value that is not an object."); 93 UString propertyName = args.at(1).toString(exec); 94 if (exec->hadException()) 95 return jsNull(); 96 JSObject* object = asObject(args.at(0)); 97 PropertyDescriptor descriptor; 98 if (!object->getOwnPropertyDescriptor(exec, Identifier(exec, propertyName), descriptor)) 99 return jsUndefined(); 100 if (exec->hadException()) 101 return jsUndefined(); 102 ASSERT(descriptor.isValid()); 103 104 JSObject* description = constructEmptyObject(exec); 105 if (!descriptor.hasAccessors()) { 106 description->putDirect(exec->propertyNames().value, descriptor.value(), 0); 107 description->putDirect(exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0); 108 } else { 109 description->putDirect(exec->propertyNames().get, descriptor.getter(), 0); 110 description->putDirect(exec->propertyNames().set, descriptor.setter(), 0); 111 } 112 113 description->putDirect(exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0); 114 description->putDirect(exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0); 115 116 return description; 117 } 118 86 119 } // namespace JSC -
trunk/JavaScriptCore/runtime/PropertyDescriptor.h
r47779 r47780 24 24 */ 25 25 26 #ifndef JSONObject_h27 #define JSONObject_h26 #ifndef PropertyDescriptor_h 27 #define PropertyDescriptor_h 28 28 29 #include "JS Object.h"29 #include "JSValue.h" 30 30 31 31 namespace JSC { 32 33 class Stringifier; 34 35 class JSONObject : public JSObject { 32 class PropertyDescriptor { 36 33 public: 37 JSONObject(PassRefPtr<Structure> structure)38 : JSObject(structure)34 PropertyDescriptor() 35 : m_attributes(0) 39 36 { 40 37 } 38 bool writable() const; 39 bool enumerable() const; 40 bool configurable() const; 41 bool hasAccessors() const; 42 unsigned attributes() const { return m_attributes; } 43 #ifndef NDEBUG 44 bool isValid() const { return m_value || ((m_getter || m_setter) && hasAccessors()); } 45 #endif 46 JSValue value() const { ASSERT(m_value); return m_value; } 47 JSValue getter() const; 48 JSValue setter() const; 49 void setUndefined(); 50 void setDescriptor(JSValue value, unsigned attributes); 51 void setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes); 52 private: 53 // May be a getter/setter 54 JSValue m_value; 55 JSValue m_getter; 56 JSValue m_setter; 57 unsigned m_attributes; 58 }; 59 } 41 60 42 static PassRefPtr<Structure> createStructure(JSValue prototype) 43 { 44 return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark)); 45 } 46 47 static void markStringifiers(MarkStack&, Stringifier*); 48 49 private: 50 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 51 52 virtual const ClassInfo* classInfo() const { return &info; } 53 static const ClassInfo info; 54 }; 55 56 } // namespace JSC 57 58 #endif // JSONObject_h 61 #endif -
trunk/JavaScriptCore/runtime/RegExpConstructor.cpp
r47288 r47780 235 235 } 236 236 237 bool RegExpConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 238 { 239 return getStaticValueDescriptor<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, descriptor); 240 } 241 237 242 JSValue regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot) 238 243 { -
trunk/JavaScriptCore/runtime/RegExpConstructor.h
r47267 r47780 42 42 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 43 43 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 44 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 44 45 45 46 static const ClassInfo info; -
trunk/JavaScriptCore/runtime/RegExpMatchesArray.h
r44224 r47780 45 45 } 46 46 47 virtual bool getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 48 { 49 if (lazyCreationData()) 50 fillArrayInstance(exec); 51 return JSArray::getOwnPropertyDescriptor(exec, propertyName, descriptor); 52 } 53 47 54 virtual void put(ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot) 48 55 { -
trunk/JavaScriptCore/runtime/RegExpObject.cpp
r44224 r47780 71 71 { 72 72 return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot); 73 } 74 75 bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 76 { 77 return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor); 73 78 } 74 79 -
trunk/JavaScriptCore/runtime/RegExpObject.h
r47267 r47780 42 42 43 43 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 44 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 44 45 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 45 46 -
trunk/JavaScriptCore/runtime/StringObject.cpp
r43122 r47780 62 62 } 63 63 64 bool StringObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 65 { 66 if (internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor)) 67 return true; 68 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 69 } 70 64 71 void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 65 72 { -
trunk/JavaScriptCore/runtime/StringObject.h
r43122 r47780 36 36 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 37 37 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 38 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 38 39 39 40 virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&); -
trunk/JavaScriptCore/runtime/StringPrototype.cpp
r47646 r47780 132 132 { 133 133 return getStaticFunctionSlot<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, slot); 134 } 135 136 bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 137 { 138 return getStaticFunctionDescriptor<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, descriptor); 134 139 } 135 140 -
trunk/JavaScriptCore/runtime/StringPrototype.h
r38440 r47780 33 33 34 34 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 35 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 35 36 36 37 virtual const ClassInfo* classInfo() const { return &info; } -
trunk/LayoutTests/ChangeLog
r47773 r47780 1 2009-08-25 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 [ES5] Implement getOwnPropertyDescriptor 6 https://bugs.webkit.org/show_bug.cgi?id=28724 7 8 Add tests for getOwnProeprtyDescriptor 9 10 * fast/js/getOwnPropertyDescriptor-expected.txt: Added. 11 * fast/js/getOwnPropertyDescriptor.html: Added. 12 * fast/js/resources/getOwnPropertyDescriptor.js: Added. 13 (): 14 1 15 2009-08-25 Dmitry Titov <dimich@chromium.org> 2 16 -
trunk/WebCore/ChangeLog
r47779 r47780 1 2009-08-25 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 [ES5] Implement getOwnPropertyDescriptor 6 https://bugs.webkit.org/show_bug.cgi?id=28724 7 8 Implement the WebCore side of getOwnPropertyDescriptor. This 9 requires a custom implementation of getOwnPropertyDescriptor 10 for every class with a custom implementation of getOwnPropertySlot. 11 12 The bindings generator has been updated to generate appropriate 13 versions of getOwnPropertyDescriptor for the general case where 14 a custom getOwnPropertyDescriptor is not needed. ES5 is vague 15 about how getOwnPropertyDescriptor should work in the context of 16 "host" functions with polymorphic [[GetOwnProperty]], so it seems 17 okay that occasionally we "guess" what attributes -- eg. determining 18 whether a property is writable. 19 20 Test: fast/js/getOwnPropertyDescriptor.html 21 22 * bindings/js/JSDOMWindowCustom.cpp: 23 (WebCore::JSDOMWindow::getOwnPropertyDescriptor): 24 * bindings/js/JSDOMWindowShell.cpp: 25 (WebCore::JSDOMWindowShell::getOwnPropertyDescriptor): 26 * bindings/js/JSDOMWindowShell.h: 27 * bindings/js/JSHTMLAppletElementCustom.cpp: 28 (WebCore::JSHTMLAppletElement::getOwnPropertyDescriptorDelegate): 29 * bindings/js/JSHTMLEmbedElementCustom.cpp: 30 (WebCore::JSHTMLEmbedElement::getOwnPropertyDescriptorDelegate): 31 * bindings/js/JSHTMLObjectElementCustom.cpp: 32 (WebCore::JSHTMLObjectElement::getOwnPropertyDescriptorDelegate): 33 * bindings/js/JSHistoryCustom.cpp: 34 (WebCore::JSHistory::getOwnPropertyDescriptorDelegate): 35 * bindings/js/JSLocationCustom.cpp: 36 (WebCore::JSLocation::getOwnPropertyDescriptorDelegate): 37 * bindings/js/JSNamedNodesCollection.cpp: 38 (WebCore::JSNamedNodesCollection::getOwnPropertyDescriptor): 39 * bindings/js/JSNamedNodesCollection.h: 40 * bindings/js/JSPluginElementFunctions.cpp: 41 (WebCore::runtimeObjectCustomGetOwnPropertyDescriptor): 42 * bindings/js/JSPluginElementFunctions.h: 43 * bindings/js/JSQuarantinedObjectWrapper.cpp: 44 (WebCore::JSQuarantinedObjectWrapper::getOwnPropertyDescriptor): 45 * bindings/js/JSQuarantinedObjectWrapper.h: 46 * bindings/js/JSWorkerContextCustom.cpp: 47 (WebCore::JSWorkerContext::getOwnPropertyDescriptorDelegate): 48 * bindings/scripts/CodeGeneratorJS.pm: 49 * bridge/objc/objc_runtime.h: 50 * bridge/objc/objc_runtime.mm: 51 (JSC::Bindings::ObjcFallbackObjectImp::getOwnPropertyDescriptor): 52 * bridge/runtime.h: 53 (JSC::Bindings::Instance::getOwnPropertyDescriptor): 54 * bridge/runtime_array.cpp: 55 (JSC::RuntimeArray::getOwnPropertyDescriptor): 56 * bridge/runtime_array.h: 57 * bridge/runtime_method.cpp: 58 (JSC::RuntimeMethod::getOwnPropertyDescriptor): 59 * bridge/runtime_method.h: 60 * bridge/runtime_object.cpp: 61 (JSC::RuntimeObjectImp::getOwnPropertyDescriptor): 62 * bridge/runtime_object.h: 63 1 64 2009-08-26 Vincent Untz <vuntz@gnome.org> 2 65 -
trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp
r47697 r47780 280 280 } 281 281 282 bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 283 { 284 // When accessing a Window cross-domain, functions are always the native built-in ones, and they 285 // are not affected by properties changed on the Window or anything in its prototype chain. 286 // This is consistent with the behavior of Firefox. 287 288 const HashEntry* entry; 289 290 // We don't want any properties other than "close" and "closed" on a closed window. 291 if (!impl()->frame()) { 292 // The following code is safe for cross-domain and same domain use. 293 // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). 294 entry = s_info.propHashTable(exec)->entry(exec, propertyName); 295 if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) { 296 descriptor.setDescriptor(jsBoolean(true), ReadOnly | DontDelete | DontEnum); 297 return true; 298 } 299 entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); 300 if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { 301 PropertySlot slot; 302 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); 303 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 304 return true; 305 } 306 descriptor.setUndefined(); 307 return true; 308 } 309 310 String errorMessage; 311 bool allowsAccess = allowsAccessFrom(exec, errorMessage); 312 if (allowsAccess && JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor)) 313 return true; 314 315 // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the 316 // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot. 317 // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of 318 // what prototype is actually set on this object. 319 entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); 320 if (entry) { 321 if (entry->attributes() & Function) { 322 if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { 323 if (!allowsAccess) { 324 PropertySlot slot; 325 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); 326 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 327 return true; 328 } 329 } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { 330 if (!allowsAccess) { 331 PropertySlot slot; 332 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); 333 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 334 return true; 335 } 336 } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { 337 if (!allowsAccess) { 338 PropertySlot slot; 339 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); 340 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 341 return true; 342 } 343 } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { 344 if (!allowsAccess) { 345 PropertySlot slot; 346 slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); 347 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 348 return true; 349 } 350 } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { 351 if (!DOMWindow::canShowModalDialog(impl()->frame())) { 352 descriptor.setUndefined(); 353 return true; 354 } 355 } 356 } 357 } else { 358 // Allow access to toString() cross-domain, but always Object.prototype.toString. 359 if (propertyName == exec->propertyNames().toString) { 360 if (!allowsAccess) { 361 PropertySlot slot; 362 slot.setCustom(this, objectToStringFunctionGetter); 363 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 364 return true; 365 } 366 } 367 } 368 369 entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); 370 if (entry) { 371 PropertySlot slot; 372 slot.setCustom(this, entry->propertyGetter()); 373 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 374 return true; 375 } 376 377 // Check for child frames by name before built-in properties to 378 // match Mozilla. This does not match IE, but some sites end up 379 // naming frames things that conflict with window properties that 380 // are in Moz but not IE. Since we have some of these, we have to do 381 // it the Moz way. 382 if (impl()->frame()->tree()->child(propertyName)) { 383 PropertySlot slot; 384 slot.setCustom(this, childFrameGetter); 385 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 386 return true; 387 } 388 389 // Do prototype lookup early so that functions and attributes in the prototype can have 390 // precedence over the index and name getters. 391 JSValue proto = prototype(); 392 if (proto.isObject()) { 393 if (asObject(proto)->getPropertyDescriptor(exec, propertyName, descriptor)) { 394 if (!allowsAccess) { 395 printErrorMessage(errorMessage); 396 descriptor.setUndefined(); 397 } 398 return true; 399 } 400 } 401 402 bool ok; 403 unsigned i = propertyName.toArrayIndex(&ok); 404 if (ok && i < impl()->frame()->tree()->childCount()) { 405 PropertySlot slot; 406 slot.setCustomIndex(this, i, indexGetter); 407 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 408 return true; 409 } 410 411 // Allow shortcuts like 'Image1' instead of document.images.Image1 412 Document* document = impl()->frame()->document(); 413 if (document->isHTMLDocument()) { 414 AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName); 415 if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { 416 PropertySlot slot; 417 slot.setCustom(this, namedItemGetter); 418 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 419 return true; 420 } 421 } 422 423 return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); 424 } 425 282 426 void JSDOMWindow::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 283 427 { -
trunk/WebCore/bindings/js/JSDOMWindowShell.cpp
r47022 r47780 89 89 } 90 90 91 bool JSDOMWindowShell::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 92 { 93 return m_window->getOwnPropertyDescriptor(exec, propertyName, descriptor); 94 } 95 91 96 void JSDOMWindowShell::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 92 97 { -
trunk/WebCore/bindings/js/JSDOMWindowShell.h
r47022 r47780 68 68 virtual JSC::UString className() const; 69 69 virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); 70 virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&); 70 71 virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); 71 72 virtual void putWithAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, unsigned attributes); -
trunk/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
r44677 r47780 39 39 } 40 40 41 bool JSHTMLAppletElement::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 42 { 43 return runtimeObjectCustomGetOwnPropertyDescriptor(exec, propertyName, descriptor, this); 44 } 45 41 46 bool JSHTMLAppletElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 42 47 { -
trunk/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
r44677 r47780 39 39 } 40 40 41 bool JSHTMLEmbedElement::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 42 { 43 return runtimeObjectCustomGetOwnPropertyDescriptor(exec, propertyName, descriptor, this); 44 } 45 41 46 bool JSHTMLEmbedElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 42 47 { -
trunk/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
r44677 r47780 39 39 } 40 40 41 bool JSHTMLObjectElement::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 42 { 43 return runtimeObjectCustomGetOwnPropertyDescriptor(exec, propertyName, descriptor, this); 44 } 45 41 46 bool JSHTMLObjectElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 42 47 { -
trunk/WebCore/bindings/js/JSHistoryCustom.cpp
r47236 r47780 94 94 } 95 95 96 bool JSHistory::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 97 { 98 // When accessing History cross-domain, functions are always the native built-in ones. 99 // See JSDOMWindow::getOwnPropertySlotDelegate for additional details. 100 101 // Our custom code is only needed to implement the Window cross-domain scheme, so if access is 102 // allowed, return false so the normal lookup will take place. 103 String message; 104 if (allowsAccessFromFrame(exec, impl()->frame(), message)) 105 return false; 106 107 // Check for the few functions that we allow, even when called cross-domain. 108 const HashEntry* entry = JSHistoryPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); 109 if (entry) { 110 PropertySlot slot; 111 // Allow access to back(), forward() and go() from any frame. 112 if (entry->attributes() & Function) { 113 if (entry->function() == jsHistoryPrototypeFunctionBack) { 114 slot.setCustom(this, nonCachingStaticBackFunctionGetter); 115 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 116 return true; 117 } else if (entry->function() == jsHistoryPrototypeFunctionForward) { 118 slot.setCustom(this, nonCachingStaticForwardFunctionGetter); 119 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 120 return true; 121 } else if (entry->function() == jsHistoryPrototypeFunctionGo) { 122 slot.setCustom(this, nonCachingStaticGoFunctionGetter); 123 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 124 return true; 125 } 126 } 127 } else { 128 // Allow access to toString() cross-domain, but always Object.toString. 129 if (propertyName == exec->propertyNames().toString) { 130 PropertySlot slot; 131 slot.setCustom(this, objectToStringFunctionGetter); 132 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 133 return true; 134 } 135 } 136 137 printErrorMessageForFrame(impl()->frame(), message); 138 descriptor.setUndefined(); 139 return true; 140 } 141 96 142 bool JSHistory::putDelegate(ExecState* exec, const Identifier&, JSValue, PutPropertySlot&) 97 143 { -
trunk/WebCore/bindings/js/JSLocationCustom.cpp
r47236 r47780 95 95 } 96 96 97 bool JSLocation::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 98 { 99 Frame* frame = impl()->frame(); 100 if (!frame) { 101 descriptor.setUndefined(); 102 return true; 103 } 104 105 // When accessing Location cross-domain, functions are always the native built-in ones. 106 // See JSDOMWindow::getOwnPropertySlotDelegate for additional details. 107 108 // Our custom code is only needed to implement the Window cross-domain scheme, so if access is 109 // allowed, return false so the normal lookup will take place. 110 String message; 111 if (allowsAccessFromFrame(exec, frame, message)) 112 return false; 113 114 // Check for the few functions that we allow, even when called cross-domain. 115 const HashEntry* entry = JSLocationPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); 116 PropertySlot slot; 117 if (entry && (entry->attributes() & Function)) { 118 if (entry->function() == jsLocationPrototypeFunctionReplace) { 119 slot.setCustom(this, nonCachingStaticReplaceFunctionGetter); 120 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 121 return true; 122 } else if (entry->function() == jsLocationPrototypeFunctionReload) { 123 slot.setCustom(this, nonCachingStaticReloadFunctionGetter); 124 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 125 return true; 126 } else if (entry->function() == jsLocationPrototypeFunctionAssign) { 127 slot.setCustom(this, nonCachingStaticAssignFunctionGetter); 128 descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); 129 return true; 130 } 131 } 132 133 // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString, 134 // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in 135 // such cases when normally the string form of Location would be the URL. 136 137 printErrorMessageForFrame(frame, message); 138 descriptor.setUndefined(); 139 return true; 140 } 141 97 142 bool JSLocation::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 98 143 { -
trunk/WebCore/bindings/js/JSNamedNodesCollection.cpp
r46322 r47780 90 90 } 91 91 92 bool JSNamedNodesCollection::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 93 { 94 if (propertyName == exec->propertyNames().length) { 95 descriptor.setDescriptor(jsNumber(exec, m_nodes->size()), ReadOnly | DontDelete | DontEnum); 96 return true; 97 } 98 99 bool ok; 100 unsigned index = propertyName.toUInt32(&ok); 101 if (ok && index < m_nodes->size()) { 102 PropertySlot slot; 103 slot.setCustomIndex(this, index, indexGetter); 104 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete); 105 return true; 106 } 107 108 // For IE compatibility, we need to be able to look up elements in a 109 // document.formName.name result by id as well as be index. 110 111 AtomicString atomicPropertyName = propertyName; 112 for (unsigned i = 0; i < m_nodes->size(); i++) { 113 Node* node = (*m_nodes)[i].get(); 114 if (node->hasAttributes() && node->attributes()->id() == atomicPropertyName) { 115 PropertySlot slot; 116 slot.setCustomIndex(this, i, indexGetter); 117 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete); 118 return true; 119 } 120 } 121 122 return DOMObjectWithGlobalPointer::getOwnPropertyDescriptor(exec, propertyName, descriptor); 123 } 124 92 125 } // namespace WebCore -
trunk/WebCore/bindings/js/JSNamedNodesCollection.h
r46320 r47780 41 41 42 42 virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); 43 virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&); 43 44 44 45 virtual const JSC::ClassInfo* classInfo() const { return &s_info; } -
trunk/WebCore/bindings/js/JSPluginElementFunctions.cpp
r43372 r47780 87 87 } 88 88 89 bool runtimeObjectCustomGetOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, JSHTMLElement* element) 90 { 91 RuntimeObjectImp* runtimeObject = getRuntimeObject(exec, element->impl()); 92 if (!runtimeObject) 93 return false; 94 if (!runtimeObject->hasProperty(exec, propertyName)) 95 return false; 96 PropertySlot slot; 97 slot.setCustom(element, runtimeObjectPropertyGetter); 98 // While we don't know what the plugin allows, we do know that we prevent 99 // enumeration or deletion of properties, so we mark plugin properties 100 // as DontEnum | DontDelete 101 descriptor.setDescriptor(slot.getValue(exec, propertyName), DontEnum | DontDelete); 102 return true; 103 } 104 89 105 bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValue value, HTMLElement* element, PutPropertySlot& slot) 90 106 { -
trunk/WebCore/bindings/js/JSPluginElementFunctions.h
r43122 r47780 34 34 JSC::JSValue runtimeObjectPropertyGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); 35 35 bool runtimeObjectCustomGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&, JSHTMLElement*); 36 bool runtimeObjectCustomGetOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, JSHTMLElement*); 36 37 bool runtimeObjectCustomPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, HTMLElement*, JSC::PutPropertySlot&); 37 38 JSC::CallType runtimeObjectGetCallData(HTMLElement*, JSC::CallData&); -
trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
r47022 r47780 139 139 } 140 140 141 bool JSQuarantinedObjectWrapper::getOwnPropertyDescriptor(ExecState* exec, const Identifier& identifier, PropertyDescriptor& descriptor) 142 { 143 if (!allowsGetProperty()) { 144 descriptor.setUndefined(); 145 return true; 146 } 147 148 PropertyDescriptor unwrappedDescriptor; 149 bool result = m_unwrappedObject->getOwnPropertyDescriptor(unwrappedExecState(), identifier, unwrappedDescriptor); 150 151 if (unwrappedDescriptor.hasAccessors()) { 152 descriptor.setAccessorDescriptor(wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.getter()), 153 wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.setter()), 154 unwrappedDescriptor.attributes()); 155 } else 156 descriptor.setDescriptor(wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.value()), unwrappedDescriptor.attributes()); 157 transferExceptionToExecState(exec); 158 return result; 159 } 160 141 161 void JSQuarantinedObjectWrapper::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot) 142 162 { -
trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.h
r47022 r47780 59 59 virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&); 60 60 virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned, JSC::PropertySlot&); 61 virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&); 61 62 62 63 virtual void put(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&); -
trunk/WebCore/bindings/js/JSWorkerContextCustom.cpp
r47323 r47780 78 78 // Look for overrides before looking at any of our own properties. 79 79 if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) 80 return true; 81 return false; 82 } 83 84 bool JSWorkerContext::getOwnPropertyDescriptorDelegate(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 85 { 86 // Look for overrides before looking at any of our own properties. 87 if (JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor)) 80 88 return true; 81 89 return false; -
trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm
r47288 r47780 349 349 } 350 350 351 sub GenerateGetOwnPropertyDescriptorBody 352 { 353 my ($dataNode, $interfaceName, $className, $implClassName, $hasAttributes, $inlined) = @_; 354 355 my $namespaceMaybe = ($inlined ? "JSC::" : ""); 356 357 my @getOwnPropertyDescriptorImpl = (); 358 359 if ($interfaceName eq "NamedNodeMap" or $interfaceName eq "HTMLCollection") { 360 push(@getOwnPropertyDescriptorImpl, " ${namespaceMaybe}JSValue proto = prototype();\n"); 361 push(@getOwnPropertyDescriptorImpl, " if (proto.isObject() && static_cast<${namespaceMaybe}JSObject*>(asObject(proto))->hasProperty(exec, propertyName))\n"); 362 push(@getOwnPropertyDescriptorImpl, " return false;\n\n"); 363 } 364 365 my $manualLookupGetterGeneration = sub { 366 my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"}; 367 if ($requiresManualLookup) { 368 push(@getOwnPropertyDescriptorImpl, " const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n"); 369 push(@getOwnPropertyDescriptorImpl, " if (entry) {\n"); 370 push(@getOwnPropertyDescriptorImpl, " PropertySlot slot;\n"); 371 push(@getOwnPropertyDescriptorImpl, " slot.setCustom(this, entry->propertyGetter());\n"); 372 push(@getOwnPropertyDescriptorImpl, " descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());\n"); 373 push(@getOwnPropertyDescriptorImpl, " return true;\n"); 374 push(@getOwnPropertyDescriptorImpl, " }\n"); 375 } 376 }; 377 378 if (!$dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { 379 &$manualLookupGetterGeneration(); 380 } 381 382 if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) { 383 push(@getOwnPropertyDescriptorImpl, " bool ok;\n"); 384 push(@getOwnPropertyDescriptorImpl, " unsigned index = propertyName.toUInt32(&ok, false);\n"); 385 push(@getOwnPropertyDescriptorImpl, " if (ok && index < static_cast<$implClassName*>(impl())->length()) {\n"); 386 if ($dataNode->extendedAttributes->{"HasCustomIndexGetter"}) { 387 # Assume that if there's a setter, the index will be writable 388 if ($dataNode->extendedAttributes->{"HasIndexSetter"} || $dataNode->extendedAttributes->{"HasCustomIndexSetter"}) { 389 push(@getOwnPropertyDescriptorImpl, " descriptor.setDescriptor(getByIndex(exec, index), ${namespaceMaybe}DontDelete);\n"); 390 } else { 391 push(@getOwnPropertyDescriptorImpl, " descriptor.setDescriptor(getByIndex(exec, index), ${namespaceMaybe}DontDelete | ${namespaceMaybe}ReadOnly);\n"); 392 } 393 } else { 394 push(@getOwnPropertyDescriptorImpl, " ${namespaceMaybe}PropertySlot slot;\n"); 395 push(@getOwnPropertyDescriptorImpl, " slot.setCustomIndex(this, index, indexGetter);\n"); 396 # Assume that if there's a setter, the index will be writable 397 if ($dataNode->extendedAttributes->{"HasIndexSetter"} || $dataNode->extendedAttributes->{"HasCustomIndexSetter"}) { 398 push(@getOwnPropertyDescriptorImpl, " descriptor.setDescriptor(slot.getValue(exec, propertyName), ${namespaceMaybe}DontDelete);\n"); 399 } else { 400 push(@getOwnPropertyDescriptorImpl, " descriptor.setDescriptor(slot.getValue(exec, propertyName), ${namespaceMaybe}DontDelete | ${namespaceMaybe}ReadOnly);\n"); 401 } 402 } 403 push(@getOwnPropertyDescriptorImpl, " return true;\n"); 404 push(@getOwnPropertyDescriptorImpl, " }\n"); 405 } 406 407 if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { 408 push(@getOwnPropertyDescriptorImpl, " if (canGetItemsForName(exec, static_cast<$implClassName*>(impl()), propertyName)) {\n"); 409 push(@getOwnPropertyDescriptorImpl, " ${namespaceMaybe}PropertySlot slot;\n"); 410 push(@getOwnPropertyDescriptorImpl, " slot.setCustom(this, nameGetter);\n"); 411 push(@getOwnPropertyDescriptorImpl, " descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);\n"); 412 push(@getOwnPropertyDescriptorImpl, " return true;\n"); 413 push(@getOwnPropertyDescriptorImpl, " }\n"); 414 if ($inlined) { 415 $headerIncludes{"AtomicString.h"} = 1; 416 } else { 417 $implIncludes{"AtomicString.h"} = 1; 418 } 419 } 420 421 if ($dataNode->extendedAttributes->{"HasOverridingNameGetter"}) { 422 &$manualLookupGetterGeneration(); 423 } 424 425 if ($dataNode->extendedAttributes->{"DelegatingGetOwnPropertySlot"}) { 426 push(@getOwnPropertyDescriptorImpl, " if (getOwnPropertyDescriptorDelegate(exec, propertyName, descriptor))\n"); 427 push(@getOwnPropertyDescriptorImpl, " return true;\n"); 428 } 429 430 if ($hasAttributes) { 431 if ($inlined) { 432 die "Cannot inline if NoStaticTables is set." if ($dataNode->extendedAttributes->{"NoStaticTables"}); 433 push(@getOwnPropertyDescriptorImpl, " return ${namespaceMaybe}getStaticValueDescriptor<$className, Base>(exec, s_info.staticPropHashTable, this, propertyName, descriptor);\n"); 434 } else { 435 push(@getOwnPropertyDescriptorImpl, " return ${namespaceMaybe}getStaticValueDescriptor<$className, Base>(exec, " . hashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, descriptor);\n"); 436 } 437 } else { 438 push(@getOwnPropertyDescriptorImpl, " return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);\n"); 439 } 440 441 return @getOwnPropertyDescriptorImpl; 442 } 443 351 444 sub GenerateHeader 352 445 { … … 461 554 if ($hasGetter) { 462 555 push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);\n"); 556 push(@headerContent, " virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&);\n"); 463 557 push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);\n") if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) && !$dataNode->extendedAttributes->{"HasOverridingNameGetter"}; 464 558 push(@headerContent, " bool getOwnPropertySlotDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"DelegatingGetOwnPropertySlot"}; 559 push(@headerContent, " bool getOwnPropertyDescriptorDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&);\n") if $dataNode->extendedAttributes->{"DelegatingGetOwnPropertySlot"}; 465 560 } 466 561 … … 622 717 push(@headerContent, GenerateGetOwnPropertySlotBody($dataNode, $interfaceName, $className, $implClassName, $numAttributes > 0, 1)); 623 718 push(@headerContent, "}\n\n"); 719 push(@headerContent, "ALWAYS_INLINE bool ${className}::getOwnPropertyDescriptor(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor)\n"); 720 push(@headerContent, "{\n"); 721 push(@headerContent, GenerateGetOwnPropertyDescriptorBody($dataNode, $interfaceName, $className, $implClassName, $numAttributes > 0, 1)); 722 push(@headerContent, "}\n\n"); 624 723 } 625 724 … … 663 762 if ($numFunctions > 0 || $numConstants > 0 || $dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}) { 664 763 push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n"); 764 push(@headerContent, " virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&);\n"); 665 765 push(@headerContent, " bool getOwnPropertySlotDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}; 766 push(@headerContent, " bool getOwnPropertyDescriptorDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&);\n") if $dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}; 666 767 667 768 push(@headerContent, … … 938 1039 } else { 939 1040 push(@implContent, " return getStaticPropertySlot<${className}Prototype, JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, slot);\n"); 1041 } 1042 push(@implContent, "}\n\n"); 1043 1044 push(@implContent, "bool ${className}Prototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)\n"); 1045 push(@implContent, "{\n"); 1046 1047 if ($dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}) { 1048 push(@implContent, " if (getOwnPropertyDescriptorDelegate(exec, propertyName, descriptor))\n"); 1049 push(@implContent, " return true;\n"); 1050 } 1051 1052 if ($numConstants eq 0 && $numFunctions eq 0) { 1053 push(@implContent, " return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);\n"); 1054 } elsif ($numConstants eq 0) { 1055 push(@implContent, " return getStaticFunctionDescriptor<JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, descriptor);\n"); 1056 } elsif ($numFunctions eq 0) { 1057 push(@implContent, " return getStaticValueDescriptor<${className}Prototype, JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, descriptor);\n"); 1058 } else { 1059 push(@implContent, " return getStaticPropertyDescriptor<${className}Prototype, JSObject>(exec, " . prototypeHashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, propertyName, descriptor);\n"); 940 1060 } 941 1061 push(@implContent, "}\n\n"); … … 1067 1187 push(@implContent, "{\n"); 1068 1188 push(@implContent, GenerateGetOwnPropertySlotBody($dataNode, $interfaceName, $className, $implClassName, $numAttributes > 0, 0)); 1189 push(@implContent, "}\n\n"); 1190 push(@implContent, "bool ${className}::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)\n"); 1191 push(@implContent, "{\n"); 1192 push(@implContent, GenerateGetOwnPropertyDescriptorBody($dataNode, $interfaceName, $className, $implClassName, $numAttributes > 0, 0)); 1069 1193 push(@implContent, "}\n\n"); 1070 1194 } … … 2048 2172 } 2049 2173 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 2174 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 2050 2175 virtual const ClassInfo* classInfo() const { return &s_info; } 2051 2176 static const ClassInfo s_info; … … 2081 2206 } 2082 2207 2208 bool ${constructorClassName}::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 2209 { 2210 return getStaticValueDescriptor<${constructorClassName}, DOMObject>(exec, &${constructorClassName}Table, this, propertyName, descriptor); 2211 } 2212 2083 2213 EOF 2084 2214 -
trunk/WebCore/bridge/objc/objc_runtime.h
r43122 r47780 110 110 private: 111 111 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 112 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 112 113 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 113 114 virtual CallType getCallData(CallData&); -
trunk/WebCore/bridge/objc/objc_runtime.mm
r47288 r47780 204 204 } 205 205 206 bool ObjcFallbackObjectImp::getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor& descriptor) 207 { 208 // keep the prototype from getting called instead of just returning false 209 descriptor.setUndefined(); 210 return true; 211 } 212 206 213 void ObjcFallbackObjectImp::put(ExecState*, const Identifier&, JSValue, PutPropertySlot&) 207 214 { -
trunk/WebCore/bridge/runtime.h
r45891 r47780 112 112 113 113 virtual bool getOwnPropertySlot(JSObject*, ExecState*, const Identifier&, PropertySlot&) { return false; } 114 virtual bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&) { return false; } 114 115 virtual void put(JSObject*, ExecState*, const Identifier&, JSValue, PutPropertySlot&) { } 115 116 -
trunk/WebCore/bridge/runtime_array.cpp
r45724 r47780 76 76 } 77 77 78 bool RuntimeArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 79 { 80 if (propertyName == exec->propertyNames().length) { 81 PropertySlot slot; 82 slot.setCustom(this, lengthGetter); 83 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 84 return true; 85 } 86 87 bool ok; 88 unsigned index = propertyName.toArrayIndex(&ok); 89 if (ok) { 90 if (index < getLength()) { 91 PropertySlot slot; 92 slot.setCustomIndex(this, index, indexGetter); 93 descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | DontEnum); 94 return true; 95 } 96 } 97 98 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 99 } 100 78 101 bool RuntimeArray::getOwnPropertySlot(ExecState *exec, unsigned index, PropertySlot& slot) 79 102 { -
trunk/WebCore/bridge/runtime_array.h
r43122 r47780 38 38 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 39 39 virtual bool getOwnPropertySlot(ExecState *, unsigned, PropertySlot&); 40 virtual bool getOwnPropertyDescriptor(ExecState *, const Identifier&, PropertyDescriptor&); 40 41 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 41 42 virtual void put(ExecState*, unsigned propertyName, JSValue); -
trunk/WebCore/bridge/runtime_method.cpp
r47288 r47780 74 74 } 75 75 76 bool RuntimeMethod::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor &descriptor) 77 { 78 if (propertyName == exec->propertyNames().length) { 79 PropertySlot slot; 80 slot.setCustom(this, lengthGetter); 81 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 82 return true; 83 } 84 85 return InternalFunction::getOwnPropertyDescriptor(exec, propertyName, descriptor); 86 } 87 76 88 static JSValue JSC_HOST_CALL callRuntimeMethod(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args) 77 89 { -
trunk/WebCore/bridge/runtime_method.h
r43122 r47780 54 54 static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&); 55 55 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 56 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); 56 57 virtual CallType getCallData(CallData&); 57 58 -
trunk/WebCore/bridge/runtime_object.cpp
r45724 r47780 168 168 } 169 169 170 bool RuntimeObjectImp::getOwnPropertyDescriptor(ExecState *exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 171 { 172 if (!instance) { 173 throwInvalidAccessError(exec); 174 return false; 175 } 176 177 instance->begin(); 178 179 Class *aClass = instance->getClass(); 180 181 if (aClass) { 182 // See if the instance has a field with the specified name. 183 Field *aField = aClass->fieldNamed(propertyName, instance.get()); 184 if (aField) { 185 PropertySlot slot; 186 slot.setCustom(this, fieldGetter); 187 instance->end(); 188 descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete); 189 return true; 190 } else { 191 // Now check if a method with specified name exists, if so return a function object for 192 // that method. 193 MethodList methodList = aClass->methodsNamed(propertyName, instance.get()); 194 if (methodList.size() > 0) { 195 PropertySlot slot; 196 slot.setCustom(this, methodGetter); 197 instance->end(); 198 descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly); 199 return true; 200 } 201 } 202 203 // Try a fallback object. 204 if (!aClass->fallbackObject(exec, instance.get(), propertyName).isUndefined()) { 205 PropertySlot slot; 206 slot.setCustom(this, fallbackObjectGetter); 207 instance->end(); 208 descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly | DontEnum); 209 return true; 210 } 211 } 212 213 instance->end(); 214 215 return instance->getOwnPropertyDescriptor(this, exec, propertyName, descriptor); 216 } 217 170 218 void RuntimeObjectImp::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 171 219 { -
trunk/WebCore/bridge/runtime_object.h
r43122 r47780 39 39 40 40 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 41 virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); 41 42 virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 42 43 virtual bool deleteProperty(ExecState* , const Identifier& propertyName);
Note: See TracChangeset
for help on using the changeset viewer.