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

Side by Side Diff: src/objects.cc

Issue 1431443003: Refactor Object::SetSuperProperty and others. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Revert unintended change to test262 status file. Created 5 years, 1 month 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') | src/objects-inl.h » ('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 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 "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 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 Handle<Map> map) { 877 Handle<Map> map) {
878 if (!info->HasExpectedReceiverType()) return true; 878 if (!info->HasExpectedReceiverType()) return true;
879 if (!map->IsJSObjectMap()) return false; 879 if (!map->IsJSObjectMap()) return false;
880 return FunctionTemplateInfo::cast(info->expected_receiver_type()) 880 return FunctionTemplateInfo::cast(info->expected_receiver_type())
881 ->IsTemplateFor(*map); 881 ->IsTemplateFor(*map);
882 } 882 }
883 883
884 884
885 Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it, 885 Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
886 Handle<Object> value, 886 Handle<Object> value,
887 LanguageMode language_mode,
888 ShouldThrow should_throw) { 887 ShouldThrow should_throw) {
889 Isolate* isolate = it->isolate(); 888 Isolate* isolate = it->isolate();
890 Handle<Object> structure = it->GetAccessors(); 889 Handle<Object> structure = it->GetAccessors();
891 Handle<Object> receiver = it->GetReceiver(); 890 Handle<Object> receiver = it->GetReceiver();
892 891
893 // We should never get here to initialize a const with the hole value since a 892 // We should never get here to initialize a const with the hole value since a
894 // const declaration would conflict with the setter. 893 // const declaration would conflict with the setter.
895 DCHECK(!structure->IsForeign()); 894 DCHECK(!structure->IsForeign());
896 895
897 // API style callbacks. 896 // API style callbacks.
(...skipping 24 matching lines...) Expand all
922 } 921 }
923 922
924 // Regular accessor. 923 // Regular accessor.
925 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); 924 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
926 if (setter->IsCallable()) { 925 if (setter->IsCallable()) {
927 // TODO(rossberg): nicer would be to cast to some JSCallable here... 926 // TODO(rossberg): nicer would be to cast to some JSCallable here...
928 return SetPropertyWithDefinedSetter( 927 return SetPropertyWithDefinedSetter(
929 receiver, Handle<JSReceiver>::cast(setter), value, should_throw); 928 receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
930 } 929 }
931 930
932 if (is_sloppy(language_mode)) return Just(true);
933 RETURN_FAILURE(isolate, should_throw, 931 RETURN_FAILURE(isolate, should_throw,
934 NewTypeError(MessageTemplate::kNoSetterInCallback, 932 NewTypeError(MessageTemplate::kNoSetterInCallback,
935 it->GetName(), it->GetHolder<JSObject>())); 933 it->GetName(), it->GetHolder<JSObject>()));
936 } 934 }
937 935
938 936
939 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( 937 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
940 Handle<Object> receiver, 938 Handle<Object> receiver,
941 Handle<JSReceiver> getter) { 939 Handle<JSReceiver> getter) {
942 Isolate* isolate = getter->GetIsolate(); 940 Isolate* isolate = getter->GetIsolate();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 } 1059 }
1062 } 1060 }
1063 return false; 1061 return false;
1064 } 1062 }
1065 1063
1066 1064
1067 Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck( 1065 Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
1068 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) { 1066 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
1069 Handle<JSObject> checked = it->GetHolder<JSObject>(); 1067 Handle<JSObject> checked = it->GetHolder<JSObject>();
1070 if (AllCanWrite(it)) { 1068 if (AllCanWrite(it)) {
1071 // The supplied language-mode is ignored by SetPropertyWithAccessor. 1069 return SetPropertyWithAccessor(it, value, should_throw);
1072 return SetPropertyWithAccessor(it, value, SLOPPY, should_throw);
1073 } 1070 }
1074 1071
1075 it->isolate()->ReportFailedAccessCheck(checked); 1072 it->isolate()->ReportFailedAccessCheck(checked);
1076 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>()); 1073 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
1077 UNREACHABLE(); 1074 UNREACHABLE();
1078 it->isolate()->Throw( 1075 it->isolate()->Throw(
1079 *it->isolate()->factory()->NewTypeError(MessageTemplate::kNoAccess)); 1076 *it->isolate()->factory()->NewTypeError(MessageTemplate::kNoAccess));
1080 return Nothing<bool>(); 1077 return Nothing<bool>();
1081 } 1078 }
1082 1079
(...skipping 2514 matching lines...) Expand 10 before | Expand all | Expand 10 after
3597 #endif 3594 #endif
3598 return Just(true); 3595 return Just(true);
3599 } 3596 }
3600 3597
3601 3598
3602 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, 3599 MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
3603 Handle<Name> name, Handle<Object> value, 3600 Handle<Name> name, Handle<Object> value,
3604 LanguageMode language_mode, 3601 LanguageMode language_mode,
3605 StoreFromKeyed store_mode) { 3602 StoreFromKeyed store_mode) {
3606 LookupIterator it(object, name); 3603 LookupIterator it(object, name);
3607 return SetProperty(&it, value, language_mode, store_mode); 3604 MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode));
3605 return value;
3608 } 3606 }
3609 3607
3610 3608
3611 Maybe<bool> Object::SetPropertyInternal( 3609 Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
3612 LookupIterator* it, Handle<Object> value, LanguageMode language_mode, 3610 Handle<Object> value,
3613 ShouldThrow should_throw, StoreFromKeyed store_mode, bool* found) { 3611 LanguageMode language_mode,
3612 StoreFromKeyed store_mode,
3613 bool* found) {
3614 ShouldThrow should_throw =
3615 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
3616
3614 // Make sure that the top context does not change when doing callbacks or 3617 // Make sure that the top context does not change when doing callbacks or
3615 // interceptor calls. 3618 // interceptor calls.
3616 AssertNoContextChange ncc(it->isolate()); 3619 AssertNoContextChange ncc(it->isolate());
3617 3620
3618 *found = true; 3621 *found = true;
3619 3622
3620 bool done = false; 3623 bool done = false;
3621 for (; it->IsFound(); it->Next()) { 3624 for (; it->IsFound(); it->Next()) {
3622 switch (it->state()) { 3625 switch (it->state()) {
3623 case LookupIterator::NOT_FOUND: 3626 case LookupIterator::NOT_FOUND:
3624 UNREACHABLE(); 3627 UNREACHABLE();
3625 3628
3626 case LookupIterator::ACCESS_CHECK: 3629 case LookupIterator::ACCESS_CHECK:
3627 if (it->HasAccess()) break; 3630 if (it->HasAccess()) break;
3628 // Check whether it makes sense to reuse the lookup iterator. Here it 3631 // Check whether it makes sense to reuse the lookup iterator. Here it
3629 // might still call into setters up the prototype chain. 3632 // might still call into setters up the prototype chain.
3630 return JSObject::SetPropertyWithFailedAccessCheck(it, value, 3633 return JSObject::SetPropertyWithFailedAccessCheck(it, value,
3631 should_throw); 3634 should_throw);
3632 3635
3633 case LookupIterator::JSPROXY: 3636 case LookupIterator::JSPROXY:
3634 if (it->HolderIsReceiverOrHiddenPrototype()) { 3637 if (it->HolderIsReceiverOrHiddenPrototype()) {
3635 return JSProxy::SetPropertyWithHandler( 3638 return JSProxy::SetPropertyWithHandler(
3636 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value, 3639 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value,
3637 language_mode, should_throw); 3640 should_throw);
3638 } else { 3641 } else {
3639 // TODO(verwaest): Use the MaybeHandle to indicate result. 3642 // TODO(verwaest): Use the MaybeHandle to indicate result.
3640 bool has_result = false; 3643 bool has_result = false;
3641 Maybe<bool> maybe_result = 3644 Maybe<bool> maybe_result =
3642 JSProxy::SetPropertyViaPrototypesWithHandler( 3645 JSProxy::SetPropertyViaPrototypesWithHandler(
3643 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), 3646 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(),
3644 value, language_mode, should_throw, &has_result); 3647 value, should_throw, &has_result);
3645 if (has_result) return maybe_result; 3648 if (has_result) return maybe_result;
3646 done = true; 3649 done = true;
3647 } 3650 }
3648 break; 3651 break;
3649 3652
3650 case LookupIterator::INTERCEPTOR: 3653 case LookupIterator::INTERCEPTOR:
3651 if (it->HolderIsReceiverOrHiddenPrototype()) { 3654 if (it->HolderIsReceiverOrHiddenPrototype()) {
3652 Maybe<bool> maybe_result = 3655 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value);
3653 JSObject::SetPropertyWithInterceptor(it, value); 3656 if (result.IsNothing() || result.FromJust()) return result;
3654 if (maybe_result.IsNothing()) return Nothing<bool>();
3655 if (maybe_result.FromJust()) return Just(true);
3656 } else { 3657 } else {
3657 Maybe<PropertyAttributes> maybe_attributes = 3658 Maybe<PropertyAttributes> maybe_attributes =
3658 JSObject::GetPropertyAttributesWithInterceptor(it); 3659 JSObject::GetPropertyAttributesWithInterceptor(it);
3659 if (!maybe_attributes.IsJust()) return Nothing<bool>(); 3660 if (!maybe_attributes.IsJust()) return Nothing<bool>();
3660 done = maybe_attributes.FromJust() != ABSENT; 3661 done = maybe_attributes.FromJust() != ABSENT;
3661 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) { 3662 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) {
3662 return WriteToReadOnlyProperty(it, value, language_mode, 3663 return WriteToReadOnlyProperty(it, value, should_throw);
3663 should_throw);
3664 } 3664 }
3665 } 3665 }
3666 break; 3666 break;
3667 3667
3668 case LookupIterator::ACCESSOR: { 3668 case LookupIterator::ACCESSOR: {
3669 if (it->IsReadOnly()) { 3669 if (it->IsReadOnly()) {
3670 return WriteToReadOnlyProperty(it, value, language_mode, 3670 return WriteToReadOnlyProperty(it, value, should_throw);
3671 should_throw);
3672 } 3671 }
3673 Handle<Object> accessors = it->GetAccessors(); 3672 Handle<Object> accessors = it->GetAccessors();
3674 if (accessors->IsAccessorInfo() && 3673 if (accessors->IsAccessorInfo() &&
3675 !it->HolderIsReceiverOrHiddenPrototype() && 3674 !it->HolderIsReceiverOrHiddenPrototype() &&
3676 AccessorInfo::cast(*accessors)->is_special_data_property()) { 3675 AccessorInfo::cast(*accessors)->is_special_data_property()) {
3677 done = true; 3676 done = true;
3678 break; 3677 break;
3679 } 3678 }
3680 return SetPropertyWithAccessor(it, value, language_mode, should_throw); 3679 return SetPropertyWithAccessor(it, value, should_throw);
3681 } 3680 }
3682 case LookupIterator::INTEGER_INDEXED_EXOTIC: 3681 case LookupIterator::INTEGER_INDEXED_EXOTIC:
3683 // TODO(verwaest): We should throw an exception. 3682 // TODO(verwaest): We should throw an exception.
3684 return Just(true); 3683 return Just(true);
3685 3684
3686 case LookupIterator::DATA: 3685 case LookupIterator::DATA:
3687 if (it->IsReadOnly()) { 3686 if (it->IsReadOnly()) {
3688 return WriteToReadOnlyProperty(it, value, language_mode, 3687 return WriteToReadOnlyProperty(it, value, should_throw);
3689 should_throw);
3690 } 3688 }
3691 if (it->HolderIsReceiverOrHiddenPrototype()) { 3689 if (it->HolderIsReceiverOrHiddenPrototype()) {
3692 return SetDataProperty(it, value, should_throw); 3690 return SetDataProperty(it, value, should_throw);
3693 } 3691 }
3694 done = true; 3692 done = true;
3695 break; 3693 break;
3696 3694
3697 case LookupIterator::TRANSITION: 3695 case LookupIterator::TRANSITION:
3698 done = true; 3696 done = true;
3699 break; 3697 break;
3700 } 3698 }
3701 3699
3702 if (done) break; 3700 if (done) break;
3703 } 3701 }
3704 3702
3705 // If the receiver is the JSGlobalObject, the store was contextual. In case 3703 // If the receiver is the JSGlobalObject, the store was contextual. In case
3706 // the property did not exist yet on the global object itself, we have to 3704 // the property did not exist yet on the global object itself, we have to
3707 // throw a reference error in strict mode. 3705 // throw a reference error in strict mode. In sloppy mode, we continue.
3708 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { 3706 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) {
3709 RETURN_FAILURE(it->isolate(), should_throw, 3707 it->isolate()->Throw(*it->isolate()->factory()->NewReferenceError(
3710 NewReferenceError(MessageTemplate::kNotDefined, it->name())); 3708 MessageTemplate::kNotDefined, it->name()));
3709 return Nothing<bool>();
3711 } 3710 }
3712 3711
3713 *found = false; 3712 *found = false;
3714 return Nothing<bool>(); 3713 return Nothing<bool>();
3715 } 3714 }
3716 3715
3717 3716
3718 MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
3719 Handle<Object> value,
3720 LanguageMode language_mode,
3721 StoreFromKeyed store_mode) {
3722 MAYBE_RETURN_NULL(
3723 SetProperty(it, value, language_mode, THROW_ON_ERROR, store_mode));
3724 return value;
3725 }
3726
3727
3728 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value, 3717 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
3729 LanguageMode language_mode, 3718 LanguageMode language_mode,
3730 ShouldThrow should_throw,
3731 StoreFromKeyed store_mode) { 3719 StoreFromKeyed store_mode) {
3732 bool found = false; 3720 bool found = false;
3733 Maybe<bool> result = SetPropertyInternal(it, value, language_mode, 3721 Maybe<bool> result =
3734 should_throw, store_mode, &found); 3722 SetPropertyInternal(it, value, language_mode, store_mode, &found);
3735 if (found) return result; 3723 if (found) return result;
3736 return AddDataProperty(it, value, NONE, language_mode, should_throw, 3724 ShouldThrow should_throw =
3737 store_mode); 3725 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
3726 return AddDataProperty(it, value, NONE, should_throw, store_mode);
3738 } 3727 }
3739 3728
3740 3729
3741 MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it, 3730 Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
3742 Handle<Object> value, 3731 LanguageMode language_mode,
3743 LanguageMode language_mode, 3732 StoreFromKeyed store_mode) {
3744 StoreFromKeyed store_mode) { 3733 ShouldThrow should_throw =
3734 is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
3735
3745 bool found = false; 3736 bool found = false;
3746 Maybe<bool> result = SetPropertyInternal(it, value, language_mode, 3737 Maybe<bool> result =
3747 THROW_ON_ERROR, store_mode, &found); 3738 SetPropertyInternal(it, value, language_mode, store_mode, &found);
3748 if (found) { 3739 if (found) return result;
3749 MAYBE_RETURN_NULL(result);
3750 return value;
3751 }
3752 3740
3753 if (!it->GetReceiver()->IsJSReceiver()) { 3741 if (!it->GetReceiver()->IsJSReceiver()) {
3754 MAYBE_RETURN_NULL( 3742 return WriteToReadOnlyProperty(it, value, should_throw);
3755 WriteToReadOnlyProperty(it, value, language_mode, THROW_ON_ERROR));
3756 return value;
3757 } 3743 }
3758 3744
3759 LookupIterator::Configuration c = LookupIterator::OWN; 3745 LookupIterator::Configuration c = LookupIterator::OWN;
3760 LookupIterator own_lookup = 3746 LookupIterator own_lookup =
3761 it->IsElement() 3747 it->IsElement()
3762 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c) 3748 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c)
3763 : LookupIterator(it->GetReceiver(), it->name(), c); 3749 : LookupIterator(it->GetReceiver(), it->name(), c);
3764 3750
3765 for (; own_lookup.IsFound(); own_lookup.Next()) { 3751 for (; own_lookup.IsFound(); own_lookup.Next()) {
3766 switch (own_lookup.state()) { 3752 switch (own_lookup.state()) {
3767 case LookupIterator::ACCESS_CHECK: 3753 case LookupIterator::ACCESS_CHECK:
3768 if (!own_lookup.HasAccess()) { 3754 if (!own_lookup.HasAccess()) {
3769 MAYBE_RETURN_NULL(JSObject::SetPropertyWithFailedAccessCheck( 3755 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value,
3770 &own_lookup, value, THROW_ON_ERROR)); 3756 should_throw);
3771 return value;
3772 } 3757 }
3773 break; 3758 break;
3774 3759
3775 case LookupIterator::INTEGER_INDEXED_EXOTIC: 3760 case LookupIterator::INTEGER_INDEXED_EXOTIC:
3776 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 3761 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
3777 value, language_mode); 3762 value, should_throw);
3778 3763
3779 case LookupIterator::DATA: { 3764 case LookupIterator::DATA: {
3780 PropertyDetails details = own_lookup.property_details(); 3765 PropertyDetails details = own_lookup.property_details();
3781 if (details.IsConfigurable() || !details.IsReadOnly()) { 3766 if (details.IsConfigurable() || !details.IsReadOnly()) {
3782 return JSObject::DefineOwnPropertyIgnoreAttributes( 3767 return JSObject::DefineOwnPropertyIgnoreAttributes(
3783 &own_lookup, value, details.attributes()); 3768 &own_lookup, value, details.attributes(), should_throw);
3784 } 3769 }
3785 MAYBE_RETURN_NULL(WriteToReadOnlyProperty( 3770 return WriteToReadOnlyProperty(&own_lookup, value, should_throw);
3786 &own_lookup, value, language_mode, THROW_ON_ERROR));
3787 return value;
3788 } 3771 }
3789 3772
3790 case LookupIterator::ACCESSOR: { 3773 case LookupIterator::ACCESSOR: {
3791 PropertyDetails details = own_lookup.property_details(); 3774 PropertyDetails details = own_lookup.property_details();
3792 if (details.IsConfigurable()) { 3775 if (details.IsConfigurable()) {
3793 return JSObject::DefineOwnPropertyIgnoreAttributes( 3776 return JSObject::DefineOwnPropertyIgnoreAttributes(
3794 &own_lookup, value, details.attributes()); 3777 &own_lookup, value, details.attributes(), should_throw);
3795 } 3778 }
3796 3779
3797 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 3780 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
3798 value, language_mode); 3781 value, should_throw);
3799 } 3782 }
3800 3783
3801 case LookupIterator::INTERCEPTOR: 3784 case LookupIterator::INTERCEPTOR:
3802 case LookupIterator::JSPROXY: { 3785 case LookupIterator::JSPROXY: {
3803 bool found = false; 3786 bool found = false;
3804 Maybe<bool> result = 3787 Maybe<bool> result = SetPropertyInternal(
3805 SetPropertyInternal(&own_lookup, value, language_mode, 3788 &own_lookup, value, language_mode, store_mode, &found);
3806 THROW_ON_ERROR, store_mode, &found); 3789 if (found) return result;
3807 if (found) {
3808 MAYBE_RETURN_NULL(result);
3809 return value;
3810 }
3811 break; 3790 break;
3812 } 3791 }
3813 3792
3814 case LookupIterator::NOT_FOUND: 3793 case LookupIterator::NOT_FOUND:
3815 case LookupIterator::TRANSITION: 3794 case LookupIterator::TRANSITION:
3816 UNREACHABLE(); 3795 UNREACHABLE();
3817 } 3796 }
3818 } 3797 }
3819 3798
3820 return JSObject::AddDataProperty(&own_lookup, value, NONE, language_mode, 3799 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw,
3821 store_mode); 3800 store_mode);
3822 } 3801 }
3823 3802
3824 3803
3825 MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it, 3804 MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it,
3826 LanguageMode language_mode) { 3805 LanguageMode language_mode) {
3827 if (is_strong(language_mode)) { 3806 if (is_strong(language_mode)) {
3828 THROW_NEW_ERROR(it->isolate(), 3807 THROW_NEW_ERROR(it->isolate(),
3829 NewTypeError(MessageTemplate::kStrongPropertyAccess, 3808 NewTypeError(MessageTemplate::kStrongPropertyAccess,
3830 it->GetName(), it->GetReceiver()), 3809 it->GetName(), it->GetReceiver()),
(...skipping 13 matching lines...) Expand all
3844 Object); 3823 Object);
3845 } 3824 }
3846 return isolate->factory()->undefined_value(); 3825 return isolate->factory()->undefined_value();
3847 } 3826 }
3848 3827
3849 3828
3850 Maybe<bool> Object::CannotCreateProperty(Isolate* isolate, 3829 Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
3851 Handle<Object> receiver, 3830 Handle<Object> receiver,
3852 Handle<Object> name, 3831 Handle<Object> name,
3853 Handle<Object> value, 3832 Handle<Object> value,
3854 LanguageMode language_mode,
3855 ShouldThrow should_throw) { 3833 ShouldThrow should_throw) {
3856 if (is_sloppy(language_mode)) return Just(true);
3857 RETURN_FAILURE( 3834 RETURN_FAILURE(
3858 isolate, should_throw, 3835 isolate, should_throw,
3859 NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name, 3836 NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
3860 Object::TypeOf(isolate, receiver), receiver)); 3837 Object::TypeOf(isolate, receiver), receiver));
3861 } 3838 }
3862 3839
3863 3840
3864 Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it, 3841 Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
3865 Handle<Object> value, 3842 Handle<Object> value,
3866 LanguageMode language_mode,
3867 ShouldThrow should_throw) { 3843 ShouldThrow should_throw) {
3868 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), 3844 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
3869 it->GetName(), value, language_mode, 3845 it->GetName(), value, should_throw);
3870 should_throw);
3871 } 3846 }
3872 3847
3873 3848
3874 Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate, 3849 Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
3875 Handle<Object> receiver, 3850 Handle<Object> receiver,
3876 Handle<Object> name, 3851 Handle<Object> name,
3877 Handle<Object> value, 3852 Handle<Object> value,
3878 LanguageMode language_mode,
3879 ShouldThrow should_throw) { 3853 ShouldThrow should_throw) {
3880 if (is_sloppy(language_mode)) return Just(true);
3881 RETURN_FAILURE(isolate, should_throw, 3854 RETURN_FAILURE(isolate, should_throw,
3882 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name, 3855 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
3883 Object::TypeOf(isolate, receiver), receiver)); 3856 Object::TypeOf(isolate, receiver), receiver));
3884 } 3857 }
3885 3858
3886 3859
3887 MaybeHandle<Object> Object::RedefineNonconfigurableProperty( 3860 Maybe<bool> Object::RedefineNonconfigurableProperty(Isolate* isolate,
3888 Isolate* isolate, Handle<Object> name, Handle<Object> value, 3861 Handle<Object> name,
3889 LanguageMode language_mode) { 3862 Handle<Object> value,
3890 if (is_sloppy(language_mode)) return value; 3863 ShouldThrow should_throw) {
3891 THROW_NEW_ERROR(isolate, 3864 RETURN_FAILURE(isolate, should_throw,
3892 NewTypeError(MessageTemplate::kRedefineDisallowed, name), 3865 NewTypeError(MessageTemplate::kRedefineDisallowed, name));
3893 Object);
3894 } 3866 }
3895 3867
3896 3868
3897 Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value, 3869 Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value,
3898 ShouldThrow should_throw) { 3870 ShouldThrow should_throw) {
3899 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot 3871 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
3900 // have own properties. 3872 // have own properties.
3901 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 3873 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
3902 3874
3903 // Store on the holder which may be hidden behind the receiver. 3875 // Store on the holder which may be hidden behind the receiver.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3993 isolate->factory()->NewNumberFromUint(add_count); 3965 isolate->factory()->NewNumberFromUint(add_count);
3994 3966
3995 Handle<Object> args[] = {object, index_object, deleted, add_count_object}; 3967 Handle<Object> args[] = {object, index_object, deleted, add_count_object};
3996 3968
3997 return Execution::Call( 3969 return Execution::Call(
3998 isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()), 3970 isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()),
3999 isolate->factory()->undefined_value(), arraysize(args), args); 3971 isolate->factory()->undefined_value(), arraysize(args), args);
4000 } 3972 }
4001 3973
4002 3974
4003 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
4004 Handle<Object> value,
4005 PropertyAttributes attributes,
4006 LanguageMode language_mode,
4007 StoreFromKeyed store_mode) {
4008 MAYBE_RETURN_NULL(AddDataProperty(it, value, attributes, language_mode,
4009 THROW_ON_ERROR, store_mode));
4010 return value;
4011 }
4012
4013
4014 Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value, 3975 Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
4015 PropertyAttributes attributes, 3976 PropertyAttributes attributes,
4016 LanguageMode language_mode,
4017 ShouldThrow should_throw, 3977 ShouldThrow should_throw,
4018 StoreFromKeyed store_mode) { 3978 StoreFromKeyed store_mode) {
4019 DCHECK(!it->GetReceiver()->IsJSProxy()); 3979 DCHECK(!it->GetReceiver()->IsJSProxy());
4020 if (!it->GetReceiver()->IsJSObject()) { 3980 if (!it->GetReceiver()->IsJSObject()) {
4021 return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(), 3981 return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
4022 value, language_mode, should_throw); 3982 value, should_throw);
4023 } 3983 }
4024 3984
4025 DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state()); 3985 DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
4026 3986
4027 Handle<JSObject> receiver = it->GetStoreTarget(); 3987 Handle<JSObject> receiver = it->GetStoreTarget();
4028 3988
4029 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) 3989 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
4030 // instead. If the prototype is Null, the proxy is detached. 3990 // instead. If the prototype is Null, the proxy is detached.
4031 if (receiver->IsJSGlobalProxy()) return Just(true); 3991 if (receiver->IsJSGlobalProxy()) return Just(true);
4032 3992
4033 Isolate* isolate = it->isolate(); 3993 Isolate* isolate = it->isolate();
4034 3994
4035 if (!receiver->map()->is_extensible() && 3995 if (!receiver->map()->is_extensible() &&
4036 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) { 3996 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) {
4037 if (is_sloppy(language_mode)) return Just(true);
4038 RETURN_FAILURE( 3997 RETURN_FAILURE(
4039 isolate, should_throw, 3998 isolate, should_throw,
4040 NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName())); 3999 NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
4041 } 4000 }
4042 4001
4043 if (it->IsElement()) { 4002 if (it->IsElement()) {
4044 if (receiver->IsJSArray()) { 4003 if (receiver->IsJSArray()) {
4045 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 4004 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
4046 if (JSArray::WouldChangeReadOnlyLength(array, it->index())) { 4005 if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
4047 if (is_sloppy(language_mode)) return Just(true);
4048 RETURN_FAILURE(array->GetIsolate(), should_throw, 4006 RETURN_FAILURE(array->GetIsolate(), should_throw,
4049 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, 4007 NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
4050 isolate->factory()->length_string(), 4008 isolate->factory()->length_string(),
4051 Object::TypeOf(isolate, array), array)); 4009 Object::TypeOf(isolate, array), array));
4052 } 4010 }
4053 4011
4054 if (FLAG_trace_external_array_abuse && 4012 if (FLAG_trace_external_array_abuse &&
4055 array->HasFixedTypedArrayElements()) { 4013 array->HasFixedTypedArrayElements()) {
4056 CheckArrayAbuse(array, "typed elements write", it->index(), true); 4014 CheckArrayAbuse(array, "typed elements write", it->index(), true);
4057 } 4015 }
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
4447 Nothing<bool>()); 4405 Nothing<bool>());
4448 4406
4449 return Just(result->BooleanValue()); 4407 return Just(result->BooleanValue());
4450 } 4408 }
4451 4409
4452 4410
4453 Maybe<bool> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy, 4411 Maybe<bool> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
4454 Handle<Object> receiver, 4412 Handle<Object> receiver,
4455 Handle<Name> name, 4413 Handle<Name> name,
4456 Handle<Object> value, 4414 Handle<Object> value,
4457 LanguageMode language_mode,
4458 ShouldThrow should_throw) { 4415 ShouldThrow should_throw) {
4459 Isolate* isolate = proxy->GetIsolate(); 4416 Isolate* isolate = proxy->GetIsolate();
4460 4417
4461 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4418 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4462 if (name->IsSymbol()) return Just(true); 4419 if (name->IsSymbol()) return Just(true);
4463 4420
4464 Handle<Object> args[] = { receiver, name, value }; 4421 Handle<Object> args[] = { receiver, name, value };
4465 RETURN_ON_EXCEPTION_VALUE(isolate, 4422 RETURN_ON_EXCEPTION_VALUE(isolate,
4466 CallTrap(proxy, "set", isolate->derived_set_trap(), 4423 CallTrap(proxy, "set", isolate->derived_set_trap(),
4467 arraysize(args), args), 4424 arraysize(args), args),
4468 Nothing<bool>()); 4425 Nothing<bool>());
4469 4426
4470 return Just(true); 4427 return Just(true);
4471 // TODO(neis): This needs to be made spec-conformant by throwing a TypeError 4428 // TODO(neis): This needs to be made spec-conformant by looking at the
4472 // if the trap's result is falsish. 4429 // trap's result.
4473 } 4430 }
4474 4431
4475 4432
4476 Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler( 4433 Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler(
4477 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, 4434 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
4478 Handle<Object> value, LanguageMode language_mode, ShouldThrow should_throw, 4435 Handle<Object> value, ShouldThrow should_throw, bool* done) {
4479 bool* done) {
4480 Isolate* isolate = proxy->GetIsolate(); 4436 Isolate* isolate = proxy->GetIsolate();
4481 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. 4437 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
4482 4438
4483 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4439 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4484 if (name->IsSymbol()) { 4440 if (name->IsSymbol()) {
4485 *done = false; // Return value will be ignored. 4441 *done = false; // Return value will be ignored.
4486 return Nothing<bool>(); 4442 return Nothing<bool>();
4487 } 4443 }
4488 4444
4489 *done = true; // except where redefined... 4445 *done = true; // except where redefined...
(...skipping 19 matching lines...) Expand all
4509 Nothing<bool>()); 4465 Nothing<bool>());
4510 4466
4511 // [[GetProperty]] requires to check that all properties are configurable. 4467 // [[GetProperty]] requires to check that all properties are configurable.
4512 Handle<String> configurable_name = 4468 Handle<String> configurable_name =
4513 isolate->factory()->InternalizeOneByteString( 4469 isolate->factory()->InternalizeOneByteString(
4514 STATIC_CHAR_VECTOR("configurable_")); 4470 STATIC_CHAR_VECTOR("configurable_"));
4515 Handle<Object> configurable = 4471 Handle<Object> configurable =
4516 Object::GetProperty(desc, configurable_name).ToHandleChecked(); 4472 Object::GetProperty(desc, configurable_name).ToHandleChecked();
4517 DCHECK(configurable->IsBoolean()); 4473 DCHECK(configurable->IsBoolean());
4518 if (configurable->IsFalse()) { 4474 if (configurable->IsFalse()) {
4519 RETURN_FAILURE( 4475 isolate->Throw(*isolate->factory()->NewTypeError(
4520 isolate, should_throw, 4476 MessageTemplate::kProxyPropNotConfigurable, handler, name,
4521 NewTypeError(MessageTemplate::kProxyPropNotConfigurable, handler, name, 4477 isolate->factory()->NewStringFromAsciiChecked(
4522 isolate->factory()->NewStringFromAsciiChecked( 4478 "getPropertyDescriptor")));
4523 "getPropertyDescriptor"))); 4479 return Nothing<bool>();
4524 } 4480 }
4525 DCHECK(configurable->IsTrue()); 4481 DCHECK(configurable->IsTrue());
4526 4482
4527 // Check for DataDescriptor. 4483 // Check for DataDescriptor.
4528 Handle<String> hasWritable_name = 4484 Handle<String> hasWritable_name =
4529 isolate->factory()->InternalizeOneByteString( 4485 isolate->factory()->InternalizeOneByteString(
4530 STATIC_CHAR_VECTOR("hasWritable_")); 4486 STATIC_CHAR_VECTOR("hasWritable_"));
4531 Handle<Object> hasWritable = 4487 Handle<Object> hasWritable =
4532 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); 4488 Object::GetProperty(desc, hasWritable_name).ToHandleChecked();
4533 DCHECK(hasWritable->IsBoolean()); 4489 DCHECK(hasWritable->IsBoolean());
4534 if (hasWritable->IsTrue()) { 4490 if (hasWritable->IsTrue()) {
4535 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( 4491 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString(
4536 STATIC_CHAR_VECTOR("writable_")); 4492 STATIC_CHAR_VECTOR("writable_"));
4537 Handle<Object> writable = 4493 Handle<Object> writable =
4538 Object::GetProperty(desc, writable_name).ToHandleChecked(); 4494 Object::GetProperty(desc, writable_name).ToHandleChecked();
4539 DCHECK(writable->IsBoolean()); 4495 DCHECK(writable->IsBoolean());
4540 *done = writable->IsFalse(); 4496 *done = writable->IsFalse();
4541 if (!*done) return Nothing<bool>(); // Return value will be ignored. 4497 if (!*done) return Nothing<bool>(); // Return value will be ignored.
4542 return WriteToReadOnlyProperty(isolate, receiver, name, value, 4498 return WriteToReadOnlyProperty(isolate, receiver, name, value,
4543 language_mode, should_throw); 4499 should_throw);
4544 } 4500 }
4545 4501
4546 // We have an AccessorDescriptor. 4502 // We have an AccessorDescriptor.
4547 Handle<String> set_name = 4503 Handle<String> set_name =
4548 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); 4504 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_"));
4549 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); 4505 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked();
4550 if (!setter->IsUndefined()) { 4506 if (!setter->IsUndefined()) {
4551 // TODO(rossberg): nicer would be to cast to some JSCallable here... 4507 // TODO(rossberg): nicer would be to cast to some JSCallable here...
4552 return SetPropertyWithDefinedSetter( 4508 return SetPropertyWithDefinedSetter(
4553 receiver, Handle<JSReceiver>::cast(setter), value, should_throw); 4509 receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
4554 } 4510 }
4555 4511
4556 if (is_sloppy(language_mode)) return Just(true);
4557 RETURN_FAILURE( 4512 RETURN_FAILURE(
4558 isolate, should_throw, 4513 isolate, should_throw,
4559 NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy)); 4514 NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy));
4560 } 4515 }
4561 4516
4562 4517
4563 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( 4518 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
4564 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) { 4519 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) {
4565 Isolate* isolate = proxy->GetIsolate(); 4520 Isolate* isolate = proxy->GetIsolate();
4566 4521
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
4780 #ifdef DEBUG 4735 #ifdef DEBUG
4781 uint32_t index; 4736 uint32_t index;
4782 DCHECK(!object->IsJSProxy()); 4737 DCHECK(!object->IsJSProxy());
4783 DCHECK(!name->AsArrayIndex(&index)); 4738 DCHECK(!name->AsArrayIndex(&index));
4784 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); 4739 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
4785 DCHECK(maybe.IsJust()); 4740 DCHECK(maybe.IsJust());
4786 DCHECK(!it.IsFound()); 4741 DCHECK(!it.IsFound());
4787 DCHECK(object->map()->is_extensible() || 4742 DCHECK(object->map()->is_extensible() ||
4788 it.isolate()->IsInternallyUsedPropertyName(name)); 4743 it.isolate()->IsInternallyUsedPropertyName(name));
4789 #endif 4744 #endif
4790 AddDataProperty(&it, value, attributes, STRICT, 4745 CHECK(AddDataProperty(&it, value, attributes, THROW_ON_ERROR,
4791 CERTAINLY_NOT_STORE_FROM_KEYED).Check(); 4746 CERTAINLY_NOT_STORE_FROM_KEYED)
4747 .IsJust());
4792 } 4748 }
4793 4749
4794 4750
4795 // static 4751 // static
4796 void ExecutableAccessorInfo::ClearSetter(Handle<ExecutableAccessorInfo> info) { 4752 void ExecutableAccessorInfo::ClearSetter(Handle<ExecutableAccessorInfo> info) {
4797 Handle<Object> object = v8::FromCData(info->GetIsolate(), nullptr); 4753 Handle<Object> object = v8::FromCData(info->GetIsolate(), nullptr);
4798 info->set_setter(*object); 4754 info->set_setter(*object);
4799 } 4755 }
4800 4756
4801 4757
4802 // Reconfigures a property to a data property with attributes, even if it is not 4758 // Reconfigures a property to a data property with attributes, even if it is not
4803 // reconfigurable. 4759 // reconfigurable.
4804 // Requires a LookupIterator that does not look at the prototype chain beyond 4760 // Requires a LookupIterator that does not look at the prototype chain beyond
4805 // hidden prototypes. 4761 // hidden prototypes.
4806 MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes( 4762 MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
4807 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes, 4763 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
4808 ExecutableAccessorInfoHandling handling) { 4764 ExecutableAccessorInfoHandling handling) {
4765 MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes(
4766 it, value, attributes, THROW_ON_ERROR, handling));
4767 return value;
4768 }
4769
4770
4771 Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
4772 LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
4773 ShouldThrow should_throw, ExecutableAccessorInfoHandling handling) {
4809 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); 4774 Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
4810 bool is_observed = object->map()->is_observed() && 4775 bool is_observed = object->map()->is_observed() &&
4811 (it->IsElement() || 4776 (it->IsElement() ||
4812 !it->isolate()->IsInternallyUsedPropertyName(it->name())); 4777 !it->isolate()->IsInternallyUsedPropertyName(it->name()));
4813 4778
4814 for (; it->IsFound(); it->Next()) { 4779 for (; it->IsFound(); it->Next()) {
4815 switch (it->state()) { 4780 switch (it->state()) {
4816 case LookupIterator::JSPROXY: 4781 case LookupIterator::JSPROXY:
4817 case LookupIterator::NOT_FOUND: 4782 case LookupIterator::NOT_FOUND:
4818 case LookupIterator::TRANSITION: 4783 case LookupIterator::TRANSITION:
4819 UNREACHABLE(); 4784 UNREACHABLE();
4820 4785
4821 case LookupIterator::ACCESS_CHECK: 4786 case LookupIterator::ACCESS_CHECK:
4822 if (!it->HasAccess()) { 4787 if (!it->HasAccess()) {
4823 it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>()); 4788 it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
4824 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 4789 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
4825 return value; 4790 return Just(true);
4826 } 4791 }
4827 break; 4792 break;
4828 4793
4829 // If there's an interceptor, try to store the property with the 4794 // If there's an interceptor, try to store the property with the
4830 // interceptor. 4795 // interceptor.
4831 // In case of success, the attributes will have been reset to the default 4796 // In case of success, the attributes will have been reset to the default
4832 // attributes of the interceptor, rather than the incoming attributes. 4797 // attributes of the interceptor, rather than the incoming attributes.
4833 // 4798 //
4834 // TODO(verwaest): JSProxy afterwards verify the attributes that the 4799 // TODO(verwaest): JSProxy afterwards verify the attributes that the
4835 // JSProxy claims it has, and verifies that they are compatible. If not, 4800 // JSProxy claims it has, and verifies that they are compatible. If not,
4836 // they throw. Here we should do the same. 4801 // they throw. Here we should do the same.
4837 case LookupIterator::INTERCEPTOR: 4802 case LookupIterator::INTERCEPTOR:
4838 if (handling == DONT_FORCE_FIELD) { 4803 if (handling == DONT_FORCE_FIELD) {
4839 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value); 4804 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value);
4840 if (result.IsNothing()) return MaybeHandle<Object>(); 4805 if (result.IsNothing() || result.FromJust()) return result;
4841 if (result.FromJust()) return value;
4842 } 4806 }
4843 break; 4807 break;
4844 4808
4845 case LookupIterator::ACCESSOR: { 4809 case LookupIterator::ACCESSOR: {
4846 Handle<Object> accessors = it->GetAccessors(); 4810 Handle<Object> accessors = it->GetAccessors();
4847 4811
4848 // Special handling for ExecutableAccessorInfo, which behaves like a 4812 // Special handling for ExecutableAccessorInfo, which behaves like a
4849 // data property. 4813 // data property.
4850 if (accessors->IsExecutableAccessorInfo() && 4814 if (accessors->IsExecutableAccessorInfo() &&
4851 handling == DONT_FORCE_FIELD) { 4815 handling == DONT_FORCE_FIELD) {
4852 PropertyDetails details = it->property_details(); 4816 PropertyDetails details = it->property_details();
4853 // Ensure the context isn't changed after calling into accessors. 4817 // Ensure the context isn't changed after calling into accessors.
4854 AssertNoContextChange ncc(it->isolate()); 4818 AssertNoContextChange ncc(it->isolate());
4855 4819
4856 Maybe<bool> result = JSObject::SetPropertyWithAccessor( 4820 Maybe<bool> result =
4857 it, value, STRICT, THROW_ON_ERROR); 4821 JSObject::SetPropertyWithAccessor(it, value, should_throw);
4858 if (result.IsNothing()) return MaybeHandle<Object>(); 4822 if (result.IsNothing() || !result.FromJust()) return result;
4859 4823
4860 if (details.attributes() == attributes) return value; 4824 if (details.attributes() == attributes) return Just(true);
4861 4825
4862 // Reconfigure the accessor if attributes mismatch. 4826 // Reconfigure the accessor if attributes mismatch.
4863 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( 4827 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor(
4864 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); 4828 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors));
4865 new_data->set_property_attributes(attributes); 4829 new_data->set_property_attributes(attributes);
4866 // By clearing the setter we don't have to introduce a lookup to 4830 // By clearing the setter we don't have to introduce a lookup to
4867 // the setter, simply make it unavailable to reflect the 4831 // the setter, simply make it unavailable to reflect the
4868 // attributes. 4832 // attributes.
4869 if (attributes & READ_ONLY) { 4833 if (attributes & READ_ONLY) {
4870 ExecutableAccessorInfo::ClearSetter(new_data); 4834 ExecutableAccessorInfo::ClearSetter(new_data);
4871 } 4835 }
4872 4836
4873 it->TransitionToAccessorPair(new_data, attributes); 4837 it->TransitionToAccessorPair(new_data, attributes);
4874 } else { 4838 } else {
4875 it->ReconfigureDataProperty(value, attributes); 4839 it->ReconfigureDataProperty(value, attributes);
4876 } 4840 }
4877 4841
4878 if (is_observed) { 4842 if (is_observed) {
4879 RETURN_ON_EXCEPTION( 4843 RETURN_ON_EXCEPTION_VALUE(
4880 it->isolate(), 4844 it->isolate(),
4881 EnqueueChangeRecord(object, "reconfigure", it->GetName(), 4845 EnqueueChangeRecord(object, "reconfigure", it->GetName(),
4882 it->factory()->the_hole_value()), 4846 it->factory()->the_hole_value()),
4883 Object); 4847 Nothing<bool>());
4884 } 4848 }
4885 4849
4886 return value; 4850 return Just(true);
4887 } 4851 }
4888 case LookupIterator::INTEGER_INDEXED_EXOTIC: 4852 case LookupIterator::INTEGER_INDEXED_EXOTIC:
4889 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 4853 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
4890 value, STRICT); 4854 value, should_throw);
4891 4855
4892 case LookupIterator::DATA: { 4856 case LookupIterator::DATA: {
4893 PropertyDetails details = it->property_details(); 4857 PropertyDetails details = it->property_details();
4894 Handle<Object> old_value = it->factory()->the_hole_value(); 4858 Handle<Object> old_value = it->factory()->the_hole_value();
4895 // Regular property update if the attributes match. 4859 // Regular property update if the attributes match.
4896 if (details.attributes() == attributes) { 4860 if (details.attributes() == attributes) {
4897 MAYBE_RETURN_NULL(SetDataProperty(it, value, THROW_ON_ERROR)); 4861 return SetDataProperty(it, value, should_throw);
4898 return value;
4899 } 4862 }
4900 4863
4901 // Special case: properties of typed arrays cannot be reconfigured to 4864 // Special case: properties of typed arrays cannot be reconfigured to
4902 // non-writable nor to non-enumerable. 4865 // non-writable nor to non-enumerable.
4903 if (it->IsElement() && object->HasFixedTypedArrayElements()) { 4866 if (it->IsElement() && object->HasFixedTypedArrayElements()) {
4904 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 4867 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
4905 value, STRICT); 4868 value, should_throw);
4906 } 4869 }
4907 4870
4908 // Reconfigure the data property if the attributes mismatch. 4871 // Reconfigure the data property if the attributes mismatch.
4909 if (is_observed) old_value = it->GetDataValue(); 4872 if (is_observed) old_value = it->GetDataValue();
4910 4873
4911 it->ReconfigureDataProperty(value, attributes); 4874 it->ReconfigureDataProperty(value, attributes);
4912 4875
4913 if (is_observed) { 4876 if (is_observed) {
4914 if (old_value->SameValue(*value)) { 4877 if (old_value->SameValue(*value)) {
4915 old_value = it->factory()->the_hole_value(); 4878 old_value = it->factory()->the_hole_value();
4916 } 4879 }
4917 RETURN_ON_EXCEPTION(it->isolate(), 4880 RETURN_ON_EXCEPTION_VALUE(
4918 EnqueueChangeRecord(object, "reconfigure", 4881 it->isolate(), EnqueueChangeRecord(object, "reconfigure",
4919 it->GetName(), old_value), 4882 it->GetName(), old_value),
4920 Object); 4883 Nothing<bool>());
4921 } 4884 }
4922 return value; 4885 return Just(true);
4923 } 4886 }
4924 } 4887 }
4925 } 4888 }
4926 4889
4927 return AddDataProperty(it, value, attributes, STRICT, 4890 return AddDataProperty(it, value, attributes, should_throw,
4928 CERTAINLY_NOT_STORE_FROM_KEYED); 4891 CERTAINLY_NOT_STORE_FROM_KEYED);
4929 } 4892 }
4930 4893
4931 4894
4932 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( 4895 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
4933 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, 4896 Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
4934 PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) { 4897 PropertyAttributes attributes, ExecutableAccessorInfoHandling handling) {
4935 DCHECK(!value->IsTheHole()); 4898 DCHECK(!value->IsTheHole());
4936 LookupIterator it(object, name, LookupIterator::OWN); 4899 LookupIterator it(object, name, LookupIterator::OWN);
4937 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes, handling); 4900 return DefineOwnPropertyIgnoreAttributes(&it, value, attributes, handling);
(...skipping 12993 matching lines...) Expand 10 before | Expand all | Expand 10 after
17931 if (cell->value() != *new_value) { 17894 if (cell->value() != *new_value) {
17932 cell->set_value(*new_value); 17895 cell->set_value(*new_value);
17933 Isolate* isolate = cell->GetIsolate(); 17896 Isolate* isolate = cell->GetIsolate();
17934 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17897 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17935 isolate, DependentCode::kPropertyCellChangedGroup); 17898 isolate, DependentCode::kPropertyCellChangedGroup);
17936 } 17899 }
17937 } 17900 }
17938 17901
17939 } // namespace internal 17902 } // namespace internal
17940 } // namespace v8 17903 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698