Fix Object.freeze for objects with mixed accessors and data properties
The bug in the existing code was that it modified the |attributes| local variable on its way through the loop in CopyUpToAddAttributes. But that affected any properties updated after an accessor property. The code now sets up a mask each time and applies that instead of mutating |attributes|. R=verwaest@chromium.org Review URL: https://chromiumcodereview.appspot.com/16051002 Patch from Adam Klein <adamk@chromium.org>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14818 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3e41834721
commit
9d3e7e5b81
@ -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<PropertyAttributes>(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<PropertyAttributes>(attributes & mask));
|
||||
Descriptor desc(GetKey(i), value, details);
|
||||
descriptors->Set(i, &desc, witness);
|
||||
}
|
||||
} else {
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user