Modified: trunk/LayoutTests/fast/js/script-tests/preventExtensions.js (108650 => 108651)
--- trunk/LayoutTests/fast/js/script-tests/preventExtensions.js 2012-02-23 19:41:12 UTC (rev 108650)
+++ trunk/LayoutTests/fast/js/script-tests/preventExtensions.js 2012-02-23 19:43:07 UTC (rev 108651)
@@ -91,8 +91,11 @@
var array = freeze([0,1,2]);
array[0] = 3;
shouldBe('array[0]', '0');
+shouldBeFalse('Object.getOwnPropertyDescriptor(array, "length").writable')
// Check that freezing arguments objects works correctly.
var args = freeze((function(){ return arguments; })(0,1,2));
args[0] = 3;
shouldBe('args[0]', '0');
+shouldBeFalse('Object.getOwnPropertyDescriptor(args, "length").writable')
+shouldBeFalse('Object.getOwnPropertyDescriptor(args, "callee").writable')
Modified: trunk/Source/_javascript_Core/runtime/Arguments.cpp (108650 => 108651)
--- trunk/Source/_javascript_Core/runtime/Arguments.cpp 2012-02-23 19:41:12 UTC (rev 108650)
+++ trunk/Source/_javascript_Core/runtime/Arguments.cpp 2012-02-23 19:43:07 UTC (rev 108651)
@@ -302,13 +302,13 @@
bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool shouldThrow)
{
- if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
- return false;
-
Arguments* thisObject = jsCast<Arguments*>(object);
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(isArrayIndex);
if (isArrayIndex && i < thisObject->d->numArguments) {
+ if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
+ return false;
+
if (!thisObject->d->deletedArguments) {
thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
@@ -328,8 +328,38 @@
thisObject->d->deletedArguments[i] = true; // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
}
}
+
+ return true;
}
- return true;
+
+ if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
+ thisObject->d->overrodeLength = true;
+ if (!descriptor.isAccessorDescriptor()) {
+ if (!descriptor.value())
+ descriptor.setValue(jsNumber(thisObject->d->numArguments));
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+
+ if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
+ thisObject->d->overrodeCallee = true;
+ if (!descriptor.isAccessorDescriptor()) {
+ if (!descriptor.value())
+ descriptor.setValue(thisObject->d->callee.get());
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+
+ if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
+ thisObject->createStrictModeCallerIfNecessary(exec);
+
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
}
void Arguments::tearOff(CallFrame* callFrame)
Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (108650 => 108651)
--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2012-02-23 19:41:12 UTC (rev 108650)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp 2012-02-23 19:43:07 UTC (rev 108651)
@@ -365,30 +365,31 @@
return throwVMError(exec, createTypeError(exec, "Object.seal can only be called on Objects."));
JSObject* object = asObject(obj);
- if (isJSFinalObject(obj))
+ if (isJSFinalObject(object)) {
object->seal(exec->globalData());
- else {
- // 2. For each named own property name P of O,
- PropertyNameArray properties(exec);
- object->methodTable()->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
- PropertyNameArray::const_iterator end = properties.end();
- for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
- // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
- PropertyDescriptor desc;
- if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, *iter, desc))
- continue;
- // b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
- desc.setConfigurable(false);
- // c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
- object->methodTable()->defineOwnProperty(object, exec, *iter, desc, true);
- if (exec->hadException())
- return JSValue::encode(obj);
- }
+ return JSValue::encode(obj);
+ }
- // 3. Set the [[Extensible]] internal property of O to false.
- object->preventExtensions(exec->globalData());
+ // 2. For each named own property name P of O,
+ PropertyNameArray properties(exec);
+ object->methodTable()->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ PropertyNameArray::const_iterator end = properties.end();
+ for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
+ PropertyDescriptor desc;
+ if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, *iter, desc))
+ continue;
+ // b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
+ desc.setConfigurable(false);
+ // c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
+ object->methodTable()->defineOwnProperty(object, exec, *iter, desc, true);
+ if (exec->hadException())
+ return JSValue::encode(obj);
}
+ // 3. Set the [[Extensible]] internal property of O to false.
+ object->preventExtensions(exec->globalData());
+
// 4. Return O.
return JSValue::encode(obj);
}
@@ -401,34 +402,35 @@
return throwVMError(exec, createTypeError(exec, "Object.freeze can only be called on Objects."));
JSObject* object = asObject(obj);
- if (isJSFinalObject(obj))
+ if (isJSFinalObject(object)) {
object->freeze(exec->globalData());
- else {
- // 2. For each named own property name P of O,
- PropertyNameArray properties(exec);
- object->methodTable()->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
- PropertyNameArray::const_iterator end = properties.end();
- for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
- // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
- PropertyDescriptor desc;
- if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, *iter, desc))
- continue;
- // b. If IsDataDescriptor(desc) is true, then
- // i. If desc.[[Writable]] is true, set desc.[[Writable]] to false.
- if (desc.isDataDescriptor())
- desc.setWritable(false);
- // c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
- desc.setConfigurable(false);
- // d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
- object->methodTable()->defineOwnProperty(object, exec, *iter, desc, true);
- if (exec->hadException())
- return JSValue::encode(obj);
- }
+ return JSValue::encode(obj);
+ }
- // 3. Set the [[Extensible]] internal property of O to false.
- object->preventExtensions(exec->globalData());
+ // 2. For each named own property name P of O,
+ PropertyNameArray properties(exec);
+ object->methodTable()->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ PropertyNameArray::const_iterator end = properties.end();
+ for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
+ PropertyDescriptor desc;
+ if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, *iter, desc))
+ continue;
+ // b. If IsDataDescriptor(desc) is true, then
+ // i. If desc.[[Writable]] is true, set desc.[[Writable]] to false.
+ if (desc.isDataDescriptor())
+ desc.setWritable(false);
+ // c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
+ desc.setConfigurable(false);
+ // d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
+ object->methodTable()->defineOwnProperty(object, exec, *iter, desc, true);
+ if (exec->hadException())
+ return JSValue::encode(obj);
}
+ // 3. Set the [[Extensible]] internal property of O to false.
+ object->preventExtensions(exec->globalData());
+
// 4. Return O.
return JSValue::encode(obj);
}
@@ -444,18 +446,63 @@
EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
{
+ // 1. If Type(O) is not Object throw a TypeError exception.
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, "Object.isSealed can only be called on Objects."));
- return JSValue::encode(jsBoolean(asObject(obj)->isSealed(exec->globalData())));
+ JSObject* object = asObject(obj);
+
+ if (isJSFinalObject(object))
+ return JSValue::encode(jsBoolean(object->isSealed(exec->globalData())));
+
+ // 2. For each named own property name P of O,
+ PropertyNameArray properties(exec);
+ object->methodTable()->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ PropertyNameArray::const_iterator end = properties.end();
+ for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
+ PropertyDescriptor desc;
+ if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, *iter, desc))
+ continue;
+ // b. If desc.[[Configurable]] is true, then return false.
+ if (desc.configurable())
+ return JSValue::encode(jsBoolean(false));
+ }
+
+ // 3. If the [[Extensible]] internal property of O is false, then return true.
+ // 4. Otherwise, return false.
+ return JSValue::encode(jsBoolean(!object->isExtensible()));
}
EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
{
+ // 1. If Type(O) is not Object throw a TypeError exception.
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, "Object.isFrozen can only be called on Objects."));
- return JSValue::encode(jsBoolean(asObject(obj)->isFrozen(exec->globalData())));
+ JSObject* object = asObject(obj);
+
+ if (isJSFinalObject(object))
+ return JSValue::encode(jsBoolean(object->isFrozen(exec->globalData())));
+
+ // 2. For each named own property name P of O,
+ PropertyNameArray properties(exec);
+ object->methodTable()->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ PropertyNameArray::const_iterator end = properties.end();
+ for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
+ PropertyDescriptor desc;
+ if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, *iter, desc))
+ continue;
+ // b. If IsDataDescriptor(desc) is true then
+ // i. If desc.[[Writable]] is true, return false. c. If desc.[[Configurable]] is true, then return false.
+ if ((desc.isDataDescriptor() && desc.writable()) || desc.configurable())
+ return JSValue::encode(jsBoolean(false));
+ }
+
+ // 3. If the [[Extensible]] internal property of O is false, then return true.
+ // 4. Otherwise, return false.
+ return JSValue::encode(jsBoolean(!object->isExtensible()));
}
EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState* exec)