https://bugs.webkit.org/show_bug.cgi?id=79170
Reviewed by Sam Weinig.
See ES5.1 8.12.9 10.a.i - the spec prohibits making a read-only property writable,
but does not inhibit making a writable property read-only.
Source/JavaScriptCore:
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalData.h:
(JSC::JSGlobalData::setInDefineOwnProperty):
(JSGlobalData):
(JSC::JSGlobalData::isInDefineOwnProperty):
- Added flag, tracking whether we are in JSObject::defineOwnProperty.
* runtime/JSObject.cpp:
(JSC::JSObject::deleteProperty):
(DefineOwnPropertyScope):
- Always allow properties to be deleted by DefineOwnProperty - assume it knows what it is doing!
(JSC::DefineOwnPropertyScope::DefineOwnPropertyScope):
(JSC::DefineOwnPropertyScope::~DefineOwnPropertyScope):
- Added RAII helper.
(JSC::JSObject::defineOwnProperty):
- Track on the globalData when we are in this method.
LayoutTests:
* fast/js/Object-defineProperty-expected.txt:
* fast/js/script-tests/Object-defineProperty.js:
- Update test result (this was enforcing incorrect behaviour).
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@108427
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-02-21 Gavin Barraclough <barraclough@apple.com>
+
+ Should be able to reconfigure a non-configurable property as read-only
+ https://bugs.webkit.org/show_bug.cgi?id=79170
+
+ Reviewed by Sam Weinig.
+
+ See ES5.1 8.12.9 10.a.i - the spec prohibits making a read-only property writable,
+ but does not inhibit making a writable property read-only.
+
+ * fast/js/Object-defineProperty-expected.txt:
+ * fast/js/script-tests/Object-defineProperty.js:
+ - Update test result (this was enforcing incorrect behaviour).
+
2012-02-21 Adam Klein <adamk@chromium.org>
Setting innerText causes DOMSubtreeModified to be dispatched too early
PASS Object.defineProperty(createUnconfigurableProperty({}, 'foo'), 'foo', {writable: true}) threw exception TypeError: Attempting to change writable attribute of unconfigurable property..
PASS Object.defineProperty(createUnconfigurableProperty({}, 'foo'), 'foo', {enumerable: true}) threw exception TypeError: Attempting to change enumerable attribute of unconfigurable property..
PASS Object.defineProperty(createUnconfigurableProperty({}, 'foo', false, true), 'foo', {enumerable: false}), 'foo' threw exception TypeError: Attempting to change enumerable attribute of unconfigurable property..
-PASS JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty(createUnconfigurableProperty({}, 'foo', true), 'foo', {writable: false}), 'foo')) is JSON.stringify({value: 1, writable: true, enumerable: false, configurable: false})
+PASS JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty(createUnconfigurableProperty({}, 'foo', true), 'foo', {writable: false}), 'foo')) is JSON.stringify({value: 1, writable: false, enumerable: false, configurable: false})
PASS Object.defineProperty({}, 'foo', {value:1, get: function(){}}) threw exception TypeError: Invalid property. 'value' present on property with getter or setter..
PASS Object.defineProperty({}, 'foo', {value:1, set: function(){}}) threw exception TypeError: Invalid property. 'value' present on property with getter or setter..
PASS Object.defineProperty({}, 'foo', {writable:true, get: function(){}}) threw exception TypeError: Invalid property. 'writable' present on property with getter or setter..
shouldThrow("Object.defineProperty(createUnconfigurableProperty({}, 'foo', false, true), 'foo', {enumerable: false}), 'foo'");
shouldBe("JSON.stringify(Object.getOwnPropertyDescriptor(Object.defineProperty(createUnconfigurableProperty({}, 'foo', true), 'foo', {writable: false}), 'foo'))",
- "JSON.stringify({value: 1, writable: true, enumerable: false, configurable: false})");
+ "JSON.stringify({value: 1, writable: false, enumerable: false, configurable: false})");
shouldThrow("Object.defineProperty({}, 'foo', {value:1, get: function(){}})");
shouldThrow("Object.defineProperty({}, 'foo', {value:1, set: function(){}})");
+2012-02-21 Gavin Barraclough <barraclough@apple.com>
+
+ Should be able to reconfigure a non-configurable property as read-only
+ https://bugs.webkit.org/show_bug.cgi?id=79170
+
+ Reviewed by Sam Weinig.
+
+ See ES5.1 8.12.9 10.a.i - the spec prohibits making a read-only property writable,
+ but does not inhibit making a writable property read-only.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSC::JSGlobalData::setInDefineOwnProperty):
+ (JSGlobalData):
+ (JSC::JSGlobalData::isInDefineOwnProperty):
+ - Added flag, tracking whether we are in JSObject::defineOwnProperty.
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::deleteProperty):
+ (DefineOwnPropertyScope):
+ - Always allow properties to be deleted by DefineOwnProperty - assume it knows what it is doing!
+ (JSC::DefineOwnPropertyScope::DefineOwnPropertyScope):
+ (JSC::DefineOwnPropertyScope::~DefineOwnPropertyScope):
+ - Added RAII helper.
+ (JSC::JSObject::defineOwnProperty):
+ - Track on the globalData when we are in this method.
+
2012-02-21 Oliver Hunt <oliver@apple.com>
Make TypedArrays be available in commandline jsc
#if ENABLE(GC_VALIDATION)
, m_isInitializingObject(false)
#endif
+ , m_inDefineOwnProperty(false)
{
interpreter = new Interpreter;
codeBlocksBeingCompiled.removeLast();
}
+ void setInDefineOwnProperty(bool inDefineOwnProperty)
+ {
+ m_inDefineOwnProperty = inDefineOwnProperty;
+ }
+
+ bool isInDefineOwnProperty()
+ {
+ return m_inDefineOwnProperty;
+ }
+
#if ENABLE(ASSEMBLER)
ExecutableAllocator executableAllocator;
#endif
#if ENABLE(GC_VALIDATION)
bool m_isInitializingObject;
#endif
+ bool m_inDefineOwnProperty;
+
TypedArrayDescriptor m_int8ArrayDescriptor;
TypedArrayDescriptor m_int16ArrayDescriptor;
TypedArrayDescriptor m_int32ArrayDescriptor;
unsigned attributes;
JSCell* specificValue;
if (thisObject->structure()->get(exec->globalData(), propertyName, attributes, specificValue) != WTF::notFound) {
- if ((attributes & DontDelete))
+ if (attributes & DontDelete && !exec->globalData().isInDefineOwnProperty())
return false;
thisObject->removeDirect(exec->globalData(), propertyName);
return true;
// Look in the static hashtable of properties
const HashEntry* entry = thisObject->findPropertyHashEntry(exec, propertyName);
- if (entry && entry->attributes() & DontDelete)
+ if (entry && entry->attributes() & DontDelete && !exec->globalData().isInDefineOwnProperty())
return false; // this builtin property can't be deleted
// FIXME: Should the code here actually do some deletion?
return true;
}
+class DefineOwnPropertyScope {
+public:
+ DefineOwnPropertyScope(ExecState* exec)
+ : m_globalData(exec->globalData())
+ {
+ m_globalData.setInDefineOwnProperty(true);
+ }
+
+ ~DefineOwnPropertyScope()
+ {
+ m_globalData.setInDefineOwnProperty(false);
+ }
+
+private:
+ JSGlobalData& m_globalData;
+};
+
bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
{
+ // Track on the globaldata that we're in define property.
+ // Currently DefineOwnProperty uses delete to remove properties when they are being replaced
+ // (particularly when changing attributes), however delete won't allow non-configurable (i.e.
+ // DontDelete) properties to be deleted. For now, we can use this flag to make this work.
+ DefineOwnPropertyScope scope(exec);
+
// If we have a new property we can just put it on normally
PropertyDescriptor current;
if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, propertyName, current)) {