if (IS_UNDEFINED(current) && !extensible)
throw MakeTypeError("define_disallowed", ["defineProperty"]);
- if (!IS_UNDEFINED(current)) {
+ if (!IS_UNDEFINED(current) && !current.isConfigurable()) {
// Step 5 and 6
- if ((IsGenericDescriptor(desc) ||
- IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
- (!desc.hasEnumerable() ||
- SameValue(desc.isEnumerable(), current.isEnumerable())) &&
+ if ((!desc.hasEnumerable() ||
+ SameValue(desc.isEnumerable() && current.isEnumerable())) &&
(!desc.hasConfigurable() ||
SameValue(desc.isConfigurable(), current.isConfigurable())) &&
(!desc.hasWritable() ||
SameValue(desc.getSet(), current.getSet()))) {
return true;
}
- if (!current.isConfigurable()) {
- // Step 7
- if (desc.isConfigurable() ||
- (desc.hasEnumerable() &&
- desc.isEnumerable() != current.isEnumerable()))
+
+ // Step 7
+ if (desc.isConfigurable() || desc.isEnumerable() != current.isEnumerable())
+ throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ // Step 9
+ if (IsDataDescriptor(current) != IsDataDescriptor(desc))
+ throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ // Step 10
+ if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
+ if (!current.isWritable() && desc.isWritable())
+ throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ if (!current.isWritable() && desc.hasValue() &&
+ !SameValue(desc.getValue(), current.getValue())) {
+ throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ }
+ }
+ // Step 11
+ if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
+ if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())){
throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
- // Step 8
- if (!IsGenericDescriptor(desc)) {
- // Step 9a
- if (IsDataDescriptor(current) != IsDataDescriptor(desc))
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
- // Step 10a
- if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
- if (!current.isWritable() && desc.isWritable())
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
- if (!current.isWritable() && desc.hasValue() &&
- !SameValue(desc.getValue(), current.getValue())) {
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
- }
- }
- // Step 11
- if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
- if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())){
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
- }
- if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet()))
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
- }
}
+ if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet()))
+ throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
}
}
} else
flag |= DONT_DELETE;
- if (IsDataDescriptor(desc) ||
- (IsGenericDescriptor(desc) &&
- (IS_UNDEFINED(current) || IsDataDescriptor(current)))) {
- // There are 3 cases that lead here:
- // Step 4a - defining a new data property.
- // Steps 9b & 12 - replacing an existing accessor property with a data
- // property.
- // Step 12 - updating an existing data property with a data or generic
- // descriptor.
-
+ if (IsDataDescriptor(desc) || IsGenericDescriptor(desc)) {
if (desc.hasWritable()) {
flag |= desc.isWritable() ? 0 : READ_ONLY;
} else if (!IS_UNDEFINED(current)) {
} else {
flag |= READ_ONLY;
}
-
var value = void 0; // Default value is undefined.
if (desc.hasValue()) {
value = desc.getValue();
- } else if (!IS_UNDEFINED(current) && IsDataDescriptor(current)) {
+ } else if (!IS_UNDEFINED(current)) {
value = current.getValue();
}
-
%DefineOrRedefineDataProperty(obj, p, value, flag);
- } else if (IsGenericDescriptor(desc)) {
- // Step 12 - updating an existing accessor property with a generic
- // descriptor. Changing flags only.
- %DefineOrRedefineAccessorProperty(obj, p, GETTER, current.getGet(), flag);
} else {
- // There are 3 cases that lead here:
- // Step 4b - defining a new accessor property.
- // Steps 9c & 12 - replacing an existing data property with an accessor
- // property.
- // Step 12 - updating an existing accessor property with an accessor
- // descriptor.
- if (desc.hasGetter()) {
- %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
+ if (desc.hasGetter() &&
+ (IS_FUNCTION(desc.getGet()) || IS_UNDEFINED(desc.getGet()))) {
+ %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
}
- if (desc.hasSetter()) {
+ if (desc.hasSetter() &&
+ (IS_FUNCTION(desc.getSet()) || IS_UNDEFINED(desc.getSet()))) {
%DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag);
}
}
assertTrue(desc.enumerable);
assertFalse(desc.configurable);
-// Can use defineProperty to change the value of a non
-// configurable property.
+// Ensure that we can't overwrite the non configurable element.
try {
Object.defineProperty(obj6, '2', descElement);
- desc = Object.getOwnPropertyDescriptor(obj6, '2');
- assertEquals(desc.value, 'foobar');
-} catch (e) {
- assertUnreachable();
-}
-
-// Ensure that we can't change the descriptor of a
-// non configurable property.
-try {
- var descAccessor = { get: function() { return 0; } };
- Object.defineProperty(obj6, '2', descAccessor);
assertUnreachable();
} catch (e) {
assertTrue(/Cannot redefine property/.test(e));
}
-Object.defineProperty(obj6, '2', descElementNonWritable);
-desc = Object.getOwnPropertyDescriptor(obj6, '2');
-assertEquals(desc.value, 'foofoo');
-assertFalse(desc.writable);
-assertTrue(desc.enumerable);
-assertFalse(desc.configurable);
-
Object.defineProperty(obj6, '3', descElementNonWritable);
desc = Object.getOwnPropertyDescriptor(obj6, '3');
assertEquals(desc.value, 'foofoo');
assertTrue(desc.enumerable);
assertFalse(desc.configurable);
-// Can use defineProperty to change the value of a non
-// configurable property of an array.
+// Ensure that we can't overwrite the non configurable element.
try {
Object.defineProperty(arr, '2', descElement);
- desc = Object.getOwnPropertyDescriptor(arr, '2');
- assertEquals(desc.value, 'foobar');
-} catch (e) {
- assertUnreachable();
-}
-
-// Ensure that we can't change the descriptor of a
-// non configurable property.
-try {
- var descAccessor = { get: function() { return 0; } };
- Object.defineProperty(arr, '2', descAccessor);
assertUnreachable();
} catch (e) {
assertTrue(/Cannot redefine property/.test(e));
}
-Object.defineProperty(arr, '2', descElementNonWritable);
-desc = Object.getOwnPropertyDescriptor(arr, '2');
-assertEquals(desc.value, 'foofoo');
-assertFalse(desc.writable);
-assertTrue(desc.enumerable);
-assertFalse(desc.configurable);
-
Object.defineProperty(arr, '3', descElementNonWritable);
desc = Object.getOwnPropertyDescriptor(arr, '3');
assertEquals(desc.value, 'foofoo');