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 8265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8276 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); | 8276 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); |
8277 // Ignore accessors on typed arrays. | 8277 // Ignore accessors on typed arrays. |
8278 if (it->IsElement() && object->HasFixedTypedArrayElements()) { | 8278 if (it->IsElement() && object->HasFixedTypedArrayElements()) { |
8279 return it->factory()->undefined_value(); | 8279 return it->factory()->undefined_value(); |
8280 } | 8280 } |
8281 | 8281 |
8282 DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull() || | 8282 DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull() || |
8283 getter->IsFunctionTemplateInfo()); | 8283 getter->IsFunctionTemplateInfo()); |
8284 DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull() || | 8284 DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull() || |
8285 getter->IsFunctionTemplateInfo()); | 8285 getter->IsFunctionTemplateInfo()); |
8286 // At least one of the accessors needs to be a new value. | 8286 it->TransitionToAccessorProperty(getter, setter, attributes); |
8287 DCHECK(!getter->IsNull() || !setter->IsNull()); | |
8288 if (!getter->IsNull()) { | |
8289 it->TransitionToAccessorProperty(ACCESSOR_GETTER, getter, attributes); | |
8290 } | |
8291 if (!setter->IsNull()) { | |
8292 it->TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); | |
8293 } | |
8294 | 8287 |
8295 return isolate->factory()->undefined_value(); | 8288 return isolate->factory()->undefined_value(); |
8296 } | 8289 } |
8297 | 8290 |
8298 | 8291 |
8299 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, | 8292 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, |
8300 Handle<AccessorInfo> info) { | 8293 Handle<AccessorInfo> info) { |
8301 Isolate* isolate = object->GetIsolate(); | 8294 Isolate* isolate = object->GetIsolate(); |
8302 Handle<Name> name(Name::cast(info->name()), isolate); | 8295 Handle<Name> name(Name::cast(info->name()), isolate); |
8303 | 8296 |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9081 map->PrintReconfiguration(stdout, descriptor, kind, attributes); | 9074 map->PrintReconfiguration(stdout, descriptor, kind, attributes); |
9082 } | 9075 } |
9083 | 9076 |
9084 Isolate* isolate = map->GetIsolate(); | 9077 Isolate* isolate = map->GetIsolate(); |
9085 Handle<Map> new_map = ReconfigureProperty( | 9078 Handle<Map> new_map = ReconfigureProperty( |
9086 map, descriptor, kind, attributes, Representation::None(), | 9079 map, descriptor, kind, attributes, Representation::None(), |
9087 FieldType::None(isolate), FORCE_FIELD); | 9080 FieldType::None(isolate), FORCE_FIELD); |
9088 return new_map; | 9081 return new_map; |
9089 } | 9082 } |
9090 | 9083 |
9091 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 9084 Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map, |
9092 Handle<Name> name, int descriptor, | 9085 Handle<Name> name, int descriptor, |
9093 AccessorComponent component, | 9086 Handle<Object> getter, |
9094 Handle<Object> accessor, | 9087 Handle<Object> setter, |
9095 PropertyAttributes attributes) { | 9088 PropertyAttributes attributes) { |
| 9089 // At least one of the accessors needs to be a new value. |
| 9090 DCHECK(!getter->IsNull() || !setter->IsNull()); |
9096 DCHECK(name->IsUniqueName()); | 9091 DCHECK(name->IsUniqueName()); |
9097 Isolate* isolate = name->GetIsolate(); | |
9098 | 9092 |
9099 // Dictionary maps can always have additional data properties. | 9093 // Dictionary maps can always have additional data properties. |
9100 if (map->is_dictionary_map()) return map; | 9094 if (map->is_dictionary_map()) return map; |
9101 | 9095 |
9102 // Migrate to the newest map before transitioning to the new property. | 9096 // Migrate to the newest map before transitioning to the new property. |
9103 map = Update(map); | 9097 map = Update(map); |
9104 | 9098 |
9105 PropertyNormalizationMode mode = map->is_prototype_map() | 9099 PropertyNormalizationMode mode = map->is_prototype_map() |
9106 ? KEEP_INOBJECT_PROPERTIES | 9100 ? KEEP_INOBJECT_PROPERTIES |
9107 : CLEAR_INOBJECT_PROPERTIES; | 9101 : CLEAR_INOBJECT_PROPERTIES; |
9108 | 9102 |
9109 Map* maybe_transition = | 9103 Map* maybe_transition = |
9110 TransitionArray::SearchTransition(*map, kAccessor, *name, attributes); | 9104 TransitionArray::SearchTransition(*map, kAccessor, *name, attributes); |
9111 if (maybe_transition != NULL) { | 9105 if (maybe_transition != NULL) { |
9112 Handle<Map> transition(maybe_transition, isolate); | 9106 Handle<Map> transition(maybe_transition, isolate); |
9113 DescriptorArray* descriptors = transition->instance_descriptors(); | 9107 DescriptorArray* descriptors = transition->instance_descriptors(); |
9114 int descriptor = transition->LastAdded(); | 9108 int descriptor = transition->LastAdded(); |
9115 DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); | 9109 DCHECK(descriptors->GetKey(descriptor)->Equals(*name)); |
9116 | 9110 |
9117 DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind()); | 9111 DCHECK_EQ(kAccessor, descriptors->GetDetails(descriptor).kind()); |
9118 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); | 9112 DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes()); |
9119 | 9113 |
9120 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); | 9114 Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate); |
9121 if (!maybe_pair->IsAccessorPair()) { | 9115 if (!maybe_pair->IsAccessorPair()) { |
9122 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair"); | 9116 return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair"); |
9123 } | 9117 } |
9124 | 9118 |
9125 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); | 9119 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair); |
9126 if (pair->get(component) != *accessor) { | 9120 if (!pair->Equals(*getter, *setter)) { |
9127 return Map::Normalize(map, mode, "TransitionToDifferentAccessor"); | 9121 return Map::Normalize(map, mode, "TransitionToDifferentAccessor"); |
9128 } | 9122 } |
9129 | 9123 |
9130 return transition; | 9124 return transition; |
9131 } | 9125 } |
9132 | 9126 |
9133 Handle<AccessorPair> pair; | 9127 Handle<AccessorPair> pair; |
9134 DescriptorArray* old_descriptors = map->instance_descriptors(); | 9128 DescriptorArray* old_descriptors = map->instance_descriptors(); |
9135 if (descriptor != DescriptorArray::kNotFound) { | 9129 if (descriptor != DescriptorArray::kNotFound) { |
9136 if (descriptor != map->LastAdded()) { | 9130 if (descriptor != map->LastAdded()) { |
9137 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); | 9131 return Map::Normalize(map, mode, "AccessorsOverwritingNonLast"); |
9138 } | 9132 } |
9139 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); | 9133 PropertyDetails old_details = old_descriptors->GetDetails(descriptor); |
9140 if (old_details.type() != ACCESSOR_CONSTANT) { | 9134 if (old_details.type() != ACCESSOR_CONSTANT) { |
9141 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); | 9135 return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors"); |
9142 } | 9136 } |
9143 | 9137 |
9144 if (old_details.attributes() != attributes) { | 9138 if (old_details.attributes() != attributes) { |
9145 return Map::Normalize(map, mode, "AccessorsWithAttributes"); | 9139 return Map::Normalize(map, mode, "AccessorsWithAttributes"); |
9146 } | 9140 } |
9147 | 9141 |
9148 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); | 9142 Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate); |
9149 if (!maybe_pair->IsAccessorPair()) { | 9143 if (!maybe_pair->IsAccessorPair()) { |
9150 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); | 9144 return Map::Normalize(map, mode, "AccessorsOverwritingNonPair"); |
9151 } | 9145 } |
9152 | 9146 |
9153 Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component); | 9147 Handle<AccessorPair> current_pair = Handle<AccessorPair>::cast(maybe_pair); |
9154 if (current == *accessor) return map; | 9148 if (current_pair->Equals(*getter, *setter)) return map; |
9155 | 9149 |
9156 if (!current->IsNull()) { | 9150 bool overwriting_accessor = false; |
| 9151 if (!getter->IsNull() && !current_pair->get(ACCESSOR_GETTER)->IsNull() && |
| 9152 current_pair->get(ACCESSOR_GETTER) != *getter) { |
| 9153 overwriting_accessor = true; |
| 9154 } |
| 9155 if (!setter->IsNull() && !current_pair->get(ACCESSOR_SETTER)->IsNull() && |
| 9156 current_pair->get(ACCESSOR_SETTER) != *setter) { |
| 9157 overwriting_accessor = true; |
| 9158 } |
| 9159 if (overwriting_accessor) { |
9157 return Map::Normalize(map, mode, "AccessorsOverwritingAccessors"); | 9160 return Map::Normalize(map, mode, "AccessorsOverwritingAccessors"); |
9158 } | 9161 } |
9159 | 9162 |
9160 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair)); | 9163 pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair)); |
9161 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || | 9164 } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors || |
9162 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { | 9165 map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) { |
9163 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); | 9166 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors"); |
9164 } else { | 9167 } else { |
9165 pair = isolate->factory()->NewAccessorPair(); | 9168 pair = isolate->factory()->NewAccessorPair(); |
9166 } | 9169 } |
9167 | 9170 |
9168 pair->set(component, *accessor); | 9171 pair->SetComponents(*getter, *setter); |
| 9172 |
9169 TransitionFlag flag = INSERT_TRANSITION; | 9173 TransitionFlag flag = INSERT_TRANSITION; |
9170 AccessorConstantDescriptor new_desc(name, pair, attributes); | 9174 AccessorConstantDescriptor new_desc(name, pair, attributes); |
9171 return Map::CopyInsertDescriptor(map, &new_desc, flag); | 9175 return Map::CopyInsertDescriptor(map, &new_desc, flag); |
9172 } | 9176 } |
9173 | 9177 |
9174 | 9178 |
9175 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, | 9179 Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
9176 Descriptor* descriptor, | 9180 Descriptor* descriptor, |
9177 TransitionFlag flag) { | 9181 TransitionFlag flag) { |
9178 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 9182 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
(...skipping 9073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18252 if (cell->value() != *new_value) { | 18256 if (cell->value() != *new_value) { |
18253 cell->set_value(*new_value); | 18257 cell->set_value(*new_value); |
18254 Isolate* isolate = cell->GetIsolate(); | 18258 Isolate* isolate = cell->GetIsolate(); |
18255 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18259 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18256 isolate, DependentCode::kPropertyCellChangedGroup); | 18260 isolate, DependentCode::kPropertyCellChangedGroup); |
18257 } | 18261 } |
18258 } | 18262 } |
18259 | 18263 |
18260 } // namespace internal | 18264 } // namespace internal |
18261 } // namespace v8 | 18265 } // namespace v8 |
OLD | NEW |