Index: src/objects.cc |
=================================================================== |
--- src/objects.cc (revision 5007) |
+++ src/objects.cc (working copy) |
@@ -1386,6 +1386,11 @@ |
Object* value, |
PropertyAttributes attributes) { |
ASSERT(!IsJSGlobalProxy()); |
+ if (!map()->is_extensible()) { |
+ Handle<Object> args[1] = {Handle<String>(name)}; |
+ return Top::Throw(*Factory::NewTypeError("object_not_extensible", |
+ HandleVector(args, 1))); |
+ } |
if (HasFastProperties()) { |
// Ensure the descriptor array does not get too big. |
if (map()->instance_descriptors()->number_of_descriptors() < |
@@ -2576,6 +2581,25 @@ |
} |
+Object* JSObject::PreventExtensions() { |
+ // If there are fast elements we normalize. |
+ if (HasFastElements()) { |
+ NormalizeElements(); |
+ } |
+ // Make sure that we never go back to fast case. |
+ element_dictionary()->set_requires_slow_elements(); |
+ |
+ // Do a map transition, other objects with this map may still |
+ // be extensible. |
+ Object* new_map = map()->CopyDropTransitions(); |
+ if (new_map->IsFailure()) return new_map; |
+ Map::cast(new_map)->set_is_extensible(false); |
+ set_map(Map::cast(new_map)); |
+ ASSERT(!map()->is_extensible()); |
+ return new_map; |
+} |
+ |
+ |
// Tests for the fast common case for property enumeration: |
// - This object and all prototypes has an enum cache (which means that it has |
// no interceptors and needs no access checks). |
@@ -3076,7 +3100,7 @@ |
Object* descriptors = instance_descriptors()->RemoveTransitions(); |
if (descriptors->IsFailure()) return descriptors; |
cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); |
- return cast(new_map); |
+ return new_map; |
} |
@@ -6209,6 +6233,15 @@ |
return value; |
} |
} |
+ // When we set the is_extensible flag to false we always force |
+ // the element into dictionary mode (and force them to stay there). |
+ if (!map()->is_extensible()) { |
+ Handle<Object> number(Heap::NumberFromUint32(index)); |
+ Handle<String> index_string(Factory::NumberToString(number)); |
+ Handle<Object> args[1] = { index_string }; |
+ return Top::Throw(*Factory::NewTypeError("object_not_extensible", |
+ HandleVector(args, 1))); |
+ } |
Object* result = dictionary->AtNumberPut(index, value); |
if (result->IsFailure()) return result; |
if (elms != FixedArray::cast(result)) { |