• barraclough@apple.com's avatar
    Allow accessor get/set property to be set to undefined · c709a123
    barraclough@apple.com authored
    https://bugs.webkit.org/show_bug.cgi?id=76148
    
    Reviewed by Oliver Hunt.
    
    Source/JavaScriptCore: 
    
    AccessorDescriptor properties may have their get & set properties defined to reference a function
    (Callable object) or be set to undefined. Valid PropertyDescriptors created by toPropertyDescriptor
    (defined from JS code via Object.defineProperty, etc) have get and set properties that are in one of
    three states (1) nonexistent, (2) set to undefined, or (3) a function (any Callable object).
    
    On the PropertyDescriptor object these three states are represneted by JSValue(), jsUndefined(), and
    any JSObject* (with a constraint that this must be callable).
    
    Logically the get/set property of an accessor descriptor on an object might be in any of the three
    states above, but in practice there is no way to distinguish between the first two states. As such
    we stor the get/set values in property storage in a JSObject* field, with 0 indicating absent or
    undefined. When unboxing to a PropertyDescriptor, map this back to a JS undefined value.
    
    * runtime/GetterSetter.h:
    (JSC::GetterSetter::setGetter):
    (JSC::GetterSetter::setSetter):
        - Allow the getter/setter to be cleared.
    * runtime/JSArray.cpp:
    (JSC::JSArray::putDescriptor):
        - Changed to call getterObject/setterObject.
    (JSC::JSArray::defineOwnNumericProperty):
        - Added ASSERT.
    * runtime/JSObject.cpp:
    (JSC::putDescriptor):
    (JSC::JSObject::defineOwnProperty):
        - Changed to call getterObject/setterObject.
    * runtime/ObjectConstructor.cpp:
    (JSC::objectConstructorGetOwnPropertyDescriptor):
        - getter/setter values read from properties on object are never missing, they will now be set as undefined by 'setDescriptor'.
    (JSC::toPropertyDescriptor):
        - Do not translate undefined->empty, this loses an important distinction between a get/set property being absent, or being explicitly set to undefined.
    * runtime/PropertyDescriptor.cpp:
    (JSC::PropertyDescriptor::getterObject):
    (JSC::PropertyDescriptor::setterObject):
        - Accessors to convert the get/set property to an object pointer, converting undefined to 0.
    (JSC::PropertyDescriptor::setDescriptor):
    (JSC::PropertyDescriptor::setAccessorDescriptor):
        - Translate a getter/setter internally represented at 0 to undefined, indicating that it is present.
    * runtime/PropertyDescriptor.h:
        - Declare getterObject/setterObject.
    
    LayoutTests: 
    
    * fast/js/Object-defineProperty-expected.txt:
    * fast/js/script-tests/Object-defineProperty.js:
        - Update a couple of inaccurate tests (it is invalid for a property to have
          both a get: and value: field; AccessorDescritor properties do not have a
          writable property). Add more test cases.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@104836 268f45cc-cd09-0410-ab3c-d52691b4dbfc
    c709a123
PropertyDescriptor.cpp 7.2 KB