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

Side by Side Diff: src/objects.cc

Issue 1394983005: Restructure Object::SetProperty and related functions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Redo again, now using ShouldThrow argument. Created 5 years, 2 months 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
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | 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 847 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate, 858 bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate,
859 Handle<AccessorInfo> info, 859 Handle<AccessorInfo> info,
860 Handle<Map> map) { 860 Handle<Map> map) {
861 if (!info->HasExpectedReceiverType()) return true; 861 if (!info->HasExpectedReceiverType()) return true;
862 if (!map->IsJSObjectMap()) return false; 862 if (!map->IsJSObjectMap()) return false;
863 return FunctionTemplateInfo::cast(info->expected_receiver_type()) 863 return FunctionTemplateInfo::cast(info->expected_receiver_type())
864 ->IsTemplateFor(*map); 864 ->IsTemplateFor(*map);
865 } 865 }
866 866
867 867
868 MaybeHandle<Object> Object::SetPropertyWithAccessor( 868 #define RETURN_FAILURE(isolate, should_throw, call) \
869 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { 869 do { \
870 if ((should_throw) == DONT_THROW) { \
871 return Just(false); \
872 } else { \
873 isolate->Throw(*isolate->factory()->call); \
874 return Nothing<bool>(); \
875 } \
876 } while (false)
877
878
879 Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
880 Handle<Object> value,
881 LanguageMode language_mode,
882 ShouldThrow should_throw) {
870 Isolate* isolate = it->isolate(); 883 Isolate* isolate = it->isolate();
871 Handle<Object> structure = it->GetAccessors(); 884 Handle<Object> structure = it->GetAccessors();
872 Handle<Object> receiver = it->GetReceiver(); 885 Handle<Object> receiver = it->GetReceiver();
873 886
874 // We should never get here to initialize a const with the hole value since a 887 // We should never get here to initialize a const with the hole value since a
875 // const declaration would conflict with the setter. 888 // const declaration would conflict with the setter.
876 DCHECK(!structure->IsForeign()); 889 DCHECK(!structure->IsForeign());
877 890
878 // API style callbacks. 891 // API style callbacks.
879 if (structure->IsExecutableAccessorInfo()) { 892 if (structure->IsExecutableAccessorInfo()) {
880 Handle<JSObject> holder = it->GetHolder<JSObject>(); 893 Handle<JSObject> holder = it->GetHolder<JSObject>();
881 Handle<Name> name = it->GetName(); 894 Handle<Name> name = it->GetName();
882 Handle<ExecutableAccessorInfo> info = 895 Handle<ExecutableAccessorInfo> info =
883 Handle<ExecutableAccessorInfo>::cast(structure); 896 Handle<ExecutableAccessorInfo>::cast(structure);
884 if (!info->IsCompatibleReceiver(*receiver)) { 897 if (!info->IsCompatibleReceiver(*receiver)) {
885 THROW_NEW_ERROR(isolate, 898 isolate->Throw(*isolate->factory()->NewTypeError(
886 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, 899 MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
887 name, receiver), 900 return Nothing<bool>();
888 Object);
889 } 901 }
890 902
891 v8::AccessorNameSetterCallback call_fun = 903 v8::AccessorNameSetterCallback call_fun =
892 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter()); 904 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter());
893 if (call_fun == nullptr) return value; 905 if (call_fun == nullptr) return Just(true);
Toon Verwaest 2015/10/20 15:25:06 Shouldn't this case be unreachable (at least in th
neis 2015/10/21 14:42:25 Done.
894 906
895 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name)); 907 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
896 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder); 908 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
897 args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); 909 args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
898 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 910 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
899 return value; 911 return Just(true);
900 } 912 }
901 913
902 // Regular accessor. 914 // Regular accessor.
903 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); 915 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
904 if (setter->IsCallable()) { 916 if (setter->IsCallable()) {
905 // TODO(rossberg): nicer would be to cast to some JSCallable here... 917 // TODO(rossberg): nicer would be to cast to some JSCallable here...
906 return SetPropertyWithDefinedSetter( 918 return SetPropertyWithDefinedSetter(
907 receiver, Handle<JSReceiver>::cast(setter), value); 919 receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
908 } 920 }
909 921
910 if (is_sloppy(language_mode)) return value; 922 if (is_sloppy(language_mode)) return Just(true);
911 923 RETURN_FAILURE(isolate, should_throw,
912 THROW_NEW_ERROR(isolate, 924 NewTypeError(MessageTemplate::kNoSetterInCallback,
913 NewTypeError(MessageTemplate::kNoSetterInCallback, 925 it->GetName(), it->GetHolder<JSObject>()));
914 it->GetName(), it->GetHolder<JSObject>()),
915 Object);
916 } 926 }
917 927
918 928
919 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( 929 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
920 Handle<Object> receiver, 930 Handle<Object> receiver,
921 Handle<JSReceiver> getter) { 931 Handle<JSReceiver> getter) {
922 Isolate* isolate = getter->GetIsolate(); 932 Isolate* isolate = getter->GetIsolate();
923 933
924 // Platforms with simulators like arm/arm64 expose a funny issue. If the 934 // Platforms with simulators like arm/arm64 expose a funny issue. If the
925 // simulator has a separate JS stack pointer from the C++ stack pointer, it 935 // simulator has a separate JS stack pointer from the C++ stack pointer, it
(...skipping 11 matching lines...) Expand all
937 947
938 Debug* debug = isolate->debug(); 948 Debug* debug = isolate->debug();
939 // Handle stepping into a getter if step into is active. 949 // Handle stepping into a getter if step into is active.
940 // TODO(rossberg): should this apply to getters that are function proxies? 950 // TODO(rossberg): should this apply to getters that are function proxies?
941 if (debug->is_active()) debug->HandleStepIn(getter, false); 951 if (debug->is_active()) debug->HandleStepIn(getter, false);
942 952
943 return Execution::Call(isolate, getter, receiver, 0, NULL); 953 return Execution::Call(isolate, getter, receiver, 0, NULL);
944 } 954 }
945 955
946 956
947 MaybeHandle<Object> Object::SetPropertyWithDefinedSetter( 957 Maybe<bool> Object::SetPropertyWithDefinedSetter(Handle<Object> receiver,
948 Handle<Object> receiver, 958 Handle<JSReceiver> setter,
949 Handle<JSReceiver> setter, 959 Handle<Object> value,
950 Handle<Object> value) { 960 ShouldThrow should_throw) {
951 Isolate* isolate = setter->GetIsolate(); 961 Isolate* isolate = setter->GetIsolate();
952 962
953 Debug* debug = isolate->debug(); 963 Debug* debug = isolate->debug();
954 // Handle stepping into a setter if step into is active. 964 // Handle stepping into a setter if step into is active.
955 // TODO(rossberg): should this apply to getters that are function proxies? 965 // TODO(rossberg): should this apply to getters that are function proxies?
956 if (debug->is_active()) debug->HandleStepIn(setter, false); 966 if (debug->is_active()) debug->HandleStepIn(setter, false);
957 967
958 Handle<Object> argv[] = { value }; 968 Handle<Object> argv[] = { value };
959 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver, 969 RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
960 arraysize(argv), argv), 970 arraysize(argv), argv),
961 Object); 971 Nothing<bool>());
962 return value; 972 return Just(true);
963 } 973 }
964 974
965 975
966 // static 976 // static
967 bool JSObject::AllCanRead(LookupIterator* it) { 977 bool JSObject::AllCanRead(LookupIterator* it) {
968 // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of 978 // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
969 // which have already been checked. 979 // which have already been checked.
970 DCHECK(it->state() == LookupIterator::ACCESS_CHECK || 980 DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
971 it->state() == LookupIterator::INTERCEPTOR); 981 it->state() == LookupIterator::INTERCEPTOR);
972 for (it->Next(); it->IsFound(); it->Next()) { 982 for (it->Next(); it->IsFound(); it->Next()) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 Handle<Object> accessors = it->GetAccessors(); 1047 Handle<Object> accessors = it->GetAccessors();
1038 if (accessors->IsAccessorInfo()) { 1048 if (accessors->IsAccessorInfo()) {
1039 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; 1049 if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
1040 } 1050 }
1041 } 1051 }
1042 } 1052 }
1043 return false; 1053 return false;
1044 } 1054 }
1045 1055
1046 1056
1047 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( 1057 Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
1048 LookupIterator* it, Handle<Object> value) { 1058 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
1049 Handle<JSObject> checked = it->GetHolder<JSObject>(); 1059 Handle<JSObject> checked = it->GetHolder<JSObject>();
1050 if (AllCanWrite(it)) { 1060 if (AllCanWrite(it)) {
1051 // The supplied language-mode is ignored by SetPropertyWithAccessor. 1061 // The supplied language-mode is ignored by SetPropertyWithAccessor.
1052 return SetPropertyWithAccessor(it, value, SLOPPY); 1062 return SetPropertyWithAccessor(it, value, SLOPPY, should_throw);
1053 } 1063 }
1054 1064
1055 it->isolate()->ReportFailedAccessCheck(checked); 1065 it->isolate()->ReportFailedAccessCheck(checked);
1056 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 1066 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
1057 return value; 1067 UNREACHABLE();
1068 it->isolate()->Throw(
1069 *it->isolate()->factory()->NewTypeError(MessageTemplate::kNoAccess));
1070 return Nothing<bool>();
Toon Verwaest 2015/10/20 15:25:06 Nice. Wouldn't it be helpful to extract this to a
neis 2015/10/21 14:42:25 Yes, and this should probably be used in many othe
1058 } 1071 }
1059 1072
1060 1073
1061 void JSObject::SetNormalizedProperty(Handle<JSObject> object, 1074 void JSObject::SetNormalizedProperty(Handle<JSObject> object,
1062 Handle<Name> name, 1075 Handle<Name> name,
1063 Handle<Object> value, 1076 Handle<Object> value,
1064 PropertyDetails details) { 1077 PropertyDetails details) {
1065 DCHECK(!object->HasFastProperties()); 1078 DCHECK(!object->HasFastProperties());
1066 if (!name->IsUniqueName()) { 1079 if (!name->IsUniqueName()) {
1067 name = object->GetIsolate()->factory()->InternalizeString( 1080 name = object->GetIsolate()->factory()->InternalizeString(
(...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after
3506 3519
3507 // static 3520 // static
3508 Handle<Map> Map::Update(Handle<Map> map) { 3521 Handle<Map> Map::Update(Handle<Map> map) {
3509 if (!map->is_deprecated()) return map; 3522 if (!map->is_deprecated()) return map;
3510 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), 3523 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(),
3511 HeapType::None(map->GetIsolate()), 3524 HeapType::None(map->GetIsolate()),
3512 ALLOW_IN_DESCRIPTOR); 3525 ALLOW_IN_DESCRIPTOR);
3513 } 3526 }
3514 3527
3515 3528
3516 MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it, 3529 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
3517 Handle<Object> value) { 3530 Handle<Object> value,
3531 ShouldThrow should_throw) {
3518 Isolate* isolate = it->isolate(); 3532 Isolate* isolate = it->isolate();
3519 // Make sure that the top context does not change when doing callbacks or 3533 // Make sure that the top context does not change when doing callbacks or
3520 // interceptor calls. 3534 // interceptor calls.
3521 AssertNoContextChange ncc(isolate); 3535 AssertNoContextChange ncc(isolate);
3522 3536
3523 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); 3537 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
3524 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); 3538 Handle<InterceptorInfo> interceptor(it->GetInterceptor());
3525 if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>(); 3539 if (interceptor->setter()->IsUndefined()) return Nothing<bool>();
3526 3540
3527 Handle<JSObject> holder = it->GetHolder<JSObject>(); 3541 Handle<JSObject> holder = it->GetHolder<JSObject>();
3528 v8::Local<v8::Value> result; 3542 v8::Local<v8::Value> result;
3529 PropertyCallbackArguments args(isolate, interceptor->data(), 3543 PropertyCallbackArguments args(isolate, interceptor->data(),
3530 *it->GetReceiver(), *holder); 3544 *it->GetReceiver(), *holder);
3531 3545
3532 if (it->IsElement()) { 3546 if (it->IsElement()) {
3533 uint32_t index = it->index(); 3547 uint32_t index = it->index();
3534 v8::IndexedPropertySetterCallback setter = 3548 v8::IndexedPropertySetterCallback setter =
3535 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); 3549 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
3536 LOG(isolate, 3550 LOG(isolate,
3537 ApiIndexedPropertyAccess("interceptor-indexed-set", *holder, index)); 3551 ApiIndexedPropertyAccess("interceptor-indexed-set", *holder, index));
3538 result = args.Call(setter, index, v8::Utils::ToLocal(value)); 3552 result = args.Call(setter, index, v8::Utils::ToLocal(value));
3539 } else { 3553 } else {
3540 Handle<Name> name = it->name(); 3554 Handle<Name> name = it->name();
3541 3555
3542 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { 3556 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) {
3543 return MaybeHandle<Object>(); 3557 return Nothing<bool>();
3544 } 3558 }
3545 3559
3546 v8::GenericNamedPropertySetterCallback setter = 3560 v8::GenericNamedPropertySetterCallback setter =
3547 v8::ToCData<v8::GenericNamedPropertySetterCallback>( 3561 v8::ToCData<v8::GenericNamedPropertySetterCallback>(
3548 interceptor->setter()); 3562 interceptor->setter());
3549 LOG(it->isolate(), 3563 LOG(it->isolate(),
3550 ApiNamedPropertyAccess("interceptor-named-set", *holder, *name)); 3564 ApiNamedPropertyAccess("interceptor-named-set", *holder, *name));
3551 result = 3565 result =
3552 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); 3566 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
3553 } 3567 }
3554 3568
3555 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 3569 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
3556 if (result.IsEmpty()) return MaybeHandle<Object>(); 3570 if (result.IsEmpty()) return Nothing<bool>();
3557 #ifdef DEBUG 3571 #ifdef DEBUG
3558 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 3572 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
3559 result_internal->VerifyApiCallResultType(); 3573 result_internal->VerifyApiCallResultType();
3560 #endif 3574 #endif
3561 return value; 3575 return Just(true);
3562 } 3576 }
3563 3577
3564 3578
3565 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, 3579 MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
3566 Handle<Name> name, Handle<Object> value, 3580 Handle<Name> name, Handle<Object> value,
3567 LanguageMode language_mode, 3581 LanguageMode language_mode,
3568 StoreFromKeyed store_mode) { 3582 StoreFromKeyed store_mode) {
3569 LookupIterator it(object, name); 3583 LookupIterator it(object, name);
3570 return SetProperty(&it, value, language_mode, store_mode); 3584 return SetProperty(&it, value, language_mode, store_mode);
3571 } 3585 }
3572 3586
3573 3587
3574 MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it, 3588 Maybe<bool> Object::SetPropertyInternal(
3575 Handle<Object> value, 3589 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
3576 LanguageMode language_mode, 3590 ShouldThrow should_throw, StoreFromKeyed store_mode, bool* found) {
3577 StoreFromKeyed store_mode,
3578 bool* found) {
3579 // Make sure that the top context does not change when doing callbacks or 3591 // Make sure that the top context does not change when doing callbacks or
3580 // interceptor calls. 3592 // interceptor calls.
3581 AssertNoContextChange ncc(it->isolate()); 3593 AssertNoContextChange ncc(it->isolate());
3582 3594
3583 *found = true; 3595 *found = true;
3584 3596
3585 bool done = false; 3597 bool done = false;
3586 for (; it->IsFound(); it->Next()) { 3598 for (; it->IsFound(); it->Next()) {
3587 switch (it->state()) { 3599 switch (it->state()) {
3588 case LookupIterator::NOT_FOUND: 3600 case LookupIterator::NOT_FOUND:
3589 UNREACHABLE(); 3601 UNREACHABLE();
3590 3602
3591 case LookupIterator::ACCESS_CHECK: 3603 case LookupIterator::ACCESS_CHECK:
3592 if (it->HasAccess()) break; 3604 if (it->HasAccess()) break;
3593 // Check whether it makes sense to reuse the lookup iterator. Here it 3605 // Check whether it makes sense to reuse the lookup iterator. Here it
3594 // might still call into setters up the prototype chain. 3606 // might still call into setters up the prototype chain.
3595 return JSObject::SetPropertyWithFailedAccessCheck(it, value); 3607 return JSObject::SetPropertyWithFailedAccessCheck(it, value,
3608 should_throw);
3596 3609
3597 case LookupIterator::JSPROXY: 3610 case LookupIterator::JSPROXY:
3598 if (it->HolderIsReceiverOrHiddenPrototype()) { 3611 if (it->HolderIsReceiverOrHiddenPrototype()) {
3599 return JSProxy::SetPropertyWithHandler( 3612 return JSProxy::SetPropertyWithHandler(
3600 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value, 3613 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value,
3601 language_mode); 3614 language_mode, should_throw);
3602 } else { 3615 } else {
3603 // TODO(verwaest): Use the MaybeHandle to indicate result. 3616 // TODO(verwaest): Use the MaybeHandle to indicate result.
3604 bool has_result = false; 3617 bool has_result = false;
3605 MaybeHandle<Object> maybe_result = 3618 Maybe<bool> maybe_result =
3606 JSProxy::SetPropertyViaPrototypesWithHandler( 3619 JSProxy::SetPropertyViaPrototypesWithHandler(
3607 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), 3620 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(),
3608 value, language_mode, &has_result); 3621 value, language_mode, should_throw, &has_result);
3609 if (has_result) return maybe_result; 3622 if (has_result) return maybe_result;
3610 done = true; 3623 done = true;
3611 } 3624 }
3612 break; 3625 break;
3613 3626
3614 case LookupIterator::INTERCEPTOR: 3627 case LookupIterator::INTERCEPTOR:
3615 if (it->HolderIsReceiverOrHiddenPrototype()) { 3628 if (it->HolderIsReceiverOrHiddenPrototype()) {
3616 MaybeHandle<Object> maybe_result = 3629 Maybe<bool> maybe_result =
3617 JSObject::SetPropertyWithInterceptor(it, value); 3630 JSObject::SetPropertyWithInterceptor(it, value, should_throw);
3618 if (!maybe_result.is_null()) return maybe_result; 3631 if (maybe_result.IsJust()) return maybe_result;
3619 if (it->isolate()->has_pending_exception()) return maybe_result; 3632 if (it->isolate()->has_pending_exception()) return maybe_result;
3620 } else { 3633 } else {
3621 Maybe<PropertyAttributes> maybe_attributes = 3634 Maybe<PropertyAttributes> maybe_attributes =
3622 JSObject::GetPropertyAttributesWithInterceptor(it); 3635 JSObject::GetPropertyAttributesWithInterceptor(it);
3623 if (!maybe_attributes.IsJust()) return MaybeHandle<Object>(); 3636 if (!maybe_attributes.IsJust()) return Nothing<bool>();
3624 done = maybe_attributes.FromJust() != ABSENT; 3637 done = maybe_attributes.FromJust() != ABSENT;
3625 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) { 3638 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) {
3626 return WriteToReadOnlyProperty(it, value, language_mode); 3639 return WriteToReadOnlyProperty(it, value, language_mode,
3640 should_throw);
3627 } 3641 }
3628 } 3642 }
3629 break; 3643 break;
3630 3644
3631 case LookupIterator::ACCESSOR: { 3645 case LookupIterator::ACCESSOR: {
3632 if (it->IsReadOnly()) { 3646 if (it->IsReadOnly()) {
3633 return WriteToReadOnlyProperty(it, value, language_mode); 3647 return WriteToReadOnlyProperty(it, value, language_mode,
3648 should_throw);
3634 } 3649 }
3635 Handle<Object> accessors = it->GetAccessors(); 3650 Handle<Object> accessors = it->GetAccessors();
3636 if (accessors->IsAccessorInfo() && 3651 if (accessors->IsAccessorInfo() &&
3637 !it->HolderIsReceiverOrHiddenPrototype() && 3652 !it->HolderIsReceiverOrHiddenPrototype() &&
3638 AccessorInfo::cast(*accessors)->is_special_data_property()) { 3653 AccessorInfo::cast(*accessors)->is_special_data_property()) {
3639 done = true; 3654 done = true;
3640 break; 3655 break;
3641 } 3656 }
3642 return SetPropertyWithAccessor(it, value, language_mode); 3657 return SetPropertyWithAccessor(it, value, language_mode, should_throw);
3643 } 3658 }
3644 case LookupIterator::INTEGER_INDEXED_EXOTIC: 3659 case LookupIterator::INTEGER_INDEXED_EXOTIC:
3645 // TODO(verwaest): We should throw an exception. 3660 // TODO(verwaest): We should throw an exception.
3646 return value; 3661 return Just(true);
3647 3662
3648 case LookupIterator::DATA: 3663 case LookupIterator::DATA:
3649 if (it->IsReadOnly()) { 3664 if (it->IsReadOnly()) {
3650 return WriteToReadOnlyProperty(it, value, language_mode); 3665 return WriteToReadOnlyProperty(it, value, language_mode,
3666 should_throw);
3651 } 3667 }
3652 if (it->HolderIsReceiverOrHiddenPrototype()) { 3668 if (it->HolderIsReceiverOrHiddenPrototype()) {
3653 return SetDataProperty(it, value); 3669 return SetDataProperty(it, value, should_throw);
3654 } 3670 }
3655 done = true; 3671 done = true;
3656 break; 3672 break;
3657 3673
3658 case LookupIterator::TRANSITION: 3674 case LookupIterator::TRANSITION:
3659 done = true; 3675 done = true;
3660 break; 3676 break;
3661 } 3677 }
3662 3678
3663 if (done) break; 3679 if (done) break;
3664 } 3680 }
3665 3681
3666 // If the receiver is the JSGlobalObject, the store was contextual. In case 3682 // If the receiver is the JSGlobalObject, the store was contextual. In case
3667 // the property did not exist yet on the global object itself, we have to 3683 // the property did not exist yet on the global object itself, we have to
3668 // throw a reference error in strict mode. 3684 // throw a reference error in strict mode.
3669 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { 3685 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) {
3670 THROW_NEW_ERROR(it->isolate(), 3686 RETURN_FAILURE(it->isolate(), should_throw,
3671 NewReferenceError(MessageTemplate::kNotDefined, it->name()), 3687 NewReferenceError(MessageTemplate::kNotDefined, it->name()));
3672 Object);
3673 } 3688 }
3674 3689
3675 *found = false; 3690 *found = false;
3676 return MaybeHandle<Object>(); 3691 return Nothing<bool>();
3677 } 3692 }
3678 3693
3679 3694
3680 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, 3695 MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
3681 Handle<Object> value, 3696 Handle<Object> value,
3682 LanguageMode language_mode, 3697 LanguageMode language_mode,
3683 StoreFromKeyed store_mode) { 3698 StoreFromKeyed store_mode) {
3684 bool found = false; 3699 Maybe<bool> result =
3685 MaybeHandle<Object> result = 3700 SetProperty(it, value, language_mode, THROW_ON_ERROR, store_mode);
3686 SetPropertyInternal(it, value, language_mode, store_mode, &found); 3701 return result.IsJust() ? value : MaybeHandle<Object>();
rossberg 2015/10/14 15:59:06 This pattern occurs several times, maybe introduce
3687 if (found) return result;
3688 return AddDataProperty(it, value, NONE, language_mode, store_mode);
3689 } 3702 }
3690 3703
3691 3704
3705 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
3706 LanguageMode language_mode,
3707 ShouldThrow should_throw,
3708 StoreFromKeyed store_mode) {
3709 bool found = false;
3710 Maybe<bool> result = SetPropertyInternal(it, value, language_mode,
3711 should_throw, store_mode, &found);
3712 if (found) return result;
3713 return AddDataProperty(it, value, NONE, language_mode, should_throw,
3714 store_mode);
3715 }
3716
3717
3692 MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it, 3718 MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
3693 Handle<Object> value, 3719 Handle<Object> value,
3694 LanguageMode language_mode, 3720 LanguageMode language_mode,
3695 StoreFromKeyed store_mode) { 3721 StoreFromKeyed store_mode) {
3696 bool found = false; 3722 bool found = false;
3697 MaybeHandle<Object> result = 3723 Maybe<bool> result = SetPropertyInternal(it, value, language_mode,
3698 SetPropertyInternal(it, value, language_mode, store_mode, &found); 3724 THROW_ON_ERROR, store_mode, &found);
3699 if (found) return result; 3725 if (found) return result.IsJust() ? value : MaybeHandle<Object>();
3700 3726
3701 if (!it->GetReceiver()->IsJSReceiver()) { 3727 if (!it->GetReceiver()->IsJSReceiver()) {
3702 return WriteToReadOnlyProperty(it, value, language_mode); 3728 Maybe<bool> result =
3729 WriteToReadOnlyProperty(it, value, language_mode, THROW_ON_ERROR);
3730 return result.IsJust() ? value : MaybeHandle<Object>();
3703 } 3731 }
3704 3732
3705 LookupIterator::Configuration c = LookupIterator::OWN; 3733 LookupIterator::Configuration c = LookupIterator::OWN;
3706 LookupIterator own_lookup = 3734 LookupIterator own_lookup =
3707 it->IsElement() 3735 it->IsElement()
3708 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c) 3736 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c)
3709 : LookupIterator(it->GetReceiver(), it->name(), c); 3737 : LookupIterator(it->GetReceiver(), it->name(), c);
3710 3738
3711 for (; own_lookup.IsFound(); own_lookup.Next()) { 3739 for (; own_lookup.IsFound(); own_lookup.Next()) {
3712 switch (own_lookup.state()) { 3740 switch (own_lookup.state()) {
3713 case LookupIterator::ACCESS_CHECK: 3741 case LookupIterator::ACCESS_CHECK:
3714 if (!own_lookup.HasAccess()) { 3742 if (!own_lookup.HasAccess()) {
3715 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value); 3743 Maybe<bool> result = JSObject::SetPropertyWithFailedAccessCheck(
3744 &own_lookup, value, THROW_ON_ERROR);
3745 return result.IsJust() ? value : MaybeHandle<Object>();
3716 } 3746 }
3717 break; 3747 break;
3718 3748
3719 case LookupIterator::INTEGER_INDEXED_EXOTIC: 3749 case LookupIterator::INTEGER_INDEXED_EXOTIC:
3720 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 3750 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
3721 value, language_mode); 3751 value, language_mode);
3722 3752
3723 case LookupIterator::DATA: { 3753 case LookupIterator::DATA: {
3724 PropertyDetails details = own_lookup.property_details(); 3754 PropertyDetails details = own_lookup.property_details();
3725 if (details.IsConfigurable() || !details.IsReadOnly()) { 3755 if (details.IsConfigurable() || !details.IsReadOnly()) {
3726 return JSObject::DefineOwnPropertyIgnoreAttributes( 3756 return JSObject::DefineOwnPropertyIgnoreAttributes(
3727 &own_lookup, value, details.attributes()); 3757 &own_lookup, value, details.attributes());
3728 } 3758 }
3729 return WriteToReadOnlyProperty(&own_lookup, value, language_mode); 3759 Maybe<bool> result = WriteToReadOnlyProperty(
3760 &own_lookup, value, language_mode, THROW_ON_ERROR);
3761 return result.IsJust() ? value : MaybeHandle<Object>();
3730 } 3762 }
3731 3763
3732 case LookupIterator::ACCESSOR: { 3764 case LookupIterator::ACCESSOR: {
3733 PropertyDetails details = own_lookup.property_details(); 3765 PropertyDetails details = own_lookup.property_details();
3734 if (details.IsConfigurable()) { 3766 if (details.IsConfigurable()) {
3735 return JSObject::DefineOwnPropertyIgnoreAttributes( 3767 return JSObject::DefineOwnPropertyIgnoreAttributes(
3736 &own_lookup, value, details.attributes()); 3768 &own_lookup, value, details.attributes());
3737 } 3769 }
3738 3770
3739 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 3771 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
3740 value, language_mode); 3772 value, language_mode);
3741 } 3773 }
3742 3774
3743 case LookupIterator::INTERCEPTOR: 3775 case LookupIterator::INTERCEPTOR:
3744 case LookupIterator::JSPROXY: { 3776 case LookupIterator::JSPROXY: {
3745 bool found = false; 3777 bool found = false;
3746 MaybeHandle<Object> result = SetPropertyInternal( 3778 Maybe<bool> result =
3747 &own_lookup, value, language_mode, store_mode, &found); 3779 SetPropertyInternal(&own_lookup, value, language_mode,
3748 if (found) return result; 3780 THROW_ON_ERROR, store_mode, &found);
3781 if (found) return result.IsJust() ? value : MaybeHandle<Object>();
3749 break; 3782 break;
3750 } 3783 }
3751 3784
3752 case LookupIterator::NOT_FOUND: 3785 case LookupIterator::NOT_FOUND:
3753 case LookupIterator::TRANSITION: 3786 case LookupIterator::TRANSITION:
3754 UNREACHABLE(); 3787 UNREACHABLE();
3755 } 3788 }
3756 } 3789 }
3757 3790
3758 return JSObject::AddDataProperty(&own_lookup, value, NONE, language_mode, 3791 return JSObject::AddDataProperty(&own_lookup, value, NONE, language_mode,
(...skipping 19 matching lines...) Expand all
3778 if (is_strong(language_mode)) { 3811 if (is_strong(language_mode)) {
3779 THROW_NEW_ERROR( 3812 THROW_NEW_ERROR(
3780 isolate, 3813 isolate,
3781 NewTypeError(MessageTemplate::kStrongPropertyAccess, name, receiver), 3814 NewTypeError(MessageTemplate::kStrongPropertyAccess, name, receiver),
3782 Object); 3815 Object);
3783 } 3816 }
3784 return isolate->factory()->undefined_value(); 3817 return isolate->factory()->undefined_value();
3785 } 3818 }
3786 3819
3787 3820
3788 MaybeHandle<Object> Object::CannotCreateProperty(LookupIterator* it, 3821 Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
3789 Handle<Object> value, 3822 Handle<Object> receiver,
3790 LanguageMode language_mode) { 3823 Handle<Object> name,
3791 return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(), 3824 Handle<Object> value,
3792 value, language_mode); 3825 LanguageMode language_mode,
3826 ShouldThrow should_throw) {
3827 if (is_sloppy(language_mode)) return Just(true);
3828 RETURN_FAILURE(
3829 isolate, should_throw,
3830 NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
3831 Object::TypeOf(isolate, receiver), receiver));
3793 } 3832 }
3794 3833
3795 3834
3796 MaybeHandle<Object> Object::CannotCreateProperty(Isolate* isolate, 3835 Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
3797 Handle<Object> receiver, 3836 Handle<Object> value,
3798 Handle<Object> name, 3837 LanguageMode language_mode,
3799 Handle<Object> value, 3838 ShouldThrow should_throw) {
3800 LanguageMode language_mode) { 3839 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
3801 if (is_sloppy(language_mode)) return value; 3840 it->GetName(), value, language_mode,
3802 Handle<String> typeof_string = Object::TypeOf(isolate, receiver); 3841 should_throw);
3803 THROW_NEW_ERROR(isolate,
3804 NewTypeError(MessageTemplate::kStrictCannotCreateProperty,
3805 name, typeof_string, receiver),
3806 Object);
3807 } 3842 }
3808 3843
3809 3844
3810 MaybeHandle<Object> Object::WriteToReadOnlyProperty( 3845 Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
3811 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { 3846 Handle<Object> receiver,
3812 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), 3847 Handle<Object> name,
3813 it->GetName(), value, language_mode); 3848 Handle<Object> value,
3849 LanguageMode language_mode,
3850 ShouldThrow should_throw) {
3851 if (is_sloppy(language_mode)) return Just(true);
3852 RETURN_FAILURE(isolate, should_throw,
3853 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
3854 Object::TypeOf(isolate, receiver), receiver));
3814 } 3855 }
3815 3856
3816 3857
3817 MaybeHandle<Object> Object::WriteToReadOnlyProperty(
3818 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
3819 Handle<Object> value, LanguageMode language_mode) {
3820 if (is_sloppy(language_mode)) return value;
3821 Handle<String> typeof_string = Object::TypeOf(isolate, receiver);
3822 THROW_NEW_ERROR(isolate,
3823 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
3824 typeof_string, receiver),
3825 Object);
3826 }
3827
3828
3829 MaybeHandle<Object> Object::RedefineNonconfigurableProperty( 3858 MaybeHandle<Object> Object::RedefineNonconfigurableProperty(
3830 Isolate* isolate, Handle<Object> name, Handle<Object> value, 3859 Isolate* isolate, Handle<Object> name, Handle<Object> value,
3831 LanguageMode language_mode) { 3860 LanguageMode language_mode) {
3832 if (is_sloppy(language_mode)) return value; 3861 if (is_sloppy(language_mode)) return value;
3833 THROW_NEW_ERROR(isolate, 3862 THROW_NEW_ERROR(isolate,
3834 NewTypeError(MessageTemplate::kRedefineDisallowed, name), 3863 NewTypeError(MessageTemplate::kRedefineDisallowed, name),
3835 Object); 3864 Object);
3836 } 3865 }
3837 3866
3838 3867
3839 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, 3868 Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value,
3840 Handle<Object> value) { 3869 ShouldThrow should_throw) {
3841 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot 3870 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
3842 // have own properties. 3871 // have own properties.
3843 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 3872 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
3844 3873
3845 // Store on the holder which may be hidden behind the receiver. 3874 // Store on the holder which may be hidden behind the receiver.
3846 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); 3875 DCHECK(it->HolderIsReceiverOrHiddenPrototype());
3847 3876
3848 // Old value for the observation change record. 3877 // Old value for the observation change record.
3849 // Fetch before transforming the object since the encoding may become 3878 // Fetch before transforming the object since the encoding may become
3850 // incompatible with what's cached in |it|. 3879 // incompatible with what's cached in |it|.
3851 bool is_observed = receiver->map()->is_observed() && 3880 bool is_observed = receiver->map()->is_observed() &&
3852 (it->IsElement() || 3881 (it->IsElement() ||
3853 !it->isolate()->IsInternallyUsedPropertyName(it->name())); 3882 !it->isolate()->IsInternallyUsedPropertyName(it->name()));
3854 MaybeHandle<Object> maybe_old; 3883 MaybeHandle<Object> maybe_old;
3855 if (is_observed) maybe_old = it->GetDataValue(); 3884 if (is_observed) maybe_old = it->GetDataValue();
3856 3885
3857 Handle<Object> to_assign = value; 3886 Handle<Object> to_assign = value;
3858 // Convert the incoming value to a number for storing into typed arrays. 3887 // Convert the incoming value to a number for storing into typed arrays.
3859 if (it->IsElement() && receiver->HasFixedTypedArrayElements()) { 3888 if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
3860 if (!value->IsNumber() && !value->IsUndefined()) { 3889 if (!value->IsNumber() && !value->IsUndefined()) {
3861 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), to_assign, 3890 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3862 Object::ToNumber(value), Object); 3891 it->isolate(), to_assign, Object::ToNumber(value), Nothing<bool>());
3863 // ToNumber above might modify the receiver, causing the cached 3892 // ToNumber above might modify the receiver, causing the cached
3864 // holder_map to mismatch the actual holder->map() after this point. 3893 // holder_map to mismatch the actual holder->map() after this point.
3865 // Reload the map to be in consistent state. Other cached state cannot 3894 // Reload the map to be in consistent state. Other cached state cannot
3866 // have been invalidated since typed array elements cannot be reconfigured 3895 // have been invalidated since typed array elements cannot be reconfigured
3867 // in any way. 3896 // in any way.
3868 it->ReloadHolderMap(); 3897 it->ReloadHolderMap();
3869 3898
3870 // We have to recheck the length. However, it can only change if the 3899 // We have to recheck the length. However, it can only change if the
3871 // underlying buffer was neutered, so just check that. 3900 // underlying buffer was neutered, so just check that.
3872 if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) { 3901 if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) {
3873 return value; 3902 return Just(true);
3903 // TODO(neis): According to the spec, this should throw a TypeError.
3874 } 3904 }
3875 } 3905 }
3876 } 3906 }
3877 3907
3878 // Possibly migrate to the most up-to-date map that will be able to store 3908 // Possibly migrate to the most up-to-date map that will be able to store
3879 // |value| under it->name(). 3909 // |value| under it->name().
3880 it->PrepareForDataProperty(to_assign); 3910 it->PrepareForDataProperty(to_assign);
3881 3911
3882 // Write the property value. 3912 // Write the property value.
3883 it->WriteDataValue(to_assign); 3913 it->WriteDataValue(to_assign);
3884 3914
3885 // Send the change record if there are observers. 3915 // Send the change record if there are observers.
3886 if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) { 3916 if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
3887 RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord( 3917 RETURN_ON_EXCEPTION_VALUE(
3888 receiver, "update", it->GetName(), 3918 it->isolate(),
3889 maybe_old.ToHandleChecked()), 3919 JSObject::EnqueueChangeRecord(receiver, "update", it->GetName(),
3890 Object); 3920 maybe_old.ToHandleChecked()),
3921 Nothing<bool>());
3891 } 3922 }
3892 3923
3893 #if VERIFY_HEAP 3924 #if VERIFY_HEAP
3894 if (FLAG_verify_heap) { 3925 if (FLAG_verify_heap) {
3895 receiver->JSObjectVerify(); 3926 receiver->JSObjectVerify();
3896 } 3927 }
3897 #endif 3928 #endif
3898 return value; 3929 return Just(true);
3899 } 3930 }
3900 3931
3901 3932
3902 MUST_USE_RESULT static MaybeHandle<Object> BeginPerformSplice( 3933 MUST_USE_RESULT static MaybeHandle<Object> BeginPerformSplice(
3903 Handle<JSArray> object) { 3934 Handle<JSArray> object) {
3904 Isolate* isolate = object->GetIsolate(); 3935 Isolate* isolate = object->GetIsolate();
3905 HandleScope scope(isolate); 3936 HandleScope scope(isolate);
3906 Handle<Object> args[] = {object}; 3937 Handle<Object> args[] = {object};
3907 3938
3908 return Execution::Call( 3939 return Execution::Call(
(...skipping 29 matching lines...) Expand all
3938 isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()), 3969 isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()),
3939 isolate->factory()->undefined_value(), arraysize(args), args); 3970 isolate->factory()->undefined_value(), arraysize(args), args);
3940 } 3971 }
3941 3972
3942 3973
3943 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, 3974 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
3944 Handle<Object> value, 3975 Handle<Object> value,
3945 PropertyAttributes attributes, 3976 PropertyAttributes attributes,
3946 LanguageMode language_mode, 3977 LanguageMode language_mode,
3947 StoreFromKeyed store_mode) { 3978 StoreFromKeyed store_mode) {
3979 Maybe<bool> result = AddDataProperty(it, value, attributes, language_mode,
3980 THROW_ON_ERROR, store_mode);
3981 return result.IsJust() ? value : MaybeHandle<Object>();
3982 }
3983
3984
3985 Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
3986 PropertyAttributes attributes,
3987 LanguageMode language_mode,
3988 ShouldThrow should_throw,
3989 StoreFromKeyed store_mode) {
3948 DCHECK(!it->GetReceiver()->IsJSProxy()); 3990 DCHECK(!it->GetReceiver()->IsJSProxy());
3949 if (!it->GetReceiver()->IsJSObject()) { 3991 if (!it->GetReceiver()->IsJSObject()) {
3950 return CannotCreateProperty(it, value, language_mode); 3992 return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
3993 value, language_mode, should_throw);
3951 } 3994 }
3952 3995
3953 DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state()); 3996 DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
3954 3997
3955 Handle<JSObject> receiver = it->GetStoreTarget(); 3998 Handle<JSObject> receiver = it->GetStoreTarget();
3956 3999
3957 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) 4000 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
3958 // instead. If the prototype is Null, the proxy is detached. 4001 // instead. If the prototype is Null, the proxy is detached.
3959 if (receiver->IsJSGlobalProxy()) return value; 4002 if (receiver->IsJSGlobalProxy()) return Just(true);
3960 4003
3961 Isolate* isolate = it->isolate(); 4004 Isolate* isolate = it->isolate();
3962 4005
3963 if (!receiver->map()->is_extensible() && 4006 if (!receiver->map()->is_extensible() &&
3964 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) { 4007 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) {
3965 if (is_sloppy(language_mode)) return value; 4008 if (is_sloppy(language_mode)) return Just(true);
3966 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kObjectNotExtensible, 4009 RETURN_FAILURE(
3967 it->GetName()), 4010 isolate, should_throw,
3968 Object); 4011 NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
3969 } 4012 }
3970 4013
3971 if (it->IsElement()) { 4014 if (it->IsElement()) {
3972 if (receiver->IsJSArray()) { 4015 if (receiver->IsJSArray()) {
3973 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 4016 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
3974 if (JSArray::WouldChangeReadOnlyLength(array, it->index())) { 4017 if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
3975 if (is_sloppy(language_mode)) return value; 4018 if (is_sloppy(language_mode)) return Just(true);
3976 return JSArray::ReadOnlyLengthError(array); 4019 RETURN_FAILURE(array->GetIsolate(), should_throw,
4020 NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
4021 isolate->factory()->length_string(),
4022 Object::TypeOf(isolate, array), array));
3977 } 4023 }
3978 4024
3979 if (FLAG_trace_external_array_abuse && 4025 if (FLAG_trace_external_array_abuse &&
3980 array->HasFixedTypedArrayElements()) { 4026 array->HasFixedTypedArrayElements()) {
3981 CheckArrayAbuse(array, "typed elements write", it->index(), true); 4027 CheckArrayAbuse(array, "typed elements write", it->index(), true);
3982 } 4028 }
3983 4029
3984 if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) { 4030 if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) {
3985 CheckArrayAbuse(array, "elements write", it->index(), false); 4031 CheckArrayAbuse(array, "elements write", it->index(), false);
3986 } 4032 }
3987 } 4033 }
3988 4034
3989 MaybeHandle<Object> result = 4035 Maybe<bool> result = JSObject::AddDataElement(receiver, it->index(), value,
3990 JSObject::AddDataElement(receiver, it->index(), value, attributes); 4036 attributes, should_throw);
3991 JSObject::ValidateElements(receiver); 4037 JSObject::ValidateElements(receiver);
3992 return result; 4038 return result;
3993 } else { 4039 } else {
3994 // Migrate to the most up-to-date map that will be able to store |value| 4040 // Migrate to the most up-to-date map that will be able to store |value|
3995 // under it->name() with |attributes|. 4041 // under it->name() with |attributes|.
3996 it->PrepareTransitionToDataProperty(value, attributes, store_mode); 4042 it->PrepareTransitionToDataProperty(value, attributes, store_mode);
3997 DCHECK_EQ(LookupIterator::TRANSITION, it->state()); 4043 DCHECK_EQ(LookupIterator::TRANSITION, it->state());
3998 it->ApplyTransitionToDataProperty(); 4044 it->ApplyTransitionToDataProperty();
3999 4045
4000 // TODO(verwaest): Encapsulate dictionary handling better. 4046 // TODO(verwaest): Encapsulate dictionary handling better.
4001 if (receiver->map()->is_dictionary_map()) { 4047 if (receiver->map()->is_dictionary_map()) {
4002 // TODO(verwaest): Probably should ensure this is done beforehand. 4048 // TODO(verwaest): Probably should ensure this is done beforehand.
4003 it->InternalizeName(); 4049 it->InternalizeName();
4004 // TODO(dcarney): just populate TransitionPropertyCell here? 4050 // TODO(dcarney): just populate TransitionPropertyCell here?
4005 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); 4051 JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
4006 } else { 4052 } else {
4007 // Write the property value. 4053 // Write the property value.
4008 it->WriteDataValue(value); 4054 it->WriteDataValue(value);
4009 } 4055 }
4010 4056
4011 // Send the change record if there are observers. 4057 // Send the change record if there are observers.
4012 if (receiver->map()->is_observed() && 4058 if (receiver->map()->is_observed() &&
4013 !isolate->IsInternallyUsedPropertyName(it->name())) { 4059 !isolate->IsInternallyUsedPropertyName(it->name())) {
4014 RETURN_ON_EXCEPTION(isolate, JSObject::EnqueueChangeRecord( 4060 RETURN_ON_EXCEPTION_VALUE(isolate, JSObject::EnqueueChangeRecord(
4015 receiver, "add", it->name(), 4061 receiver, "add", it->name(),
4016 it->factory()->the_hole_value()), 4062 it->factory()->the_hole_value()),
4017 Object); 4063 Nothing<bool>());
4018 } 4064 }
4019 #if VERIFY_HEAP 4065 #if VERIFY_HEAP
4020 if (FLAG_verify_heap) { 4066 if (FLAG_verify_heap) {
4021 receiver->JSObjectVerify(); 4067 receiver->JSObjectVerify();
4022 } 4068 }
4023 #endif 4069 #endif
4024 } 4070 }
4025 4071
4026 return value; 4072 return Just(true);
4027 } 4073 }
4028 4074
4029 4075
4030 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { 4076 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
4031 // Only supports adding slack to owned descriptors. 4077 // Only supports adding slack to owned descriptors.
4032 DCHECK(map->owns_descriptors()); 4078 DCHECK(map->owns_descriptors());
4033 4079
4034 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 4080 Handle<DescriptorArray> descriptors(map->instance_descriptors());
4035 int old_size = map->NumberOfOwnDescriptors(); 4081 int old_size = map->NumberOfOwnDescriptors();
4036 if (slack <= descriptors->NumberOfSlackDescriptors()) return; 4082 if (slack <= descriptors->NumberOfSlackDescriptors()) return;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4368 Handle<Object> result; 4414 Handle<Object> result;
4369 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 4415 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4370 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(), 4416 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(),
4371 arraysize(args), args), 4417 arraysize(args), args),
4372 Nothing<bool>()); 4418 Nothing<bool>());
4373 4419
4374 return Just(result->BooleanValue()); 4420 return Just(result->BooleanValue());
4375 } 4421 }
4376 4422
4377 4423
4378 MaybeHandle<Object> JSProxy::SetPropertyWithHandler( 4424 Maybe<bool> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
4379 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, 4425 Handle<Object> receiver,
4380 Handle<Object> value, LanguageMode language_mode) { 4426 Handle<Name> name,
4427 Handle<Object> value,
4428 LanguageMode language_mode,
4429 ShouldThrow should_throw) {
4381 Isolate* isolate = proxy->GetIsolate(); 4430 Isolate* isolate = proxy->GetIsolate();
4382 4431
4383 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4432 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4384 if (name->IsSymbol()) return value; 4433 if (name->IsSymbol()) return Just(false);
4385 4434
4386 Handle<Object> args[] = { receiver, name, value }; 4435 Handle<Object> args[] = { receiver, name, value };
4387 RETURN_ON_EXCEPTION( 4436 RETURN_ON_EXCEPTION_VALUE(isolate,
4388 isolate, 4437 CallTrap(proxy, "set", isolate->derived_set_trap(),
4389 CallTrap(proxy, 4438 arraysize(args), args),
4390 "set", 4439 Nothing<bool>());
4391 isolate->derived_set_trap(),
4392 arraysize(args),
4393 args),
4394 Object);
4395 4440
4396 return value; 4441 return Just(false);
4442
4443 // TODO(neis): This needs to be made spec-conformant, eg as follows:
4444 /*
Toon Verwaest 2015/10/20 15:25:06 I wouldn't add this commented out code. Open an is
neis 2015/10/21 14:42:25 Done.
4445 Handle<Object> result;
4446 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, result,
4447 CallTrap(proxy, "set",
4448 isolate->derived_set_trap(),
4449 arraysize(args), args),
4450 Nothing<bool>());
4451 Handle<Object> handler(proxy->handler(), isolate);
4452 if (result->BooleanValue()) return Just(true);
4453 RETURN_FAILURE(isolate, should_throw, NewTypeError(
4454 MessageTemplate::kProxyHandlerReturned, handler, result,
4455 isolate->factory()->InternalizeUtf8String("set")));
4456 */
4397 } 4457 }
4398 4458
4399 4459
4400 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( 4460 Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler(
4401 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, 4461 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
4402 Handle<Object> value, LanguageMode language_mode, bool* done) { 4462 Handle<Object> value, LanguageMode language_mode, ShouldThrow should_throw,
4463 bool* done) {
4403 Isolate* isolate = proxy->GetIsolate(); 4464 Isolate* isolate = proxy->GetIsolate();
4404 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. 4465 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
4405 4466
4406 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4467 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4407 if (name->IsSymbol()) { 4468 if (name->IsSymbol()) {
4408 *done = false; 4469 *done = false; // Return value will be ignored.
4409 return isolate->factory()->the_hole_value(); 4470 return Nothing<bool>();
4410 } 4471 }
4411 4472
4412 *done = true; // except where redefined... 4473 *done = true; // except where redefined...
4413 Handle<Object> args[] = { name }; 4474 Handle<Object> args[] = { name };
4414 Handle<Object> result; 4475 Handle<Object> result;
4415 ASSIGN_RETURN_ON_EXCEPTION( 4476 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4416 isolate, result, 4477 isolate, result, CallTrap(proxy, "getPropertyDescriptor",
4417 CallTrap(proxy, 4478 Handle<Object>(), arraysize(args), args),
4418 "getPropertyDescriptor", 4479 Nothing<bool>());
4419 Handle<Object>(),
4420 arraysize(args),
4421 args),
4422 Object);
4423 4480
4424 if (result->IsUndefined()) { 4481 if (result->IsUndefined()) {
4425 *done = false; 4482 *done = false; // Return value will be ignored.
4426 return isolate->factory()->the_hole_value(); 4483 return Nothing<bool>();
4427 } 4484 }
4428 4485
4429 // Emulate [[GetProperty]] semantics for proxies. 4486 // Emulate [[GetProperty]] semantics for proxies.
4430 Handle<Object> argv[] = { result }; 4487 Handle<Object> argv[] = { result };
4431 Handle<Object> desc; 4488 Handle<Object> desc;
4432 ASSIGN_RETURN_ON_EXCEPTION( 4489 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4433 isolate, desc, 4490 isolate, desc,
4434 Execution::Call(isolate, 4491 Execution::Call(isolate, isolate->to_complete_property_descriptor(),
4435 isolate->to_complete_property_descriptor(), 4492 result, arraysize(argv), argv),
4436 result, 4493 Nothing<bool>());
4437 arraysize(argv),
4438 argv),
4439 Object);
4440 4494
4441 // [[GetProperty]] requires to check that all properties are configurable. 4495 // [[GetProperty]] requires to check that all properties are configurable.
4442 Handle<String> configurable_name = 4496 Handle<String> configurable_name =
4443 isolate->factory()->InternalizeOneByteString( 4497 isolate->factory()->InternalizeOneByteString(
4444 STATIC_CHAR_VECTOR("configurable_")); 4498 STATIC_CHAR_VECTOR("configurable_"));
4445 Handle<Object> configurable = 4499 Handle<Object> configurable =
4446 Object::GetProperty(desc, configurable_name).ToHandleChecked(); 4500 Object::GetProperty(desc, configurable_name).ToHandleChecked();
4447 DCHECK(configurable->IsBoolean()); 4501 DCHECK(configurable->IsBoolean());
4448 if (configurable->IsFalse()) { 4502 if (configurable->IsFalse()) {
4449 Handle<String> trap = isolate->factory()->InternalizeOneByteString( 4503 RETURN_FAILURE(
4450 STATIC_CHAR_VECTOR("getPropertyDescriptor")); 4504 isolate, should_throw,
4451 THROW_NEW_ERROR(isolate, 4505 NewTypeError(MessageTemplate::kProxyPropNotConfigurable, handler, name,
4452 NewTypeError(MessageTemplate::kProxyPropNotConfigurable, 4506 isolate->factory()->NewStringFromAsciiChecked(
4453 handler, name, trap), 4507 "getPropertyDescriptor")));
4454 Object);
4455 } 4508 }
4456 DCHECK(configurable->IsTrue()); 4509 DCHECK(configurable->IsTrue());
4457 4510
4458 // Check for DataDescriptor. 4511 // Check for DataDescriptor.
4459 Handle<String> hasWritable_name = 4512 Handle<String> hasWritable_name =
4460 isolate->factory()->InternalizeOneByteString( 4513 isolate->factory()->InternalizeOneByteString(
4461 STATIC_CHAR_VECTOR("hasWritable_")); 4514 STATIC_CHAR_VECTOR("hasWritable_"));
4462 Handle<Object> hasWritable = 4515 Handle<Object> hasWritable =
4463 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); 4516 Object::GetProperty(desc, hasWritable_name).ToHandleChecked();
4464 DCHECK(hasWritable->IsBoolean()); 4517 DCHECK(hasWritable->IsBoolean());
4465 if (hasWritable->IsTrue()) { 4518 if (hasWritable->IsTrue()) {
4466 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( 4519 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString(
4467 STATIC_CHAR_VECTOR("writable_")); 4520 STATIC_CHAR_VECTOR("writable_"));
4468 Handle<Object> writable = 4521 Handle<Object> writable =
4469 Object::GetProperty(desc, writable_name).ToHandleChecked(); 4522 Object::GetProperty(desc, writable_name).ToHandleChecked();
4470 DCHECK(writable->IsBoolean()); 4523 DCHECK(writable->IsBoolean());
4471 *done = writable->IsFalse(); 4524 *done = writable->IsFalse();
4472 if (!*done) return isolate->factory()->the_hole_value(); 4525 if (!*done) return Nothing<bool>(); // Return value will be ignored.
4473 return WriteToReadOnlyProperty(isolate, receiver, name, value, 4526 return WriteToReadOnlyProperty(isolate, receiver, name, value,
4474 language_mode); 4527 language_mode, should_throw);
4475 } 4528 }
4476 4529
4477 // We have an AccessorDescriptor. 4530 // We have an AccessorDescriptor.
4478 Handle<String> set_name = 4531 Handle<String> set_name =
4479 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); 4532 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_"));
4480 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); 4533 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked();
4481 if (!setter->IsUndefined()) { 4534 if (!setter->IsUndefined()) {
4482 // TODO(rossberg): nicer would be to cast to some JSCallable here... 4535 // TODO(rossberg): nicer would be to cast to some JSCallable here...
4483 return SetPropertyWithDefinedSetter( 4536 return SetPropertyWithDefinedSetter(
4484 receiver, Handle<JSReceiver>::cast(setter), value); 4537 receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
4485 } 4538 }
4486 4539
4487 if (is_sloppy(language_mode)) return value; 4540 if (is_sloppy(language_mode)) return Just(true);
4488 THROW_NEW_ERROR( 4541 RETURN_FAILURE(
4489 isolate, NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy), 4542 isolate, should_throw,
4490 Object); 4543 NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy));
4491 } 4544 }
4492 4545
4493 4546
4494 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( 4547 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
4495 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) { 4548 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) {
4496 Isolate* isolate = proxy->GetIsolate(); 4549 Isolate* isolate = proxy->GetIsolate();
4497 4550
4498 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4551 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4499 if (name->IsSymbol()) return isolate->factory()->false_value(); 4552 if (name->IsSymbol()) return isolate->factory()->false_value();
4500 4553
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
4760 // If there's an interceptor, try to store the property with the 4813 // If there's an interceptor, try to store the property with the
4761 // interceptor. 4814 // interceptor.
4762 // In case of success, the attributes will have been reset to the default 4815 // In case of success, the attributes will have been reset to the default
4763 // attributes of the interceptor, rather than the incoming attributes. 4816 // attributes of the interceptor, rather than the incoming attributes.
4764 // 4817 //
4765 // TODO(verwaest): JSProxy afterwards verify the attributes that the 4818 // TODO(verwaest): JSProxy afterwards verify the attributes that the
4766 // JSProxy claims it has, and verifies that they are compatible. If not, 4819 // JSProxy claims it has, and verifies that they are compatible. If not,
4767 // they throw. Here we should do the same. 4820 // they throw. Here we should do the same.
4768 case LookupIterator::INTERCEPTOR: 4821 case LookupIterator::INTERCEPTOR:
4769 if (handling == DONT_FORCE_FIELD) { 4822 if (handling == DONT_FORCE_FIELD) {
4770 MaybeHandle<Object> maybe_result = 4823 Maybe<bool> result =
4771 JSObject::SetPropertyWithInterceptor(it, value); 4824 JSObject::SetPropertyWithInterceptor(it, value, THROW_ON_ERROR);
4772 if (!maybe_result.is_null()) return maybe_result; 4825 if (result.IsJust()) return value;
4773 if (it->isolate()->has_pending_exception()) return maybe_result; 4826 if (it->isolate()->has_pending_exception())
4827 return MaybeHandle<Object>();
4774 } 4828 }
4775 break; 4829 break;
4776 4830
4777 case LookupIterator::ACCESSOR: { 4831 case LookupIterator::ACCESSOR: {
4778 Handle<Object> accessors = it->GetAccessors(); 4832 Handle<Object> accessors = it->GetAccessors();
4779 4833
4780 // Special handling for ExecutableAccessorInfo, which behaves like a 4834 // Special handling for ExecutableAccessorInfo, which behaves like a
4781 // data property. 4835 // data property.
4782 if (accessors->IsExecutableAccessorInfo() && 4836 if (accessors->IsExecutableAccessorInfo() &&
4783 handling == DONT_FORCE_FIELD) { 4837 handling == DONT_FORCE_FIELD) {
4784 PropertyDetails details = it->property_details(); 4838 PropertyDetails details = it->property_details();
4785 // Ensure the context isn't changed after calling into accessors. 4839 // Ensure the context isn't changed after calling into accessors.
4786 AssertNoContextChange ncc(it->isolate()); 4840 AssertNoContextChange ncc(it->isolate());
4787 4841
4788 Handle<Object> result; 4842 Maybe<bool> result = JSObject::SetPropertyWithAccessor(
4789 ASSIGN_RETURN_ON_EXCEPTION( 4843 it, value, STRICT, THROW_ON_ERROR);
4790 it->isolate(), result, 4844 if (result.IsNothing()) return MaybeHandle<Object>();
4791 JSObject::SetPropertyWithAccessor(it, value, STRICT), Object);
4792 DCHECK(result->SameValue(*value));
4793 4845
4794 if (details.attributes() == attributes) return value; 4846 if (details.attributes() == attributes) return value;
4795 4847
4796 // Reconfigure the accessor if attributes mismatch. 4848 // Reconfigure the accessor if attributes mismatch.
4797 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( 4849 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor(
4798 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); 4850 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors));
4799 new_data->set_property_attributes(attributes); 4851 new_data->set_property_attributes(attributes);
4800 // By clearing the setter we don't have to introduce a lookup to 4852 // By clearing the setter we don't have to introduce a lookup to
4801 // the setter, simply make it unavailable to reflect the 4853 // the setter, simply make it unavailable to reflect the
4802 // attributes. 4854 // attributes.
(...skipping 18 matching lines...) Expand all
4821 } 4873 }
4822 case LookupIterator::INTEGER_INDEXED_EXOTIC: 4874 case LookupIterator::INTEGER_INDEXED_EXOTIC:
4823 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 4875 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
4824 value, STRICT); 4876 value, STRICT);
4825 4877
4826 case LookupIterator::DATA: { 4878 case LookupIterator::DATA: {
4827 PropertyDetails details = it->property_details(); 4879 PropertyDetails details = it->property_details();
4828 Handle<Object> old_value = it->factory()->the_hole_value(); 4880 Handle<Object> old_value = it->factory()->the_hole_value();
4829 // Regular property update if the attributes match. 4881 // Regular property update if the attributes match.
4830 if (details.attributes() == attributes) { 4882 if (details.attributes() == attributes) {
4831 return SetDataProperty(it, value); 4883 Maybe<bool> result = SetDataProperty(it, value, THROW_ON_ERROR);
4884 return result.IsJust() ? value : MaybeHandle<Object>();
4832 } 4885 }
4833 4886
4834 // Special case: properties of typed arrays cannot be reconfigured to 4887 // Special case: properties of typed arrays cannot be reconfigured to
4835 // non-writable nor to non-enumerable. 4888 // non-writable nor to non-enumerable.
4836 if (it->IsElement() && object->HasFixedTypedArrayElements()) { 4889 if (it->IsElement() && object->HasFixedTypedArrayElements()) {
4837 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 4890 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
4838 value, STRICT); 4891 value, STRICT);
4839 } 4892 }
4840 4893
4841 // Reconfigure the data property if the attributes mismatch. 4894 // Reconfigure the data property if the attributes mismatch.
(...skipping 1869 matching lines...) Expand 10 before | Expand all | Expand 10 after
6711 6764
6712 return context->extension_object()->ReferencesObject(obj); 6765 return context->extension_object()->ReferencesObject(obj);
6713 } 6766 }
6714 } 6767 }
6715 6768
6716 // No references to object. 6769 // No references to object.
6717 return false; 6770 return false;
6718 } 6771 }
6719 6772
6720 6773
6774 static MaybeHandle<Object> ReturnObjectOrThrowTypeError(
6775 Handle<JSObject> object, Maybe<bool> maybe, MessageTemplate::Template msg) {
6776 if (!maybe.IsJust()) return MaybeHandle<Object>();
6777 if (maybe.FromJust()) return object;
6778 Isolate* isolate = object->GetIsolate();
6779 THROW_NEW_ERROR(isolate, NewTypeError(msg), Object);
6780 }
6781
6782
6721 Maybe<bool> JSObject::PreventExtensionsInternal(Handle<JSObject> object) { 6783 Maybe<bool> JSObject::PreventExtensionsInternal(Handle<JSObject> object) {
6722 Isolate* isolate = object->GetIsolate(); 6784 Isolate* isolate = object->GetIsolate();
6723 6785
6724 if (!object->map()->is_extensible()) return Just(true); 6786 if (!object->map()->is_extensible()) return Just(true);
6725 6787
6726 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { 6788 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) {
6727 return PreventExtensionsWithTransition<NONE>(object); 6789 return PreventExtensionsWithTransition<NONE>(object);
6728 } 6790 }
6729 6791
6730 if (object->IsAccessCheckNeeded() && 6792 if (object->IsAccessCheckNeeded() &&
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
6770 RETURN_ON_EXCEPTION_VALUE( 6832 RETURN_ON_EXCEPTION_VALUE(
6771 isolate, 6833 isolate,
6772 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), 6834 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
6773 isolate->factory()->the_hole_value()), 6835 isolate->factory()->the_hole_value()),
6774 Nothing<bool>()); 6836 Nothing<bool>());
6775 } 6837 }
6776 return Just(true); 6838 return Just(true);
6777 } 6839 }
6778 6840
6779 6841
6780 static MaybeHandle<Object> ReturnObjectOrThrowTypeError(
6781 Handle<JSObject> object, Maybe<bool> maybe, MessageTemplate::Template msg) {
6782 if (!maybe.IsJust()) return MaybeHandle<Object>();
6783 if (maybe.FromJust()) return object;
6784 Isolate* isolate = object->GetIsolate();
6785 THROW_NEW_ERROR(isolate, NewTypeError(msg), Object);
6786 }
6787
6788
6789 MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { 6842 MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
6790 return ReturnObjectOrThrowTypeError(object, PreventExtensionsInternal(object), 6843 return ReturnObjectOrThrowTypeError(object, PreventExtensionsInternal(object),
6791 MessageTemplate::kCannotPreventExt); 6844 MessageTemplate::kCannotPreventExt);
6792 } 6845 }
6793 6846
6794 6847
6795 bool JSObject::IsExtensible(Handle<JSObject> object) { 6848 bool JSObject::IsExtensible(Handle<JSObject> object) {
6796 Isolate* isolate = object->GetIsolate(); 6849 Isolate* isolate = object->GetIsolate();
6797 if (object->IsAccessCheckNeeded() && 6850 if (object->IsAccessCheckNeeded() &&
6798 !isolate->MayAccess(handle(isolate->context()), object)) { 6851 !isolate->MayAccess(handle(isolate->context()), object)) {
(...skipping 7197 matching lines...) Expand 10 before | Expand all | Expand 10 after
13996 SeededNumberDictionary::kEntrySize; 14049 SeededNumberDictionary::kEntrySize;
13997 return 2 * dictionary_size >= *new_capacity; 14050 return 2 * dictionary_size >= *new_capacity;
13998 } 14051 }
13999 14052
14000 14053
14001 // static 14054 // static
14002 MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object, 14055 MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
14003 uint32_t index, 14056 uint32_t index,
14004 Handle<Object> value, 14057 Handle<Object> value,
14005 PropertyAttributes attributes) { 14058 PropertyAttributes attributes) {
14059 Maybe<bool> result =
14060 AddDataElement(object, index, value, attributes, THROW_ON_ERROR);
14061 return result.IsJust() ? value : MaybeHandle<Object>();
14062 }
14063
14064
14065 // static
14066 Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
14067 Handle<Object> value,
14068 PropertyAttributes attributes,
14069 ShouldThrow should_throw) {
14006 DCHECK(object->map()->is_extensible()); 14070 DCHECK(object->map()->is_extensible());
14007 14071
14008 Isolate* isolate = object->GetIsolate(); 14072 Isolate* isolate = object->GetIsolate();
14009 14073
14010 uint32_t old_length = 0; 14074 uint32_t old_length = 0;
14011 uint32_t new_capacity = 0; 14075 uint32_t new_capacity = 0;
14012 14076
14013 Handle<Object> old_length_handle; 14077 Handle<Object> old_length_handle;
14014 if (object->IsJSArray()) { 14078 if (object->IsJSArray()) {
14015 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length)); 14079 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
14056 new_length_handle = isolate->factory()->NewNumberFromUint(new_length); 14120 new_length_handle = isolate->factory()->NewNumberFromUint(new_length);
14057 JSArray::cast(*object)->set_length(*new_length_handle); 14121 JSArray::cast(*object)->set_length(*new_length_handle);
14058 } 14122 }
14059 14123
14060 if (!old_length_handle.is_null() && new_length != old_length) { 14124 if (!old_length_handle.is_null() && new_length != old_length) {
14061 // |old_length_handle| is kept null above unless the object is observed. 14125 // |old_length_handle| is kept null above unless the object is observed.
14062 DCHECK(object->map()->is_observed()); 14126 DCHECK(object->map()->is_observed());
14063 Handle<JSArray> array = Handle<JSArray>::cast(object); 14127 Handle<JSArray> array = Handle<JSArray>::cast(object);
14064 Handle<String> name = isolate->factory()->Uint32ToString(index); 14128 Handle<String> name = isolate->factory()->Uint32ToString(index);
14065 14129
14066 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); 14130 RETURN_ON_EXCEPTION_VALUE(isolate, BeginPerformSplice(array),
14067 RETURN_ON_EXCEPTION( 14131 Nothing<bool>());
14132 RETURN_ON_EXCEPTION_VALUE(
14068 isolate, EnqueueChangeRecord(array, "add", name, 14133 isolate, EnqueueChangeRecord(array, "add", name,
14069 isolate->factory()->the_hole_value()), 14134 isolate->factory()->the_hole_value()),
14070 Object); 14135 Nothing<bool>());
14071 RETURN_ON_EXCEPTION(isolate, 14136 RETURN_ON_EXCEPTION_VALUE(
14072 EnqueueChangeRecord(array, "update", 14137 isolate, EnqueueChangeRecord(array, "update",
14073 isolate->factory()->length_string(), 14138 isolate->factory()->length_string(),
14074 old_length_handle), 14139 old_length_handle),
14075 Object); 14140 Nothing<bool>());
14076 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); 14141 RETURN_ON_EXCEPTION_VALUE(isolate, EndPerformSplice(array),
14142 Nothing<bool>());
14077 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); 14143 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
14078 RETURN_ON_EXCEPTION(isolate, EnqueueSpliceRecord(array, old_length, deleted, 14144 RETURN_ON_EXCEPTION_VALUE(isolate,
14079 new_length - old_length), 14145 EnqueueSpliceRecord(array, old_length, deleted,
14080 Object); 14146 new_length - old_length),
14147 Nothing<bool>());
14081 } else if (object->map()->is_observed()) { 14148 } else if (object->map()->is_observed()) {
14082 Handle<String> name = isolate->factory()->Uint32ToString(index); 14149 Handle<String> name = isolate->factory()->Uint32ToString(index);
14083 RETURN_ON_EXCEPTION( 14150 RETURN_ON_EXCEPTION_VALUE(
14084 isolate, EnqueueChangeRecord(object, "add", name, 14151 isolate, EnqueueChangeRecord(object, "add", name,
14085 isolate->factory()->the_hole_value()), 14152 isolate->factory()->the_hole_value()),
14086 Object); 14153 Nothing<bool>());
14087 } 14154 }
14088 14155
14089 return value; 14156 return Just(true);
14090 } 14157 }
14091 14158
14092 14159
14093 bool JSArray::SetLengthWouldNormalize(uint32_t new_length) { 14160 bool JSArray::SetLengthWouldNormalize(uint32_t new_length) {
14094 if (!HasFastElements()) return false; 14161 if (!HasFastElements()) return false;
14095 uint32_t capacity = static_cast<uint32_t>(elements()->length()); 14162 uint32_t capacity = static_cast<uint32_t>(elements()->length());
14096 uint32_t new_capacity; 14163 uint32_t new_capacity;
14097 return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) && 14164 return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
14098 ShouldConvertToSlowElements(this, capacity, new_length - 1, 14165 ShouldConvertToSlowElements(this, capacity, new_length - 1,
14099 &new_capacity); 14166 &new_capacity);
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
14282 14349
14283 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, 14350 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
14284 uint32_t index) { 14351 uint32_t index) {
14285 uint32_t length = 0; 14352 uint32_t length = 0;
14286 CHECK(array->length()->ToArrayLength(&length)); 14353 CHECK(array->length()->ToArrayLength(&length));
14287 if (length <= index) return HasReadOnlyLength(array); 14354 if (length <= index) return HasReadOnlyLength(array);
14288 return false; 14355 return false;
14289 } 14356 }
14290 14357
14291 14358
14292 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
14293 Isolate* isolate = array->GetIsolate();
14294 Handle<Name> length = isolate->factory()->length_string();
14295 Handle<String> typeof_string = Object::TypeOf(isolate, array);
14296 THROW_NEW_ERROR(isolate,
14297 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length,
14298 typeof_string, array),
14299 Object);
14300 }
14301
14302
14303 template <typename BackingStore> 14359 template <typename BackingStore>
14304 static int FastHoleyElementsUsage(JSObject* object, BackingStore* store) { 14360 static int FastHoleyElementsUsage(JSObject* object, BackingStore* store) {
14305 int limit = object->IsJSArray() 14361 int limit = object->IsJSArray()
14306 ? Smi::cast(JSArray::cast(object)->length())->value() 14362 ? Smi::cast(JSArray::cast(object)->length())->value()
14307 : store->length(); 14363 : store->length();
14308 int used = 0; 14364 int used = 0;
14309 for (int i = 0; i < limit; ++i) { 14365 for (int i = 0; i < limit; ++i) {
14310 if (!store->is_the_hole(i)) ++used; 14366 if (!store->is_the_hole(i)) ++used;
14311 } 14367 }
14312 return used; 14368 return used;
(...skipping 3349 matching lines...) Expand 10 before | Expand all | Expand 10 after
17662 if (cell->value() != *new_value) { 17718 if (cell->value() != *new_value) {
17663 cell->set_value(*new_value); 17719 cell->set_value(*new_value);
17664 Isolate* isolate = cell->GetIsolate(); 17720 Isolate* isolate = cell->GetIsolate();
17665 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17721 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17666 isolate, DependentCode::kPropertyCellChangedGroup); 17722 isolate, DependentCode::kPropertyCellChangedGroup);
17667 } 17723 }
17668 } 17724 }
17669 17725
17670 } // namespace internal 17726 } // namespace internal
17671 } // namespace v8 17727 } // namespace v8
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698