Changeset 48542 in webkit
- Timestamp:
- Sep 18, 2009 4:12:03 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r48527 r48542 1 2009-09-18 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Geoff Garen. 4 5 Implement ES5 Object.defineProperty function 6 https://bugs.webkit.org/show_bug.cgi?id=29503 7 8 Implement Object.defineProperty. This requires adding the API to 9 ObjectConstructor, along with a helper function that implements the 10 ES5 internal [[ToPropertyDescriptor]] function. It then adds 11 JSObject::defineOwnProperty that implements the appropriate ES5 semantics. 12 Currently defineOwnProperty uses a delete followed by a put to redefine 13 attributes of a property, clearly this is less efficient than it could be 14 but we can improve this if it needs to be possible in future. 15 16 * JavaScriptCore.exp: 17 * debugger/DebuggerActivation.cpp: 18 (JSC::DebuggerActivation::defineGetter): 19 (JSC::DebuggerActivation::defineSetter): 20 * debugger/DebuggerActivation.h: 21 * interpreter/Interpreter.cpp: 22 (JSC::Interpreter::privateExecute): 23 * jit/JITStubs.cpp: 24 Update defineGetter/Setter calls 25 * runtime/CommonIdentifiers.h: 26 * runtime/JSArray.cpp: 27 (JSC::JSArray::getOwnPropertySlot): 28 * runtime/JSGlobalObject.cpp: 29 (JSC::JSGlobalObject::defineGetter): 30 (JSC::JSGlobalObject::defineSetter): 31 * runtime/JSGlobalObject.h: 32 * runtime/JSObject.cpp: 33 (JSC::JSObject::defineGetter): 34 (JSC::JSObject::defineSetter): 35 (JSC::putDescriptor): 36 (JSC::JSObject::defineOwnProperty): 37 * runtime/JSObject.h: 38 * runtime/ObjectConstructor.cpp: 39 (JSC::ObjectConstructor::ObjectConstructor): 40 (JSC::objectConstructorGetOwnPropertyDescriptor): 41 (JSC::toPropertyDescriptor): 42 (JSC::objectConstructorDefineProperty): 43 * runtime/ObjectPrototype.cpp: 44 (JSC::objectProtoFuncDefineGetter): 45 (JSC::objectProtoFuncDefineSetter): 46 * runtime/PropertyDescriptor.cpp: 47 (JSC::PropertyDescriptor::writable): 48 (JSC::PropertyDescriptor::enumerable): 49 (JSC::PropertyDescriptor::configurable): 50 (JSC::PropertyDescriptor::isDataDescriptor): 51 (JSC::PropertyDescriptor::isGenericDescriptor): 52 (JSC::PropertyDescriptor::isAccessorDescriptor): 53 (JSC::PropertyDescriptor::getter): 54 (JSC::PropertyDescriptor::setter): 55 (JSC::PropertyDescriptor::setDescriptor): 56 (JSC::PropertyDescriptor::setAccessorDescriptor): 57 (JSC::PropertyDescriptor::setWritable): 58 (JSC::PropertyDescriptor::setEnumerable): 59 (JSC::PropertyDescriptor::setConfigurable): 60 (JSC::PropertyDescriptor::setSetter): 61 (JSC::PropertyDescriptor::setGetter): 62 (JSC::PropertyDescriptor::equalTo): 63 (JSC::PropertyDescriptor::attributesEqual): 64 (JSC::PropertyDescriptor::attributesWithOverride): 65 * runtime/PropertyDescriptor.h: 66 (JSC::PropertyDescriptor::PropertyDescriptor): 67 (JSC::PropertyDescriptor::value): 68 (JSC::PropertyDescriptor::setValue): 69 (JSC::PropertyDescriptor::isEmpty): 70 (JSC::PropertyDescriptor::writablePresent): 71 (JSC::PropertyDescriptor::enumerablePresent): 72 (JSC::PropertyDescriptor::configurablePresent): 73 (JSC::PropertyDescriptor::setterPresent): 74 (JSC::PropertyDescriptor::getterPresent): 75 (JSC::PropertyDescriptor::operator==): 76 (JSC::PropertyDescriptor::): 77 1 78 2009-09-18 Gabor Loki <loki@inf.u-szeged.hu> 2 79 -
trunk/JavaScriptCore/JavaScriptCore.exp
r48403 r48542 129 129 __ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE 130 130 __ZN3JSC14JSGlobalObject10globalExecEv 131 __ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE 132 __ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE 131 __ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj 132 __ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj 133 133 __ZN3JSC14JSGlobalObject12markChildrenERNS_9MarkStackE 134 134 __ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj … … 156 156 __ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi 157 157 __ZN3JSC18DebuggerActivationC1EPNS_8JSObjectE 158 __ZN3JSC18PropertyDescriptor11setWritableEb 158 159 __ZN3JSC18PropertyDescriptor12setUndefinedEv 159 160 __ZN3JSC18PropertyDescriptor13setDescriptorENS_7JSValueEj 161 __ZN3JSC18PropertyDescriptor13setEnumerableEb 162 __ZN3JSC18PropertyDescriptor15setConfigurableEb 163 __ZN3JSC18PropertyDescriptor17defaultAttributesE 160 164 __ZN3JSC18PropertyDescriptor21setAccessorDescriptorENS_7JSValueES1_j 161 __ZN K3JSC18PropertyDescriptor6setterEv162 __ZN K3JSC18PropertyDescriptor6getterEv165 __ZN3JSC18PropertyDescriptor9setGetterENS_7JSValueE 166 __ZN3JSC18PropertyDescriptor9setSetterENS_7JSValueE 163 167 __ZN3JSC19constructEmptyArrayEPNS_9ExecStateE 164 168 __ZN3JSC19initializeThreadingEv … … 235 239 __ZN3JSC8DebuggerD2Ev 236 240 __ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_7JSValueES3_ 237 __ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_ 238 __ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_ 241 __ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j 242 __ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j 239 243 __ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE 240 244 __ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE … … 245 249 __ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE 246 250 __ZN3JSC8JSObject17createInheritorIDEv 251 __ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb 247 252 __ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj 248 253 __ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj … … 347 352 __ZNK3JSC17DebuggerCallFrame4typeEv 348 353 __ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_7JSValueE 349 __ZNK3JSC18PropertyDescriptor12hasAccessorsEv 354 __ZNK3JSC18PropertyDescriptor10enumerableEv 355 __ZNK3JSC18PropertyDescriptor12configurableEv 356 __ZNK3JSC18PropertyDescriptor16isDataDescriptorEv 357 __ZNK3JSC18PropertyDescriptor20isAccessorDescriptorEv 358 __ZNK3JSC18PropertyDescriptor6setterEv 359 __ZNK3JSC18PropertyDescriptor6getterEv 360 __ZNK3JSC18PropertyDescriptor8writableEv 350 361 __ZNK3JSC4Heap10statisticsEv 351 362 __ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE -
trunk/JavaScriptCore/debugger/DebuggerActivation.cpp
r48336 r48542 82 82 } 83 83 84 void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction )84 void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) 85 85 { 86 m_activation->defineGetter(exec, propertyName, getterFunction );86 m_activation->defineGetter(exec, propertyName, getterFunction, attributes); 87 87 } 88 88 89 void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction )89 void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) 90 90 { 91 m_activation->defineSetter(exec, propertyName, setterFunction );91 m_activation->defineSetter(exec, propertyName, setterFunction, attributes); 92 92 } 93 93 -
trunk/JavaScriptCore/debugger/DebuggerActivation.h
r48336 r48542 45 45 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); 46 46 virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const; 47 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction );48 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction );47 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes); 48 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes); 49 49 virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName); 50 50 virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName); -
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r47738 r48542 3732 3732 Identifier& ident = callFrame->codeBlock()->identifier(property); 3733 3733 ASSERT(callFrame->r(function).jsValue().isObject()); 3734 baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()) );3734 baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0); 3735 3735 3736 3736 ++vPC; -
trunk/JavaScriptCore/runtime/CommonIdentifiers.h
r48336 r48542 40 40 macro(configurable) \ 41 41 macro(constructor) \ 42 macro(defineProperty) \ 42 43 macro(enumerable) \ 43 44 macro(eval) \ -
trunk/JavaScriptCore/runtime/JSArray.cpp
r48336 r48542 224 224 } 225 225 226 return false;226 return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, i), slot); 227 227 } 228 228 -
trunk/JavaScriptCore/runtime/JSGlobalObject.cpp
r47404 r48542 176 176 } 177 177 178 void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc )178 void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes) 179 179 { 180 180 PropertySlot slot; 181 181 if (!symbolTableGet(propertyName, slot)) 182 JSVariableObject::defineGetter(exec, propertyName, getterFunc );183 } 184 185 void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc )182 JSVariableObject::defineGetter(exec, propertyName, getterFunc, attributes); 183 } 184 185 void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes) 186 186 { 187 187 PropertySlot slot; 188 188 if (!symbolTableGet(propertyName, slot)) 189 JSVariableObject::defineSetter(exec, propertyName, setterFunc );189 JSVariableObject::defineSetter(exec, propertyName, setterFunc, attributes); 190 190 } 191 191 -
trunk/JavaScriptCore/runtime/JSGlobalObject.h
r47780 r48542 176 176 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes); 177 177 178 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc );179 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc );178 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes); 179 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes); 180 180 181 181 // Linked list of all global objects that use the same JSGlobalData. -
trunk/JavaScriptCore/runtime/JSObject.cpp
r48336 r48542 276 276 } 277 277 278 void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction )278 void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) 279 279 { 280 280 JSValue object = getDirect(propertyName); … … 287 287 PutPropertySlot slot; 288 288 GetterSetter* getterSetter = new (exec) GetterSetter(exec); 289 putDirectInternal(exec->globalData(), propertyName, getterSetter, Getter, true, slot);289 putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Getter, true, slot); 290 290 291 291 // putDirect will change our Structure if we add a new property. For … … 303 303 } 304 304 305 void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction )305 void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) 306 306 { 307 307 JSValue object = getDirect(propertyName); … … 314 314 PutPropertySlot slot; 315 315 GetterSetter* getterSetter = new (exec) GetterSetter(exec); 316 putDirectInternal(exec->globalData(), propertyName, getterSetter, Setter, true, slot);316 putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Setter, true, slot); 317 317 318 318 // putDirect will change our Structure if we add a new property. For … … 542 542 } 543 543 } 544 545 static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& propertyName, PropertyDescriptor& descriptor, unsigned attributes, JSValue oldValue) 546 { 547 if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) { 548 target->putWithAttributes(exec, propertyName, descriptor.value() ? descriptor.value() : oldValue, attributes & ~(Getter | Setter)); 549 return true; 550 } 551 attributes &= ~ReadOnly; 552 if (descriptor.getter() && descriptor.getter().isObject()) 553 target->defineGetter(exec, propertyName, asObject(descriptor.getter()), attributes); 554 if (exec->hadException()) 555 return false; 556 if (descriptor.setter() && descriptor.setter().isObject()) 557 target->defineSetter(exec, propertyName, asObject(descriptor.setter()), attributes); 558 return !exec->hadException(); 559 } 560 561 bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException) 562 { 563 // If we have a new property we can just put it on normally 564 PropertyDescriptor current; 565 if (!getOwnPropertyDescriptor(exec, propertyName, current)) 566 return putDescriptor(exec, this, propertyName, descriptor, descriptor.attributes(), jsUndefined()); 567 568 if (descriptor.isEmpty()) 569 return true; 570 571 if (current.equalTo(descriptor)) 572 return true; 573 574 // Filter out invalid changes 575 if (!current.configurable()) { 576 if (descriptor.configurable()) { 577 if (throwException) 578 throwError(exec, TypeError, "Attempting to configurable attribute of unconfigurable property."); 579 return false; 580 } 581 if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) { 582 if (throwException) 583 throwError(exec, TypeError, "Attempting to change enumerable attribute of unconfigurable property."); 584 return false; 585 } 586 } 587 588 // A generic descriptor is simply changing the attributes of an existing property 589 if (descriptor.isGenericDescriptor()) { 590 if (!current.attributesEqual(descriptor)) { 591 deleteProperty(exec, propertyName); 592 putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); 593 } 594 return true; 595 } 596 597 // Changing between a normal property or an accessor property 598 if (descriptor.isDataDescriptor() != current.isDataDescriptor()) { 599 if (!current.configurable()) { 600 if (throwException) 601 throwError(exec, TypeError, "Attempting to change access mechanism for an unconfigurable property."); 602 return false; 603 } 604 deleteProperty(exec, propertyName); 605 return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value() ? current.value() : jsUndefined()); 606 } 607 608 // Changing the value and attributes of an existing property 609 if (descriptor.isDataDescriptor()) { 610 if (!current.configurable()) { 611 if (!current.writable() && descriptor.writable()) { 612 if (throwException) 613 throwError(exec, TypeError, "Attempting to change writable attribute of unconfigurable property."); 614 return false; 615 } 616 if (!current.writable()) { 617 if (descriptor.value() || !JSValue::strictEqual(current.value(), descriptor.value())) { 618 if (throwException) 619 throwError(exec, TypeError, "Attempting to change value of a readonly property."); 620 return false; 621 } 622 } 623 } else if (current.attributesEqual(descriptor)) { 624 if (!descriptor.value()) 625 return true; 626 PutPropertySlot slot; 627 put(exec, propertyName, descriptor.value(), slot); 628 if (exec->hadException()) 629 return false; 630 return true; 631 } 632 deleteProperty(exec, propertyName); 633 return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); 634 } 635 636 // Changing the accessor functions of an existing accessor property 637 ASSERT(descriptor.isAccessorDescriptor()); 638 if (!current.configurable()) { 639 if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(current.setter(), descriptor.setter()))) { 640 if (throwException) 641 throwError(exec, TypeError, "Attempting to change the setter of an unconfigurable property."); 642 return false; 643 } 644 if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(current.getter(), descriptor.getter()))) { 645 if (throwException) 646 throwError(exec, TypeError, "Attempting to change the getter of an unconfigurable property."); 647 return false; 648 } 649 } 650 JSValue accessor = getDirect(propertyName); 651 if (!accessor) 652 return false; 653 GetterSetter* getterSetter = asGetterSetter(accessor); 654 if (current.attributesEqual(descriptor)) { 655 if (descriptor.setter()) 656 getterSetter->setSetter(asObject(descriptor.setter())); 657 if (descriptor.getter()) 658 getterSetter->setGetter(asObject(descriptor.getter())); 659 return true; 660 } 661 deleteProperty(exec, propertyName); 662 unsigned attrs = current.attributesWithOverride(descriptor); 663 if (descriptor.setter()) 664 attrs |= Setter; 665 if (descriptor.getter()) 666 attrs |= Getter; 667 putDirect(propertyName, getterSetter, attrs); 668 return true; 669 } 670 544 671 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSObject.h
r48403 r48542 187 187 void fillGetterPropertySlot(PropertySlot&, JSValue* location); 188 188 189 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction );190 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction );189 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0); 190 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0); 191 191 virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName); 192 192 virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName); 193 virtual bool defineOwnProperty(ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow); 193 194 194 195 virtual bool isGlobalObject() const { return false; } -
trunk/JavaScriptCore/runtime/ObjectConstructor.cpp
r48338 r48542 38 38 static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&); 39 39 static JSValue JSC_HOST_CALL objectConstructorKeys(ExecState*, JSObject*, JSValue, const ArgList&); 40 static JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*, JSObject*, JSValue, const ArgList&); 40 41 41 42 ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure) … … 51 52 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum); 52 53 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum); 54 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 3, exec->propertyNames().defineProperty, objectConstructorDefineProperty), DontEnum); 53 55 } 54 56 … … 104 106 if (exec->hadException()) 105 107 return jsUndefined(); 106 ASSERT(descriptor.isValid());107 108 108 109 JSObject* description = constructEmptyObject(exec); 109 if (!descriptor. hasAccessors()) {110 description->putDirect(exec->propertyNames().value, descriptor.value() , 0);110 if (!descriptor.isAccessorDescriptor()) { 111 description->putDirect(exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0); 111 112 description->putDirect(exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0); 112 113 } else { 113 description->putDirect(exec->propertyNames().get, descriptor.getter() , 0);114 description->putDirect(exec->propertyNames().set, descriptor.setter() , 0);114 description->putDirect(exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0); 115 description->putDirect(exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0); 115 116 } 116 117 … … 134 135 } 135 136 137 // ES5 8.10.5 ToPropertyDescriptor 138 static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc) 139 { 140 if (!in.isObject()) { 141 throwError(exec, TypeError, "Property description must be an object."); 142 return false; 143 } 144 JSObject* description = asObject(in); 145 146 PropertySlot enumerableSlot; 147 if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) { 148 desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec)); 149 if (exec->hadException()) 150 return false; 151 } 152 153 PropertySlot configurableSlot; 154 if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) { 155 desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec)); 156 if (exec->hadException()) 157 return false; 158 } 159 160 JSValue value; 161 PropertySlot valueSlot; 162 if (description->getPropertySlot(exec, exec->propertyNames().value, valueSlot)) { 163 desc.setValue(valueSlot.getValue(exec, exec->propertyNames().value)); 164 if (exec->hadException()) 165 return false; 166 } 167 168 PropertySlot writableSlot; 169 if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) { 170 desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec)); 171 if (exec->hadException()) 172 return false; 173 } 174 175 PropertySlot getSlot; 176 if (description->getPropertySlot(exec, exec->propertyNames().get, getSlot)) { 177 JSValue get = getSlot.getValue(exec, exec->propertyNames().get); 178 if (exec->hadException()) 179 return false; 180 if (!get.isUndefined()) { 181 CallData callData; 182 if (get.getCallData(callData) == CallTypeNone) { 183 throwError(exec, TypeError, "Getter must be a function."); 184 return false; 185 } 186 } else 187 get = JSValue(); 188 desc.setGetter(get); 189 } 190 191 PropertySlot setSlot; 192 if (description->getPropertySlot(exec, exec->propertyNames().set, setSlot)) { 193 JSValue set = setSlot.getValue(exec, exec->propertyNames().set); 194 if (exec->hadException()) 195 return false; 196 if (!set.isUndefined()) { 197 CallData callData; 198 if (set.getCallData(callData) == CallTypeNone) { 199 throwError(exec, TypeError, "Setter must be a function."); 200 return false; 201 } 202 } else 203 set = JSValue(); 204 205 desc.setSetter(set); 206 } 207 208 if (!desc.isAccessorDescriptor()) 209 return true; 210 211 if (desc.value()) { 212 throwError(exec, TypeError, "Invalid property. 'value' present on property with getter or setter."); 213 return false; 214 } 215 216 if (desc.writablePresent()) { 217 throwError(exec, TypeError, "Invalid property. 'writable' present on property with getter or setter."); 218 return false; 219 } 220 return true; 221 } 222 223 JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec, JSObject*, JSValue, const ArgList& args) 224 { 225 if (!args.at(0).isObject()) 226 return throwError(exec, TypeError, "Properties can only be defined on Objects."); 227 JSObject* O = asObject(args.at(0)); 228 UString propertyName = args.at(1).toString(exec); 229 if (exec->hadException()) 230 return jsNull(); 231 PropertyDescriptor descriptor; 232 if (!toPropertyDescriptor(exec, args.at(2), descriptor)) 233 return jsNull(); 234 ASSERT((descriptor.attributes() & (Getter | Setter)) || (!descriptor.isAccessorDescriptor())); 235 ASSERT(!exec->hadException()); 236 O->defineOwnProperty(exec, Identifier(exec, propertyName), descriptor, true); 237 return O; 238 } 239 136 240 } // namespace JSC -
trunk/JavaScriptCore/runtime/PropertyDescriptor.cpp
r47780 r48542 31 31 #include "GetterSetter.h" 32 32 #include "JSObject.h" 33 #include "Operations.h" 33 34 34 35 namespace JSC { 36 unsigned PropertyDescriptor::defaultAttributes = (DontDelete << 1) - 1; 37 35 38 bool PropertyDescriptor::writable() const 36 39 { 37 ASSERT(! hasAccessors());40 ASSERT(!isAccessorDescriptor()); 38 41 return !(m_attributes & ReadOnly); 39 42 } … … 41 44 bool PropertyDescriptor::enumerable() const 42 45 { 43 ASSERT(isValid());44 46 return !(m_attributes & DontEnum); 45 47 } … … 47 49 bool PropertyDescriptor::configurable() const 48 50 { 49 ASSERT(isValid());50 51 return !(m_attributes & DontDelete); 51 52 } 52 53 53 bool PropertyDescriptor:: hasAccessors() const54 bool PropertyDescriptor::isDataDescriptor() const 54 55 { 55 return !!(m_attributes & (Getter | Setter)); 56 return m_value || (m_seenAttributes & WritablePresent); 57 } 58 59 bool PropertyDescriptor::isGenericDescriptor() const 60 { 61 return !isAccessorDescriptor() && !isDataDescriptor(); 62 } 63 64 bool PropertyDescriptor::isAccessorDescriptor() const 65 { 66 return m_getter || m_setter; 56 67 } 57 68 … … 64 75 JSValue PropertyDescriptor::getter() const 65 76 { 66 ASSERT(hasAccessors()); 67 if (!m_getter) 68 return jsUndefined(); 77 ASSERT(isAccessorDescriptor()); 69 78 return m_getter; 70 79 } … … 72 81 JSValue PropertyDescriptor::setter() const 73 82 { 74 ASSERT(hasAccessors()); 75 if (!m_setter) 76 return jsUndefined(); 83 ASSERT(isAccessorDescriptor()); 77 84 return m_setter; 78 85 } … … 81 88 { 82 89 ASSERT(value); 90 m_attributes = attributes; 83 91 if (attributes & (Getter | Setter)) { 84 92 GetterSetter* accessor = asGetterSetter(value); … … 86 94 m_setter = accessor->setter(); 87 95 ASSERT(m_getter || m_setter); 96 m_seenAttributes = EnumerablePresent | ConfigurablePresent; 97 m_attributes &= ~ReadOnly; 88 98 } else { 89 99 m_value = value; 100 m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent; 90 101 } 91 m_attributes = attributes;92 102 } 93 103 … … 99 109 m_getter = getter; 100 110 m_setter = setter; 111 m_attributes &= ~ReadOnly; 112 m_seenAttributes = EnumerablePresent | ConfigurablePresent; 113 } 114 115 void PropertyDescriptor::setWritable(bool writable) 116 { 117 if (writable) 118 m_attributes &= ~ReadOnly; 119 else 120 m_attributes |= ReadOnly; 121 m_seenAttributes |= WritablePresent; 122 } 123 124 void PropertyDescriptor::setEnumerable(bool enumerable) 125 { 126 if (enumerable) 127 m_attributes &= ~DontEnum; 128 else 129 m_attributes |= DontEnum; 130 m_seenAttributes |= EnumerablePresent; 131 } 132 133 void PropertyDescriptor::setConfigurable(bool configurable) 134 { 135 if (configurable) 136 m_attributes &= ~DontDelete; 137 else 138 m_attributes |= DontDelete; 139 m_seenAttributes |= ConfigurablePresent; 140 } 141 142 void PropertyDescriptor::setSetter(JSValue setter) 143 { 144 m_setter = setter; 145 m_attributes |= Setter; 146 m_attributes &= ~ReadOnly; 147 } 148 149 void PropertyDescriptor::setGetter(JSValue getter) 150 { 151 m_getter = getter; 152 m_attributes |= Getter; 153 m_attributes &= ~ReadOnly; 154 } 155 156 bool PropertyDescriptor::equalTo(const PropertyDescriptor& other) const 157 { 158 if (!other.m_value == m_value || 159 !other.m_getter == m_getter || 160 !other.m_setter == m_setter) 161 return false; 162 return (!m_value || JSValue::strictEqual(other.m_value, m_value)) && 163 (!m_getter || JSValue::strictEqual(other.m_getter, m_getter)) && 164 (!m_setter || JSValue::strictEqual(other.m_setter, m_setter)) && 165 attributesEqual(other); 166 } 167 168 bool PropertyDescriptor::attributesEqual(const PropertyDescriptor& other) const 169 { 170 unsigned mismatch = other.m_attributes ^ m_attributes; 171 unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; 172 if (sharedSeen & WritablePresent && mismatch & ReadOnly) 173 return false; 174 if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) 175 return false; 176 if (sharedSeen & EnumerablePresent && mismatch & DontEnum) 177 return false; 178 return true; 179 } 180 181 unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& other) const 182 { 183 unsigned mismatch = other.m_attributes ^ m_attributes; 184 unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; 185 unsigned newAttributes = m_attributes & defaultAttributes; 186 if (sharedSeen & WritablePresent && mismatch & ReadOnly) 187 newAttributes ^= ReadOnly; 188 if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) 189 newAttributes ^= DontDelete; 190 if (sharedSeen & EnumerablePresent && mismatch & DontEnum) 191 newAttributes ^= DontEnum; 192 return newAttributes; 101 193 } 102 194 -
trunk/JavaScriptCore/runtime/PropertyDescriptor.h
r47780 r48542 33 33 public: 34 34 PropertyDescriptor() 35 : m_attributes(0) 35 : m_attributes(defaultAttributes) 36 , m_seenAttributes(0) 36 37 { 37 38 } … … 39 40 bool enumerable() const; 40 41 bool configurable() const; 41 bool hasAccessors() const; 42 bool isDataDescriptor() const; 43 bool isGenericDescriptor() const; 44 bool isAccessorDescriptor() const; 42 45 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; } 46 JSValue value() const { return m_value; } 47 47 JSValue getter() const; 48 48 JSValue setter() const; … … 50 50 void setDescriptor(JSValue value, unsigned attributes); 51 51 void setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes); 52 void setWritable(bool); 53 void setEnumerable(bool); 54 void setConfigurable(bool); 55 void setValue(JSValue value) { m_value = value; } 56 void setSetter(JSValue); 57 void setGetter(JSValue); 58 bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); } 59 bool writablePresent() const { return m_seenAttributes & WritablePresent; } 60 bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; } 61 bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; } 62 bool setterPresent() const { return m_setter; } 63 bool getterPresent() const { return m_getter; } 64 bool equalTo(const PropertyDescriptor& other) const; 65 bool attributesEqual(const PropertyDescriptor& other) const; 66 unsigned attributesWithOverride(const PropertyDescriptor& other) const; 52 67 private: 68 static unsigned defaultAttributes; 69 bool operator==(const PropertyDescriptor&){ return false; } 70 enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4}; 53 71 // May be a getter/setter 54 72 JSValue m_value; … … 56 74 JSValue m_setter; 57 75 unsigned m_attributes; 76 unsigned m_seenAttributes; 58 77 }; 59 78 } -
trunk/LayoutTests/ChangeLog
r48541 r48542 1 2009-09-18 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Geoff Garen. 4 5 Implement ES5 Object.defineProperty function 6 https://bugs.webkit.org/show_bug.cgi?id=29503 7 8 Add testcases for Object.defineProperty. 9 10 * fast/js/Object-defineProperty-expected.txt: Added. 11 * fast/js/Object-defineProperty.html: Added. 12 * fast/js/resources/Object-defineProperty.js: Added. 13 * http/tests/security/resources/xss-DENIED-defineProperty-attacker.html: Added. 14 * http/tests/security/xss-DENIED-defineProperty-expected.txt: Added. 15 * http/tests/security/xss-DENIED-defineProperty.html: Added. 16 1 17 2009-09-18 Brady Eidson <beidson@apple.com> 2 18 -
trunk/WebCore/ChangeLog
r48540 r48542 1 2009-09-18 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Geoff Garen. 4 5 Implement ES5 Object.defineProperty function 6 https://bugs.webkit.org/show_bug.cgi?id=29503 7 8 Override defineOwnProperty on JSDOMWindowShell to forward appropriately, 9 and then override defineOwnProperty on JSDOMWindow to disallow cross origin 10 defineOwnProperty usage. We also override defineOwnProperty on QuarantinedObjectWrapper 11 to ensure correct wrapping semantics of quarantined objects. 12 13 One major caveat in this patch is that it currently disallows the use 14 of Object.defineProperty on DOMObjects other than the window due to 15 the significant work involved in correctly propagating attributes and 16 ensuring correct semantics on dom objects. 17 18 Tests: fast/js/Object-defineProperty.html 19 http/tests/security/xss-DENIED-defineProperty.html 20 21 * bindings/js/JSDOMBinding.cpp: 22 (WebCore::DOMObject::defineOwnProperty): 23 * bindings/js/JSDOMBinding.h: 24 * bindings/js/JSDOMWindowCustom.cpp: 25 (WebCore::JSDOMWindow::defineGetter): 26 (WebCore::JSDOMWindow::defineSetter): 27 (WebCore::JSDOMWindow::defineOwnProperty): 28 * bindings/js/JSDOMWindowShell.cpp: 29 (WebCore::JSDOMWindowShell::defineOwnProperty): 30 (WebCore::JSDOMWindowShell::defineGetter): 31 (WebCore::JSDOMWindowShell::defineSetter): 32 * bindings/js/JSDOMWindowShell.h: 33 * bindings/js/JSLocationCustom.cpp: 34 (WebCore::JSLocation::defineGetter): 35 (WebCore::JSLocationPrototype::defineGetter): 36 * bindings/js/JSQuarantinedObjectWrapper.cpp: 37 (WebCore::JSQuarantinedObjectWrapper::getOwnPropertyDescriptor): 38 (WebCore::JSQuarantinedObjectWrapper::defineOwnProperty): 39 * bindings/js/JSQuarantinedObjectWrapper.h: 40 * bindings/scripts/CodeGeneratorJS.pm: 41 1 42 2009-09-18 Alexey Proskuryakov <ap@apple.com> 2 43 -
trunk/WebCore/bindings/js/JSDOMBinding.cpp
r48025 r48542 649 649 } 650 650 651 bool DOMObject::defineOwnProperty(ExecState* exec, const Identifier&, PropertyDescriptor&, bool) 652 { 653 throwError(exec, TypeError, "defineProperty is not supported on DOM Objects"); 654 return false; 655 } 656 651 657 } // namespace WebCore -
trunk/WebCore/bindings/js/JSDOMBinding.h
r48079 r48542 56 56 } 57 57 58 virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier&, JSC::PropertyDescriptor&, bool); 59 58 60 #ifndef NDEBUG 59 61 virtual ~DOMObject(); -
trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp
r48402 r48542 489 489 } 490 490 491 void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction )491 void JSDOMWindow::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) 492 492 { 493 493 // Only allow defining getters by frames in the same origin. … … 499 499 return; 500 500 501 Base::defineGetter(exec, propertyName, getterFunction );502 } 503 504 void JSDOMWindow::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction )501 Base::defineGetter(exec, propertyName, getterFunction, attributes); 502 } 503 504 void JSDOMWindow::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) 505 505 { 506 506 // Only allow defining setters by frames in the same origin. 507 507 if (!allowsAccessFrom(exec)) 508 508 return; 509 Base::defineSetter(exec, propertyName, setterFunction); 509 Base::defineSetter(exec, propertyName, setterFunction, attributes); 510 } 511 512 bool JSDOMWindow::defineOwnProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor, bool shouldThrow) 513 { 514 // Only allow defining properties in this way by frames in the same origin, as it allows setters to be introduced. 515 if (!allowsAccessFrom(exec)) 516 return false; 517 return Base::defineOwnProperty(exec, propertyName, descriptor, shouldThrow); 510 518 } 511 519 -
trunk/WebCore/bindings/js/JSDOMWindowShell.cpp
r48336 r48542 104 104 } 105 105 106 bool JSDOMWindowShell::defineOwnProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor, bool shouldThrow) 107 { 108 return m_window->defineOwnProperty(exec, propertyName, descriptor, shouldThrow); 109 } 110 106 111 bool JSDOMWindowShell::deleteProperty(ExecState* exec, const Identifier& propertyName) 107 112 { … … 124 129 } 125 130 126 void JSDOMWindowShell::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction )131 void JSDOMWindowShell::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) 127 132 { 128 m_window->defineGetter(exec, propertyName, getterFunction );133 m_window->defineGetter(exec, propertyName, getterFunction, attributes); 129 134 } 130 135 131 void JSDOMWindowShell::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction )136 void JSDOMWindowShell::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) 132 137 { 133 m_window->defineSetter(exec, propertyName, setterFunction );138 m_window->defineSetter(exec, propertyName, setterFunction, attributes); 134 139 } 135 140 -
trunk/WebCore/bindings/js/JSDOMWindowShell.h
r48336 r48542 75 75 virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); 76 76 virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier& propertyName, unsigned& attributes) const; 77 virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); 78 virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); 77 virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes); 78 virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes); 79 virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); 79 80 virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); 80 81 virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); -
trunk/WebCore/bindings/js/JSLocationCustom.cpp
r48336 r48542 183 183 } 184 184 185 void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction )185 void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) 186 186 { 187 187 if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) 188 188 return; 189 Base::defineGetter(exec, propertyName, getterFunction );189 Base::defineGetter(exec, propertyName, getterFunction, attributes); 190 190 } 191 191 … … 363 363 } 364 364 365 void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction )365 void JSLocationPrototype::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) 366 366 { 367 367 if (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf) 368 368 return; 369 Base::defineGetter(exec, propertyName, getterFunction );369 Base::defineGetter(exec, propertyName, getterFunction, attributes); 370 370 } 371 371 -
trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
r48336 r48542 149 149 bool result = m_unwrappedObject->getOwnPropertyDescriptor(unwrappedExecState(), identifier, unwrappedDescriptor); 150 150 151 if (unwrappedDescriptor. hasAccessors()) {151 if (unwrappedDescriptor.isAccessorDescriptor()) { 152 152 descriptor.setAccessorDescriptor(wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.getter()), 153 153 wrapOutgoingValue(unwrappedExecState(), unwrappedDescriptor.setter()), … … 177 177 178 178 transferExceptionToExecState(exec); 179 } 180 181 bool JSQuarantinedObjectWrapper::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool shouldThrow) 182 { 183 if (!allowsSetProperty()) 184 return false; 185 186 PropertyDescriptor wrappedDescriptor; 187 if (descriptor.isDataDescriptor()) { 188 wrappedDescriptor.setValue(prepareIncomingValue(exec, descriptor.value())); 189 if (wrappedDescriptor.writablePresent()) 190 wrappedDescriptor.setWritable(descriptor.writable()); 191 } else if (descriptor.isAccessorDescriptor()) { 192 if (descriptor.getter()) 193 wrappedDescriptor.setGetter(prepareIncomingValue(exec, descriptor.getter())); 194 if (descriptor.setter()) 195 wrappedDescriptor.setSetter(prepareIncomingValue(exec, descriptor.setter())); 196 } 197 if (wrappedDescriptor.enumerablePresent()) 198 wrappedDescriptor.setEnumerable(descriptor.enumerable()); 199 if (wrappedDescriptor.configurablePresent()) 200 wrappedDescriptor.setConfigurable(descriptor.configurable()); 201 202 bool result = m_unwrappedObject->defineOwnProperty(unwrappedExecState(), propertyName, wrappedDescriptor, shouldThrow); 203 204 transferExceptionToExecState(exec); 205 return result; 179 206 } 180 207 -
trunk/WebCore/bindings/js/JSQuarantinedObjectWrapper.h
r48336 r48542 63 63 virtual void put(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&); 64 64 virtual void put(JSC::ExecState*, unsigned, JSC::JSValue); 65 virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow); 65 66 66 67 virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier&); -
trunk/WebCore/bindings/scripts/CodeGeneratorJS.pm
r48336 r48542 628 628 # Custom getPropertyNames function exists on DOMWindow 629 629 push(@headerContent, " virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if $interfaceName eq "DOMWindow"; 630 631 # Custom defineProperty function exists on DOMWindow 632 push(@headerContent, " virtual bool defineOwnProperty(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&, bool shouldThrow);\n") if $interfaceName eq "DOMWindow"; 633 630 634 # Custom getOwnPropertyNames function 631 635 push(@headerContent, " virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"} || $dataNode->extendedAttributes->{"HasNumericIndexGetter"}); … … 635 639 636 640 # Custom defineGetter function 637 push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction );\n") if $dataNode->extendedAttributes->{"CustomDefineGetter"};641 push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomDefineGetter"}; 638 642 639 643 # Custom defineSetter function 640 push(@headerContent, " virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction );\n") if $dataNode->extendedAttributes->{"CustomDefineSetter"};644 push(@headerContent, " virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomDefineSetter"}; 641 645 642 646 # Custom lookupGetter function … … 801 805 802 806 # Custom defineGetter function 803 push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction );\n") if $dataNode->extendedAttributes->{"CustomPrototypeDefineGetter"};807 push(@headerContent, " virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes);\n") if $dataNode->extendedAttributes->{"CustomPrototypeDefineGetter"}; 804 808 805 809 push(@headerContent, " ${className}Prototype(PassRefPtr<JSC::Structure> structure) : JSC::JSObject(structure) { }\n");
Note: See TracChangeset
for help on using the changeset viewer.