OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |