diff --git a/src/objects.cc b/src/objects.cc index 99fd8e21f0..c5abb109cd 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -6744,11 +6744,14 @@ MaybeObject* DescriptorArray::CopyUpToAddAttributes( for (int i = 0; i < size; ++i) { Object* value = GetValue(i); PropertyDetails details = GetDetails(i); + int mask = DONT_DELETE | DONT_ENUM; // READ_ONLY is an invalid attribute for JS setters/getters. - if (details.type() == CALLBACKS && value->IsAccessorPair()) { - attributes = static_cast(attributes & ~READ_ONLY); + if (details.type() != CALLBACKS || !value->IsAccessorPair()) { + mask |= READ_ONLY; } - Descriptor desc(GetKey(i), value, details.CopyAddAttributes(attributes)); + details = details.CopyAddAttributes( + static_cast(attributes & mask)); + Descriptor desc(GetKey(i), value, details); descriptors->Set(i, &desc, witness); } } else { diff --git a/test/mjsunit/object-freeze.js b/test/mjsunit/object-freeze.js index 7b457900aa..a0717a171c 100644 --- a/test/mjsunit/object-freeze.js +++ b/test/mjsunit/object-freeze.js @@ -296,3 +296,21 @@ assertEquals(42, obj.accessor); accessorDidRun = false; obj.accessor = 'ignored value'; assertTrue(accessorDidRun); + +// Test for regression in mixed accessor/data property objects. +// The strict function is one such object. +assertTrue(Object.isFrozen(Object.freeze(function(){"use strict";}))); + +// Also test a simpler case +obj = {}; +Object.defineProperty(obj, 'accessor', { + get: function() { return 42 }, + set: function() { accessorDidRun = true }, + configurable: true, + enumerable: true +}); +obj.data = 'foo'; +assertTrue(%HasFastProperties(obj)); +Object.freeze(obj); +assertTrue(%HasFastProperties(obj)); +assertTrue(Object.isFrozen(obj));