Allow accessor get/set property to be set to undefined
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jan 2012 18:38:24 +0000 (18:38 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jan 2012 18:38:24 +0000 (18:38 +0000)
commitbbec85fe111565a7c4851342abd8a7a0c6d94451
treeeda3a07f7d1cfb6189aa7ba6db51bde4d7c6b4ce
parentd839c02ac636d92bf968ebed67b4196002d39ba1
Allow accessor get/set property to be set to undefined
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: https://svn.webkit.org/repository/webkit/trunk@104836 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/fast/js/Object-defineProperty-expected.txt
LayoutTests/fast/js/script-tests/Object-defineProperty.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/GetterSetter.h
Source/JavaScriptCore/runtime/JSArray.cpp
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
Source/JavaScriptCore/runtime/PropertyDescriptor.h