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

Side by Side Diff: src/objects.cc

Issue 7278033: Fix a bug in for/in iteration of arguments objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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') | test/mjsunit/regress/regress-1531.js » ('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 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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/regress/regress-1531.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698