Chromium Code Reviews| 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 |