| 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 6420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6431 isolate, EnqueueChangeRecord(object, type, name, old_value), Object); | 6431 isolate, EnqueueChangeRecord(object, type, name, old_value), Object); |
| 6432 } | 6432 } |
| 6433 | 6433 |
| 6434 return isolate->factory()->undefined_value(); | 6434 return isolate->factory()->undefined_value(); |
| 6435 } | 6435 } |
| 6436 | 6436 |
| 6437 | 6437 |
| 6438 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, | 6438 MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, |
| 6439 Handle<AccessorInfo> info) { | 6439 Handle<AccessorInfo> info) { |
| 6440 Isolate* isolate = object->GetIsolate(); | 6440 Isolate* isolate = object->GetIsolate(); |
| 6441 Factory* factory = isolate->factory(); | |
| 6442 Handle<Name> name(Name::cast(info->name())); | |
| 6443 | |
| 6444 // Check access rights if needed. | |
| 6445 if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { | |
| 6446 isolate->ReportFailedAccessCheck(object); | |
| 6447 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | |
| 6448 return factory->undefined_value(); | |
| 6449 } | |
| 6450 | |
| 6451 if (object->IsJSGlobalProxy()) { | |
| 6452 PrototypeIterator iter(isolate, object); | |
| 6453 if (iter.IsAtEnd()) return object; | |
| 6454 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | |
| 6455 return SetAccessor( | |
| 6456 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), info); | |
| 6457 } | |
| 6458 | 6441 |
| 6459 // Make sure that the top context does not change when doing callbacks or | 6442 // Make sure that the top context does not change when doing callbacks or |
| 6460 // interceptor calls. | 6443 // interceptor calls. |
| 6461 AssertNoContextChange ncc(isolate); | 6444 AssertNoContextChange ncc(isolate); |
| 6462 | 6445 |
| 6463 // Try to flatten before operating on the string. | 6446 // Try to flatten before operating on the string. |
| 6447 Handle<Name> name(Name::cast(info->name())); |
| 6464 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 6448 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
| 6465 | 6449 |
| 6466 uint32_t index = 0; | 6450 uint32_t index = 0; |
| 6467 bool is_element = name->AsArrayIndex(&index); | 6451 LookupIterator::Configuration c = LookupIterator::HIDDEN_SKIP_INTERCEPTOR; |
| 6452 LookupIterator it = name->AsArrayIndex(&index) |
| 6453 ? LookupIterator(isolate, object, index, c) |
| 6454 : LookupIterator(object, name, c); |
| 6468 | 6455 |
| 6469 if (is_element) { | 6456 // Duplicate ACCESS_CHECK outside of GetPropertyAttributes for the case that |
| 6470 if (object->IsJSArray()) return factory->undefined_value(); | 6457 // the FailedAccessCheckCallbackFunction doesn't throw an exception. |
| 6458 // |
| 6459 // TODO(verwaest): Force throw an exception if the callback doesn't, so we can |
| 6460 // remove reliance on default return values. |
| 6461 if (it.state() == LookupIterator::ACCESS_CHECK) { |
| 6462 if (!it.HasAccess()) { |
| 6463 isolate->ReportFailedAccessCheck(object); |
| 6464 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 6465 return it.factory()->undefined_value(); |
| 6466 } |
| 6467 it.Next(); |
| 6468 } |
| 6471 | 6469 |
| 6472 // Accessors overwrite previous callbacks (cf. with getters/setters). | 6470 CHECK(GetPropertyAttributes(&it).IsJust()); |
| 6473 switch (object->GetElementsKind()) { | |
| 6474 case FAST_SMI_ELEMENTS: | |
| 6475 case FAST_ELEMENTS: | |
| 6476 case FAST_DOUBLE_ELEMENTS: | |
| 6477 case FAST_HOLEY_SMI_ELEMENTS: | |
| 6478 case FAST_HOLEY_ELEMENTS: | |
| 6479 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
| 6480 break; | |
| 6481 | 6471 |
| 6482 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 6472 // ES5 forbids turning a property into an accessor if it's not |
| 6483 case EXTERNAL_##TYPE##_ELEMENTS: \ | 6473 // configurable. See 8.6.1 (Table 5). |
| 6484 case TYPE##_ELEMENTS: \ | 6474 if (it.IsFound() && (it.IsReadOnly() || !it.IsConfigurable())) { |
| 6475 return it.factory()->undefined_value(); |
| 6476 } |
| 6485 | 6477 |
| 6486 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 6478 // Ignore accessors on typed arrays. |
| 6487 #undef TYPED_ARRAY_CASE | 6479 if (it.IsElement() && (object->HasFixedTypedArrayElements() || |
| 6488 // Ignore getters and setters on pixel and external array | 6480 object->HasExternalArrayElements())) { |
| 6489 // elements. | 6481 return it.factory()->undefined_value(); |
| 6490 return factory->undefined_value(); | 6482 } |
| 6491 | 6483 |
| 6492 case DICTIONARY_ELEMENTS: | 6484 if (it.IsElement()) { |
| 6493 break; | |
| 6494 case SLOPPY_ARGUMENTS_ELEMENTS: | |
| 6495 UNIMPLEMENTED(); | |
| 6496 break; | |
| 6497 } | |
| 6498 | |
| 6499 SetElementCallback(object, index, info, info->property_attributes()); | 6485 SetElementCallback(object, index, info, info->property_attributes()); |
| 6500 } else { | 6486 } else { |
| 6501 // Lookup the name. | |
| 6502 LookupIterator it(object, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); | |
| 6503 CHECK(GetPropertyAttributes(&it).IsJust()); | |
| 6504 // ES5 forbids turning a property into an accessor if it's not | |
| 6505 // configurable. See 8.6.1 (Table 5). | |
| 6506 if (it.IsFound() && (it.IsReadOnly() || !it.IsConfigurable())) { | |
| 6507 return factory->undefined_value(); | |
| 6508 } | |
| 6509 | |
| 6510 SetPropertyCallback(object, name, info, info->property_attributes()); | 6487 SetPropertyCallback(object, name, info, info->property_attributes()); |
| 6511 } | 6488 } |
| 6512 | 6489 |
| 6513 return object; | 6490 return object; |
| 6514 } | 6491 } |
| 6515 | 6492 |
| 6516 | 6493 |
| 6517 MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object, | 6494 MaybeHandle<Object> JSObject::GetAccessor(Handle<JSObject> object, |
| 6518 Handle<Name> name, | 6495 Handle<Name> name, |
| 6519 AccessorComponent component) { | 6496 AccessorComponent component) { |
| (...skipping 10133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16653 Handle<Object> new_value) { | 16630 Handle<Object> new_value) { |
| 16654 if (cell->value() != *new_value) { | 16631 if (cell->value() != *new_value) { |
| 16655 cell->set_value(*new_value); | 16632 cell->set_value(*new_value); |
| 16656 Isolate* isolate = cell->GetIsolate(); | 16633 Isolate* isolate = cell->GetIsolate(); |
| 16657 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16634 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 16658 isolate, DependentCode::kPropertyCellChangedGroup); | 16635 isolate, DependentCode::kPropertyCellChangedGroup); |
| 16659 } | 16636 } |
| 16660 } | 16637 } |
| 16661 } // namespace internal | 16638 } // namespace internal |
| 16662 } // namespace v8 | 16639 } // namespace v8 |
| OLD | NEW |