OLD | NEW |
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 4197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4208 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( | 4208 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( |
4209 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); | 4209 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); |
4210 new_data->set_property_attributes(attributes); | 4210 new_data->set_property_attributes(attributes); |
4211 // By clearing the setter we don't have to introduce a lookup to | 4211 // By clearing the setter we don't have to introduce a lookup to |
4212 // the setter, simply make it unavailable to reflect the | 4212 // the setter, simply make it unavailable to reflect the |
4213 // attributes. | 4213 // attributes. |
4214 if (attributes & READ_ONLY) { | 4214 if (attributes & READ_ONLY) { |
4215 ExecutableAccessorInfo::ClearSetter(new_data); | 4215 ExecutableAccessorInfo::ClearSetter(new_data); |
4216 } | 4216 } |
4217 | 4217 |
4218 if (it->IsElement()) { | 4218 it->TransitionToAccessorPair(new_data, attributes); |
4219 SetElementCallback(it->GetHolder<JSObject>(), it->index(), new_data, | |
4220 attributes); | |
4221 } else { | |
4222 SetPropertyCallback(it->GetHolder<JSObject>(), it->name(), new_data, | |
4223 attributes); | |
4224 } | |
4225 } else { | 4219 } else { |
4226 it->ReconfigureDataProperty(value, attributes); | 4220 it->ReconfigureDataProperty(value, attributes); |
4227 it->WriteDataValue(value); | 4221 it->WriteDataValue(value); |
4228 } | 4222 } |
4229 | 4223 |
4230 if (is_observed) { | 4224 if (is_observed) { |
4231 RETURN_ON_EXCEPTION( | 4225 RETURN_ON_EXCEPTION( |
4232 it->isolate(), | 4226 it->isolate(), |
4233 EnqueueChangeRecord(object, "reconfigure", it->GetName(), | 4227 EnqueueChangeRecord(object, "reconfigure", it->GetName(), |
4234 it->factory()->the_hole_value()), | 4228 it->factory()->the_hole_value()), |
(...skipping 2017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6252 if (IsDictionaryElementsKind( | 6246 if (IsDictionaryElementsKind( |
6253 JSObject::cast(iter.GetCurrent())->map()->elements_kind())) { | 6247 JSObject::cast(iter.GetCurrent())->map()->elements_kind())) { |
6254 return true; | 6248 return true; |
6255 } | 6249 } |
6256 } | 6250 } |
6257 | 6251 |
6258 return false; | 6252 return false; |
6259 } | 6253 } |
6260 | 6254 |
6261 | 6255 |
6262 void JSObject::SetElementCallback(Handle<JSObject> object, | |
6263 uint32_t index, | |
6264 Handle<Object> structure, | |
6265 PropertyAttributes attributes) { | |
6266 Heap* heap = object->GetHeap(); | |
6267 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0, | |
6268 PropertyCellType::kNoCell); | |
6269 | |
6270 // Normalize elements to make this operation simple. | |
6271 bool had_dictionary_elements = object->HasDictionaryElements(); | |
6272 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | |
6273 DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); | |
6274 // Update the dictionary with the new ACCESSOR_CONSTANT property. | |
6275 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | |
6276 details); | |
6277 dictionary->set_requires_slow_elements(); | |
6278 | |
6279 // Update the dictionary backing store on the object. | |
6280 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { | |
6281 // Also delete any parameter alias. | |
6282 // | |
6283 // TODO(kmillikin): when deleting the last parameter alias we could | |
6284 // switch to a direct backing store without the parameter map. This | |
6285 // would allow GC of the context. | |
6286 FixedArray* parameter_map = FixedArray::cast(object->elements()); | |
6287 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { | |
6288 parameter_map->set(index + 2, heap->the_hole_value()); | |
6289 } | |
6290 parameter_map->set(1, *dictionary); | |
6291 } else { | |
6292 object->set_elements(*dictionary); | |
6293 | |
6294 if (!had_dictionary_elements) { | |
6295 // KeyedStoreICs (at least the non-generic ones) need a reset. | |
6296 heap->ClearAllICsByKind(Code::KEYED_STORE_IC); | |
6297 } | |
6298 } | |
6299 } | |
6300 | |
6301 | |
6302 void JSObject::SetPropertyCallback(Handle<JSObject> object, | |
6303 Handle<Name> name, | |
6304 Handle<Object> structure, | |
6305 PropertyAttributes attributes) { | |
6306 PropertyNormalizationMode mode = object->map()->is_prototype_map() | |
6307 ? KEEP_INOBJECT_PROPERTIES | |
6308 : CLEAR_INOBJECT_PROPERTIES; | |
6309 // Normalize object to make this operation simple. | |
6310 NormalizeProperties(object, mode, 0, "SetPropertyCallback"); | |
6311 | |
6312 | |
6313 // Update the dictionary with the new ACCESSOR_CONSTANT property. | |
6314 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0, | |
6315 PropertyCellType::kMutable); | |
6316 SetNormalizedProperty(object, name, structure, details); | |
6317 | |
6318 ReoptimizeIfPrototype(object); | |
6319 } | |
6320 | |
6321 | |
6322 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, | 6256 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, |
6323 Handle<Name> name, | 6257 Handle<Name> name, |
6324 Handle<Object> getter, | 6258 Handle<Object> getter, |
6325 Handle<Object> setter, | 6259 Handle<Object> setter, |
6326 PropertyAttributes attributes) { | 6260 PropertyAttributes attributes) { |
6327 Isolate* isolate = object->GetIsolate(); | 6261 Isolate* isolate = object->GetIsolate(); |
6328 | 6262 |
6329 // Make sure that the top context does not change when doing callbacks or | 6263 // Make sure that the top context does not change when doing callbacks or |
6330 // interceptor calls. | 6264 // interceptor calls. |
6331 AssertNoContextChange ncc(isolate); | 6265 AssertNoContextChange ncc(isolate); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6421 if (it.IsFound() && (it.IsReadOnly() || !it.IsConfigurable())) { | 6355 if (it.IsFound() && (it.IsReadOnly() || !it.IsConfigurable())) { |
6422 return it.factory()->undefined_value(); | 6356 return it.factory()->undefined_value(); |
6423 } | 6357 } |
6424 | 6358 |
6425 // Ignore accessors on typed arrays. | 6359 // Ignore accessors on typed arrays. |
6426 if (it.IsElement() && (object->HasFixedTypedArrayElements() || | 6360 if (it.IsElement() && (object->HasFixedTypedArrayElements() || |
6427 object->HasExternalArrayElements())) { | 6361 object->HasExternalArrayElements())) { |
6428 return it.factory()->undefined_value(); | 6362 return it.factory()->undefined_value(); |
6429 } | 6363 } |
6430 | 6364 |
6431 if (it.IsElement()) { | 6365 it.TransitionToAccessorPair(info, info->property_attributes()); |
6432 SetElementCallback(object, it.index(), info, info->property_attributes()); | |
6433 } else { | |
6434 SetPropertyCallback(object, name, info, info->property_attributes()); | |
6435 } | |
6436 | 6366 |
6437 return object; | 6367 return object; |
6438 } | 6368 } |
6439 | 6369 |
6440 | 6370 |
6441 MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object, | 6371 MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object, |
6442 Handle<Name> name, | 6372 Handle<Name> name, |
6443 AccessorComponent component) { | 6373 AccessorComponent component) { |
6444 Isolate* isolate = object->GetIsolate(); | 6374 Isolate* isolate = object->GetIsolate(); |
6445 | 6375 |
(...skipping 9574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16020 Handle<Object> new_value) { | 15950 Handle<Object> new_value) { |
16021 if (cell->value() != *new_value) { | 15951 if (cell->value() != *new_value) { |
16022 cell->set_value(*new_value); | 15952 cell->set_value(*new_value); |
16023 Isolate* isolate = cell->GetIsolate(); | 15953 Isolate* isolate = cell->GetIsolate(); |
16024 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 15954 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
16025 isolate, DependentCode::kPropertyCellChangedGroup); | 15955 isolate, DependentCode::kPropertyCellChangedGroup); |
16026 } | 15956 } |
16027 } | 15957 } |
16028 } // namespace internal | 15958 } // namespace internal |
16029 } // namespace v8 | 15959 } // namespace v8 |
OLD | NEW |