OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/ic/ic.h" | 5 #include "src/ic/ic.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/api-arguments.h" | 9 #include "src/api-arguments.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 2789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2800 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, | 2800 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, |
2801 *holder, Object::DONT_THROW); | 2801 *holder, Object::DONT_THROW); |
2802 | 2802 |
2803 v8::GenericNamedPropertyGetterCallback getter = | 2803 v8::GenericNamedPropertyGetterCallback getter = |
2804 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | 2804 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( |
2805 interceptor->getter()); | 2805 interceptor->getter()); |
2806 Handle<Object> result = arguments.Call(getter, name); | 2806 Handle<Object> result = arguments.Call(getter, name); |
2807 | 2807 |
2808 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 2808 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
2809 | 2809 |
2810 Handle<Object> result_internal; | 2810 if (!result.is_null()) return *result; |
2811 if (result.is_null()) { | 2811 return isolate->heap()->no_interceptor_result_sentinel(); |
2812 return isolate->heap()->no_interceptor_result_sentinel(); | |
2813 } | |
2814 return *result; | |
2815 } | 2812 } |
2816 | 2813 |
2817 | 2814 |
2818 /** | 2815 /** |
2819 * Loads a property with an interceptor performing post interceptor | 2816 * Loads a property with an interceptor performing post interceptor |
2820 * lookup if interceptor failed. | 2817 * lookup if interceptor failed. |
2821 */ | 2818 */ |
2822 RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) { | 2819 RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) { |
2823 HandleScope scope(isolate); | 2820 HandleScope scope(isolate); |
2824 DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength); | 2821 DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength); |
2825 Handle<Name> name = | 2822 Handle<Name> name = |
2826 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex); | 2823 args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex); |
2827 Handle<JSObject> receiver = | 2824 Handle<JSObject> receiver = |
2828 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex); | 2825 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex); |
2829 Handle<JSObject> holder = | 2826 Handle<JSObject> holder = |
2830 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); | 2827 args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); |
2831 | 2828 |
2832 Handle<Object> result; | 2829 InterceptorInfo* interceptor = holder->GetNamedInterceptor(); |
2830 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, | |
2831 *holder, Object::DONT_THROW); | |
2832 | |
2833 v8::GenericNamedPropertyGetterCallback getter = | |
2834 v8::ToCData<v8::GenericNamedPropertyGetterCallback>( | |
2835 interceptor->getter()); | |
2836 Handle<Object> result = arguments.Call(getter, name); | |
2837 | |
2838 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | |
2839 | |
2840 if (!result.is_null()) return *result; | |
2841 | |
2833 LookupIterator it(receiver, name, holder); | 2842 LookupIterator it(receiver, name, holder); |
2834 // TODO(conradw): Investigate strong mode semantics for this. | 2843 // Skip past any access check on the holder. |
2844 if (it.state() == LookupIterator::ACCESS_CHECK) { | |
2845 DCHECK(it.HasAccess()); | |
2846 it.Next(); | |
2847 } | |
2848 // Skip past the interceptor. | |
2849 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | |
2850 it.Next(); | |
2835 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it)); | 2851 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it)); |
2836 | 2852 |
2837 if (it.IsFound()) return *result; | 2853 if (it.IsFound()) return *result; |
2838 | 2854 |
2839 // Return the undefined result if the reference error should not be thrown. | 2855 // Return the undefined result if no reference error was thrown. |
Jakob Kummerow
2016/03/18 13:19:03
nit: I preferred s/was/should be/, cf. condition c
| |
2840 // Note that both keyed and non-keyed loads may end up here. | 2856 // Note that both keyed and non-keyed loads may end up here. |
2841 LoadICNexus nexus(isolate); | 2857 LoadICNexus nexus(isolate); |
2842 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2858 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2843 if (!ic.ShouldThrowReferenceError(it.GetReceiver())) { | 2859 if (!ic.ShouldThrowReferenceError(it.GetReceiver())) { |
2844 return isolate->heap()->undefined_value(); | 2860 return isolate->heap()->undefined_value(); |
2845 } | 2861 } |
2846 | 2862 |
2847 // Throw a reference error. | 2863 // Throw a reference error. |
2848 THROW_NEW_ERROR_RETURN_FAILURE( | 2864 THROW_NEW_ERROR_RETURN_FAILURE( |
2849 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); | 2865 isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name())); |
2850 } | 2866 } |
2851 | 2867 |
2852 | 2868 |
2853 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { | 2869 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { |
2854 HandleScope scope(isolate); | 2870 HandleScope scope(isolate); |
2855 DCHECK(args.length() == 3); | 2871 DCHECK(args.length() == 3); |
2856 StoreICNexus nexus(isolate); | 2872 StoreICNexus nexus(isolate); |
2857 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2873 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2858 Handle<JSObject> receiver = args.at<JSObject>(0); | 2874 Handle<JSObject> receiver = args.at<JSObject>(0); |
2859 Handle<Name> name = args.at<Name>(1); | 2875 Handle<Name> name = args.at<Name>(1); |
2860 Handle<Object> value = args.at<Object>(2); | 2876 Handle<Object> value = args.at<Object>(2); |
2861 #ifdef DEBUG | |
2862 PrototypeIterator iter(isolate, receiver, | 2877 PrototypeIterator iter(isolate, receiver, |
2863 PrototypeIterator::START_AT_RECEIVER, | 2878 PrototypeIterator::START_AT_RECEIVER, |
2864 PrototypeIterator::END_AT_NON_HIDDEN); | 2879 PrototypeIterator::END_AT_NON_HIDDEN); |
2865 bool found = false; | |
2866 for (; !iter.IsAtEnd(); iter.Advance()) { | 2880 for (; !iter.IsAtEnd(); iter.Advance()) { |
2867 Handle<Object> current = PrototypeIterator::GetCurrent(iter); | 2881 Handle<Object> current = PrototypeIterator::GetCurrent(iter); |
2868 if (current->IsJSObject() && | 2882 if (current->IsJSObject() && |
2869 Handle<JSObject>::cast(current)->HasNamedInterceptor()) { | 2883 Handle<JSObject>::cast(current)->HasNamedInterceptor()) { |
2870 found = true; | |
2871 break; | 2884 break; |
2872 } | 2885 } |
2873 } | 2886 } |
2874 DCHECK(found); | 2887 |
2875 #endif | 2888 DCHECK(!iter.IsAtEnd()); |
2876 Handle<Object> result; | 2889 Handle<JSObject> holder = |
2877 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2890 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
2878 isolate, result, | 2891 |
2879 JSObject::SetProperty(receiver, name, value, ic.language_mode())); | 2892 InterceptorInfo* interceptor = holder->GetNamedInterceptor(); |
2880 return *result; | 2893 PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver, |
2894 *holder, Object::DONT_THROW); | |
2895 | |
2896 v8::GenericNamedPropertySetterCallback setter = | |
2897 v8::ToCData<v8::GenericNamedPropertySetterCallback>( | |
2898 interceptor->setter()); | |
2899 Handle<Object> result = arguments.Call(setter, name, value); | |
2900 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | |
2901 if (!result.is_null()) return *value; | |
2902 | |
2903 LookupIterator it(receiver, name, holder); | |
2904 // Skip past any access check on the holder. | |
2905 if (it.state() == LookupIterator::ACCESS_CHECK) { | |
2906 DCHECK(it.HasAccess()); | |
2907 it.Next(); | |
2908 } | |
2909 // Skip past the interceptor on the holder. | |
2910 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | |
2911 it.Next(); | |
2912 | |
2913 MAYBE_RETURN(Object::SetProperty(&it, value, ic.language_mode(), | |
2914 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED), | |
2915 isolate->heap()->exception()); | |
2916 return *value; | |
2881 } | 2917 } |
2882 | 2918 |
2883 | 2919 |
2884 RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) { | 2920 RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) { |
2885 // TODO(verwaest): This should probably get the holder and receiver as input. | 2921 // TODO(verwaest): This should probably get the holder and receiver as input. |
2886 HandleScope scope(isolate); | 2922 HandleScope scope(isolate); |
2887 Handle<JSObject> receiver = args.at<JSObject>(0); | 2923 Handle<JSObject> receiver = args.at<JSObject>(0); |
2888 DCHECK(args.smi_at(1) >= 0); | 2924 DCHECK(args.smi_at(1) >= 0); |
2889 uint32_t index = args.smi_at(1); | 2925 uint32_t index = args.smi_at(1); |
2890 | 2926 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2936 KeyedLoadICNexus nexus(vector, vector_slot); | 2972 KeyedLoadICNexus nexus(vector, vector_slot); |
2937 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2973 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2938 ic.UpdateState(receiver, key); | 2974 ic.UpdateState(receiver, key); |
2939 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2975 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
2940 } | 2976 } |
2941 | 2977 |
2942 return *result; | 2978 return *result; |
2943 } | 2979 } |
2944 } // namespace internal | 2980 } // namespace internal |
2945 } // namespace v8 | 2981 } // namespace v8 |
OLD | NEW |