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

Side by Side Diff: src/objects.cc

Issue 1242123002: Fix GetOwnPropertyNames on access-checked objects (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Handle empty case Created 5 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
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-object.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <iomanip> 5 #include <iomanip>
6 #include <sstream> 6 #include <sstream>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 if (debug->is_active()) debug->HandleStepIn(setter, false); 460 if (debug->is_active()) debug->HandleStepIn(setter, false);
461 461
462 Handle<Object> argv[] = { value }; 462 Handle<Object> argv[] = { value };
463 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver, 463 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver,
464 arraysize(argv), argv, true), 464 arraysize(argv), argv, true),
465 Object); 465 Object);
466 return value; 466 return value;
467 } 467 }
468 468
469 469
470 static bool FindAllCanReadHolder(LookupIterator* it) { 470 // static
471 bool JSObject::AllCanRead(LookupIterator* it) {
471 // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of 472 // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
472 // which have already been checked. 473 // which have already been checked.
473 DCHECK(it->state() == LookupIterator::ACCESS_CHECK || 474 DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
474 it->state() == LookupIterator::INTERCEPTOR); 475 it->state() == LookupIterator::INTERCEPTOR);
475 for (it->Next(); it->IsFound(); it->Next()) { 476 for (it->Next(); it->IsFound(); it->Next()) {
476 if (it->state() == LookupIterator::ACCESSOR) { 477 if (it->state() == LookupIterator::ACCESSOR) {
477 auto accessors = it->GetAccessors(); 478 auto accessors = it->GetAccessors();
478 if (accessors->IsAccessorInfo()) { 479 if (accessors->IsAccessorInfo()) {
479 if (AccessorInfo::cast(*accessors)->all_can_read()) return true; 480 if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
480 } 481 }
481 } else if (it->state() == LookupIterator::INTERCEPTOR) { 482 } else if (it->state() == LookupIterator::INTERCEPTOR) {
482 if (it->GetInterceptor()->all_can_read()) return true; 483 if (it->GetInterceptor()->all_can_read()) return true;
483 } 484 }
484 } 485 }
485 return false; 486 return false;
486 } 487 }
487 488
488 489
489 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( 490 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
490 LookupIterator* it) { 491 LookupIterator* it) {
491 Handle<JSObject> checked = it->GetHolder<JSObject>(); 492 Handle<JSObject> checked = it->GetHolder<JSObject>();
492 while (FindAllCanReadHolder(it)) { 493 while (AllCanRead(it)) {
493 if (it->state() == LookupIterator::ACCESSOR) { 494 if (it->state() == LookupIterator::ACCESSOR) {
494 return GetPropertyWithAccessor(it, SLOPPY); 495 return GetPropertyWithAccessor(it, SLOPPY);
495 } 496 }
496 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); 497 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
497 bool done; 498 bool done;
498 Handle<Object> result; 499 Handle<Object> result;
499 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), result, 500 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), result,
500 GetPropertyWithInterceptor(it, &done), Object); 501 GetPropertyWithInterceptor(it, &done), Object);
501 if (done) return result; 502 if (done) return result;
502 } 503 }
503 it->isolate()->ReportFailedAccessCheck(checked); 504 it->isolate()->ReportFailedAccessCheck(checked);
504 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 505 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
505 return it->factory()->undefined_value(); 506 return it->factory()->undefined_value();
506 } 507 }
507 508
508 509
509 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck( 510 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
510 LookupIterator* it) { 511 LookupIterator* it) {
511 Handle<JSObject> checked = it->GetHolder<JSObject>(); 512 Handle<JSObject> checked = it->GetHolder<JSObject>();
512 while (FindAllCanReadHolder(it)) { 513 while (AllCanRead(it)) {
513 if (it->state() == LookupIterator::ACCESSOR) { 514 if (it->state() == LookupIterator::ACCESSOR) {
514 return Just(it->property_details().attributes()); 515 return Just(it->property_details().attributes());
515 } 516 }
516 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); 517 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
517 auto result = GetPropertyAttributesWithInterceptor(it); 518 auto result = GetPropertyAttributesWithInterceptor(it);
518 if (it->isolate()->has_scheduled_exception()) break; 519 if (it->isolate()->has_scheduled_exception()) break;
519 if (result.IsJust() && result.FromJust() != ABSENT) return result; 520 if (result.IsJust() && result.FromJust() != ABSENT) return result;
520 } 521 }
521 it->isolate()->ReportFailedAccessCheck(checked); 522 it->isolate()->ReportFailedAccessCheck(checked);
522 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), 523 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(),
523 Nothing<PropertyAttributes>()); 524 Nothing<PropertyAttributes>());
524 return Just(ABSENT); 525 return Just(ABSENT);
525 } 526 }
526 527
527 528
528 static bool FindAllCanWriteHolder(LookupIterator* it) { 529 // static
530 bool JSObject::AllCanWrite(LookupIterator* it) {
529 for (; it->IsFound(); it->Next()) { 531 for (; it->IsFound(); it->Next()) {
530 if (it->state() == LookupIterator::ACCESSOR) { 532 if (it->state() == LookupIterator::ACCESSOR) {
531 Handle<Object> accessors = it->GetAccessors(); 533 Handle<Object> accessors = it->GetAccessors();
532 if (accessors->IsAccessorInfo()) { 534 if (accessors->IsAccessorInfo()) {
533 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; 535 if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
534 } 536 }
535 } 537 }
536 } 538 }
537 return false; 539 return false;
538 } 540 }
539 541
540 542
541 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( 543 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
542 LookupIterator* it, Handle<Object> value) { 544 LookupIterator* it, Handle<Object> value) {
543 Handle<JSObject> checked = it->GetHolder<JSObject>(); 545 Handle<JSObject> checked = it->GetHolder<JSObject>();
544 if (FindAllCanWriteHolder(it)) { 546 if (AllCanWrite(it)) {
545 // The supplied language-mode is ignored by SetPropertyWithAccessor. 547 // The supplied language-mode is ignored by SetPropertyWithAccessor.
546 return SetPropertyWithAccessor(it, value, SLOPPY); 548 return SetPropertyWithAccessor(it, value, SLOPPY);
547 } 549 }
548 550
549 it->isolate()->ReportFailedAccessCheck(checked); 551 it->isolate()->ReportFailedAccessCheck(checked);
550 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 552 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
551 return value; 553 return value;
552 } 554 }
553 555
554 556
(...skipping 12327 matching lines...) Expand 10 before | Expand all | Expand 10 after
12882 } else { 12884 } else {
12883 HeapSortPairs(this, numbers, len); 12885 HeapSortPairs(this, numbers, len);
12884 return; 12886 return;
12885 } 12887 }
12886 } 12888 }
12887 12889
12888 12890
12889 // Fill in the names of own properties into the supplied storage. The main 12891 // Fill in the names of own properties into the supplied storage. The main
12890 // purpose of this function is to provide reflection information for the object 12892 // purpose of this function is to provide reflection information for the object
12891 // mirrors. 12893 // mirrors.
12892 void JSObject::GetOwnPropertyNames( 12894 int JSObject::GetOwnPropertyNames(FixedArray* storage, int index,
12893 FixedArray* storage, int index, PropertyAttributes filter) { 12895 PropertyAttributes filter) {
12894 DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index)); 12896 DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index));
12895 if (HasFastProperties()) { 12897 if (HasFastProperties()) {
12898 int start_index = index;
12896 int real_size = map()->NumberOfOwnDescriptors(); 12899 int real_size = map()->NumberOfOwnDescriptors();
12897 DescriptorArray* descs = map()->instance_descriptors(); 12900 DescriptorArray* descs = map()->instance_descriptors();
12898 for (int i = 0; i < real_size; i++) { 12901 for (int i = 0; i < real_size; i++) {
12899 if ((descs->GetDetails(i).attributes() & filter) == 0 && 12902 if ((descs->GetDetails(i).attributes() & filter) == 0 &&
12900 !FilterKey(descs->GetKey(i), filter)) { 12903 !FilterKey(descs->GetKey(i), filter)) {
12901 storage->set(index++, descs->GetKey(i)); 12904 storage->set(index++, descs->GetKey(i));
12902 } 12905 }
12903 } 12906 }
12907 return index - start_index;
12904 } else if (IsGlobalObject()) { 12908 } else if (IsGlobalObject()) {
12905 global_dictionary()->CopyKeysTo(storage, index, filter, 12909 return global_dictionary()->CopyKeysTo(storage, index, filter,
12906 GlobalDictionary::UNSORTED); 12910 GlobalDictionary::UNSORTED);
12907 } else { 12911 } else {
12908 property_dictionary()->CopyKeysTo(storage, index, filter, 12912 return property_dictionary()->CopyKeysTo(storage, index, filter,
12909 NameDictionary::UNSORTED); 12913 NameDictionary::UNSORTED);
12910 } 12914 }
12911 } 12915 }
12912 12916
12913 12917
12914 int JSObject::NumberOfOwnElements(PropertyAttributes filter) { 12918 int JSObject::NumberOfOwnElements(PropertyAttributes filter) {
12915 return GetOwnElementKeys(NULL, filter); 12919 return GetOwnElementKeys(NULL, filter);
12916 } 12920 }
12917 12921
12918 12922
12919 int JSObject::NumberOfEnumElements() { 12923 int JSObject::NumberOfEnumElements() {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
12999 storage->set(counter, Smi::FromInt(counter)); 13003 storage->set(counter, Smi::FromInt(counter));
13000 } 13004 }
13001 counter++; 13005 counter++;
13002 } 13006 }
13003 DCHECK(!storage || storage->length() >= counter); 13007 DCHECK(!storage || storage->length() >= counter);
13004 break; 13008 break;
13005 } 13009 }
13006 13010
13007 case DICTIONARY_ELEMENTS: { 13011 case DICTIONARY_ELEMENTS: {
13008 if (storage != NULL) { 13012 if (storage != NULL) {
13009 element_dictionary()->CopyKeysTo(storage, filter, 13013 element_dictionary()->CopyKeysTo(storage, 0, filter,
13010 SeededNumberDictionary::SORTED); 13014 SeededNumberDictionary::SORTED);
13011 } 13015 }
13012 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); 13016 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
13013 break; 13017 break;
13014 } 13018 }
13015 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 13019 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
13016 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: { 13020 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
13017 FixedArray* parameter_map = FixedArray::cast(elements()); 13021 FixedArray* parameter_map = FixedArray::cast(elements());
13018 int mapped_length = parameter_map->length() - 2; 13022 int mapped_length = parameter_map->length() - 2;
13019 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 13023 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
13020 if (arguments->IsDictionary()) { 13024 if (arguments->IsDictionary()) {
13021 // Copy the keys from arguments first, because Dictionary::CopyKeysTo 13025 // Copy the keys from arguments first, because Dictionary::CopyKeysTo
13022 // will insert in storage starting at index 0. 13026 // will insert in storage starting at index 0.
13023 SeededNumberDictionary* dictionary = 13027 SeededNumberDictionary* dictionary =
13024 SeededNumberDictionary::cast(arguments); 13028 SeededNumberDictionary::cast(arguments);
13025 if (storage != NULL) { 13029 if (storage != NULL) {
13026 dictionary->CopyKeysTo(storage, filter, 13030 dictionary->CopyKeysTo(storage, 0, filter,
13027 SeededNumberDictionary::UNSORTED); 13031 SeededNumberDictionary::UNSORTED);
13028 } 13032 }
13029 counter += dictionary->NumberOfElementsFilterAttributes(filter); 13033 counter += dictionary->NumberOfElementsFilterAttributes(filter);
13030 for (int i = 0; i < mapped_length; ++i) { 13034 for (int i = 0; i < mapped_length; ++i) {
13031 if (!parameter_map->get(i + 2)->IsTheHole()) { 13035 if (!parameter_map->get(i + 2)->IsTheHole()) {
13032 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); 13036 if (storage != NULL) storage->set(counter, Smi::FromInt(i));
13033 ++counter; 13037 ++counter;
13034 } 13038 }
13035 } 13039 }
13036 if (storage != NULL) storage->SortPairs(storage, counter); 13040 if (storage != NULL) storage->SortPairs(storage, counter);
(...skipping 1709 matching lines...) Expand 10 before | Expand all | Expand 10 after
14746 PropertyDetails details = this->DetailsAt(i); 14750 PropertyDetails details = this->DetailsAt(i);
14747 if (details.type() == ACCESSOR_CONSTANT) return true; 14751 if (details.type() == ACCESSOR_CONSTANT) return true;
14748 PropertyAttributes attr = details.attributes(); 14752 PropertyAttributes attr = details.attributes();
14749 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; 14753 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true;
14750 } 14754 }
14751 } 14755 }
14752 return false; 14756 return false;
14753 } 14757 }
14754 14758
14755 14759
14756 template <typename Derived, typename Shape, typename Key>
14757 void Dictionary<Derived, Shape, Key>::CopyKeysTo(
14758 FixedArray* storage, PropertyAttributes filter,
14759 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
14760 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
14761 int capacity = this->Capacity();
14762 int index = 0;
14763 for (int i = 0; i < capacity; i++) {
14764 Object* k = this->KeyAt(i);
14765 if (this->IsKey(k) && !FilterKey(k, filter)) {
14766 if (this->IsDeleted(i)) continue;
14767 PropertyDetails details = this->DetailsAt(i);
14768 PropertyAttributes attr = details.attributes();
14769 if ((attr & filter) == 0) storage->set(index++, k);
14770 }
14771 }
14772 if (sort_mode == Dictionary::SORTED) {
14773 storage->SortPairs(storage, index);
14774 }
14775 DCHECK(storage->length() >= index);
14776 }
14777
14778
14779 template <typename Dictionary> 14760 template <typename Dictionary>
14780 struct EnumIndexComparator { 14761 struct EnumIndexComparator {
14781 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} 14762 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {}
14782 bool operator() (Smi* a, Smi* b) { 14763 bool operator() (Smi* a, Smi* b) {
14783 PropertyDetails da(dict->DetailsAt(a->value())); 14764 PropertyDetails da(dict->DetailsAt(a->value()));
14784 PropertyDetails db(dict->DetailsAt(b->value())); 14765 PropertyDetails db(dict->DetailsAt(b->value()));
14785 return da.dictionary_index() < db.dictionary_index(); 14766 return da.dictionary_index() < db.dictionary_index();
14786 } 14767 }
14787 Dictionary* dict; 14768 Dictionary* dict;
14788 }; 14769 };
(...skipping 19 matching lines...) Expand all
14808 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); 14789 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
14809 std::sort(start, start + length, cmp); 14790 std::sort(start, start + length, cmp);
14810 for (int i = 0; i < length; i++) { 14791 for (int i = 0; i < length; i++) {
14811 int index = Smi::cast(storage->get(i))->value(); 14792 int index = Smi::cast(storage->get(i))->value();
14812 storage->set(i, this->KeyAt(index)); 14793 storage->set(i, this->KeyAt(index));
14813 } 14794 }
14814 } 14795 }
14815 14796
14816 14797
14817 template <typename Derived, typename Shape, typename Key> 14798 template <typename Derived, typename Shape, typename Key>
14818 void Dictionary<Derived, Shape, Key>::CopyKeysTo( 14799 int Dictionary<Derived, Shape, Key>::CopyKeysTo(
14819 FixedArray* storage, int index, PropertyAttributes filter, 14800 FixedArray* storage, int index, PropertyAttributes filter,
14820 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { 14801 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
14821 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); 14802 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
14803 int start_index = index;
14822 int capacity = this->Capacity(); 14804 int capacity = this->Capacity();
14823 for (int i = 0; i < capacity; i++) { 14805 for (int i = 0; i < capacity; i++) {
14824 Object* k = this->KeyAt(i); 14806 Object* k = this->KeyAt(i);
14825 if (this->IsKey(k) && !FilterKey(k, filter)) { 14807 if (this->IsKey(k) && !FilterKey(k, filter)) {
14826 if (this->IsDeleted(i)) continue; 14808 if (this->IsDeleted(i)) continue;
14827 PropertyDetails details = this->DetailsAt(i); 14809 PropertyDetails details = this->DetailsAt(i);
14828 PropertyAttributes attr = details.attributes(); 14810 PropertyAttributes attr = details.attributes();
14829 if ((attr & filter) == 0) storage->set(index++, k); 14811 if ((attr & filter) == 0) storage->set(index++, k);
14830 } 14812 }
14831 } 14813 }
14832 if (sort_mode == Dictionary::SORTED) { 14814 if (sort_mode == Dictionary::SORTED) {
14833 storage->SortPairs(storage, index); 14815 storage->SortPairs(storage, index);
14834 } 14816 }
14835 DCHECK(storage->length() >= index); 14817 DCHECK(storage->length() >= index);
14818 return index - start_index;
14836 } 14819 }
14837 14820
14838 14821
14839 // Backwards lookup (slow). 14822 // Backwards lookup (slow).
14840 template<typename Derived, typename Shape, typename Key> 14823 template<typename Derived, typename Shape, typename Key>
14841 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { 14824 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
14842 int capacity = this->Capacity(); 14825 int capacity = this->Capacity();
14843 for (int i = 0; i < capacity; i++) { 14826 for (int i = 0; i < capacity; i++) {
14844 Object* k = this->KeyAt(i); 14827 Object* k = this->KeyAt(i);
14845 if (this->IsKey(k)) { 14828 if (this->IsKey(k)) {
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
15898 Handle<Object> new_value) { 15881 Handle<Object> new_value) {
15899 if (cell->value() != *new_value) { 15882 if (cell->value() != *new_value) {
15900 cell->set_value(*new_value); 15883 cell->set_value(*new_value);
15901 Isolate* isolate = cell->GetIsolate(); 15884 Isolate* isolate = cell->GetIsolate();
15902 cell->dependent_code()->DeoptimizeDependentCodeGroup( 15885 cell->dependent_code()->DeoptimizeDependentCodeGroup(
15903 isolate, DependentCode::kPropertyCellChangedGroup); 15886 isolate, DependentCode::kPropertyCellChangedGroup);
15904 } 15887 }
15905 } 15888 }
15906 } // namespace internal 15889 } // namespace internal
15907 } // namespace v8 15890 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698