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

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: rebase 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
« no previous file with comments | « src/objects.h ('k') | test/cctest/test-field-type-tracking.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 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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/cctest/test-field-type-tracking.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698