Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(426)

Side by Side Diff: src/objects.cc

Issue 2819034: Add ES5 Object.isExtensible and Object.preventExtensions. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 if (result->IsFailure()) return result; 1379 if (result->IsFailure()) return result;
1380 if (dict != result) set_properties(StringDictionary::cast(result)); 1380 if (dict != result) set_properties(StringDictionary::cast(result));
1381 return value; 1381 return value;
1382 } 1382 }
1383 1383
1384 1384
1385 Object* JSObject::AddProperty(String* name, 1385 Object* JSObject::AddProperty(String* name,
1386 Object* value, 1386 Object* value,
1387 PropertyAttributes attributes) { 1387 PropertyAttributes attributes) {
1388 ASSERT(!IsJSGlobalProxy()); 1388 ASSERT(!IsJSGlobalProxy());
1389 if (!map()->is_extensible()) {
1390 Handle<Object> args[1] = {Handle<String>(name)};
1391 return Top::Throw(*Factory::NewTypeError("object_not_extensible",
1392 HandleVector(args, 1)));
1393 }
1389 if (HasFastProperties()) { 1394 if (HasFastProperties()) {
1390 // Ensure the descriptor array does not get too big. 1395 // Ensure the descriptor array does not get too big.
1391 if (map()->instance_descriptors()->number_of_descriptors() < 1396 if (map()->instance_descriptors()->number_of_descriptors() <
1392 DescriptorArray::kMaxNumberOfDescriptors) { 1397 DescriptorArray::kMaxNumberOfDescriptors) {
1393 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { 1398 if (value->IsJSFunction() && !Heap::InNewSpace(value)) {
1394 return AddConstantFunctionProperty(name, 1399 return AddConstantFunctionProperty(name,
1395 JSFunction::cast(value), 1400 JSFunction::cast(value),
1396 attributes); 1401 attributes);
1397 } else { 1402 } else {
1398 return AddFastProperty(name, value, attributes); 1403 return AddFastProperty(name, value, attributes);
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2569 if (context->has_extension()) { 2574 if (context->has_extension()) {
2570 return context->extension()->ReferencesObject(obj); 2575 return context->extension()->ReferencesObject(obj);
2571 } 2576 }
2572 } 2577 }
2573 2578
2574 // No references to object. 2579 // No references to object.
2575 return false; 2580 return false;
2576 } 2581 }
2577 2582
2578 2583
2584 Object* JSObject::PreventExtensions() {
2585 // If there are fast elements we normalize.
2586 if (HasFastElements()) {
2587 NormalizeElements();
2588 }
2589 // Make sure that we never go back to fast case.
2590 element_dictionary()->set_requires_slow_elements();
2591
2592 // Do a map transition, other objects with this map may still
2593 // be extensible.
2594 Object* new_map = map()->CopyDropTransitions();
2595 if (new_map->IsFailure()) return new_map;
2596 Map::cast(new_map)->set_is_extensible(false);
2597 set_map(Map::cast(new_map));
2598 ASSERT(!map()->is_extensible());
2599 return new_map;
2600 }
2601
2602
2579 // Tests for the fast common case for property enumeration: 2603 // Tests for the fast common case for property enumeration:
2580 // - This object and all prototypes has an enum cache (which means that it has 2604 // - This object and all prototypes has an enum cache (which means that it has
2581 // no interceptors and needs no access checks). 2605 // no interceptors and needs no access checks).
2582 // - This object has no elements. 2606 // - This object has no elements.
2583 // - No prototype has enumerable properties/elements. 2607 // - No prototype has enumerable properties/elements.
2584 bool JSObject::IsSimpleEnum() { 2608 bool JSObject::IsSimpleEnum() {
2585 for (Object* o = this; 2609 for (Object* o = this;
2586 o != Heap::null_value(); 2610 o != Heap::null_value();
2587 o = JSObject::cast(o)->GetPrototype()) { 2611 o = JSObject::cast(o)->GetPrototype()) {
2588 JSObject* curr = JSObject::cast(o); 2612 JSObject* curr = JSObject::cast(o);
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
3069 return result; 3093 return result;
3070 } 3094 }
3071 3095
3072 3096
3073 Object* Map::CopyDropTransitions() { 3097 Object* Map::CopyDropTransitions() {
3074 Object* new_map = CopyDropDescriptors(); 3098 Object* new_map = CopyDropDescriptors();
3075 if (new_map->IsFailure()) return new_map; 3099 if (new_map->IsFailure()) return new_map;
3076 Object* descriptors = instance_descriptors()->RemoveTransitions(); 3100 Object* descriptors = instance_descriptors()->RemoveTransitions();
3077 if (descriptors->IsFailure()) return descriptors; 3101 if (descriptors->IsFailure()) return descriptors;
3078 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); 3102 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
3079 return cast(new_map); 3103 return new_map;
3080 } 3104 }
3081 3105
3082 3106
3083 Object* Map::UpdateCodeCache(String* name, Code* code) { 3107 Object* Map::UpdateCodeCache(String* name, Code* code) {
3084 // Allocate the code cache if not present. 3108 // Allocate the code cache if not present.
3085 if (code_cache()->IsFixedArray()) { 3109 if (code_cache()->IsFixedArray()) {
3086 Object* result = Heap::AllocateCodeCache(); 3110 Object* result = Heap::AllocateCodeCache();
3087 if (result->IsFailure()) return result; 3111 if (result->IsFailure()) return result;
3088 set_code_cache(result); 3112 set_code_cache(result);
3089 } 3113 }
(...skipping 3112 matching lines...) Expand 10 before | Expand all | Expand 10 after
6202 dictionary->UpdateMaxNumberKey(index); 6226 dictionary->UpdateMaxNumberKey(index);
6203 dictionary->ValueAtPut(entry, value); 6227 dictionary->ValueAtPut(entry, value);
6204 } 6228 }
6205 } else { 6229 } else {
6206 // Index not already used. Look for an accessor in the prototype chain. 6230 // Index not already used. Look for an accessor in the prototype chain.
6207 if (!IsJSArray()) { 6231 if (!IsJSArray()) {
6208 if (SetElementWithCallbackSetterInPrototypes(index, value)) { 6232 if (SetElementWithCallbackSetterInPrototypes(index, value)) {
6209 return value; 6233 return value;
6210 } 6234 }
6211 } 6235 }
6236 // When we set the is_extensible flag to false we always force
6237 // the element into dictionary mode (and force them to stay there).
6238 if (!map()->is_extensible()) {
6239 Handle<Object> number(Heap::NumberFromUint32(index));
6240 Handle<String> index_string(Factory::NumberToString(number));
6241 Handle<Object> args[1] = { index_string };
6242 return Top::Throw(*Factory::NewTypeError("object_not_extensible",
6243 HandleVector(args, 1)));
6244 }
6212 Object* result = dictionary->AtNumberPut(index, value); 6245 Object* result = dictionary->AtNumberPut(index, value);
6213 if (result->IsFailure()) return result; 6246 if (result->IsFailure()) return result;
6214 if (elms != FixedArray::cast(result)) { 6247 if (elms != FixedArray::cast(result)) {
6215 set_elements(FixedArray::cast(result)); 6248 set_elements(FixedArray::cast(result));
6216 } 6249 }
6217 } 6250 }
6218 6251
6219 // Update the array length if this JSObject is an array. 6252 // Update the array length if this JSObject is an array.
6220 if (IsJSArray()) { 6253 if (IsJSArray()) {
6221 JSArray* array = JSArray::cast(this); 6254 JSArray* array = JSArray::cast(this);
(...skipping 2516 matching lines...) Expand 10 before | Expand all | Expand 10 after
8738 if (break_point_objects()->IsUndefined()) return 0; 8771 if (break_point_objects()->IsUndefined()) return 0;
8739 // Single beak point. 8772 // Single beak point.
8740 if (!break_point_objects()->IsFixedArray()) return 1; 8773 if (!break_point_objects()->IsFixedArray()) return 1;
8741 // Multiple break points. 8774 // Multiple break points.
8742 return FixedArray::cast(break_point_objects())->length(); 8775 return FixedArray::cast(break_point_objects())->length();
8743 } 8776 }
8744 #endif 8777 #endif
8745 8778
8746 8779
8747 } } // namespace v8::internal 8780 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698