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 |