| Index: src/v8natives.js
|
| ===================================================================
|
| --- src/v8natives.js (revision 6231)
|
| +++ src/v8natives.js (working copy)
|
| @@ -545,12 +545,10 @@
|
| 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() ||
|
| @@ -563,36 +561,30 @@
|
| 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"]);
|
| - // 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 (!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"]);
|
| + }
|
| }
|
|
|
| // Send flags - enumerable and configurable are common - writable is
|
| @@ -615,16 +607,7 @@
|
| } 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)) {
|
| @@ -632,30 +615,20 @@
|
| } 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);
|
| }
|
| }
|
|
|