OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "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 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 | 684 |
685 // static | 685 // static |
686 MaybeHandle<Object> Object::GetProperty(LookupIterator* it, | 686 MaybeHandle<Object> Object::GetProperty(LookupIterator* it, |
687 LanguageMode language_mode) { | 687 LanguageMode language_mode) { |
688 for (; it->IsFound(); it->Next()) { | 688 for (; it->IsFound(); it->Next()) { |
689 switch (it->state()) { | 689 switch (it->state()) { |
690 case LookupIterator::NOT_FOUND: | 690 case LookupIterator::NOT_FOUND: |
691 case LookupIterator::TRANSITION: | 691 case LookupIterator::TRANSITION: |
692 UNREACHABLE(); | 692 UNREACHABLE(); |
693 case LookupIterator::JSPROXY: | 693 case LookupIterator::JSPROXY: |
694 return JSProxy::GetPropertyWithHandler( | 694 return JSProxy::GetProperty(it->isolate(), it->GetHolder<JSProxy>(), |
695 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName()); | 695 it->GetName(), it->GetReceiver(), |
| 696 language_mode); |
696 case LookupIterator::INTERCEPTOR: { | 697 case LookupIterator::INTERCEPTOR: { |
697 bool done; | 698 bool done; |
698 Handle<Object> result; | 699 Handle<Object> result; |
699 ASSIGN_RETURN_ON_EXCEPTION( | 700 ASSIGN_RETURN_ON_EXCEPTION( |
700 it->isolate(), result, | 701 it->isolate(), result, |
701 JSObject::GetPropertyWithInterceptor(it, &done), Object); | 702 JSObject::GetPropertyWithInterceptor(it, &done), Object); |
702 if (done) return result; | 703 if (done) return result; |
703 break; | 704 break; |
704 } | 705 } |
705 case LookupIterator::ACCESS_CHECK: | 706 case LookupIterator::ACCESS_CHECK: |
706 if (it->HasAccess()) break; | 707 if (it->HasAccess()) break; |
707 return JSObject::GetPropertyWithFailedAccessCheck(it); | 708 return JSObject::GetPropertyWithFailedAccessCheck(it); |
708 case LookupIterator::ACCESSOR: | 709 case LookupIterator::ACCESSOR: |
709 return GetPropertyWithAccessor(it, language_mode); | 710 return GetPropertyWithAccessor(it, language_mode); |
710 case LookupIterator::INTEGER_INDEXED_EXOTIC: | 711 case LookupIterator::INTEGER_INDEXED_EXOTIC: |
711 return ReadAbsentProperty(it, language_mode); | 712 return ReadAbsentProperty(it, language_mode); |
712 case LookupIterator::DATA: | 713 case LookupIterator::DATA: |
713 return it->GetDataValue(); | 714 return it->GetDataValue(); |
714 } | 715 } |
715 } | 716 } |
716 return ReadAbsentProperty(it, language_mode); | 717 return ReadAbsentProperty(it, language_mode); |
717 } | 718 } |
718 | 719 |
719 | 720 |
| 721 // static |
| 722 MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate, |
| 723 Handle<JSProxy> proxy, |
| 724 Handle<Name> name, |
| 725 Handle<Object> receiver, |
| 726 LanguageMode language_mode) { |
| 727 Handle<Name> trap_name = isolate->factory()->get_string(); |
| 728 // 1. Assert: IsPropertyKey(P) is true. |
| 729 // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| 730 Handle<Object> handler(proxy->handler(), isolate); |
| 731 // 3. If handler is null, throw a TypeError exception. |
| 732 if (proxy->IsRevoked()) { |
| 733 THROW_NEW_ERROR(isolate, |
| 734 NewTypeError(MessageTemplate::kProxyRevoked, trap_name), |
| 735 Object); |
| 736 } |
| 737 // 4. Assert: Type(handler) is Object. |
| 738 DCHECK(handler->IsJSReceiver()); |
| 739 DCHECK(proxy->target()->IsJSReceiver()); |
| 740 // 5. Let target be the value of the [[ProxyTarget]] internal slot of O. |
| 741 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 742 // 6. Let trap be ? GetMethod(handler, "get"). |
| 743 Handle<Object> trap; |
| 744 ASSIGN_RETURN_ON_EXCEPTION( |
| 745 isolate, trap, |
| 746 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name), Object); |
| 747 // 7. If trap is undefined, then |
| 748 if (trap->IsUndefined()) { |
| 749 // 7.a Return target.[[Get]](P, Receiver). |
| 750 LookupIterator it = |
| 751 LookupIterator::PropertyOrElement(isolate, receiver, name, target); |
| 752 return Object::GetProperty(&it, language_mode); |
| 753 } |
| 754 // 8. Let trapResult be ? Call(trap, handler, «target, P, Receiver»). |
| 755 Handle<Object> trap_result; |
| 756 Handle<Object> args[] = {target, name, receiver}; |
| 757 ASSIGN_RETURN_ON_EXCEPTION( |
| 758 isolate, trap_result, |
| 759 Execution::Call(isolate, trap, handler, arraysize(args), args), Object); |
| 760 // 9. Let targetDesc be ? target.[[GetOwnProperty]](P). |
| 761 PropertyDescriptor target_desc; |
| 762 bool target_found = |
| 763 JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc); |
| 764 if (isolate->has_pending_exception()) return MaybeHandle<Object>(); |
| 765 // 10. If targetDesc is not undefined, then |
| 766 if (target_found) { |
| 767 // 10.a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is |
| 768 // false and targetDesc.[[Writable]] is false, then |
| 769 // 10.a.i. If SameValue(trapResult, targetDesc.[[Value]]) is false, |
| 770 // throw a TypeError exception. |
| 771 bool inconsistent = PropertyDescriptor::IsDataDescriptor(&target_desc) && |
| 772 !target_desc.configurable() && |
| 773 !target_desc.writable() && |
| 774 !trap_result->SameValue(*target_desc.value()); |
| 775 // 10.b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]] |
| 776 // is false and targetDesc.[[Get]] is undefined, then |
| 777 // 10.b.i. If trapResult is not undefined, throw a TypeError exception. |
| 778 inconsistent = |
| 779 inconsistent || |
| 780 (PropertyDescriptor::IsAccessorDescriptor(&target_desc) && |
| 781 !target_desc.configurable() && target_desc.get()->IsUndefined()); |
| 782 if (inconsistent) { |
| 783 THROW_NEW_ERROR( |
| 784 isolate, |
| 785 NewTypeError(MessageTemplate::kProxyTrapViolatesInvariant, trap_name), |
| 786 Object); |
| 787 } |
| 788 } |
| 789 // 11. Return trap_result |
| 790 return trap_result; |
| 791 } |
| 792 |
| 793 |
720 Handle<Object> JSReceiver::GetDataProperty(Handle<JSReceiver> object, | 794 Handle<Object> JSReceiver::GetDataProperty(Handle<JSReceiver> object, |
721 Handle<Name> name) { | 795 Handle<Name> name) { |
722 LookupIterator it(object, name, | 796 LookupIterator it(object, name, |
723 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); | 797 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); |
724 return GetDataProperty(&it); | 798 return GetDataProperty(&it); |
725 } | 799 } |
726 | 800 |
727 | 801 |
728 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { | 802 Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) { |
729 for (; it->IsFound(); it->Next()) { | 803 for (; it->IsFound(); it->Next()) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 | 986 |
913 bool JSProxy::IsRevoked() { | 987 bool JSProxy::IsRevoked() { |
914 // TODO(neis): Decide on how to represent revocation. For now, revocation is | 988 // TODO(neis): Decide on how to represent revocation. For now, revocation is |
915 // unsupported. | 989 // unsupported. |
916 DCHECK(target()->IsJSReceiver()); | 990 DCHECK(target()->IsJSReceiver()); |
917 DCHECK(handler()->IsJSReceiver()); | 991 DCHECK(handler()->IsJSReceiver()); |
918 return false; | 992 return false; |
919 } | 993 } |
920 | 994 |
921 | 995 |
922 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, | |
923 Handle<Object> receiver, | |
924 Handle<Name> name) { | |
925 Isolate* isolate = proxy->GetIsolate(); | |
926 | |
927 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | |
928 if (name->IsSymbol()) return isolate->factory()->undefined_value(); | |
929 | |
930 Handle<Object> args[] = { receiver, name }; | |
931 return CallTrap( | |
932 proxy, "get", isolate->derived_get_trap(), arraysize(args), args); | |
933 } | |
934 | |
935 | |
936 MaybeHandle<Object> Object::GetPropertyWithAccessor( | 996 MaybeHandle<Object> Object::GetPropertyWithAccessor( |
937 LookupIterator* it, LanguageMode language_mode) { | 997 LookupIterator* it, LanguageMode language_mode) { |
938 Isolate* isolate = it->isolate(); | 998 Isolate* isolate = it->isolate(); |
939 Handle<Object> structure = it->GetAccessors(); | 999 Handle<Object> structure = it->GetAccessors(); |
940 Handle<Object> receiver = it->GetReceiver(); | 1000 Handle<Object> receiver = it->GetReceiver(); |
941 | 1001 |
942 // We should never get here to initialize a const with the hole value since a | 1002 // We should never get here to initialize a const with the hole value since a |
943 // const declaration would conflict with the getter. | 1003 // const declaration would conflict with the getter. |
944 DCHECK(!structure->IsForeign()); | 1004 DCHECK(!structure->IsForeign()); |
945 | 1005 |
(...skipping 18003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18949 if (cell->value() != *new_value) { | 19009 if (cell->value() != *new_value) { |
18950 cell->set_value(*new_value); | 19010 cell->set_value(*new_value); |
18951 Isolate* isolate = cell->GetIsolate(); | 19011 Isolate* isolate = cell->GetIsolate(); |
18952 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19012 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18953 isolate, DependentCode::kPropertyCellChangedGroup); | 19013 isolate, DependentCode::kPropertyCellChangedGroup); |
18954 } | 19014 } |
18955 } | 19015 } |
18956 | 19016 |
18957 } // namespace internal | 19017 } // namespace internal |
18958 } // namespace v8 | 19018 } // namespace v8 |
OLD | NEW |