OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 accumulator->Add("=====================\n\n"); | 686 accumulator->Add("=====================\n\n"); |
687 } | 687 } |
688 | 688 |
689 | 689 |
690 void Isolate::SetFailedAccessCheckCallback( | 690 void Isolate::SetFailedAccessCheckCallback( |
691 v8::FailedAccessCheckCallback callback) { | 691 v8::FailedAccessCheckCallback callback) { |
692 thread_local_top()->failed_access_check_callback_ = callback; | 692 thread_local_top()->failed_access_check_callback_ = callback; |
693 } | 693 } |
694 | 694 |
695 | 695 |
696 void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) { | 696 AccessCheckInfo* GetAccessCheckInfo(Isolate* isolate, |
Igor Sheludko
2014/04/11 17:10:55
static inline?
Yang
2014/04/14 06:22:51
Done.
| |
697 Handle<JSObject> receiver) { | |
698 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); | |
699 if (!constructor->shared()->IsApiFunction()) return NULL; | |
700 | |
701 Object* data_obj = | |
702 constructor->shared()->get_api_func_data()->access_check_info(); | |
703 if (data_obj == isolate->heap()->undefined_value()) return NULL; | |
704 | |
705 return AccessCheckInfo::cast(data_obj); | |
706 } | |
707 | |
708 | |
709 void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver, | |
710 v8::AccessType type) { | |
697 if (!thread_local_top()->failed_access_check_callback_) return; | 711 if (!thread_local_top()->failed_access_check_callback_) return; |
698 | 712 |
699 ASSERT(receiver->IsAccessCheckNeeded()); | 713 ASSERT(receiver->IsAccessCheckNeeded()); |
700 ASSERT(context()); | 714 ASSERT(context()); |
701 | 715 |
702 // Get the data object from access check info. | 716 // Get the data object from access check info. |
703 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); | 717 HandleScope scope(this); |
704 if (!constructor->shared()->IsApiFunction()) return; | 718 Handle<Object> data; |
705 Object* data_obj = | 719 { DisallowHeapAllocation no_gc; |
706 constructor->shared()->get_api_func_data()->access_check_info(); | 720 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); |
707 if (data_obj == heap_.undefined_value()) return; | 721 if (!access_check_info) return; |
722 data = handle(GetAccessCheckInfo(this, receiver)->data(), this); | |
Igor Sheludko
2014/04/11 17:10:55
I think you intended to use |access_check_info| he
Yang
2014/04/14 06:22:51
Done. Thanks for catching this.
| |
723 } | |
708 | 724 |
709 HandleScope scope(this); | 725 // Leaving JavaScript. |
710 Handle<JSObject> receiver_handle(receiver); | 726 VMState<EXTERNAL> state(this); |
711 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this); | 727 thread_local_top()->failed_access_check_callback_( |
712 { VMState<EXTERNAL> state(this); | 728 v8::Utils::ToLocal(receiver), |
713 thread_local_top()->failed_access_check_callback_( | |
714 v8::Utils::ToLocal(receiver_handle), | |
715 type, | 729 type, |
716 v8::Utils::ToLocal(data)); | 730 v8::Utils::ToLocal(data)); |
717 } | |
718 } | 731 } |
719 | 732 |
720 | 733 |
721 enum MayAccessDecision { | 734 enum MayAccessDecision { |
722 YES, NO, UNKNOWN | 735 YES, NO, UNKNOWN |
723 }; | 736 }; |
724 | 737 |
725 | 738 |
726 static MayAccessDecision MayAccessPreCheck(Isolate* isolate, | 739 static MayAccessDecision MayAccessPreCheck(Isolate* isolate, |
727 JSObject* receiver, | 740 Handle<JSObject> receiver, |
728 v8::AccessType type) { | 741 v8::AccessType type) { |
742 DisallowHeapAllocation no_gc; | |
729 // During bootstrapping, callback functions are not enabled yet. | 743 // During bootstrapping, callback functions are not enabled yet. |
730 if (isolate->bootstrapper()->IsActive()) return YES; | 744 if (isolate->bootstrapper()->IsActive()) return YES; |
731 | 745 |
732 if (receiver->IsJSGlobalProxy()) { | 746 if (receiver->IsJSGlobalProxy()) { |
733 Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context(); | 747 Object* receiver_context = JSGlobalProxy::cast(*receiver)->native_context(); |
734 if (!receiver_context->IsContext()) return NO; | 748 if (!receiver_context->IsContext()) return NO; |
735 | 749 |
736 // Get the native context of current top context. | 750 // Get the native context of current top context. |
737 // avoid using Isolate::native_context() because it uses Handle. | 751 // avoid using Isolate::native_context() because it uses Handle. |
738 Context* native_context = | 752 Context* native_context = |
739 isolate->context()->global_object()->native_context(); | 753 isolate->context()->global_object()->native_context(); |
740 if (receiver_context == native_context) return YES; | 754 if (receiver_context == native_context) return YES; |
741 | 755 |
742 if (Context::cast(receiver_context)->security_token() == | 756 if (Context::cast(receiver_context)->security_token() == |
743 native_context->security_token()) | 757 native_context->security_token()) |
744 return YES; | 758 return YES; |
745 } | 759 } |
746 | 760 |
747 return UNKNOWN; | 761 return UNKNOWN; |
748 } | 762 } |
749 | 763 |
750 | 764 |
751 bool Isolate::MayNamedAccess(JSObject* receiver, Object* key, | 765 bool Isolate::MayNamedAccess(Handle<JSObject> receiver, |
766 Handle<Object> key, | |
752 v8::AccessType type) { | 767 v8::AccessType type) { |
753 ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); | 768 ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); |
754 | 769 |
755 // The callers of this method are not expecting a GC. | |
756 DisallowHeapAllocation no_gc; | |
757 | |
758 // Skip checks for hidden properties access. Note, we do not | 770 // Skip checks for hidden properties access. Note, we do not |
759 // require existence of a context in this case. | 771 // require existence of a context in this case. |
760 if (key == heap_.hidden_string()) return true; | 772 if (key.is_identical_to(factory()->hidden_string())) return true; |
761 | 773 |
762 // Check for compatibility between the security tokens in the | 774 // Check for compatibility between the security tokens in the |
763 // current lexical context and the accessed object. | 775 // current lexical context and the accessed object. |
764 ASSERT(context()); | 776 ASSERT(context()); |
765 | 777 |
766 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); | 778 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); |
767 if (decision != UNKNOWN) return decision == YES; | 779 if (decision != UNKNOWN) return decision == YES; |
768 | 780 |
769 // Get named access check callback | 781 HandleScope scope(this); |
770 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); | 782 Handle<Object> data; |
771 if (!constructor->shared()->IsApiFunction()) return false; | 783 v8::NamedSecurityCallback callback; |
784 { DisallowHeapAllocation no_gc; | |
785 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); | |
786 if (!access_check_info) return false; | |
787 Object* fun_obj = access_check_info->named_callback(); | |
788 callback = v8::ToCData<v8::NamedSecurityCallback>(fun_obj); | |
789 if (!callback) return false; | |
790 data = handle(access_check_info->data(), this); | |
791 } | |
772 | 792 |
773 Object* data_obj = | 793 LOG(this, ApiNamedSecurityCheck(*key)); |
774 constructor->shared()->get_api_func_data()->access_check_info(); | |
775 if (data_obj == heap_.undefined_value()) return false; | |
776 | 794 |
777 Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback(); | 795 // Leaving JavaScript. |
778 v8::NamedSecurityCallback callback = | 796 VMState<EXTERNAL> state(this); |
779 v8::ToCData<v8::NamedSecurityCallback>(fun_obj); | 797 return callback(v8::Utils::ToLocal(receiver), |
780 | 798 v8::Utils::ToLocal(key), |
781 if (!callback) return false; | 799 type, |
782 | 800 v8::Utils::ToLocal(data)); |
783 HandleScope scope(this); | |
784 Handle<JSObject> receiver_handle(receiver, this); | |
785 Handle<Object> key_handle(key, this); | |
786 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this); | |
787 LOG(this, ApiNamedSecurityCheck(key)); | |
788 bool result = false; | |
789 { | |
790 // Leaving JavaScript. | |
791 VMState<EXTERNAL> state(this); | |
792 result = callback(v8::Utils::ToLocal(receiver_handle), | |
793 v8::Utils::ToLocal(key_handle), | |
794 type, | |
795 v8::Utils::ToLocal(data)); | |
796 } | |
797 return result; | |
798 } | 801 } |
799 | 802 |
800 | 803 |
801 bool Isolate::MayIndexedAccess(JSObject* receiver, | 804 bool Isolate::MayIndexedAccess(Handle<JSObject> receiver, |
802 uint32_t index, | 805 uint32_t index, |
803 v8::AccessType type) { | 806 v8::AccessType type) { |
804 ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); | 807 ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); |
805 // Check for compatibility between the security tokens in the | 808 // Check for compatibility between the security tokens in the |
806 // current lexical context and the accessed object. | 809 // current lexical context and the accessed object. |
807 ASSERT(context()); | 810 ASSERT(context()); |
808 | 811 |
809 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); | 812 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); |
810 if (decision != UNKNOWN) return decision == YES; | 813 if (decision != UNKNOWN) return decision == YES; |
811 | 814 |
812 // Get indexed access check callback | 815 HandleScope scope(this); |
813 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); | 816 Handle<Object> data; |
814 if (!constructor->shared()->IsApiFunction()) return false; | 817 v8::IndexedSecurityCallback callback; |
818 { DisallowHeapAllocation no_gc; | |
819 // Get named access check callback | |
820 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); | |
821 if (!access_check_info) return false; | |
822 Object* fun_obj = access_check_info->indexed_callback(); | |
823 callback = v8::ToCData<v8::IndexedSecurityCallback>(fun_obj); | |
824 if (!callback) return false; | |
825 data = handle(access_check_info->data(), this); | |
826 } | |
815 | 827 |
816 Object* data_obj = | 828 LOG(this, ApiIndexedSecurityCheck(index)); |
817 constructor->shared()->get_api_func_data()->access_check_info(); | |
818 if (data_obj == heap_.undefined_value()) return false; | |
819 | 829 |
820 Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback(); | 830 // Leaving JavaScript. |
821 v8::IndexedSecurityCallback callback = | 831 VMState<EXTERNAL> state(this); |
822 v8::ToCData<v8::IndexedSecurityCallback>(fun_obj); | 832 return callback( |
823 | 833 v8::Utils::ToLocal(receiver), index, type, v8::Utils::ToLocal(data)); |
824 if (!callback) return false; | |
825 | |
826 HandleScope scope(this); | |
827 Handle<JSObject> receiver_handle(receiver, this); | |
828 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this); | |
829 LOG(this, ApiIndexedSecurityCheck(index)); | |
830 bool result = false; | |
831 { | |
832 // Leaving JavaScript. | |
833 VMState<EXTERNAL> state(this); | |
834 result = callback(v8::Utils::ToLocal(receiver_handle), | |
835 index, | |
836 type, | |
837 v8::Utils::ToLocal(data)); | |
838 } | |
839 return result; | |
840 } | 834 } |
841 | 835 |
842 | 836 |
843 const char* const Isolate::kStackOverflowMessage = | 837 const char* const Isolate::kStackOverflowMessage = |
844 "Uncaught RangeError: Maximum call stack size exceeded"; | 838 "Uncaught RangeError: Maximum call stack size exceeded"; |
845 | 839 |
846 | 840 |
847 Failure* Isolate::StackOverflow() { | 841 Failure* Isolate::StackOverflow() { |
848 HandleScope scope(this); | 842 HandleScope scope(this); |
849 // At this point we cannot create an Error object using its javascript | 843 // At this point we cannot create an Error object using its javascript |
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2287 Handle<JSObject> obj = factory()->NewJSObjectFromMap(map); | 2281 Handle<JSObject> obj = factory()->NewJSObjectFromMap(map); |
2288 JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 8); | 2282 JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 8); |
2289 JSObject::SetProperty(registry, name, obj, NONE, STRICT).Assert(); | 2283 JSObject::SetProperty(registry, name, obj, NONE, STRICT).Assert(); |
2290 } | 2284 } |
2291 } | 2285 } |
2292 return Handle<JSObject>::cast(factory()->symbol_registry()); | 2286 return Handle<JSObject>::cast(factory()->symbol_registry()); |
2293 } | 2287 } |
2294 | 2288 |
2295 | 2289 |
2296 } } // namespace v8::internal | 2290 } } // namespace v8::internal |
OLD | NEW |