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