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

Side by Side Diff: src/objects.cc

Issue 1943303002: Make it possible to set a getter and a setter at the same time (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 8839 matching lines...) Expand 10 before | Expand all | Expand 10 after
8850 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); 8850 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
8851 // Ignore accessors on typed arrays. 8851 // Ignore accessors on typed arrays.
8852 if (it->IsElement() && object->HasFixedTypedArrayElements()) { 8852 if (it->IsElement() && object->HasFixedTypedArrayElements()) {
8853 return it->factory()->undefined_value(); 8853 return it->factory()->undefined_value();
8854 } 8854 }
8855 8855
8856 DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull() || 8856 DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull() ||
8857 getter->IsFunctionTemplateInfo()); 8857 getter->IsFunctionTemplateInfo());
8858 DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull() || 8858 DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull() ||
8859 getter->IsFunctionTemplateInfo()); 8859 getter->IsFunctionTemplateInfo());
8860 // At least one of the accessors needs to be a new value. 8860 it->TransitionToAccessorProperty(getter, setter, attributes);
8861 DCHECK(!getter->IsNull() || !setter->IsNull());
8862 if (!getter->IsNull()) {
8863 it->TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes);
8864 }
8865 if (!setter->IsNull()) {
8866 it->TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes);
8867 }
8868 8861
8869 return isolate->factory()->undefined_value(); 8862 return isolate->factory()->undefined_value();
8870 } 8863 }
8871 8864
8872 8865
8873 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, 8866 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
8874 Handle<AccessorInfo> info) { 8867 Handle<AccessorInfo> info) {
8875 Isolate* isolate = object->GetIsolate(); 8868 Isolate* isolate = object->GetIsolate();
8876 Handle<Name> name(Name::cast(info->name()), isolate); 8869 Handle<Name> name(Name::cast(info->name()), isolate);
8877 8870
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
9655 map->PrintReconfiguration(stdout, descriptor, kind, attributes); 9648 map->PrintReconfiguration(stdout, descriptor, kind, attributes);
9656 } 9649 }
9657 9650
9658 Isolate* isolate = map->GetIsolate(); 9651 Isolate* isolate = map->GetIsolate();
9659 Handle<Map> new_map = ReconfigureProperty( 9652 Handle<Map> new_map = ReconfigureProperty(
9660 map, descriptor, kind, attributes, Representation::None(), 9653 map, descriptor, kind, attributes, Representation::None(),
9661 FieldType::None(isolate), FORCE_FIELD); 9654 FieldType::None(isolate), FORCE_FIELD);
9662 return new_map; 9655 return new_map;
9663 } 9656 }
9664 9657
9665 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, 9658 Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
9666 Handle<Name> name, int descriptor, 9659 Handle<Name> name, int descriptor,
9667 AccessorComponent component, 9660 Handle<Object> getter,
9668 Handle<Object> accessor, 9661 Handle<Object> setter,
9669 PropertyAttributes attributes) { 9662 PropertyAttributes attributes) {
9663 // At least one of the accessors needs to be a new value.
9664 DCHECK(!getter->IsNull() || !setter->IsNull());
9670 DCHECK(name->IsUniqueName()); 9665 DCHECK(name->IsUniqueName());
9671 Isolate* isolate = name->GetIsolate();
9672 9666
9673 // Dictionary maps can always have additional data properties. 9667 // Dictionary maps can always have additional data properties.
9674 if (map->is_dictionary_map()) return map; 9668 if (map->is_dictionary_map()) return map;
9675 9669
9676 // Migrate to the newest map before transitioning to the new property. 9670 // Migrate to the newest map before transitioning to the new property.
9677 map = Update(map); 9671 map = Update(map);
9678 9672
9679 PropertyNormalizationMode mode = map->is_prototype_map() 9673 PropertyNormalizationMode mode = map->is_prototype_map()
9680 ? KEEP_INOBJECT_PROPERTIES 9674 ? KEEP_INOBJECT_PROPERTIES
9681 : CLEAR_INOBJECT_PROPERTIES; 9675 : CLEAR_INOBJECT_PROPERTIES;
9682 9676
9683 Map* maybe_transition = 9677 Map* maybe_transition =
9684 TransitionArray::SearchTransition(*map, kAccessor, *name, attributes); 9678 TransitionArray::SearchTransition(*map, kAccessor, *name, attributes);
9685 if (maybe_transition != NULL) { 9679 if (maybe_transition != NULL) {
9686 Handle<Map> transition(maybe_transition, isolate); 9680 Handle<Map> transition(maybe_transition, isolate);
9687 DescriptorArray* descriptors = transition->instance_descriptors(); 9681 DescriptorArray* descriptors = transition->instance_descriptors();
9688 int descriptor = transition->LastAdded(); 9682 int descriptor = transition->LastAdded();
9689 DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); 9683 DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
9690 9684
9691 DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind()); 9685 DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind());
9692 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); 9686 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
9693 9687
9694 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); 9688 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
9695 if (!maybe_pair->IsAccessorPair()) { 9689 if (!maybe_pair->IsAccessorPair()) {
9696 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair"); 9690 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
9697 } 9691 }
9698 9692
9699 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); 9693 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
9700 if (pair->get(component) != *accessor) { 9694 if (!pair->Equals(*getter, *setter)) {
9701 return Map::Normalize(map, mode, "TransitionToDifferentAccessor"); 9695 return Map::Normalize(map, mode, "TransitionToDifferentAccessor");
9702 } 9696 }
9703 9697
9704 return transition; 9698 return transition;
9705 } 9699 }
9706 9700
9707 Handle<AccessorPair> pair; 9701 Handle<AccessorPair> pair;
9708 DescriptorArray* old_descriptors = map->instance_descriptors(); 9702 DescriptorArray* old_descriptors = map->instance_descriptors();
9709 if (descriptor != DescriptorArray::kNotFound) { 9703 if (descriptor != DescriptorArray::kNotFound) {
9710 if (descriptor != map->LastAdded()) { 9704 if (descriptor != map->LastAdded()) {
9711 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); 9705 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast");
9712 } 9706 }
9713 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); 9707 PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
9714 if (old_details.type() != ACCESSOR_CONSTANT) { 9708 if (old_details.type() != ACCESSOR_CONSTANT) {
9715 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); 9709 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors");
9716 } 9710 }
9717 9711
9718 if (old_details.attributes() != attributes) { 9712 if (old_details.attributes() != attributes) {
9719 return Map::Normalize(map, mode, "AccessorsWithAttributes"); 9713 return Map::Normalize(map, mode, "AccessorsWithAttributes");
9720 } 9714 }
9721 9715
9722 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); 9716 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
9723 if (!maybe_pair->IsAccessorPair()) { 9717 if (!maybe_pair->IsAccessorPair()) {
9724 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); 9718 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair");
9725 } 9719 }
9726 9720
9727 Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component); 9721 Handle<AccessorPair> current_pair = Handle<AccessorPair>::cast(maybe_pair);
9728 if (current == *accessor) return map; 9722 if (current_pair->Equals(*getter, *setter)) return map;
9729 9723
9730 if (!current->IsTheHole()) { 9724 bool overwriting_accessor = false;
9725 if (!getter->IsNull() && !current_pair->get(ACCESSOR_GETTER)->IsTheHole() &&
Toon Verwaest 2016/05/04 09:32:42 What about just unifying the accessor-missing sent
9726 current_pair->get(ACCESSOR_GETTER) != *getter) {
9727 overwriting_accessor = true;
9728 }
9729 if (!setter->IsNull() && !current_pair->get(ACCESSOR_SETTER)->IsTheHole() &&
9730 current_pair->get(ACCESSOR_SETTER) != *setter) {
9731 overwriting_accessor = true;
9732 }
9733 if (overwriting_accessor) {
9731 return Map::Normalize(map, mode, "AccessorsOverwritingAccessors"); 9734 return Map::Normalize(map, mode, "AccessorsOverwritingAccessors");
9732 } 9735 }
9733 9736
9734 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair)); 9737 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair));
9735 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || 9738 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
9736 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { 9739 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) {
9737 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); 9740 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors");
9738 } else { 9741 } else {
9739 pair = isolate->factory()->NewAccessorPair(); 9742 pair = isolate->factory()->NewAccessorPair();
9740 } 9743 }
9741 9744
9742 pair->set(component, *accessor); 9745 pair->SetComponents(*getter, *setter);
Toon Verwaest 2016/05/04 09:32:42 Unless you do the above, this probably will alread
9746
9743 TransitionFlag flag = INSERT_TRANSITION; 9747 TransitionFlag flag = INSERT_TRANSITION;
9744 AccessorConstantDescriptor new_desc(name, pair, attributes); 9748 AccessorConstantDescriptor new_desc(name, pair, attributes);
9745 return Map::CopyInsertDescriptor(map, &new_desc, flag); 9749 return Map::CopyInsertDescriptor(map, &new_desc, flag);
9746 } 9750 }
9747 9751
9748 9752
9749 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, 9753 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
9750 Descriptor* descriptor, 9754 Descriptor* descriptor,
9751 TransitionFlag flag) { 9755 TransitionFlag flag) {
9752 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 9756 Handle<DescriptorArray> descriptors(map->instance_descriptors());
(...skipping 9079 matching lines...) Expand 10 before | Expand all | Expand 10 after
18832 if (cell->value() != *new_value) { 18836 if (cell->value() != *new_value) {
18833 cell->set_value(*new_value); 18837 cell->set_value(*new_value);
18834 Isolate* isolate = cell->GetIsolate(); 18838 Isolate* isolate = cell->GetIsolate();
18835 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18839 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18836 isolate, DependentCode::kPropertyCellChangedGroup); 18840 isolate, DependentCode::kPropertyCellChangedGroup);
18837 } 18841 }
18838 } 18842 }
18839 18843
18840 } // namespace internal 18844 } // namespace internal
18841 } // namespace v8 18845 } // namespace v8
OLDNEW
« src/lookup.cc ('K') | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698