OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3061 } | 3061 } |
3062 return heap->true_value(); | 3062 return heap->true_value(); |
3063 } | 3063 } |
3064 | 3064 |
3065 | 3065 |
3066 MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index, | 3066 MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index, |
3067 DeleteMode mode) { | 3067 DeleteMode mode) { |
3068 Isolate* isolate = GetIsolate(); | 3068 Isolate* isolate = GetIsolate(); |
3069 Heap* heap = isolate->heap(); | 3069 Heap* heap = isolate->heap(); |
3070 FixedArray* backing_store = FixedArray::cast(elements()); | 3070 FixedArray* backing_store = FixedArray::cast(elements()); |
3071 if (backing_store->map() == heap->non_strict_arguments_elements_map()) { | 3071 bool is_arguments = |
3072 (GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); | |
3073 if (is_arguments) { | |
3072 backing_store = FixedArray::cast(backing_store->get(1)); | 3074 backing_store = FixedArray::cast(backing_store->get(1)); |
3073 } | 3075 } |
3074 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); | 3076 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); |
3075 int entry = dictionary->FindEntry(index); | 3077 int entry = dictionary->FindEntry(index); |
3076 if (entry != NumberDictionary::kNotFound) { | 3078 if (entry != NumberDictionary::kNotFound) { |
3077 Object* result = dictionary->DeleteProperty(entry, mode); | 3079 Object* result = dictionary->DeleteProperty(entry, mode); |
3078 if (result == heap->true_value()) { | 3080 if (result == heap->true_value()) { |
3079 MaybeObject* maybe_elements = dictionary->Shrink(index); | 3081 MaybeObject* maybe_elements = dictionary->Shrink(index); |
3080 FixedArray* new_elements = NULL; | 3082 FixedArray* new_elements = NULL; |
3081 if (!maybe_elements->To(&new_elements)) { | 3083 if (!maybe_elements->To(&new_elements)) { |
3082 return maybe_elements; | 3084 return maybe_elements; |
3083 } | 3085 } |
3084 set_elements(new_elements); | 3086 if (is_arguments) { |
3087 FixedArray::cast(elements())->set(1, new_elements); | |
fschneider
2011/07/07 09:03:34
Is there a named constant for the slots in the arg
| |
3088 } else { | |
3089 set_elements(new_elements); | |
3090 } | |
3085 } | 3091 } |
3086 if (mode == STRICT_DELETION && result == heap->false_value()) { | 3092 if (mode == STRICT_DELETION && result == heap->false_value()) { |
3087 // In strict mode, attempting to delete a non-configurable property | 3093 // In strict mode, attempting to delete a non-configurable property |
3088 // throws an exception. | 3094 // throws an exception. |
3089 HandleScope scope(isolate); | 3095 HandleScope scope(isolate); |
3090 Handle<Object> holder(this); | 3096 Handle<Object> holder(this); |
3091 Handle<Object> name = isolate->factory()->NewNumberFromUint(index); | 3097 Handle<Object> name = isolate->factory()->NewNumberFromUint(index); |
3092 Handle<Object> args[2] = { name, holder }; | 3098 Handle<Object> args[2] = { name, holder }; |
3093 Handle<Object> error = | 3099 Handle<Object> error = |
3094 isolate->factory()->NewTypeError("strict_delete_property", | 3100 isolate->factory()->NewTypeError("strict_delete_property", |
(...skipping 6326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9421 // mirrors. | 9427 // mirrors. |
9422 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { | 9428 void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) { |
9423 ASSERT(storage->length() >= (NumberOfLocalProperties(NONE) - index)); | 9429 ASSERT(storage->length() >= (NumberOfLocalProperties(NONE) - index)); |
9424 if (HasFastProperties()) { | 9430 if (HasFastProperties()) { |
9425 DescriptorArray* descs = map()->instance_descriptors(); | 9431 DescriptorArray* descs = map()->instance_descriptors(); |
9426 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 9432 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
9427 if (descs->IsProperty(i)) storage->set(index++, descs->GetKey(i)); | 9433 if (descs->IsProperty(i)) storage->set(index++, descs->GetKey(i)); |
9428 } | 9434 } |
9429 ASSERT(storage->length() >= index); | 9435 ASSERT(storage->length() >= index); |
9430 } else { | 9436 } else { |
9431 property_dictionary()->CopyKeysTo(storage); | 9437 property_dictionary()->CopyKeysTo(storage, StringDictionary::UNSORTED); |
9432 } | 9438 } |
9433 } | 9439 } |
9434 | 9440 |
9435 | 9441 |
9436 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { | 9442 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { |
9437 return GetLocalElementKeys(NULL, filter); | 9443 return GetLocalElementKeys(NULL, filter); |
9438 } | 9444 } |
9439 | 9445 |
9440 | 9446 |
9441 int JSObject::NumberOfEnumElements() { | 9447 int JSObject::NumberOfEnumElements() { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9498 counter++; | 9504 counter++; |
9499 } | 9505 } |
9500 ASSERT(!storage || storage->length() >= counter); | 9506 ASSERT(!storage || storage->length() >= counter); |
9501 break; | 9507 break; |
9502 } | 9508 } |
9503 case FAST_DOUBLE_ELEMENTS: | 9509 case FAST_DOUBLE_ELEMENTS: |
9504 UNREACHABLE(); | 9510 UNREACHABLE(); |
9505 break; | 9511 break; |
9506 case DICTIONARY_ELEMENTS: { | 9512 case DICTIONARY_ELEMENTS: { |
9507 if (storage != NULL) { | 9513 if (storage != NULL) { |
9508 element_dictionary()->CopyKeysTo(storage, filter); | 9514 element_dictionary()->CopyKeysTo(storage, |
9515 filter, | |
9516 NumberDictionary::SORTED); | |
9509 } | 9517 } |
9510 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 9518 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
9511 break; | 9519 break; |
9512 } | 9520 } |
9513 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 9521 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
9514 FixedArray* parameter_map = FixedArray::cast(elements()); | 9522 FixedArray* parameter_map = FixedArray::cast(elements()); |
9515 int length = parameter_map->length(); | 9523 int mapped_length = parameter_map->length() - 2; |
9516 for (int i = 2; i < length; ++i) { | |
9517 if (!parameter_map->get(i)->IsTheHole()) { | |
9518 if (storage != NULL) storage->set(i - 2, Smi::FromInt(i - 2)); | |
9519 ++counter; | |
9520 } | |
9521 } | |
9522 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 9524 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
9523 if (arguments->IsDictionary()) { | 9525 if (arguments->IsDictionary()) { |
9526 // Copy the keys from arguments first, because Dictionary::CopyKeysTo | |
9527 // will insert in storage starting at index 0. | |
9524 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 9528 NumberDictionary* dictionary = NumberDictionary::cast(arguments); |
9525 if (storage != NULL) dictionary->CopyKeysTo(storage, filter); | 9529 if (storage != NULL) { |
9530 dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED); | |
9531 } | |
9526 counter += dictionary->NumberOfElementsFilterAttributes(filter); | 9532 counter += dictionary->NumberOfElementsFilterAttributes(filter); |
9527 } else { | 9533 for (int i = 0; i < mapped_length; ++i) { |
9528 int length = arguments->length(); | 9534 if (!parameter_map->get(i + 2)->IsTheHole()) { |
9529 for (int i = 0; i < length; ++i) { | 9535 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); |
9530 if (!arguments->get(i)->IsTheHole()) { | |
9531 if (storage != NULL) storage->set(i, Smi::FromInt(i)); | |
9532 ++counter; | 9536 ++counter; |
9533 } | 9537 } |
9534 } | 9538 } |
9539 if (storage != NULL) storage->SortPairs(storage, counter); | |
9540 | |
9541 } else { | |
9542 int backing_length = arguments->length(); | |
9543 int i = 0; | |
9544 for (; i < mapped_length; ++i) { | |
9545 if (!parameter_map->get(i + 2)->IsTheHole()) { | |
9546 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | |
9547 ++counter; | |
9548 } else if (i < backing_length && !arguments->get(i)->IsTheHole()) { | |
9549 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | |
9550 ++counter; | |
9551 } | |
9552 } | |
9553 for (; i < backing_length; ++i) { | |
9554 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | |
9555 ++counter; | |
9556 } | |
9535 } | 9557 } |
9536 break; | 9558 break; |
9537 } | 9559 } |
9538 } | 9560 } |
9539 | 9561 |
9540 if (this->IsJSValue()) { | 9562 if (this->IsJSValue()) { |
9541 Object* val = JSValue::cast(this)->value(); | 9563 Object* val = JSValue::cast(this)->value(); |
9542 if (val->IsString()) { | 9564 if (val->IsString()) { |
9543 String* str = String::cast(val); | 9565 String* str = String::cast(val); |
9544 if (storage) { | 9566 if (storage) { |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10125 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( | 10147 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( |
10126 uint32_t, Object*); | 10148 uint32_t, Object*); |
10127 | 10149 |
10128 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( | 10150 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( |
10129 Object*); | 10151 Object*); |
10130 | 10152 |
10131 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( | 10153 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( |
10132 Object*); | 10154 Object*); |
10133 | 10155 |
10134 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( | 10156 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( |
10135 FixedArray*, PropertyAttributes); | 10157 FixedArray*, |
10158 PropertyAttributes, | |
10159 Dictionary<NumberDictionaryShape, uint32_t>::SortMode); | |
10136 | 10160 |
10137 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( | 10161 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( |
10138 int, JSObject::DeleteMode); | 10162 int, JSObject::DeleteMode); |
10139 | 10163 |
10140 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty( | 10164 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty( |
10141 int, JSObject::DeleteMode); | 10165 int, JSObject::DeleteMode); |
10142 | 10166 |
10143 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( | 10167 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( |
10144 String*); | 10168 String*); |
10145 | 10169 |
10146 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink( | 10170 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink( |
10147 uint32_t); | 10171 uint32_t); |
10148 | 10172 |
10149 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( | 10173 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( |
10150 FixedArray*); | 10174 FixedArray*, |
10175 Dictionary<StringDictionaryShape, String*>::SortMode); | |
10151 | 10176 |
10152 template int | 10177 template int |
10153 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( | 10178 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( |
10154 PropertyAttributes); | 10179 PropertyAttributes); |
10155 | 10180 |
10156 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( | 10181 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( |
10157 String*, Object*, PropertyDetails); | 10182 String*, Object*, PropertyDetails); |
10158 | 10183 |
10159 template MaybeObject* | 10184 template MaybeObject* |
10160 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); | 10185 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); |
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11192 | 11217 |
11193 | 11218 |
11194 template<typename Shape, typename Key> | 11219 template<typename Shape, typename Key> |
11195 int Dictionary<Shape, Key>::NumberOfEnumElements() { | 11220 int Dictionary<Shape, Key>::NumberOfEnumElements() { |
11196 return NumberOfElementsFilterAttributes( | 11221 return NumberOfElementsFilterAttributes( |
11197 static_cast<PropertyAttributes>(DONT_ENUM)); | 11222 static_cast<PropertyAttributes>(DONT_ENUM)); |
11198 } | 11223 } |
11199 | 11224 |
11200 | 11225 |
11201 template<typename Shape, typename Key> | 11226 template<typename Shape, typename Key> |
11202 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage, | 11227 void Dictionary<Shape, Key>::CopyKeysTo( |
11203 PropertyAttributes filter) { | 11228 FixedArray* storage, |
11229 PropertyAttributes filter, | |
11230 Dictionary<Shape, Key>::SortMode sort_mode) { | |
11204 ASSERT(storage->length() >= NumberOfEnumElements()); | 11231 ASSERT(storage->length() >= NumberOfEnumElements()); |
11205 int capacity = HashTable<Shape, Key>::Capacity(); | 11232 int capacity = HashTable<Shape, Key>::Capacity(); |
11206 int index = 0; | 11233 int index = 0; |
11207 for (int i = 0; i < capacity; i++) { | 11234 for (int i = 0; i < capacity; i++) { |
11208 Object* k = HashTable<Shape, Key>::KeyAt(i); | 11235 Object* k = HashTable<Shape, Key>::KeyAt(i); |
11209 if (HashTable<Shape, Key>::IsKey(k)) { | 11236 if (HashTable<Shape, Key>::IsKey(k)) { |
11210 PropertyDetails details = DetailsAt(i); | 11237 PropertyDetails details = DetailsAt(i); |
11211 if (details.IsDeleted()) continue; | 11238 if (details.IsDeleted()) continue; |
11212 PropertyAttributes attr = details.attributes(); | 11239 PropertyAttributes attr = details.attributes(); |
11213 if ((attr & filter) == 0) storage->set(index++, k); | 11240 if ((attr & filter) == 0) storage->set(index++, k); |
11214 } | 11241 } |
11215 } | 11242 } |
11216 storage->SortPairs(storage, index); | 11243 if (sort_mode == Dictionary<Shape, Key>::SORTED) { |
11244 storage->SortPairs(storage, index); | |
11245 } | |
11217 ASSERT(storage->length() >= index); | 11246 ASSERT(storage->length() >= index); |
11218 } | 11247 } |
11219 | 11248 |
11220 | 11249 |
11221 void StringDictionary::CopyEnumKeysTo(FixedArray* storage, | 11250 void StringDictionary::CopyEnumKeysTo(FixedArray* storage, |
11222 FixedArray* sort_array) { | 11251 FixedArray* sort_array) { |
11223 ASSERT(storage->length() >= NumberOfEnumElements()); | 11252 ASSERT(storage->length() >= NumberOfEnumElements()); |
11224 int capacity = Capacity(); | 11253 int capacity = Capacity(); |
11225 int index = 0; | 11254 int index = 0; |
11226 for (int i = 0; i < capacity; i++) { | 11255 for (int i = 0; i < capacity; i++) { |
11227 Object* k = KeyAt(i); | 11256 Object* k = KeyAt(i); |
11228 if (IsKey(k)) { | 11257 if (IsKey(k)) { |
11229 PropertyDetails details = DetailsAt(i); | 11258 PropertyDetails details = DetailsAt(i); |
11230 if (details.IsDeleted() || details.IsDontEnum()) continue; | 11259 if (details.IsDeleted() || details.IsDontEnum()) continue; |
11231 storage->set(index, k); | 11260 storage->set(index, k); |
11232 sort_array->set(index, Smi::FromInt(details.index())); | 11261 sort_array->set(index, Smi::FromInt(details.index())); |
11233 index++; | 11262 index++; |
11234 } | 11263 } |
11235 } | 11264 } |
11236 storage->SortPairs(sort_array, sort_array->length()); | 11265 storage->SortPairs(sort_array, sort_array->length()); |
11237 ASSERT(storage->length() >= index); | 11266 ASSERT(storage->length() >= index); |
11238 } | 11267 } |
11239 | 11268 |
11240 | 11269 |
11241 template<typename Shape, typename Key> | 11270 template<typename Shape, typename Key> |
11242 void Dictionary<Shape, Key>::CopyKeysTo(FixedArray* storage) { | 11271 void Dictionary<Shape, Key>::CopyKeysTo( |
11272 FixedArray* storage, | |
11273 Dictionary<Shape, Key>::SortMode sort_mode) { | |
11243 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( | 11274 ASSERT(storage->length() >= NumberOfElementsFilterAttributes( |
11244 static_cast<PropertyAttributes>(NONE))); | 11275 static_cast<PropertyAttributes>(NONE))); |
11245 int capacity = HashTable<Shape, Key>::Capacity(); | 11276 int capacity = HashTable<Shape, Key>::Capacity(); |
11246 int index = 0; | 11277 int index = 0; |
11247 for (int i = 0; i < capacity; i++) { | 11278 for (int i = 0; i < capacity; i++) { |
11248 Object* k = HashTable<Shape, Key>::KeyAt(i); | 11279 Object* k = HashTable<Shape, Key>::KeyAt(i); |
11249 if (HashTable<Shape, Key>::IsKey(k)) { | 11280 if (HashTable<Shape, Key>::IsKey(k)) { |
11250 PropertyDetails details = DetailsAt(i); | 11281 PropertyDetails details = DetailsAt(i); |
11251 if (details.IsDeleted()) continue; | 11282 if (details.IsDeleted()) continue; |
11252 storage->set(index++, k); | 11283 storage->set(index++, k); |
11253 } | 11284 } |
11254 } | 11285 } |
11286 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | |
11287 storage->SortPairs(storage, index); | |
11288 } | |
11255 ASSERT(storage->length() >= index); | 11289 ASSERT(storage->length() >= index); |
11256 } | 11290 } |
11257 | 11291 |
11258 | 11292 |
11259 // Backwards lookup (slow). | 11293 // Backwards lookup (slow). |
11260 template<typename Shape, typename Key> | 11294 template<typename Shape, typename Key> |
11261 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 11295 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
11262 int capacity = HashTable<Shape, Key>::Capacity(); | 11296 int capacity = HashTable<Shape, Key>::Capacity(); |
11263 for (int i = 0; i < capacity; i++) { | 11297 for (int i = 0; i < capacity; i++) { |
11264 Object* k = HashTable<Shape, Key>::KeyAt(i); | 11298 Object* k = HashTable<Shape, Key>::KeyAt(i); |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11658 if (break_point_objects()->IsUndefined()) return 0; | 11692 if (break_point_objects()->IsUndefined()) return 0; |
11659 // Single beak point. | 11693 // Single beak point. |
11660 if (!break_point_objects()->IsFixedArray()) return 1; | 11694 if (!break_point_objects()->IsFixedArray()) return 1; |
11661 // Multiple break points. | 11695 // Multiple break points. |
11662 return FixedArray::cast(break_point_objects())->length(); | 11696 return FixedArray::cast(break_point_objects())->length(); |
11663 } | 11697 } |
11664 #endif | 11698 #endif |
11665 | 11699 |
11666 | 11700 |
11667 } } // namespace v8::internal | 11701 } } // namespace v8::internal |
OLD | NEW |