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

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: Rebase. 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/runtime/runtime-array.cc » ('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 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate, 859 bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate,
860 Handle<AccessorInfo> info, 860 Handle<AccessorInfo> info,
861 Handle<Map> map) { 861 Handle<Map> map) {
862 if (!info->HasExpectedReceiverType()) return true; 862 if (!info->HasExpectedReceiverType()) return true;
863 if (!map->IsJSObjectMap()) return false; 863 if (!map->IsJSObjectMap()) return false;
864 return FunctionTemplateInfo::cast(info->expected_receiver_type()) 864 return FunctionTemplateInfo::cast(info->expected_receiver_type())
865 ->IsTemplateFor(*map); 865 ->IsTemplateFor(*map);
866 } 866 }
867 867
868 868
869 MaybeHandle<Object> Object::SetPropertyWithAccessor( 869 Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
870 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { 870 Handle<Object> value,
871 LanguageMode language_mode,
872 ShouldThrow should_throw) {
871 Isolate* isolate = it->isolate(); 873 Isolate* isolate = it->isolate();
872 Handle<Object> structure = it->GetAccessors(); 874 Handle<Object> structure = it->GetAccessors();
873 Handle<Object> receiver = it->GetReceiver(); 875 Handle<Object> receiver = it->GetReceiver();
874 876
875 // We should never get here to initialize a const with the hole value since a 877 // We should never get here to initialize a const with the hole value since a
876 // const declaration would conflict with the setter. 878 // const declaration would conflict with the setter.
877 DCHECK(!structure->IsForeign()); 879 DCHECK(!structure->IsForeign());
878 880
879 // API style callbacks. 881 // API style callbacks.
880 if (structure->IsExecutableAccessorInfo()) { 882 if (structure->IsExecutableAccessorInfo()) {
881 Handle<JSObject> holder = it->GetHolder<JSObject>(); 883 Handle<JSObject> holder = it->GetHolder<JSObject>();
882 Handle<Name> name = it->GetName(); 884 Handle<Name> name = it->GetName();
883 Handle<ExecutableAccessorInfo> info = 885 Handle<ExecutableAccessorInfo> info =
884 Handle<ExecutableAccessorInfo>::cast(structure); 886 Handle<ExecutableAccessorInfo>::cast(structure);
885 if (!info->IsCompatibleReceiver(*receiver)) { 887 if (!info->IsCompatibleReceiver(*receiver)) {
886 THROW_NEW_ERROR(isolate, 888 isolate->Throw(*isolate->factory()->NewTypeError(
887 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, 889 MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
888 name, receiver), 890 return Nothing<bool>();
889 Object);
890 } 891 }
891 892
892 v8::AccessorNameSetterCallback call_fun = 893 v8::AccessorNameSetterCallback call_fun =
893 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter()); 894 v8::ToCData<v8::AccessorNameSetterCallback>(info->setter());
894 if (call_fun == nullptr) return value; 895 if (call_fun == nullptr) return Just(true);
896 // TODO(verwaest): Shouldn't this case be unreachable (at least in the
897 // long run?) Should we have ExecutableAccessorPairs with missing setter
898 // that are "writable"? If they aren't writable, shouldn't we have bailed
899 // out already earlier?
895 900
896 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name)); 901 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
897 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder); 902 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
898 args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); 903 args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
899 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 904 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
900 return value; 905 return Just(true);
901 } 906 }
902 907
903 // Regular accessor. 908 // Regular accessor.
904 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); 909 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
905 if (setter->IsCallable()) { 910 if (setter->IsCallable()) {
906 // TODO(rossberg): nicer would be to cast to some JSCallable here... 911 // TODO(rossberg): nicer would be to cast to some JSCallable here...
907 return SetPropertyWithDefinedSetter( 912 return SetPropertyWithDefinedSetter(
908 receiver, Handle<JSReceiver>::cast(setter), value); 913 receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
909 } 914 }
910 915
911 if (is_sloppy(language_mode)) return value; 916 if (is_sloppy(language_mode)) return Just(true);
912 917 RETURN_FAILURE(isolate, should_throw,
913 THROW_NEW_ERROR(isolate, 918 NewTypeError(MessageTemplate::kNoSetterInCallback,
914 NewTypeError(MessageTemplate::kNoSetterInCallback, 919 it->GetName(), it->GetHolder<JSObject>()));
915 it->GetName(), it->GetHolder<JSObject>()),
916 Object);
917 } 920 }
918 921
919 922
920 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( 923 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
921 Handle<Object> receiver, 924 Handle<Object> receiver,
922 Handle<JSReceiver> getter) { 925 Handle<JSReceiver> getter) {
923 Isolate* isolate = getter->GetIsolate(); 926 Isolate* isolate = getter->GetIsolate();
924 927
925 // Platforms with simulators like arm/arm64 expose a funny issue. If the 928 // Platforms with simulators like arm/arm64 expose a funny issue. If the
926 // simulator has a separate JS stack pointer from the C++ stack pointer, it 929 // simulator has a separate JS stack pointer from the C++ stack pointer, it
(...skipping 11 matching lines...) Expand all
938 941
939 Debug* debug = isolate->debug(); 942 Debug* debug = isolate->debug();
940 // Handle stepping into a getter if step into is active. 943 // Handle stepping into a getter if step into is active.
941 // TODO(rossberg): should this apply to getters that are function proxies? 944 // TODO(rossberg): should this apply to getters that are function proxies?
942 if (debug->is_active()) debug->HandleStepIn(getter, false); 945 if (debug->is_active()) debug->HandleStepIn(getter, false);
943 946
944 return Execution::Call(isolate, getter, receiver, 0, NULL); 947 return Execution::Call(isolate, getter, receiver, 0, NULL);
945 } 948 }
946 949
947 950
948 MaybeHandle<Object> Object::SetPropertyWithDefinedSetter( 951 Maybe<bool> Object::SetPropertyWithDefinedSetter(Handle<Object> receiver,
949 Handle<Object> receiver, 952 Handle<JSReceiver> setter,
950 Handle<JSReceiver> setter, 953 Handle<Object> value,
951 Handle<Object> value) { 954 ShouldThrow should_throw) {
952 Isolate* isolate = setter->GetIsolate(); 955 Isolate* isolate = setter->GetIsolate();
953 956
954 Debug* debug = isolate->debug(); 957 Debug* debug = isolate->debug();
955 // Handle stepping into a setter if step into is active. 958 // Handle stepping into a setter if step into is active.
956 // TODO(rossberg): should this apply to getters that are function proxies? 959 // TODO(rossberg): should this apply to getters that are function proxies?
957 if (debug->is_active()) debug->HandleStepIn(setter, false); 960 if (debug->is_active()) debug->HandleStepIn(setter, false);
958 961
959 Handle<Object> argv[] = { value }; 962 Handle<Object> argv[] = { value };
960 RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver, 963 RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
961 arraysize(argv), argv), 964 arraysize(argv), argv),
962 Object); 965 Nothing<bool>());
963 return value; 966 return Just(true);
964 } 967 }
965 968
966 969
967 // static 970 // static
968 bool JSObject::AllCanRead(LookupIterator* it) { 971 bool JSObject::AllCanRead(LookupIterator* it) {
969 // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of 972 // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
970 // which have already been checked. 973 // which have already been checked.
971 DCHECK(it->state() == LookupIterator::ACCESS_CHECK || 974 DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
972 it->state() == LookupIterator::INTERCEPTOR); 975 it->state() == LookupIterator::INTERCEPTOR);
973 for (it->Next(); it->IsFound(); it->Next()) { 976 for (it->Next(); it->IsFound(); it->Next()) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 Handle<Object> accessors = it->GetAccessors(); 1041 Handle<Object> accessors = it->GetAccessors();
1039 if (accessors->IsAccessorInfo()) { 1042 if (accessors->IsAccessorInfo()) {
1040 if (AccessorInfo::cast(*accessors)->all_can_write()) return true; 1043 if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
1041 } 1044 }
1042 } 1045 }
1043 } 1046 }
1044 return false; 1047 return false;
1045 } 1048 }
1046 1049
1047 1050
1048 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck( 1051 Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
1049 LookupIterator* it, Handle<Object> value) { 1052 LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
1050 Handle<JSObject> checked = it->GetHolder<JSObject>(); 1053 Handle<JSObject> checked = it->GetHolder<JSObject>();
1051 if (AllCanWrite(it)) { 1054 if (AllCanWrite(it)) {
1052 // The supplied language-mode is ignored by SetPropertyWithAccessor. 1055 // The supplied language-mode is ignored by SetPropertyWithAccessor.
1053 return SetPropertyWithAccessor(it, value, SLOPPY); 1056 return SetPropertyWithAccessor(it, value, SLOPPY, should_throw);
1054 } 1057 }
1055 1058
1056 it->isolate()->ReportFailedAccessCheck(checked); 1059 it->isolate()->ReportFailedAccessCheck(checked);
1057 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 1060 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
1058 return value; 1061 UNREACHABLE();
Jakob Kummerow 2015/10/27 15:51:52 We're hitting this in the wild (crbug.com/548194).
1062 it->isolate()->Throw(
1063 *it->isolate()->factory()->NewTypeError(MessageTemplate::kNoAccess));
1064 return Nothing<bool>();
1059 } 1065 }
1060 1066
1061 1067
1062 void JSObject::SetNormalizedProperty(Handle<JSObject> object, 1068 void JSObject::SetNormalizedProperty(Handle<JSObject> object,
1063 Handle<Name> name, 1069 Handle<Name> name,
1064 Handle<Object> value, 1070 Handle<Object> value,
1065 PropertyDetails details) { 1071 PropertyDetails details) {
1066 DCHECK(!object->HasFastProperties()); 1072 DCHECK(!object->HasFastProperties());
1067 if (!name->IsUniqueName()) { 1073 if (!name->IsUniqueName()) {
1068 name = object->GetIsolate()->factory()->InternalizeString( 1074 name = object->GetIsolate()->factory()->InternalizeString(
(...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after
3507 3513
3508 // static 3514 // static
3509 Handle<Map> Map::Update(Handle<Map> map) { 3515 Handle<Map> Map::Update(Handle<Map> map) {
3510 if (!map->is_deprecated()) return map; 3516 if (!map->is_deprecated()) return map;
3511 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(), 3517 return ReconfigureProperty(map, -1, kData, NONE, Representation::None(),
3512 HeapType::None(map->GetIsolate()), 3518 HeapType::None(map->GetIsolate()),
3513 ALLOW_IN_DESCRIPTOR); 3519 ALLOW_IN_DESCRIPTOR);
3514 } 3520 }
3515 3521
3516 3522
3517 MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it, 3523 Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
3518 Handle<Object> value) { 3524 Handle<Object> value) {
3519 Isolate* isolate = it->isolate(); 3525 Isolate* isolate = it->isolate();
3520 // Make sure that the top context does not change when doing callbacks or 3526 // Make sure that the top context does not change when doing callbacks or
3521 // interceptor calls. 3527 // interceptor calls.
3522 AssertNoContextChange ncc(isolate); 3528 AssertNoContextChange ncc(isolate);
3523 3529
3524 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); 3530 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
3525 Handle<InterceptorInfo> interceptor(it->GetInterceptor()); 3531 Handle<InterceptorInfo> interceptor(it->GetInterceptor());
3526 if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>(); 3532 if (interceptor->setter()->IsUndefined()) return Just(false);
3527 3533
3528 Handle<JSObject> holder = it->GetHolder<JSObject>(); 3534 Handle<JSObject> holder = it->GetHolder<JSObject>();
3529 v8::Local<v8::Value> result; 3535 v8::Local<v8::Value> result;
3530 PropertyCallbackArguments args(isolate, interceptor->data(), 3536 PropertyCallbackArguments args(isolate, interceptor->data(),
3531 *it->GetReceiver(), *holder); 3537 *it->GetReceiver(), *holder);
3532 3538
3533 if (it->IsElement()) { 3539 if (it->IsElement()) {
3534 uint32_t index = it->index(); 3540 uint32_t index = it->index();
3535 v8::IndexedPropertySetterCallback setter = 3541 v8::IndexedPropertySetterCallback setter =
3536 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); 3542 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
3537 LOG(isolate, 3543 LOG(isolate,
3538 ApiIndexedPropertyAccess("interceptor-indexed-set", *holder, index)); 3544 ApiIndexedPropertyAccess("interceptor-indexed-set", *holder, index));
3539 result = args.Call(setter, index, v8::Utils::ToLocal(value)); 3545 result = args.Call(setter, index, v8::Utils::ToLocal(value));
3540 } else { 3546 } else {
3541 Handle<Name> name = it->name(); 3547 Handle<Name> name = it->name();
3542 3548
3543 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) { 3549 if (name->IsSymbol() && !interceptor->can_intercept_symbols()) {
3544 return MaybeHandle<Object>(); 3550 return Just(false);
3545 } 3551 }
3546 3552
3547 v8::GenericNamedPropertySetterCallback setter = 3553 v8::GenericNamedPropertySetterCallback setter =
3548 v8::ToCData<v8::GenericNamedPropertySetterCallback>( 3554 v8::ToCData<v8::GenericNamedPropertySetterCallback>(
3549 interceptor->setter()); 3555 interceptor->setter());
3550 LOG(it->isolate(), 3556 LOG(it->isolate(),
3551 ApiNamedPropertyAccess("interceptor-named-set", *holder, *name)); 3557 ApiNamedPropertyAccess("interceptor-named-set", *holder, *name));
3552 result = 3558 result =
3553 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); 3559 args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
3554 } 3560 }
3555 3561
3556 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); 3562 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
3557 if (result.IsEmpty()) return MaybeHandle<Object>(); 3563 if (result.IsEmpty()) return Just(false);
3558 #ifdef DEBUG 3564 #ifdef DEBUG
3559 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 3565 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
3560 result_internal->VerifyApiCallResultType(); 3566 result_internal->VerifyApiCallResultType();
3561 #endif 3567 #endif
3562 return value; 3568 return Just(true);
3563 } 3569 }
3564 3570
3565 3571
3566 MaybeHandle<Object> Object::SetProperty(Handle<Object> object, 3572 MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
3567 Handle<Name> name, Handle<Object> value, 3573 Handle<Name> name, Handle<Object> value,
3568 LanguageMode language_mode, 3574 LanguageMode language_mode,
3569 StoreFromKeyed store_mode) { 3575 StoreFromKeyed store_mode) {
3570 LookupIterator it(object, name); 3576 LookupIterator it(object, name);
3571 return SetProperty(&it, value, language_mode, store_mode); 3577 return SetProperty(&it, value, language_mode, store_mode);
3572 } 3578 }
3573 3579
3574 3580
3575 MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it, 3581 Maybe<bool> Object::SetPropertyInternal(
3576 Handle<Object> value, 3582 LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
3577 LanguageMode language_mode, 3583 ShouldThrow should_throw, StoreFromKeyed store_mode, bool* found) {
3578 StoreFromKeyed store_mode,
3579 bool* found) {
3580 // Make sure that the top context does not change when doing callbacks or 3584 // Make sure that the top context does not change when doing callbacks or
3581 // interceptor calls. 3585 // interceptor calls.
3582 AssertNoContextChange ncc(it->isolate()); 3586 AssertNoContextChange ncc(it->isolate());
3583 3587
3584 *found = true; 3588 *found = true;
3585 3589
3586 bool done = false; 3590 bool done = false;
3587 for (; it->IsFound(); it->Next()) { 3591 for (; it->IsFound(); it->Next()) {
3588 switch (it->state()) { 3592 switch (it->state()) {
3589 case LookupIterator::NOT_FOUND: 3593 case LookupIterator::NOT_FOUND:
3590 UNREACHABLE(); 3594 UNREACHABLE();
3591 3595
3592 case LookupIterator::ACCESS_CHECK: 3596 case LookupIterator::ACCESS_CHECK:
3593 if (it->HasAccess()) break; 3597 if (it->HasAccess()) break;
3594 // Check whether it makes sense to reuse the lookup iterator. Here it 3598 // Check whether it makes sense to reuse the lookup iterator. Here it
3595 // might still call into setters up the prototype chain. 3599 // might still call into setters up the prototype chain.
3596 return JSObject::SetPropertyWithFailedAccessCheck(it, value); 3600 return JSObject::SetPropertyWithFailedAccessCheck(it, value,
3601 should_throw);
3597 3602
3598 case LookupIterator::JSPROXY: 3603 case LookupIterator::JSPROXY:
3599 if (it->HolderIsReceiverOrHiddenPrototype()) { 3604 if (it->HolderIsReceiverOrHiddenPrototype()) {
3600 return JSProxy::SetPropertyWithHandler( 3605 return JSProxy::SetPropertyWithHandler(
3601 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value, 3606 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value,
3602 language_mode); 3607 language_mode, should_throw);
3603 } else { 3608 } else {
3604 // TODO(verwaest): Use the MaybeHandle to indicate result. 3609 // TODO(verwaest): Use the MaybeHandle to indicate result.
3605 bool has_result = false; 3610 bool has_result = false;
3606 MaybeHandle<Object> maybe_result = 3611 Maybe<bool> maybe_result =
3607 JSProxy::SetPropertyViaPrototypesWithHandler( 3612 JSProxy::SetPropertyViaPrototypesWithHandler(
3608 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), 3613 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(),
3609 value, language_mode, &has_result); 3614 value, language_mode, should_throw, &has_result);
3610 if (has_result) return maybe_result; 3615 if (has_result) return maybe_result;
3611 done = true; 3616 done = true;
3612 } 3617 }
3613 break; 3618 break;
3614 3619
3615 case LookupIterator::INTERCEPTOR: 3620 case LookupIterator::INTERCEPTOR:
3616 if (it->HolderIsReceiverOrHiddenPrototype()) { 3621 if (it->HolderIsReceiverOrHiddenPrototype()) {
3617 MaybeHandle<Object> maybe_result = 3622 Maybe<bool> maybe_result =
3618 JSObject::SetPropertyWithInterceptor(it, value); 3623 JSObject::SetPropertyWithInterceptor(it, value);
3619 if (!maybe_result.is_null()) return maybe_result; 3624 if (maybe_result.IsNothing()) return Nothing<bool>();
3620 if (it->isolate()->has_pending_exception()) return maybe_result; 3625 if (maybe_result.FromJust()) return Just(true);
3621 } else { 3626 } else {
3622 Maybe<PropertyAttributes> maybe_attributes = 3627 Maybe<PropertyAttributes> maybe_attributes =
3623 JSObject::GetPropertyAttributesWithInterceptor(it); 3628 JSObject::GetPropertyAttributesWithInterceptor(it);
3624 if (!maybe_attributes.IsJust()) return MaybeHandle<Object>(); 3629 if (!maybe_attributes.IsJust()) return Nothing<bool>();
3625 done = maybe_attributes.FromJust() != ABSENT; 3630 done = maybe_attributes.FromJust() != ABSENT;
3626 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) { 3631 if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) {
3627 return WriteToReadOnlyProperty(it, value, language_mode); 3632 return WriteToReadOnlyProperty(it, value, language_mode,
3633 should_throw);
3628 } 3634 }
3629 } 3635 }
3630 break; 3636 break;
3631 3637
3632 case LookupIterator::ACCESSOR: { 3638 case LookupIterator::ACCESSOR: {
3633 if (it->IsReadOnly()) { 3639 if (it->IsReadOnly()) {
3634 return WriteToReadOnlyProperty(it, value, language_mode); 3640 return WriteToReadOnlyProperty(it, value, language_mode,
3641 should_throw);
3635 } 3642 }
3636 Handle<Object> accessors = it->GetAccessors(); 3643 Handle<Object> accessors = it->GetAccessors();
3637 if (accessors->IsAccessorInfo() && 3644 if (accessors->IsAccessorInfo() &&
3638 !it->HolderIsReceiverOrHiddenPrototype() && 3645 !it->HolderIsReceiverOrHiddenPrototype() &&
3639 AccessorInfo::cast(*accessors)->is_special_data_property()) { 3646 AccessorInfo::cast(*accessors)->is_special_data_property()) {
3640 done = true; 3647 done = true;
3641 break; 3648 break;
3642 } 3649 }
3643 return SetPropertyWithAccessor(it, value, language_mode); 3650 return SetPropertyWithAccessor(it, value, language_mode, should_throw);
3644 } 3651 }
3645 case LookupIterator::INTEGER_INDEXED_EXOTIC: 3652 case LookupIterator::INTEGER_INDEXED_EXOTIC:
3646 // TODO(verwaest): We should throw an exception. 3653 // TODO(verwaest): We should throw an exception.
3647 return value; 3654 return Just(true);
3648 3655
3649 case LookupIterator::DATA: 3656 case LookupIterator::DATA:
3650 if (it->IsReadOnly()) { 3657 if (it->IsReadOnly()) {
3651 return WriteToReadOnlyProperty(it, value, language_mode); 3658 return WriteToReadOnlyProperty(it, value, language_mode,
3659 should_throw);
3652 } 3660 }
3653 if (it->HolderIsReceiverOrHiddenPrototype()) { 3661 if (it->HolderIsReceiverOrHiddenPrototype()) {
3654 return SetDataProperty(it, value); 3662 return SetDataProperty(it, value, should_throw);
3655 } 3663 }
3656 done = true; 3664 done = true;
3657 break; 3665 break;
3658 3666
3659 case LookupIterator::TRANSITION: 3667 case LookupIterator::TRANSITION:
3660 done = true; 3668 done = true;
3661 break; 3669 break;
3662 } 3670 }
3663 3671
3664 if (done) break; 3672 if (done) break;
3665 } 3673 }
3666 3674
3667 // If the receiver is the JSGlobalObject, the store was contextual. In case 3675 // If the receiver is the JSGlobalObject, the store was contextual. In case
3668 // the property did not exist yet on the global object itself, we have to 3676 // the property did not exist yet on the global object itself, we have to
3669 // throw a reference error in strict mode. 3677 // throw a reference error in strict mode.
3670 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) { 3678 if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) {
3671 THROW_NEW_ERROR(it->isolate(), 3679 RETURN_FAILURE(it->isolate(), should_throw,
3672 NewReferenceError(MessageTemplate::kNotDefined, it->name()), 3680 NewReferenceError(MessageTemplate::kNotDefined, it->name()));
3673 Object);
3674 } 3681 }
3675 3682
3676 *found = false; 3683 *found = false;
3677 return MaybeHandle<Object>(); 3684 return Nothing<bool>();
3678 } 3685 }
3679 3686
3680 3687
3681 MaybeHandle<Object> Object::SetProperty(LookupIterator* it, 3688 MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
3682 Handle<Object> value, 3689 Handle<Object> value,
3683 LanguageMode language_mode, 3690 LanguageMode language_mode,
3684 StoreFromKeyed store_mode) { 3691 StoreFromKeyed store_mode) {
3685 bool found = false; 3692 MAYBE_RETURN_NULL(
3686 MaybeHandle<Object> result = 3693 SetProperty(it, value, language_mode, THROW_ON_ERROR, store_mode));
3687 SetPropertyInternal(it, value, language_mode, store_mode, &found); 3694 return value;
3688 if (found) return result;
3689 return AddDataProperty(it, value, NONE, language_mode, store_mode);
3690 } 3695 }
3691 3696
3692 3697
3698 Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
3699 LanguageMode language_mode,
3700 ShouldThrow should_throw,
3701 StoreFromKeyed store_mode) {
3702 bool found = false;
3703 Maybe<bool> result = SetPropertyInternal(it, value, language_mode,
3704 should_throw, store_mode, &found);
3705 if (found) return result;
3706 return AddDataProperty(it, value, NONE, language_mode, should_throw,
3707 store_mode);
3708 }
3709
3710
3693 MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it, 3711 MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
3694 Handle<Object> value, 3712 Handle<Object> value,
3695 LanguageMode language_mode, 3713 LanguageMode language_mode,
3696 StoreFromKeyed store_mode) { 3714 StoreFromKeyed store_mode) {
3697 bool found = false; 3715 bool found = false;
3698 MaybeHandle<Object> result = 3716 Maybe<bool> result = SetPropertyInternal(it, value, language_mode,
3699 SetPropertyInternal(it, value, language_mode, store_mode, &found); 3717 THROW_ON_ERROR, store_mode, &found);
3700 if (found) return result; 3718 if (found) {
3719 MAYBE_RETURN_NULL(result);
3720 return value;
3721 }
3701 3722
3702 if (!it->GetReceiver()->IsJSReceiver()) { 3723 if (!it->GetReceiver()->IsJSReceiver()) {
3703 return WriteToReadOnlyProperty(it, value, language_mode); 3724 MAYBE_RETURN_NULL(
3725 WriteToReadOnlyProperty(it, value, language_mode, THROW_ON_ERROR));
3726 return value;
3704 } 3727 }
3705 3728
3706 LookupIterator::Configuration c = LookupIterator::OWN; 3729 LookupIterator::Configuration c = LookupIterator::OWN;
3707 LookupIterator own_lookup = 3730 LookupIterator own_lookup =
3708 it->IsElement() 3731 it->IsElement()
3709 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c) 3732 ? LookupIterator(it->isolate(), it->GetReceiver(), it->index(), c)
3710 : LookupIterator(it->GetReceiver(), it->name(), c); 3733 : LookupIterator(it->GetReceiver(), it->name(), c);
3711 3734
3712 for (; own_lookup.IsFound(); own_lookup.Next()) { 3735 for (; own_lookup.IsFound(); own_lookup.Next()) {
3713 switch (own_lookup.state()) { 3736 switch (own_lookup.state()) {
3714 case LookupIterator::ACCESS_CHECK: 3737 case LookupIterator::ACCESS_CHECK:
3715 if (!own_lookup.HasAccess()) { 3738 if (!own_lookup.HasAccess()) {
3716 return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value); 3739 MAYBE_RETURN_NULL(JSObject::SetPropertyWithFailedAccessCheck(
3740 &own_lookup, value, THROW_ON_ERROR));
3741 return value;
3717 } 3742 }
3718 break; 3743 break;
3719 3744
3720 case LookupIterator::INTEGER_INDEXED_EXOTIC: 3745 case LookupIterator::INTEGER_INDEXED_EXOTIC:
3721 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 3746 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
3722 value, language_mode); 3747 value, language_mode);
3723 3748
3724 case LookupIterator::DATA: { 3749 case LookupIterator::DATA: {
3725 PropertyDetails details = own_lookup.property_details(); 3750 PropertyDetails details = own_lookup.property_details();
3726 if (details.IsConfigurable() || !details.IsReadOnly()) { 3751 if (details.IsConfigurable() || !details.IsReadOnly()) {
3727 return JSObject::DefineOwnPropertyIgnoreAttributes( 3752 return JSObject::DefineOwnPropertyIgnoreAttributes(
3728 &own_lookup, value, details.attributes()); 3753 &own_lookup, value, details.attributes());
3729 } 3754 }
3730 return WriteToReadOnlyProperty(&own_lookup, value, language_mode); 3755 MAYBE_RETURN_NULL(WriteToReadOnlyProperty(
3756 &own_lookup, value, language_mode, THROW_ON_ERROR));
3757 return value;
3731 } 3758 }
3732 3759
3733 case LookupIterator::ACCESSOR: { 3760 case LookupIterator::ACCESSOR: {
3734 PropertyDetails details = own_lookup.property_details(); 3761 PropertyDetails details = own_lookup.property_details();
3735 if (details.IsConfigurable()) { 3762 if (details.IsConfigurable()) {
3736 return JSObject::DefineOwnPropertyIgnoreAttributes( 3763 return JSObject::DefineOwnPropertyIgnoreAttributes(
3737 &own_lookup, value, details.attributes()); 3764 &own_lookup, value, details.attributes());
3738 } 3765 }
3739 3766
3740 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 3767 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
3741 value, language_mode); 3768 value, language_mode);
3742 } 3769 }
3743 3770
3744 case LookupIterator::INTERCEPTOR: 3771 case LookupIterator::INTERCEPTOR:
3745 case LookupIterator::JSPROXY: { 3772 case LookupIterator::JSPROXY: {
3746 bool found = false; 3773 bool found = false;
3747 MaybeHandle<Object> result = SetPropertyInternal( 3774 Maybe<bool> result =
3748 &own_lookup, value, language_mode, store_mode, &found); 3775 SetPropertyInternal(&own_lookup, value, language_mode,
3749 if (found) return result; 3776 THROW_ON_ERROR, store_mode, &found);
3777 if (found) {
3778 MAYBE_RETURN_NULL(result);
3779 return value;
3780 }
3750 break; 3781 break;
3751 } 3782 }
3752 3783
3753 case LookupIterator::NOT_FOUND: 3784 case LookupIterator::NOT_FOUND:
3754 case LookupIterator::TRANSITION: 3785 case LookupIterator::TRANSITION:
3755 UNREACHABLE(); 3786 UNREACHABLE();
3756 } 3787 }
3757 } 3788 }
3758 3789
3759 return JSObject::AddDataProperty(&own_lookup, value, NONE, language_mode, 3790 return JSObject::AddDataProperty(&own_lookup, value, NONE, language_mode,
(...skipping 19 matching lines...) Expand all
3779 if (is_strong(language_mode)) { 3810 if (is_strong(language_mode)) {
3780 THROW_NEW_ERROR( 3811 THROW_NEW_ERROR(
3781 isolate, 3812 isolate,
3782 NewTypeError(MessageTemplate::kStrongPropertyAccess, name, receiver), 3813 NewTypeError(MessageTemplate::kStrongPropertyAccess, name, receiver),
3783 Object); 3814 Object);
3784 } 3815 }
3785 return isolate->factory()->undefined_value(); 3816 return isolate->factory()->undefined_value();
3786 } 3817 }
3787 3818
3788 3819
3789 MaybeHandle<Object> Object::CannotCreateProperty(LookupIterator* it, 3820 Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
3790 Handle<Object> value, 3821 Handle<Object> receiver,
3791 LanguageMode language_mode) { 3822 Handle<Object> name,
3792 return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(), 3823 Handle<Object> value,
3793 value, language_mode); 3824 LanguageMode language_mode,
3825 ShouldThrow should_throw) {
3826 if (is_sloppy(language_mode)) return Just(true);
3827 RETURN_FAILURE(
3828 isolate, should_throw,
3829 NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
3830 Object::TypeOf(isolate, receiver), receiver));
3794 } 3831 }
3795 3832
3796 3833
3797 MaybeHandle<Object> Object::CannotCreateProperty(Isolate* isolate, 3834 Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
3798 Handle<Object> receiver, 3835 Handle<Object> value,
3799 Handle<Object> name, 3836 LanguageMode language_mode,
3800 Handle<Object> value, 3837 ShouldThrow should_throw) {
3801 LanguageMode language_mode) { 3838 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
3802 if (is_sloppy(language_mode)) return value; 3839 it->GetName(), value, language_mode,
3803 Handle<String> typeof_string = Object::TypeOf(isolate, receiver); 3840 should_throw);
3804 THROW_NEW_ERROR(isolate,
3805 NewTypeError(MessageTemplate::kStrictCannotCreateProperty,
3806 name, typeof_string, receiver),
3807 Object);
3808 } 3841 }
3809 3842
3810 3843
3811 MaybeHandle<Object> Object::WriteToReadOnlyProperty( 3844 Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
3812 LookupIterator* it, Handle<Object> value, LanguageMode language_mode) { 3845 Handle<Object> receiver,
3813 return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(), 3846 Handle<Object> name,
3814 it->GetName(), value, language_mode); 3847 Handle<Object> value,
3848 LanguageMode language_mode,
3849 ShouldThrow should_throw) {
3850 if (is_sloppy(language_mode)) return Just(true);
3851 RETURN_FAILURE(isolate, should_throw,
3852 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
3853 Object::TypeOf(isolate, receiver), receiver));
3815 } 3854 }
3816 3855
3817 3856
3818 MaybeHandle<Object> Object::WriteToReadOnlyProperty(
3819 Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
3820 Handle<Object> value, LanguageMode language_mode) {
3821 if (is_sloppy(language_mode)) return value;
3822 Handle<String> typeof_string = Object::TypeOf(isolate, receiver);
3823 THROW_NEW_ERROR(isolate,
3824 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
3825 typeof_string, receiver),
3826 Object);
3827 }
3828
3829
3830 MaybeHandle<Object> Object::RedefineNonconfigurableProperty( 3857 MaybeHandle<Object> Object::RedefineNonconfigurableProperty(
3831 Isolate* isolate, Handle<Object> name, Handle<Object> value, 3858 Isolate* isolate, Handle<Object> name, Handle<Object> value,
3832 LanguageMode language_mode) { 3859 LanguageMode language_mode) {
3833 if (is_sloppy(language_mode)) return value; 3860 if (is_sloppy(language_mode)) return value;
3834 THROW_NEW_ERROR(isolate, 3861 THROW_NEW_ERROR(isolate,
3835 NewTypeError(MessageTemplate::kRedefineDisallowed, name), 3862 NewTypeError(MessageTemplate::kRedefineDisallowed, name),
3836 Object); 3863 Object);
3837 } 3864 }
3838 3865
3839 3866
3840 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, 3867 Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value,
3841 Handle<Object> value) { 3868 ShouldThrow should_throw) {
3842 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot 3869 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
3843 // have own properties. 3870 // have own properties.
3844 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 3871 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
3845 3872
3846 // Store on the holder which may be hidden behind the receiver. 3873 // Store on the holder which may be hidden behind the receiver.
3847 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); 3874 DCHECK(it->HolderIsReceiverOrHiddenPrototype());
3848 3875
3849 // Old value for the observation change record. 3876 // Old value for the observation change record.
3850 // Fetch before transforming the object since the encoding may become 3877 // Fetch before transforming the object since the encoding may become
3851 // incompatible with what's cached in |it|. 3878 // incompatible with what's cached in |it|.
3852 bool is_observed = receiver->map()->is_observed() && 3879 bool is_observed = receiver->map()->is_observed() &&
3853 (it->IsElement() || 3880 (it->IsElement() ||
3854 !it->isolate()->IsInternallyUsedPropertyName(it->name())); 3881 !it->isolate()->IsInternallyUsedPropertyName(it->name()));
3855 MaybeHandle<Object> maybe_old; 3882 MaybeHandle<Object> maybe_old;
3856 if (is_observed) maybe_old = it->GetDataValue(); 3883 if (is_observed) maybe_old = it->GetDataValue();
3857 3884
3858 Handle<Object> to_assign = value; 3885 Handle<Object> to_assign = value;
3859 // Convert the incoming value to a number for storing into typed arrays. 3886 // Convert the incoming value to a number for storing into typed arrays.
3860 if (it->IsElement() && receiver->HasFixedTypedArrayElements()) { 3887 if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
3861 if (!value->IsNumber() && !value->IsUndefined()) { 3888 if (!value->IsNumber() && !value->IsUndefined()) {
3862 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), to_assign, 3889 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3863 Object::ToNumber(value), Object); 3890 it->isolate(), to_assign, Object::ToNumber(value), Nothing<bool>());
3864 // ToNumber above might modify the receiver, causing the cached 3891 // ToNumber above might modify the receiver, causing the cached
3865 // holder_map to mismatch the actual holder->map() after this point. 3892 // holder_map to mismatch the actual holder->map() after this point.
3866 // Reload the map to be in consistent state. Other cached state cannot 3893 // Reload the map to be in consistent state. Other cached state cannot
3867 // have been invalidated since typed array elements cannot be reconfigured 3894 // have been invalidated since typed array elements cannot be reconfigured
3868 // in any way. 3895 // in any way.
3869 it->ReloadHolderMap(); 3896 it->ReloadHolderMap();
3870 3897
3871 // We have to recheck the length. However, it can only change if the 3898 // We have to recheck the length. However, it can only change if the
3872 // underlying buffer was neutered, so just check that. 3899 // underlying buffer was neutered, so just check that.
3873 if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) { 3900 if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) {
3874 return value; 3901 return Just(true);
3902 // TODO(neis): According to the spec, this should throw a TypeError.
3875 } 3903 }
3876 } 3904 }
3877 } 3905 }
3878 3906
3879 // Possibly migrate to the most up-to-date map that will be able to store 3907 // Possibly migrate to the most up-to-date map that will be able to store
3880 // |value| under it->name(). 3908 // |value| under it->name().
3881 it->PrepareForDataProperty(to_assign); 3909 it->PrepareForDataProperty(to_assign);
3882 3910
3883 // Write the property value. 3911 // Write the property value.
3884 it->WriteDataValue(to_assign); 3912 it->WriteDataValue(to_assign);
3885 3913
3886 // Send the change record if there are observers. 3914 // Send the change record if there are observers.
3887 if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) { 3915 if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
3888 RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord( 3916 RETURN_ON_EXCEPTION_VALUE(
3889 receiver, "update", it->GetName(), 3917 it->isolate(),
3890 maybe_old.ToHandleChecked()), 3918 JSObject::EnqueueChangeRecord(receiver, "update", it->GetName(),
3891 Object); 3919 maybe_old.ToHandleChecked()),
3920 Nothing<bool>());
3892 } 3921 }
3893 3922
3894 #if VERIFY_HEAP 3923 #if VERIFY_HEAP
3895 if (FLAG_verify_heap) { 3924 if (FLAG_verify_heap) {
3896 receiver->JSObjectVerify(); 3925 receiver->JSObjectVerify();
3897 } 3926 }
3898 #endif 3927 #endif
3899 return value; 3928 return Just(true);
3900 } 3929 }
3901 3930
3902 3931
3903 MUST_USE_RESULT static MaybeHandle<Object> BeginPerformSplice( 3932 MUST_USE_RESULT static MaybeHandle<Object> BeginPerformSplice(
3904 Handle<JSArray> object) { 3933 Handle<JSArray> object) {
3905 Isolate* isolate = object->GetIsolate(); 3934 Isolate* isolate = object->GetIsolate();
3906 HandleScope scope(isolate); 3935 HandleScope scope(isolate);
3907 Handle<Object> args[] = {object}; 3936 Handle<Object> args[] = {object};
3908 3937
3909 return Execution::Call( 3938 return Execution::Call(
(...skipping 29 matching lines...) Expand all
3939 isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()), 3968 isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()),
3940 isolate->factory()->undefined_value(), arraysize(args), args); 3969 isolate->factory()->undefined_value(), arraysize(args), args);
3941 } 3970 }
3942 3971
3943 3972
3944 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, 3973 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
3945 Handle<Object> value, 3974 Handle<Object> value,
3946 PropertyAttributes attributes, 3975 PropertyAttributes attributes,
3947 LanguageMode language_mode, 3976 LanguageMode language_mode,
3948 StoreFromKeyed store_mode) { 3977 StoreFromKeyed store_mode) {
3978 MAYBE_RETURN_NULL(AddDataProperty(it, value, attributes, language_mode,
3979 THROW_ON_ERROR, store_mode));
3980 return value;
3981 }
3982
3983
3984 Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
3985 PropertyAttributes attributes,
3986 LanguageMode language_mode,
3987 ShouldThrow should_throw,
3988 StoreFromKeyed store_mode) {
3949 DCHECK(!it->GetReceiver()->IsJSProxy()); 3989 DCHECK(!it->GetReceiver()->IsJSProxy());
3950 if (!it->GetReceiver()->IsJSObject()) { 3990 if (!it->GetReceiver()->IsJSObject()) {
3951 return CannotCreateProperty(it, value, language_mode); 3991 return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
3992 value, language_mode, should_throw);
3952 } 3993 }
3953 3994
3954 DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state()); 3995 DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
3955 3996
3956 Handle<JSObject> receiver = it->GetStoreTarget(); 3997 Handle<JSObject> receiver = it->GetStoreTarget();
3957 3998
3958 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) 3999 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
3959 // instead. If the prototype is Null, the proxy is detached. 4000 // instead. If the prototype is Null, the proxy is detached.
3960 if (receiver->IsJSGlobalProxy()) return value; 4001 if (receiver->IsJSGlobalProxy()) return Just(true);
3961 4002
3962 Isolate* isolate = it->isolate(); 4003 Isolate* isolate = it->isolate();
3963 4004
3964 if (!receiver->map()->is_extensible() && 4005 if (!receiver->map()->is_extensible() &&
3965 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) { 4006 (it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) {
3966 if (is_sloppy(language_mode)) return value; 4007 if (is_sloppy(language_mode)) return Just(true);
3967 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kObjectNotExtensible, 4008 RETURN_FAILURE(
3968 it->GetName()), 4009 isolate, should_throw,
3969 Object); 4010 NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
3970 } 4011 }
3971 4012
3972 if (it->IsElement()) { 4013 if (it->IsElement()) {
3973 if (receiver->IsJSArray()) { 4014 if (receiver->IsJSArray()) {
3974 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 4015 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
3975 if (JSArray::WouldChangeReadOnlyLength(array, it->index())) { 4016 if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
3976 if (is_sloppy(language_mode)) return value; 4017 if (is_sloppy(language_mode)) return Just(true);
3977 return JSArray::ReadOnlyLengthError(array); 4018 RETURN_FAILURE(array->GetIsolate(), should_throw,
4019 NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
4020 isolate->factory()->length_string(),
4021 Object::TypeOf(isolate, array), array));
3978 } 4022 }
3979 4023
3980 if (FLAG_trace_external_array_abuse && 4024 if (FLAG_trace_external_array_abuse &&
3981 array->HasFixedTypedArrayElements()) { 4025 array->HasFixedTypedArrayElements()) {
3982 CheckArrayAbuse(array, "typed elements write", it->index(), true); 4026 CheckArrayAbuse(array, "typed elements write", it->index(), true);
3983 } 4027 }
3984 4028
3985 if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) { 4029 if (FLAG_trace_js_array_abuse && !array->HasFixedTypedArrayElements()) {
3986 CheckArrayAbuse(array, "elements write", it->index(), false); 4030 CheckArrayAbuse(array, "elements write", it->index(), false);
3987 } 4031 }
3988 } 4032 }
3989 4033
3990 MaybeHandle<Object> result = 4034 Maybe<bool> result = JSObject::AddDataElement(receiver, it->index(), value,
3991 JSObject::AddDataElement(receiver, it->index(), value, attributes); 4035 attributes, should_throw);
3992 JSObject::ValidateElements(receiver); 4036 JSObject::ValidateElements(receiver);
3993 return result; 4037 return result;
3994 } else { 4038 } else {
3995 // Migrate to the most up-to-date map that will be able to store |value| 4039 // Migrate to the most up-to-date map that will be able to store |value|
3996 // under it->name() with |attributes|. 4040 // under it->name() with |attributes|.
3997 it->PrepareTransitionToDataProperty(value, attributes, store_mode); 4041 it->PrepareTransitionToDataProperty(value, attributes, store_mode);
3998 DCHECK_EQ(LookupIterator::TRANSITION, it->state()); 4042 DCHECK_EQ(LookupIterator::TRANSITION, it->state());
3999 it->ApplyTransitionToDataProperty(); 4043 it->ApplyTransitionToDataProperty();
4000 4044
4001 // TODO(verwaest): Encapsulate dictionary handling better. 4045 // TODO(verwaest): Encapsulate dictionary handling better.
4002 if (receiver->map()->is_dictionary_map()) { 4046 if (receiver->map()->is_dictionary_map()) {
4003 // TODO(verwaest): Probably should ensure this is done beforehand. 4047 // TODO(verwaest): Probably should ensure this is done beforehand.
4004 it->InternalizeName(); 4048 it->InternalizeName();
4005 // TODO(dcarney): just populate TransitionPropertyCell here? 4049 // TODO(dcarney): just populate TransitionPropertyCell here?
4006 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); 4050 JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
4007 } else { 4051 } else {
4008 // Write the property value. 4052 // Write the property value.
4009 it->WriteDataValue(value); 4053 it->WriteDataValue(value);
4010 } 4054 }
4011 4055
4012 // Send the change record if there are observers. 4056 // Send the change record if there are observers.
4013 if (receiver->map()->is_observed() && 4057 if (receiver->map()->is_observed() &&
4014 !isolate->IsInternallyUsedPropertyName(it->name())) { 4058 !isolate->IsInternallyUsedPropertyName(it->name())) {
4015 RETURN_ON_EXCEPTION(isolate, JSObject::EnqueueChangeRecord( 4059 RETURN_ON_EXCEPTION_VALUE(isolate, JSObject::EnqueueChangeRecord(
4016 receiver, "add", it->name(), 4060 receiver, "add", it->name(),
4017 it->factory()->the_hole_value()), 4061 it->factory()->the_hole_value()),
4018 Object); 4062 Nothing<bool>());
4019 } 4063 }
4020 #if VERIFY_HEAP 4064 #if VERIFY_HEAP
4021 if (FLAG_verify_heap) { 4065 if (FLAG_verify_heap) {
4022 receiver->JSObjectVerify(); 4066 receiver->JSObjectVerify();
4023 } 4067 }
4024 #endif 4068 #endif
4025 } 4069 }
4026 4070
4027 return value; 4071 return Just(true);
4028 } 4072 }
4029 4073
4030 4074
4031 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { 4075 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
4032 // Only supports adding slack to owned descriptors. 4076 // Only supports adding slack to owned descriptors.
4033 DCHECK(map->owns_descriptors()); 4077 DCHECK(map->owns_descriptors());
4034 4078
4035 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 4079 Handle<DescriptorArray> descriptors(map->instance_descriptors());
4036 int old_size = map->NumberOfOwnDescriptors(); 4080 int old_size = map->NumberOfOwnDescriptors();
4037 if (slack <= descriptors->NumberOfSlackDescriptors()) return; 4081 if (slack <= descriptors->NumberOfSlackDescriptors()) return;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4369 Handle<Object> result; 4413 Handle<Object> result;
4370 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 4414 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4371 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(), 4415 isolate, result, CallTrap(proxy, "has", isolate->derived_has_trap(),
4372 arraysize(args), args), 4416 arraysize(args), args),
4373 Nothing<bool>()); 4417 Nothing<bool>());
4374 4418
4375 return Just(result->BooleanValue()); 4419 return Just(result->BooleanValue());
4376 } 4420 }
4377 4421
4378 4422
4379 MaybeHandle<Object> JSProxy::SetPropertyWithHandler( 4423 Maybe<bool> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
4380 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, 4424 Handle<Object> receiver,
4381 Handle<Object> value, LanguageMode language_mode) { 4425 Handle<Name> name,
4426 Handle<Object> value,
4427 LanguageMode language_mode,
4428 ShouldThrow should_throw) {
4382 Isolate* isolate = proxy->GetIsolate(); 4429 Isolate* isolate = proxy->GetIsolate();
4383 4430
4384 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4431 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4385 if (name->IsSymbol()) return value; 4432 if (name->IsSymbol()) return Just(true);
4386 4433
4387 Handle<Object> args[] = { receiver, name, value }; 4434 Handle<Object> args[] = { receiver, name, value };
4388 RETURN_ON_EXCEPTION( 4435 RETURN_ON_EXCEPTION_VALUE(isolate,
4389 isolate, 4436 CallTrap(proxy, "set", isolate->derived_set_trap(),
4390 CallTrap(proxy, 4437 arraysize(args), args),
4391 "set", 4438 Nothing<bool>());
4392 isolate->derived_set_trap(),
4393 arraysize(args),
4394 args),
4395 Object);
4396 4439
4397 return value; 4440 return Just(true);
4441 // TODO(neis): This needs to be made spec-conformant by throwing a TypeError
4442 // if the trap's result is falsish.
4398 } 4443 }
4399 4444
4400 4445
4401 MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler( 4446 Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler(
4402 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, 4447 Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
4403 Handle<Object> value, LanguageMode language_mode, bool* done) { 4448 Handle<Object> value, LanguageMode language_mode, ShouldThrow should_throw,
4449 bool* done) {
4404 Isolate* isolate = proxy->GetIsolate(); 4450 Isolate* isolate = proxy->GetIsolate();
4405 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy. 4451 Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
4406 4452
4407 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4453 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4408 if (name->IsSymbol()) { 4454 if (name->IsSymbol()) {
4409 *done = false; 4455 *done = false; // Return value will be ignored.
4410 return isolate->factory()->the_hole_value(); 4456 return Nothing<bool>();
4411 } 4457 }
4412 4458
4413 *done = true; // except where redefined... 4459 *done = true; // except where redefined...
4414 Handle<Object> args[] = { name }; 4460 Handle<Object> args[] = { name };
4415 Handle<Object> result; 4461 Handle<Object> result;
4416 ASSIGN_RETURN_ON_EXCEPTION( 4462 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4417 isolate, result, 4463 isolate, result, CallTrap(proxy, "getPropertyDescriptor",
4418 CallTrap(proxy, 4464 Handle<Object>(), arraysize(args), args),
4419 "getPropertyDescriptor", 4465 Nothing<bool>());
4420 Handle<Object>(),
4421 arraysize(args),
4422 args),
4423 Object);
4424 4466
4425 if (result->IsUndefined()) { 4467 if (result->IsUndefined()) {
4426 *done = false; 4468 *done = false; // Return value will be ignored.
4427 return isolate->factory()->the_hole_value(); 4469 return Nothing<bool>();
4428 } 4470 }
4429 4471
4430 // Emulate [[GetProperty]] semantics for proxies. 4472 // Emulate [[GetProperty]] semantics for proxies.
4431 Handle<Object> argv[] = { result }; 4473 Handle<Object> argv[] = { result };
4432 Handle<Object> desc; 4474 Handle<Object> desc;
4433 ASSIGN_RETURN_ON_EXCEPTION( 4475 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
4434 isolate, desc, 4476 isolate, desc,
4435 Execution::Call(isolate, 4477 Execution::Call(isolate, isolate->to_complete_property_descriptor(),
4436 isolate->to_complete_property_descriptor(), 4478 result, arraysize(argv), argv),
4437 result, 4479 Nothing<bool>());
4438 arraysize(argv),
4439 argv),
4440 Object);
4441 4480
4442 // [[GetProperty]] requires to check that all properties are configurable. 4481 // [[GetProperty]] requires to check that all properties are configurable.
4443 Handle<String> configurable_name = 4482 Handle<String> configurable_name =
4444 isolate->factory()->InternalizeOneByteString( 4483 isolate->factory()->InternalizeOneByteString(
4445 STATIC_CHAR_VECTOR("configurable_")); 4484 STATIC_CHAR_VECTOR("configurable_"));
4446 Handle<Object> configurable = 4485 Handle<Object> configurable =
4447 Object::GetProperty(desc, configurable_name).ToHandleChecked(); 4486 Object::GetProperty(desc, configurable_name).ToHandleChecked();
4448 DCHECK(configurable->IsBoolean()); 4487 DCHECK(configurable->IsBoolean());
4449 if (configurable->IsFalse()) { 4488 if (configurable->IsFalse()) {
4450 Handle<String> trap = isolate->factory()->InternalizeOneByteString( 4489 RETURN_FAILURE(
4451 STATIC_CHAR_VECTOR("getPropertyDescriptor")); 4490 isolate, should_throw,
4452 THROW_NEW_ERROR(isolate, 4491 NewTypeError(MessageTemplate::kProxyPropNotConfigurable, handler, name,
4453 NewTypeError(MessageTemplate::kProxyPropNotConfigurable, 4492 isolate->factory()->NewStringFromAsciiChecked(
4454 handler, name, trap), 4493 "getPropertyDescriptor")));
4455 Object);
4456 } 4494 }
4457 DCHECK(configurable->IsTrue()); 4495 DCHECK(configurable->IsTrue());
4458 4496
4459 // Check for DataDescriptor. 4497 // Check for DataDescriptor.
4460 Handle<String> hasWritable_name = 4498 Handle<String> hasWritable_name =
4461 isolate->factory()->InternalizeOneByteString( 4499 isolate->factory()->InternalizeOneByteString(
4462 STATIC_CHAR_VECTOR("hasWritable_")); 4500 STATIC_CHAR_VECTOR("hasWritable_"));
4463 Handle<Object> hasWritable = 4501 Handle<Object> hasWritable =
4464 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); 4502 Object::GetProperty(desc, hasWritable_name).ToHandleChecked();
4465 DCHECK(hasWritable->IsBoolean()); 4503 DCHECK(hasWritable->IsBoolean());
4466 if (hasWritable->IsTrue()) { 4504 if (hasWritable->IsTrue()) {
4467 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( 4505 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString(
4468 STATIC_CHAR_VECTOR("writable_")); 4506 STATIC_CHAR_VECTOR("writable_"));
4469 Handle<Object> writable = 4507 Handle<Object> writable =
4470 Object::GetProperty(desc, writable_name).ToHandleChecked(); 4508 Object::GetProperty(desc, writable_name).ToHandleChecked();
4471 DCHECK(writable->IsBoolean()); 4509 DCHECK(writable->IsBoolean());
4472 *done = writable->IsFalse(); 4510 *done = writable->IsFalse();
4473 if (!*done) return isolate->factory()->the_hole_value(); 4511 if (!*done) return Nothing<bool>(); // Return value will be ignored.
4474 return WriteToReadOnlyProperty(isolate, receiver, name, value, 4512 return WriteToReadOnlyProperty(isolate, receiver, name, value,
4475 language_mode); 4513 language_mode, should_throw);
4476 } 4514 }
4477 4515
4478 // We have an AccessorDescriptor. 4516 // We have an AccessorDescriptor.
4479 Handle<String> set_name = 4517 Handle<String> set_name =
4480 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); 4518 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_"));
4481 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); 4519 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked();
4482 if (!setter->IsUndefined()) { 4520 if (!setter->IsUndefined()) {
4483 // TODO(rossberg): nicer would be to cast to some JSCallable here... 4521 // TODO(rossberg): nicer would be to cast to some JSCallable here...
4484 return SetPropertyWithDefinedSetter( 4522 return SetPropertyWithDefinedSetter(
4485 receiver, Handle<JSReceiver>::cast(setter), value); 4523 receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
4486 } 4524 }
4487 4525
4488 if (is_sloppy(language_mode)) return value; 4526 if (is_sloppy(language_mode)) return Just(true);
4489 THROW_NEW_ERROR( 4527 RETURN_FAILURE(
4490 isolate, NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy), 4528 isolate, should_throw,
4491 Object); 4529 NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy));
4492 } 4530 }
4493 4531
4494 4532
4495 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler( 4533 MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
4496 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) { 4534 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) {
4497 Isolate* isolate = proxy->GetIsolate(); 4535 Isolate* isolate = proxy->GetIsolate();
4498 4536
4499 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 4537 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
4500 if (name->IsSymbol()) return isolate->factory()->false_value(); 4538 if (name->IsSymbol()) return isolate->factory()->false_value();
4501 4539
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
4761 // If there's an interceptor, try to store the property with the 4799 // If there's an interceptor, try to store the property with the
4762 // interceptor. 4800 // interceptor.
4763 // In case of success, the attributes will have been reset to the default 4801 // In case of success, the attributes will have been reset to the default
4764 // attributes of the interceptor, rather than the incoming attributes. 4802 // attributes of the interceptor, rather than the incoming attributes.
4765 // 4803 //
4766 // TODO(verwaest): JSProxy afterwards verify the attributes that the 4804 // TODO(verwaest): JSProxy afterwards verify the attributes that the
4767 // JSProxy claims it has, and verifies that they are compatible. If not, 4805 // JSProxy claims it has, and verifies that they are compatible. If not,
4768 // they throw. Here we should do the same. 4806 // they throw. Here we should do the same.
4769 case LookupIterator::INTERCEPTOR: 4807 case LookupIterator::INTERCEPTOR:
4770 if (handling == DONT_FORCE_FIELD) { 4808 if (handling == DONT_FORCE_FIELD) {
4771 MaybeHandle<Object> maybe_result = 4809 Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value);
4772 JSObject::SetPropertyWithInterceptor(it, value); 4810 if (result.IsNothing()) return MaybeHandle<Object>();
4773 if (!maybe_result.is_null()) return maybe_result; 4811 if (result.FromJust()) return value;
4774 if (it->isolate()->has_pending_exception()) return maybe_result;
4775 } 4812 }
4776 break; 4813 break;
4777 4814
4778 case LookupIterator::ACCESSOR: { 4815 case LookupIterator::ACCESSOR: {
4779 Handle<Object> accessors = it->GetAccessors(); 4816 Handle<Object> accessors = it->GetAccessors();
4780 4817
4781 // Special handling for ExecutableAccessorInfo, which behaves like a 4818 // Special handling for ExecutableAccessorInfo, which behaves like a
4782 // data property. 4819 // data property.
4783 if (accessors->IsExecutableAccessorInfo() && 4820 if (accessors->IsExecutableAccessorInfo() &&
4784 handling == DONT_FORCE_FIELD) { 4821 handling == DONT_FORCE_FIELD) {
4785 PropertyDetails details = it->property_details(); 4822 PropertyDetails details = it->property_details();
4786 // Ensure the context isn't changed after calling into accessors. 4823 // Ensure the context isn't changed after calling into accessors.
4787 AssertNoContextChange ncc(it->isolate()); 4824 AssertNoContextChange ncc(it->isolate());
4788 4825
4789 Handle<Object> result; 4826 Maybe<bool> result = JSObject::SetPropertyWithAccessor(
4790 ASSIGN_RETURN_ON_EXCEPTION( 4827 it, value, STRICT, THROW_ON_ERROR);
4791 it->isolate(), result, 4828 if (result.IsNothing()) return MaybeHandle<Object>();
4792 JSObject::SetPropertyWithAccessor(it, value, STRICT), Object);
4793 DCHECK(result->SameValue(*value));
4794 4829
4795 if (details.attributes() == attributes) return value; 4830 if (details.attributes() == attributes) return value;
4796 4831
4797 // Reconfigure the accessor if attributes mismatch. 4832 // Reconfigure the accessor if attributes mismatch.
4798 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor( 4833 Handle<ExecutableAccessorInfo> new_data = Accessors::CloneAccessor(
4799 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors)); 4834 it->isolate(), Handle<ExecutableAccessorInfo>::cast(accessors));
4800 new_data->set_property_attributes(attributes); 4835 new_data->set_property_attributes(attributes);
4801 // By clearing the setter we don't have to introduce a lookup to 4836 // By clearing the setter we don't have to introduce a lookup to
4802 // the setter, simply make it unavailable to reflect the 4837 // the setter, simply make it unavailable to reflect the
4803 // attributes. 4838 // attributes.
(...skipping 18 matching lines...) Expand all
4822 } 4857 }
4823 case LookupIterator::INTEGER_INDEXED_EXOTIC: 4858 case LookupIterator::INTEGER_INDEXED_EXOTIC:
4824 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 4859 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
4825 value, STRICT); 4860 value, STRICT);
4826 4861
4827 case LookupIterator::DATA: { 4862 case LookupIterator::DATA: {
4828 PropertyDetails details = it->property_details(); 4863 PropertyDetails details = it->property_details();
4829 Handle<Object> old_value = it->factory()->the_hole_value(); 4864 Handle<Object> old_value = it->factory()->the_hole_value();
4830 // Regular property update if the attributes match. 4865 // Regular property update if the attributes match.
4831 if (details.attributes() == attributes) { 4866 if (details.attributes() == attributes) {
4832 return SetDataProperty(it, value); 4867 MAYBE_RETURN_NULL(SetDataProperty(it, value, THROW_ON_ERROR));
4868 return value;
4833 } 4869 }
4834 4870
4835 // Special case: properties of typed arrays cannot be reconfigured to 4871 // Special case: properties of typed arrays cannot be reconfigured to
4836 // non-writable nor to non-enumerable. 4872 // non-writable nor to non-enumerable.
4837 if (it->IsElement() && object->HasFixedTypedArrayElements()) { 4873 if (it->IsElement() && object->HasFixedTypedArrayElements()) {
4838 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(), 4874 return RedefineNonconfigurableProperty(it->isolate(), it->GetName(),
4839 value, STRICT); 4875 value, STRICT);
4840 } 4876 }
4841 4877
4842 // Reconfigure the data property if the attributes mismatch. 4878 // Reconfigure the data property if the attributes mismatch.
(...skipping 2112 matching lines...) Expand 10 before | Expand all | Expand 10 after
6955 if (attrs != NONE) { 6991 if (attrs != NONE) {
6956 ApplyAttributesToDictionary(dictionary, attrs); 6992 ApplyAttributesToDictionary(dictionary, attrs);
6957 } 6993 }
6958 } 6994 }
6959 6995
6960 return Just(true); 6996 return Just(true);
6961 } 6997 }
6962 6998
6963 6999
6964 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { 7000 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
6965 return PreventExtensionsWithTransition<FROZEN>(object, THROW_ON_ERROR) 7001 MAYBE_RETURN_NULL(
6966 .IsJust() 7002 PreventExtensionsWithTransition<FROZEN>(object, THROW_ON_ERROR));
6967 ? object 7003 return object;
6968 : MaybeHandle<Object>();
6969 } 7004 }
6970 7005
6971 7006
6972 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) { 7007 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) {
6973 return PreventExtensionsWithTransition<SEALED>(object, THROW_ON_ERROR) 7008 MAYBE_RETURN_NULL(
6974 .IsJust() 7009 PreventExtensionsWithTransition<SEALED>(object, THROW_ON_ERROR));
6975 ? object 7010 return object;
6976 : MaybeHandle<Object>();
6977 } 7011 }
6978 7012
6979 7013
6980 void JSObject::SetObserved(Handle<JSObject> object) { 7014 void JSObject::SetObserved(Handle<JSObject> object) {
6981 DCHECK(!object->IsJSGlobalProxy()); 7015 DCHECK(!object->IsJSGlobalProxy());
6982 DCHECK(!object->IsJSGlobalObject()); 7016 DCHECK(!object->IsJSGlobalObject());
6983 Isolate* isolate = object->GetIsolate(); 7017 Isolate* isolate = object->GetIsolate();
6984 Handle<Map> new_map; 7018 Handle<Map> new_map;
6985 Handle<Map> old_map(object->map(), isolate); 7019 Handle<Map> old_map(object->map(), isolate);
6986 DCHECK(!old_map->is_observed()); 7020 DCHECK(!old_map->is_observed());
(...skipping 7161 matching lines...) Expand 10 before | Expand all | Expand 10 after
14148 SeededNumberDictionary::kEntrySize; 14182 SeededNumberDictionary::kEntrySize;
14149 return 2 * dictionary_size >= *new_capacity; 14183 return 2 * dictionary_size >= *new_capacity;
14150 } 14184 }
14151 14185
14152 14186
14153 // static 14187 // static
14154 MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object, 14188 MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
14155 uint32_t index, 14189 uint32_t index,
14156 Handle<Object> value, 14190 Handle<Object> value,
14157 PropertyAttributes attributes) { 14191 PropertyAttributes attributes) {
14192 MAYBE_RETURN_NULL(
14193 AddDataElement(object, index, value, attributes, THROW_ON_ERROR));
14194 return value;
14195 }
14196
14197
14198 // static
14199 Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
14200 Handle<Object> value,
14201 PropertyAttributes attributes,
14202 ShouldThrow should_throw) {
14158 DCHECK(object->map()->is_extensible()); 14203 DCHECK(object->map()->is_extensible());
14159 14204
14160 Isolate* isolate = object->GetIsolate(); 14205 Isolate* isolate = object->GetIsolate();
14161 14206
14162 uint32_t old_length = 0; 14207 uint32_t old_length = 0;
14163 uint32_t new_capacity = 0; 14208 uint32_t new_capacity = 0;
14164 14209
14165 Handle<Object> old_length_handle; 14210 Handle<Object> old_length_handle;
14166 if (object->IsJSArray()) { 14211 if (object->IsJSArray()) {
14167 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length)); 14212 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
14208 new_length_handle = isolate->factory()->NewNumberFromUint(new_length); 14253 new_length_handle = isolate->factory()->NewNumberFromUint(new_length);
14209 JSArray::cast(*object)->set_length(*new_length_handle); 14254 JSArray::cast(*object)->set_length(*new_length_handle);
14210 } 14255 }
14211 14256
14212 if (!old_length_handle.is_null() && new_length != old_length) { 14257 if (!old_length_handle.is_null() && new_length != old_length) {
14213 // |old_length_handle| is kept null above unless the object is observed. 14258 // |old_length_handle| is kept null above unless the object is observed.
14214 DCHECK(object->map()->is_observed()); 14259 DCHECK(object->map()->is_observed());
14215 Handle<JSArray> array = Handle<JSArray>::cast(object); 14260 Handle<JSArray> array = Handle<JSArray>::cast(object);
14216 Handle<String> name = isolate->factory()->Uint32ToString(index); 14261 Handle<String> name = isolate->factory()->Uint32ToString(index);
14217 14262
14218 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); 14263 RETURN_ON_EXCEPTION_VALUE(isolate, BeginPerformSplice(array),
14219 RETURN_ON_EXCEPTION( 14264 Nothing<bool>());
14265 RETURN_ON_EXCEPTION_VALUE(
14220 isolate, EnqueueChangeRecord(array, "add", name, 14266 isolate, EnqueueChangeRecord(array, "add", name,
14221 isolate->factory()->the_hole_value()), 14267 isolate->factory()->the_hole_value()),
14222 Object); 14268 Nothing<bool>());
14223 RETURN_ON_EXCEPTION(isolate, 14269 RETURN_ON_EXCEPTION_VALUE(
14224 EnqueueChangeRecord(array, "update", 14270 isolate, EnqueueChangeRecord(array, "update",
14225 isolate->factory()->length_string(), 14271 isolate->factory()->length_string(),
14226 old_length_handle), 14272 old_length_handle),
14227 Object); 14273 Nothing<bool>());
14228 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); 14274 RETURN_ON_EXCEPTION_VALUE(isolate, EndPerformSplice(array),
14275 Nothing<bool>());
14229 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); 14276 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
14230 RETURN_ON_EXCEPTION(isolate, EnqueueSpliceRecord(array, old_length, deleted, 14277 RETURN_ON_EXCEPTION_VALUE(isolate,
14231 new_length - old_length), 14278 EnqueueSpliceRecord(array, old_length, deleted,
14232 Object); 14279 new_length - old_length),
14280 Nothing<bool>());
14233 } else if (object->map()->is_observed()) { 14281 } else if (object->map()->is_observed()) {
14234 Handle<String> name = isolate->factory()->Uint32ToString(index); 14282 Handle<String> name = isolate->factory()->Uint32ToString(index);
14235 RETURN_ON_EXCEPTION( 14283 RETURN_ON_EXCEPTION_VALUE(
14236 isolate, EnqueueChangeRecord(object, "add", name, 14284 isolate, EnqueueChangeRecord(object, "add", name,
14237 isolate->factory()->the_hole_value()), 14285 isolate->factory()->the_hole_value()),
14238 Object); 14286 Nothing<bool>());
14239 } 14287 }
14240 14288
14241 return value; 14289 return Just(true);
14242 } 14290 }
14243 14291
14244 14292
14245 bool JSArray::SetLengthWouldNormalize(uint32_t new_length) { 14293 bool JSArray::SetLengthWouldNormalize(uint32_t new_length) {
14246 if (!HasFastElements()) return false; 14294 if (!HasFastElements()) return false;
14247 uint32_t capacity = static_cast<uint32_t>(elements()->length()); 14295 uint32_t capacity = static_cast<uint32_t>(elements()->length());
14248 uint32_t new_capacity; 14296 uint32_t new_capacity;
14249 return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) && 14297 return JSArray::SetLengthWouldNormalize(GetHeap(), new_length) &&
14250 ShouldConvertToSlowElements(this, capacity, new_length - 1, 14298 ShouldConvertToSlowElements(this, capacity, new_length - 1,
14251 &new_capacity); 14299 &new_capacity);
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
14434 14482
14435 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, 14483 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
14436 uint32_t index) { 14484 uint32_t index) {
14437 uint32_t length = 0; 14485 uint32_t length = 0;
14438 CHECK(array->length()->ToArrayLength(&length)); 14486 CHECK(array->length()->ToArrayLength(&length));
14439 if (length <= index) return HasReadOnlyLength(array); 14487 if (length <= index) return HasReadOnlyLength(array);
14440 return false; 14488 return false;
14441 } 14489 }
14442 14490
14443 14491
14444 MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
14445 Isolate* isolate = array->GetIsolate();
14446 Handle<Name> length = isolate->factory()->length_string();
14447 Handle<String> typeof_string = Object::TypeOf(isolate, array);
14448 THROW_NEW_ERROR(isolate,
14449 NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length,
14450 typeof_string, array),
14451 Object);
14452 }
14453
14454
14455 template <typename BackingStore> 14492 template <typename BackingStore>
14456 static int FastHoleyElementsUsage(JSObject* object, BackingStore* store) { 14493 static int FastHoleyElementsUsage(JSObject* object, BackingStore* store) {
14457 int limit = object->IsJSArray() 14494 int limit = object->IsJSArray()
14458 ? Smi::cast(JSArray::cast(object)->length())->value() 14495 ? Smi::cast(JSArray::cast(object)->length())->value()
14459 : store->length(); 14496 : store->length();
14460 int used = 0; 14497 int used = 0;
14461 for (int i = 0; i < limit; ++i) { 14498 for (int i = 0; i < limit; ++i) {
14462 if (!store->is_the_hole(i)) ++used; 14499 if (!store->is_the_hole(i)) ++used;
14463 } 14500 }
14464 return used; 14501 return used;
(...skipping 3367 matching lines...) Expand 10 before | Expand all | Expand 10 after
17832 if (cell->value() != *new_value) { 17869 if (cell->value() != *new_value) {
17833 cell->set_value(*new_value); 17870 cell->set_value(*new_value);
17834 Isolate* isolate = cell->GetIsolate(); 17871 Isolate* isolate = cell->GetIsolate();
17835 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17872 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17836 isolate, DependentCode::kPropertyCellChangedGroup); 17873 isolate, DependentCode::kPropertyCellChangedGroup);
17837 } 17874 }
17838 } 17875 }
17839 17876
17840 } // namespace internal 17877 } // namespace internal
17841 } // namespace v8 17878 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698