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