OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 case LookupIterator::ACCESSOR: | 701 case LookupIterator::ACCESSOR: |
702 case LookupIterator::DATA: | 702 case LookupIterator::DATA: |
703 return Just(true); | 703 return Just(true); |
704 } | 704 } |
705 } | 705 } |
706 return Just(false); | 706 return Just(false); |
707 } | 707 } |
708 | 708 |
709 | 709 |
710 // static | 710 // static |
711 MaybeHandle<Object> Object::GetProperty(LookupIterator* it, | 711 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { |
712 LanguageMode language_mode) { | |
713 for (; it->IsFound(); it->Next()) { | 712 for (; it->IsFound(); it->Next()) { |
714 switch (it->state()) { | 713 switch (it->state()) { |
715 case LookupIterator::NOT_FOUND: | 714 case LookupIterator::NOT_FOUND: |
716 case LookupIterator::TRANSITION: | 715 case LookupIterator::TRANSITION: |
717 UNREACHABLE(); | 716 UNREACHABLE(); |
718 case LookupIterator::JSPROXY: | 717 case LookupIterator::JSPROXY: |
719 return JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(), | 718 return JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(), |
720 it->GetName(), it->GetReceiver(), | 719 it->GetName(), it->GetReceiver()); |
721 language_mode); | |
722 case LookupIterator::INTERCEPTOR: { | 720 case LookupIterator::INTERCEPTOR: { |
723 bool done; | 721 bool done; |
724 Handle<Object> result; | 722 Handle<Object> result; |
725 ASSIGN_RETURN_ON_EXCEPTION( | 723 ASSIGN_RETURN_ON_EXCEPTION( |
726 it->isolate(), result, | 724 it->isolate(), result, |
727 JSObject::GetPropertyWithInterceptor(it, &done), Object); | 725 JSObject::GetPropertyWithInterceptor(it, &done), Object); |
728 if (done) return result; | 726 if (done) return result; |
729 break; | 727 break; |
730 } | 728 } |
731 case LookupIterator::ACCESS_CHECK: | 729 case LookupIterator::ACCESS_CHECK: |
732 if (it->HasAccess()) break; | 730 if (it->HasAccess()) break; |
733 return JSObject::GetPropertyWithFailedAccessCheck(it); | 731 return JSObject::GetPropertyWithFailedAccessCheck(it); |
734 case LookupIterator::ACCESSOR: | 732 case LookupIterator::ACCESSOR: |
735 return GetPropertyWithAccessor(it, language_mode); | 733 return GetPropertyWithAccessor(it); |
736 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 734 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
737 return ReadAbsentProperty(it, language_mode); | 735 return ReadAbsentProperty(it); |
738 case LookupIterator::DATA: | 736 case LookupIterator::DATA: |
739 return it->GetDataValue(); | 737 return it->GetDataValue(); |
740 } | 738 } |
741 } | 739 } |
742 return ReadAbsentProperty(it, language_mode); | 740 return ReadAbsentProperty(it); |
743 } | 741 } |
744 | 742 |
745 | 743 |
746 #define STACK_CHECK(result_value) \ | 744 #define STACK_CHECK(result_value) \ |
747 do { \ | 745 do { \ |
748 StackLimitCheck stack_check(isolate); \ | 746 StackLimitCheck stack_check(isolate); \ |
749 if (stack_check.HasOverflowed()) { \ | 747 if (stack_check.HasOverflowed()) { \ |
750 isolate->Throw(*isolate->factory()->NewRangeError( \ | 748 isolate->Throw(*isolate->factory()->NewRangeError( \ |
751 MessageTemplate::kStackOverflow)); \ | 749 MessageTemplate::kStackOverflow)); \ |
752 return result_value; \ | 750 return result_value; \ |
753 } \ | 751 } \ |
754 } while (false) | 752 } while (false) |
755 | 753 |
756 | 754 |
757 // static | 755 // static |
758 MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate, | 756 MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate, |
759 Handle<JSProxy> proxy, | 757 Handle<JSProxy> proxy, |
760 Handle<Name> name, | 758 Handle<Name> name, |
761 Handle<Object> receiver, | 759 Handle<Object> receiver) { |
762 LanguageMode language_mode) { | |
763 if (receiver->IsJSGlobalObject()) { | 760 if (receiver->IsJSGlobalObject()) { |
764 THROW_NEW_ERROR( | 761 THROW_NEW_ERROR( |
765 isolate, | 762 isolate, |
766 NewTypeError(MessageTemplate::kReadGlobalReferenceThroughProxy, name), | 763 NewTypeError(MessageTemplate::kReadGlobalReferenceThroughProxy, name), |
767 Object); | 764 Object); |
768 } | 765 } |
769 | 766 |
770 DCHECK(!name->IsPrivate()); | 767 DCHECK(!name->IsPrivate()); |
771 STACK_CHECK(MaybeHandle<Object>()); | 768 STACK_CHECK(MaybeHandle<Object>()); |
772 Handle<Name> trap_name = isolate->factory()->get_string(); | 769 Handle<Name> trap_name = isolate->factory()->get_string(); |
(...skipping 12 matching lines...) Expand all Loading... |
785 // 6. Let trap be ? GetMethod(handler, "get"). | 782 // 6. Let trap be ? GetMethod(handler, "get"). |
786 Handle<Object> trap; | 783 Handle<Object> trap; |
787 ASSIGN_RETURN_ON_EXCEPTION( | 784 ASSIGN_RETURN_ON_EXCEPTION( |
788 isolate, trap, | 785 isolate, trap, |
789 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object); | 786 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object); |
790 // 7. If trap is undefined, then | 787 // 7. If trap is undefined, then |
791 if (trap->IsUndefined()) { | 788 if (trap->IsUndefined()) { |
792 // 7.a Return target.[[Get]](P, Receiver). | 789 // 7.a Return target.[[Get]](P, Receiver). |
793 LookupIterator it = | 790 LookupIterator it = |
794 LookupIterator::PropertyOrElement(isolate, receiver, name, target); | 791 LookupIterator::PropertyOrElement(isolate, receiver, name, target); |
795 return Object::GetProperty(&it, language_mode); | 792 return Object::GetProperty(&it); |
796 } | 793 } |
797 // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»). | 794 // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»). |
798 Handle<Object> trap_result; | 795 Handle<Object> trap_result; |
799 Handle<Object> args[] = {target, name, receiver}; | 796 Handle<Object> args[] = {target, name, receiver}; |
800 ASSIGN_RETURN_ON_EXCEPTION( | 797 ASSIGN_RETURN_ON_EXCEPTION( |
801 isolate, trap_result, | 798 isolate, trap_result, |
802 Execution::Call(isolate, trap, handler, arraysize(args), args), Object); | 799 Execution::Call(isolate, trap, handler, arraysize(args), args), Object); |
803 // 9. Let targetDesc be ? target.[[GetOwnProperty]](P). | 800 // 9. Let targetDesc be ? target.[[GetOwnProperty]](P). |
804 PropertyDescriptor target_desc; | 801 PropertyDescriptor target_desc; |
805 Maybe<bool> target_found = | 802 Maybe<bool> target_found = |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 if (!handler_proto->SameValue(*target_proto)) { | 1052 if (!handler_proto->SameValue(*target_proto)) { |
1056 THROW_NEW_ERROR( | 1053 THROW_NEW_ERROR( |
1057 isolate, | 1054 isolate, |
1058 NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible), | 1055 NewTypeError(MessageTemplate::kProxyGetPrototypeOfNonExtensible), |
1059 Object); | 1056 Object); |
1060 } | 1057 } |
1061 // 13. Return handlerProto. | 1058 // 13. Return handlerProto. |
1062 return handler_proto; | 1059 return handler_proto; |
1063 } | 1060 } |
1064 | 1061 |
1065 | 1062 MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { |
1066 MaybeHandle<Object> Object::GetPropertyWithAccessor( | |
1067 LookupIterator* it, LanguageMode language_mode) { | |
1068 Isolate* isolate = it->isolate(); | 1063 Isolate* isolate = it->isolate(); |
1069 Handle<Object> structure = it->GetAccessors(); | 1064 Handle<Object> structure = it->GetAccessors(); |
1070 Handle<Object> receiver = it->GetReceiver(); | 1065 Handle<Object> receiver = it->GetReceiver(); |
1071 | 1066 |
1072 // We should never get here to initialize a const with the hole value since a | 1067 // We should never get here to initialize a const with the hole value since a |
1073 // const declaration would conflict with the getter. | 1068 // const declaration would conflict with the getter. |
1074 DCHECK(!structure->IsForeign()); | 1069 DCHECK(!structure->IsForeign()); |
1075 | 1070 |
1076 // API style callbacks. | 1071 // API style callbacks. |
1077 if (structure->IsAccessorInfo()) { | 1072 if (structure->IsAccessorInfo()) { |
(...skipping 10 matching lines...) Expand all Loading... |
1088 v8::AccessorNameGetterCallback call_fun = | 1083 v8::AccessorNameGetterCallback call_fun = |
1089 v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); | 1084 v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); |
1090 if (call_fun == nullptr) return isolate->factory()->undefined_value(); | 1085 if (call_fun == nullptr) return isolate->factory()->undefined_value(); |
1091 | 1086 |
1092 LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name)); | 1087 LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name)); |
1093 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, | 1088 PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, |
1094 Object::DONT_THROW); | 1089 Object::DONT_THROW); |
1095 v8::Local<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(name)); | 1090 v8::Local<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(name)); |
1096 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 1091 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
1097 if (result.IsEmpty()) { | 1092 if (result.IsEmpty()) { |
1098 return ReadAbsentProperty(isolate, receiver, name, language_mode); | 1093 return ReadAbsentProperty(isolate, receiver, name); |
1099 } | 1094 } |
1100 Handle<Object> return_value = v8::Utils::OpenHandle(*result); | 1095 Handle<Object> return_value = v8::Utils::OpenHandle(*result); |
1101 return_value->VerifyApiCallResultType(); | 1096 return_value->VerifyApiCallResultType(); |
1102 // Rebox handle before return. | 1097 // Rebox handle before return. |
1103 return handle(*return_value, isolate); | 1098 return handle(*return_value, isolate); |
1104 } | 1099 } |
1105 | 1100 |
1106 // Regular accessor. | 1101 // Regular accessor. |
1107 Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate); | 1102 Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate); |
1108 if (getter->IsFunctionTemplateInfo()) { | 1103 if (getter->IsFunctionTemplateInfo()) { |
1109 auto result = Builtins::InvokeApiFunction( | 1104 auto result = Builtins::InvokeApiFunction( |
1110 Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, nullptr); | 1105 Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, nullptr); |
1111 if (isolate->has_pending_exception()) { | 1106 if (isolate->has_pending_exception()) { |
1112 return MaybeHandle<Object>(); | 1107 return MaybeHandle<Object>(); |
1113 } | 1108 } |
1114 Handle<Object> return_value; | 1109 Handle<Object> return_value; |
1115 if (result.ToHandle(&return_value)) { | 1110 if (result.ToHandle(&return_value)) { |
1116 return_value->VerifyApiCallResultType(); | 1111 return_value->VerifyApiCallResultType(); |
1117 return handle(*return_value, isolate); | 1112 return handle(*return_value, isolate); |
1118 } | 1113 } |
1119 } else if (getter->IsCallable()) { | 1114 } else if (getter->IsCallable()) { |
1120 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 1115 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
1121 return Object::GetPropertyWithDefinedGetter( | 1116 return Object::GetPropertyWithDefinedGetter( |
1122 receiver, Handle<JSReceiver>::cast(getter)); | 1117 receiver, Handle<JSReceiver>::cast(getter)); |
1123 } | 1118 } |
1124 // Getter is not a function. | 1119 // Getter is not a function. |
1125 return ReadAbsentProperty(isolate, receiver, it->GetName(), language_mode); | 1120 return ReadAbsentProperty(isolate, receiver, it->GetName()); |
1126 } | 1121 } |
1127 | 1122 |
1128 | 1123 |
1129 bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate, | 1124 bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate, |
1130 Handle<AccessorInfo> info, | 1125 Handle<AccessorInfo> info, |
1131 Handle<Map> map) { | 1126 Handle<Map> map) { |
1132 if (!info->HasExpectedReceiverType()) return true; | 1127 if (!info->HasExpectedReceiverType()) return true; |
1133 if (!map->IsJSObjectMap()) return false; | 1128 if (!map->IsJSObjectMap()) return false; |
1134 return FunctionTemplateInfo::cast(info->expected_receiver_type()) | 1129 return FunctionTemplateInfo::cast(info->expected_receiver_type()) |
1135 ->IsTemplateFor(*map); | 1130 ->IsTemplateFor(*map); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 } | 1260 } |
1266 return false; | 1261 return false; |
1267 } | 1262 } |
1268 | 1263 |
1269 | 1264 |
1270 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( | 1265 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
1271 LookupIterator* it) { | 1266 LookupIterator* it) { |
1272 Handle<JSObject> checked = it->GetHolder<JSObject>(); | 1267 Handle<JSObject> checked = it->GetHolder<JSObject>(); |
1273 while (AllCanRead(it)) { | 1268 while (AllCanRead(it)) { |
1274 if (it->state() == LookupIterator::ACCESSOR) { | 1269 if (it->state() == LookupIterator::ACCESSOR) { |
1275 return GetPropertyWithAccessor(it, SLOPPY); | 1270 return GetPropertyWithAccessor(it); |
1276 } | 1271 } |
1277 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); | 1272 DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state()); |
1278 bool done; | 1273 bool done; |
1279 Handle<Object> result; | 1274 Handle<Object> result; |
1280 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), result, | 1275 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), result, |
1281 GetPropertyWithInterceptor(it, &done), Object); | 1276 GetPropertyWithInterceptor(it, &done), Object); |
1282 if (done) return result; | 1277 if (done) return result; |
1283 } | 1278 } |
1284 | 1279 |
1285 // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns | 1280 // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns |
(...skipping 3050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4336 case LookupIterator::NOT_FOUND: | 4331 case LookupIterator::NOT_FOUND: |
4337 case LookupIterator::TRANSITION: | 4332 case LookupIterator::TRANSITION: |
4338 UNREACHABLE(); | 4333 UNREACHABLE(); |
4339 } | 4334 } |
4340 } | 4335 } |
4341 | 4336 |
4342 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw, | 4337 return JSObject::AddDataProperty(&own_lookup, value, NONE, should_throw, |
4343 store_mode); | 4338 store_mode); |
4344 } | 4339 } |
4345 | 4340 |
4346 | 4341 MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it) { |
4347 MaybeHandle<Object> Object::ReadAbsentProperty(LookupIterator* it, | |
4348 LanguageMode language_mode) { | |
4349 if (is_strong(language_mode)) { | |
4350 THROW_NEW_ERROR(it->isolate(), | |
4351 NewTypeError(MessageTemplate::kStrongPropertyAccess, | |
4352 it->GetName(), it->GetReceiver()), | |
4353 Object); | |
4354 } | |
4355 return it->isolate()->factory()->undefined_value(); | 4342 return it->isolate()->factory()->undefined_value(); |
4356 } | 4343 } |
4357 | 4344 |
4358 MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate, | 4345 MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate, |
4359 Handle<Object> receiver, | 4346 Handle<Object> receiver, |
4360 Handle<Object> name, | 4347 Handle<Object> name) { |
4361 LanguageMode language_mode) { | |
4362 if (is_strong(language_mode)) { | |
4363 THROW_NEW_ERROR( | |
4364 isolate, | |
4365 NewTypeError(MessageTemplate::kStrongPropertyAccess, name, receiver), | |
4366 Object); | |
4367 } | |
4368 return isolate->factory()->undefined_value(); | 4348 return isolate->factory()->undefined_value(); |
4369 } | 4349 } |
4370 | 4350 |
4371 | 4351 |
4372 Maybe<bool> Object::CannotCreateProperty(Isolate* isolate, | 4352 Maybe<bool> Object::CannotCreateProperty(Isolate* isolate, |
4373 Handle<Object> receiver, | 4353 Handle<Object> receiver, |
4374 Handle<Object> name, | 4354 Handle<Object> name, |
4375 Handle<Object> value, | 4355 Handle<Object> value, |
4376 ShouldThrow should_throw) { | 4356 ShouldThrow should_throw) { |
4377 RETURN_FAILURE( | 4357 RETURN_FAILURE( |
(...skipping 4586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8964 if (filter & ONLY_ENUMERABLE) { | 8944 if (filter & ONLY_ENUMERABLE) { |
8965 PropertyDescriptor descriptor; | 8945 PropertyDescriptor descriptor; |
8966 Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor( | 8946 Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor( |
8967 isolate, object, key, &descriptor); | 8947 isolate, object, key, &descriptor); |
8968 MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>()); | 8948 MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>()); |
8969 if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue; | 8949 if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue; |
8970 } | 8950 } |
8971 | 8951 |
8972 Handle<Object> value; | 8952 Handle<Object> value; |
8973 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 8953 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
8974 isolate, value, JSReceiver::GetPropertyOrElement(object, key, STRICT), | 8954 isolate, value, JSReceiver::GetPropertyOrElement(object, key), |
8975 MaybeHandle<FixedArray>()); | 8955 MaybeHandle<FixedArray>()); |
8976 | 8956 |
8977 if (get_entries) { | 8957 if (get_entries) { |
8978 Handle<FixedArray> entry_storage = | 8958 Handle<FixedArray> entry_storage = |
8979 isolate->factory()->NewUninitializedFixedArray(2); | 8959 isolate->factory()->NewUninitializedFixedArray(2); |
8980 entry_storage->set(0, *key); | 8960 entry_storage->set(0, *key); |
8981 entry_storage->set(1, *value); | 8961 entry_storage->set(1, *value); |
8982 value = isolate->factory()->NewJSArrayWithElements(entry_storage, | 8962 value = isolate->factory()->NewJSArrayWithElements(entry_storage, |
8983 FAST_ELEMENTS, 2); | 8963 FAST_ELEMENTS, 2); |
8984 } | 8964 } |
(...skipping 10937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19922 if (cell->value() != *new_value) { | 19902 if (cell->value() != *new_value) { |
19923 cell->set_value(*new_value); | 19903 cell->set_value(*new_value); |
19924 Isolate* isolate = cell->GetIsolate(); | 19904 Isolate* isolate = cell->GetIsolate(); |
19925 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19905 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19926 isolate, DependentCode::kPropertyCellChangedGroup); | 19906 isolate, DependentCode::kPropertyCellChangedGroup); |
19927 } | 19907 } |
19928 } | 19908 } |
19929 | 19909 |
19930 } // namespace internal | 19910 } // namespace internal |
19931 } // namespace v8 | 19911 } // namespace v8 |
OLD | NEW |