LCOV - code coverage report
Current view: top level - src - api-arguments-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 115 120 95.8 %
Date: 2019-01-20 Functions: 23 29 79.3 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_API_ARGUMENTS_INL_H_
       6             : #define V8_API_ARGUMENTS_INL_H_
       7             : 
       8             : #include "src/api-arguments.h"
       9             : 
      10             : #include "src/api-inl.h"
      11             : #include "src/debug/debug.h"
      12             : #include "src/objects/api-callbacks.h"
      13             : #include "src/objects/slots-inl.h"
      14             : #include "src/tracing/trace-event.h"
      15             : #include "src/vm-state-inl.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : 
      20             : CustomArgumentsBase::CustomArgumentsBase(Isolate* isolate)
      21    10190070 :     : Relocatable(isolate) {}
      22             : 
      23             : template <typename T>
      24           0 : CustomArguments<T>::~CustomArguments() {
      25             :   slot_at(kReturnValueOffset).store(Object(kHandleZapValue));
      26     5095032 : }
      27             : 
      28             : template <typename T>
      29             : template <typename V>
      30     5094798 : Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
      31             :   // Check the ReturnValue.
      32             :   FullObjectSlot slot = slot_at(kReturnValueOffset);
      33             :   // Nothing was set, return empty handle as per previous behaviour.
      34     5094809 :   if ((*slot)->IsTheHole(isolate)) return Handle<V>();
      35     2956311 :   Handle<V> result = Handle<V>::cast(Handle<Object>(slot.location()));
      36             :   result->VerifyApiCallResultType();
      37     2956310 :   return result;
      38             : }
      39             : 
      40           0 : inline JSObject PropertyCallbackArguments::holder() {
      41           0 :   return JSObject::cast(*slot_at(T::kHolderIndex));
      42             : }
      43             : 
      44             : inline Object PropertyCallbackArguments::receiver() {
      45             :   return *slot_at(T::kThisIndex);
      46             : }
      47             : 
      48           0 : inline JSObject FunctionCallbackArguments::holder() {
      49           0 :   return JSObject::cast(*slot_at(T::kHolderIndex));
      50             : }
      51             : 
      52             : #define FOR_EACH_CALLBACK(F)                        \
      53             :   F(Query, query, Object, v8::Integer, interceptor) \
      54             :   F(Deleter, deleter, Object, v8::Boolean, Handle<Object>())
      55             : 
      56             : #define DCHECK_NAME_COMPATIBLE(interceptor, name) \
      57             :   DCHECK(interceptor->is_named());                \
      58             :   DCHECK(!name->IsPrivate());                     \
      59             :   DCHECK_IMPLIES(name->IsSymbol(), interceptor->can_intercept_symbols());
      60             : 
      61             : #define PREPARE_CALLBACK_INFO(ISOLATE, F, RETURN_VALUE, API_RETURN_TYPE, \
      62             :                               CALLBACK_INFO, RECEIVER, ACCESSOR_KIND)    \
      63             :   if (ISOLATE->debug_execution_mode() == DebugInfo::kSideEffects &&      \
      64             :       !ISOLATE->debug()->PerformSideEffectCheckForCallback(              \
      65             :           CALLBACK_INFO, RECEIVER, Debug::k##ACCESSOR_KIND)) {           \
      66             :     return RETURN_VALUE();                                               \
      67             :   }                                                                      \
      68             :   VMState<EXTERNAL> state(ISOLATE);                                      \
      69             :   ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F));           \
      70             :   PropertyCallbackInfo<API_RETURN_TYPE> callback_info(values_);
      71             : 
      72             : #define PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(ISOLATE, F, RETURN_VALUE, \
      73             :                                                      API_RETURN_TYPE)          \
      74             :   if (ISOLATE->debug_execution_mode() == DebugInfo::kSideEffects) {            \
      75             :     return RETURN_VALUE();                                                     \
      76             :   }                                                                            \
      77             :   VMState<EXTERNAL> state(ISOLATE);                                            \
      78             :   ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F));                 \
      79             :   PropertyCallbackInfo<API_RETURN_TYPE> callback_info(values_);
      80             : 
      81             : #define CREATE_NAMED_CALLBACK(FUNCTION, TYPE, RETURN_TYPE, API_RETURN_TYPE,   \
      82             :                               INFO_FOR_SIDE_EFFECT)                           \
      83             :   Handle<RETURN_TYPE> PropertyCallbackArguments::CallNamed##FUNCTION(         \
      84             :       Handle<InterceptorInfo> interceptor, Handle<Name> name) {               \
      85             :     DCHECK_NAME_COMPATIBLE(interceptor, name);                                \
      86             :     Isolate* isolate = this->isolate();                                       \
      87             :     RuntimeCallTimerScope timer(                                              \
      88             :         isolate, RuntimeCallCounterId::kNamed##FUNCTION##Callback);           \
      89             :     Handle<Object> receiver_check_unsupported;                                \
      90             :     GenericNamedProperty##FUNCTION##Callback f =                              \
      91             :         ToCData<GenericNamedProperty##FUNCTION##Callback>(                    \
      92             :             interceptor->TYPE());                                             \
      93             :     PREPARE_CALLBACK_INFO(isolate, f, Handle<RETURN_TYPE>, API_RETURN_TYPE,   \
      94             :                           INFO_FOR_SIDE_EFFECT, receiver_check_unsupported,   \
      95             :                           NotAccessor);                                       \
      96             :     LOG(isolate,                                                              \
      97             :         ApiNamedPropertyAccess("interceptor-named-" #TYPE, holder(), *name)); \
      98             :     f(v8::Utils::ToLocal(name), callback_info);                               \
      99             :     return GetReturnValue<RETURN_TYPE>(isolate);                              \
     100             :   }
     101             : 
     102        1414 : FOR_EACH_CALLBACK(CREATE_NAMED_CALLBACK)
     103             : #undef CREATE_NAMED_CALLBACK
     104             : 
     105             : #define CREATE_INDEXED_CALLBACK(FUNCTION, TYPE, RETURN_TYPE, API_RETURN_TYPE, \
     106             :                                 INFO_FOR_SIDE_EFFECT)                         \
     107             :   Handle<RETURN_TYPE> PropertyCallbackArguments::CallIndexed##FUNCTION(       \
     108             :       Handle<InterceptorInfo> interceptor, uint32_t index) {                  \
     109             :     DCHECK(!interceptor->is_named());                                         \
     110             :     Isolate* isolate = this->isolate();                                       \
     111             :     RuntimeCallTimerScope timer(                                              \
     112             :         isolate, RuntimeCallCounterId::kIndexed##FUNCTION##Callback);         \
     113             :     Handle<Object> receiver_check_unsupported;                                \
     114             :     IndexedProperty##FUNCTION##Callback f =                                   \
     115             :         ToCData<IndexedProperty##FUNCTION##Callback>(interceptor->TYPE());    \
     116             :     PREPARE_CALLBACK_INFO(isolate, f, Handle<RETURN_TYPE>, API_RETURN_TYPE,   \
     117             :                           INFO_FOR_SIDE_EFFECT, receiver_check_unsupported,   \
     118             :                           NotAccessor);                                       \
     119             :     LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-" #TYPE,       \
     120             :                                           holder(), index));                  \
     121             :     f(index, callback_info);                                                  \
     122             :     return GetReturnValue<RETURN_TYPE>(isolate);                              \
     123             :   }
     124             : 
     125        1688 : FOR_EACH_CALLBACK(CREATE_INDEXED_CALLBACK)
     126             : 
     127             : #undef FOR_EACH_CALLBACK
     128             : #undef CREATE_INDEXED_CALLBACK
     129             : 
     130     2475051 : Handle<Object> FunctionCallbackArguments::Call(CallHandlerInfo handler) {
     131     4950248 :   Isolate* isolate = this->isolate();
     132     2475051 :   LOG(isolate, ApiObjectAccess("call", holder()));
     133     2475051 :   RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kFunctionCallback);
     134             :   v8::FunctionCallback f =
     135     2475057 :       v8::ToCData<v8::FunctionCallback>(handler->callback());
     136             :   Handle<Object> receiver_check_unsupported;
     137     7425174 :   if (isolate->debug_execution_mode() == DebugInfo::kSideEffects &&
     138             :       !isolate->debug()->PerformSideEffectCheckForCallback(
     139             :           handle(handler, isolate), receiver_check_unsupported,
     140     2475336 :           Debug::kNotAccessor)) {
     141          64 :     return Handle<Object>();
     142             :   }
     143     4949982 :   VMState<EXTERNAL> state(isolate);
     144     4949985 :   ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
     145     2474989 :   FunctionCallbackInfo<v8::Value> info(values_, argv_, argc_);
     146     2474989 :   f(info);
     147     2474981 :   return GetReturnValue<Object>(isolate);
     148             : }
     149             : 
     150         240 : Handle<JSObject> PropertyCallbackArguments::CallNamedEnumerator(
     151             :     Handle<InterceptorInfo> interceptor) {
     152             :   DCHECK(interceptor->is_named());
     153         240 :   LOG(isolate(), ApiObjectAccess("interceptor-named-enumerator", holder()));
     154             :   RuntimeCallTimerScope timer(isolate(),
     155         240 :                               RuntimeCallCounterId::kNamedEnumeratorCallback);
     156         480 :   return CallPropertyEnumerator(interceptor);
     157             : }
     158             : 
     159         235 : Handle<JSObject> PropertyCallbackArguments::CallIndexedEnumerator(
     160             :     Handle<InterceptorInfo> interceptor) {
     161             :   DCHECK(!interceptor->is_named());
     162         235 :   LOG(isolate(), ApiObjectAccess("interceptor-indexed-enumerator", holder()));
     163             :   RuntimeCallTimerScope timer(isolate(),
     164         235 :                               RuntimeCallCounterId::kIndexedEnumeratorCallback);
     165         470 :   return CallPropertyEnumerator(interceptor);
     166             : }
     167             : 
     168      255149 : Handle<Object> PropertyCallbackArguments::CallNamedGetter(
     169             :     Handle<InterceptorInfo> interceptor, Handle<Name> name) {
     170             :   DCHECK_NAME_COMPATIBLE(interceptor, name);
     171      255149 :   Isolate* isolate = this->isolate();
     172             :   RuntimeCallTimerScope timer(isolate,
     173      255149 :                               RuntimeCallCounterId::kNamedGetterCallback);
     174      255149 :   LOG(isolate,
     175             :       ApiNamedPropertyAccess("interceptor-named-getter", holder(), *name));
     176             :   GenericNamedPropertyGetterCallback f =
     177      255149 :       ToCData<GenericNamedPropertyGetterCallback>(interceptor->getter());
     178      510298 :   return BasicCallNamedGetterCallback(f, name, interceptor);
     179             : }
     180             : 
     181          33 : Handle<Object> PropertyCallbackArguments::CallNamedDescriptor(
     182             :     Handle<InterceptorInfo> interceptor, Handle<Name> name) {
     183             :   DCHECK_NAME_COMPATIBLE(interceptor, name);
     184          33 :   Isolate* isolate = this->isolate();
     185             :   RuntimeCallTimerScope timer(isolate,
     186          33 :                               RuntimeCallCounterId::kNamedDescriptorCallback);
     187          33 :   LOG(isolate,
     188             :       ApiNamedPropertyAccess("interceptor-named-descriptor", holder(), *name));
     189             :   GenericNamedPropertyDescriptorCallback f =
     190             :       ToCData<GenericNamedPropertyDescriptorCallback>(
     191          33 :           interceptor->descriptor());
     192          66 :   return BasicCallNamedGetterCallback(f, name, interceptor);
     193             : }
     194             : 
     195      897309 : Handle<Object> PropertyCallbackArguments::BasicCallNamedGetterCallback(
     196             :     GenericNamedPropertyGetterCallback f, Handle<Name> name,
     197             :     Handle<Object> info, Handle<Object> receiver) {
     198             :   DCHECK(!name->IsPrivate());
     199      897526 :   Isolate* isolate = this->isolate();
     200     1794791 :   PREPARE_CALLBACK_INFO(isolate, f, Handle<Object>, v8::Value, info, receiver,
     201             :                         Getter);
     202      897264 :   f(v8::Utils::ToLocal(name), callback_info);
     203     1794528 :   return GetReturnValue<Object>(isolate);
     204             : }
     205             : 
     206      667166 : Handle<Object> PropertyCallbackArguments::CallNamedSetter(
     207             :     Handle<InterceptorInfo> interceptor, Handle<Name> name,
     208             :     Handle<Object> value) {
     209             :   DCHECK_NAME_COMPATIBLE(interceptor, name);
     210             :   GenericNamedPropertySetterCallback f =
     211      667166 :       ToCData<GenericNamedPropertySetterCallback>(interceptor->setter());
     212     1334332 :   Isolate* isolate = this->isolate();
     213             :   RuntimeCallTimerScope timer(isolate,
     214      667166 :                               RuntimeCallCounterId::kNamedSetterCallback);
     215     1334332 :   PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
     216             :                                                v8::Value);
     217      667166 :   LOG(isolate,
     218             :       ApiNamedPropertyAccess("interceptor-named-set", holder(), *name));
     219      667166 :   f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), callback_info);
     220      667166 :   return GetReturnValue<Object>(isolate);
     221             : }
     222             : 
     223          63 : Handle<Object> PropertyCallbackArguments::CallNamedDefiner(
     224             :     Handle<InterceptorInfo> interceptor, Handle<Name> name,
     225             :     const v8::PropertyDescriptor& desc) {
     226             :   DCHECK_NAME_COMPATIBLE(interceptor, name);
     227         126 :   Isolate* isolate = this->isolate();
     228             :   RuntimeCallTimerScope timer(isolate,
     229          63 :                               RuntimeCallCounterId::kNamedDefinerCallback);
     230             :   GenericNamedPropertyDefinerCallback f =
     231          63 :       ToCData<GenericNamedPropertyDefinerCallback>(interceptor->definer());
     232         126 :   PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
     233             :                                                v8::Value);
     234          63 :   LOG(isolate,
     235             :       ApiNamedPropertyAccess("interceptor-named-define", holder(), *name));
     236          63 :   f(v8::Utils::ToLocal(name), desc, callback_info);
     237          63 :   return GetReturnValue<Object>(isolate);
     238             : }
     239             : 
     240       65669 : Handle<Object> PropertyCallbackArguments::CallIndexedSetter(
     241             :     Handle<InterceptorInfo> interceptor, uint32_t index, Handle<Object> value) {
     242             :   DCHECK(!interceptor->is_named());
     243      131338 :   Isolate* isolate = this->isolate();
     244             :   RuntimeCallTimerScope timer(isolate,
     245       65669 :                               RuntimeCallCounterId::kIndexedSetterCallback);
     246             :   IndexedPropertySetterCallback f =
     247       65669 :       ToCData<IndexedPropertySetterCallback>(interceptor->setter());
     248      131338 :   PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
     249             :                                                v8::Value);
     250       65669 :   LOG(isolate,
     251             :       ApiIndexedPropertyAccess("interceptor-indexed-set", holder(), index));
     252       65669 :   f(index, v8::Utils::ToLocal(value), callback_info);
     253       65669 :   return GetReturnValue<Object>(isolate);
     254             : }
     255             : 
     256          24 : Handle<Object> PropertyCallbackArguments::CallIndexedDefiner(
     257             :     Handle<InterceptorInfo> interceptor, uint32_t index,
     258             :     const v8::PropertyDescriptor& desc) {
     259             :   DCHECK(!interceptor->is_named());
     260          48 :   Isolate* isolate = this->isolate();
     261             :   RuntimeCallTimerScope timer(isolate,
     262          24 :                               RuntimeCallCounterId::kIndexedDefinerCallback);
     263             :   IndexedPropertyDefinerCallback f =
     264          24 :       ToCData<IndexedPropertyDefinerCallback>(interceptor->definer());
     265          48 :   PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(isolate, f, Handle<Object>,
     266             :                                                v8::Value);
     267          24 :   LOG(isolate,
     268             :       ApiIndexedPropertyAccess("interceptor-indexed-define", holder(), index));
     269          24 :   f(index, desc, callback_info);
     270          24 :   return GetReturnValue<Object>(isolate);
     271             : }
     272             : 
     273      244791 : Handle<Object> PropertyCallbackArguments::CallIndexedGetter(
     274             :     Handle<InterceptorInfo> interceptor, uint32_t index) {
     275             :   DCHECK(!interceptor->is_named());
     276      244791 :   Isolate* isolate = this->isolate();
     277             :   RuntimeCallTimerScope timer(isolate,
     278      244791 :                               RuntimeCallCounterId::kNamedGetterCallback);
     279      244791 :   LOG(isolate,
     280             :       ApiIndexedPropertyAccess("interceptor-indexed-getter", holder(), index));
     281             :   IndexedPropertyGetterCallback f =
     282      244791 :       ToCData<IndexedPropertyGetterCallback>(interceptor->getter());
     283      489582 :   return BasicCallIndexedGetterCallback(f, index, interceptor);
     284             : }
     285             : 
     286          12 : Handle<Object> PropertyCallbackArguments::CallIndexedDescriptor(
     287             :     Handle<InterceptorInfo> interceptor, uint32_t index) {
     288             :   DCHECK(!interceptor->is_named());
     289          12 :   Isolate* isolate = this->isolate();
     290             :   RuntimeCallTimerScope timer(isolate,
     291          12 :                               RuntimeCallCounterId::kIndexedDescriptorCallback);
     292          12 :   LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-descriptor",
     293             :                                         holder(), index));
     294             :   IndexedPropertyDescriptorCallback f =
     295          12 :       ToCData<IndexedPropertyDescriptorCallback>(interceptor->descriptor());
     296          24 :   return BasicCallIndexedGetterCallback(f, index, interceptor);
     297             : }
     298             : 
     299      244803 : Handle<Object> PropertyCallbackArguments::BasicCallIndexedGetterCallback(
     300             :     IndexedPropertyGetterCallback f, uint32_t index, Handle<Object> info) {
     301      244803 :   Isolate* isolate = this->isolate();
     302             :   Handle<Object> receiver_check_unsupported;
     303      489606 :   PREPARE_CALLBACK_INFO(isolate, f, Handle<Object>, v8::Value, info,
     304             :                         receiver_check_unsupported, Getter);
     305      244803 :   f(index, callback_info);
     306      489606 :   return GetReturnValue<Object>(isolate);
     307             : }
     308             : 
     309         475 : Handle<JSObject> PropertyCallbackArguments::CallPropertyEnumerator(
     310             :     Handle<InterceptorInfo> interceptor) {
     311             :   // For now there is a single enumerator for indexed and named properties.
     312             :   IndexedPropertyEnumeratorCallback f =
     313         475 :       v8::ToCData<IndexedPropertyEnumeratorCallback>(interceptor->enumerator());
     314             :   // TODO(cbruni): assert same type for indexed and named callback.
     315         487 :   Isolate* isolate = this->isolate();
     316             :   Handle<Object> receiver_check_unsupported;
     317         956 :   PREPARE_CALLBACK_INFO(isolate, f, Handle<JSObject>, v8::Array, interceptor,
     318             :                         receiver_check_unsupported, NotAccessor);
     319         469 :   f(callback_info);
     320         938 :   return GetReturnValue<JSObject>(isolate);
     321             : }
     322             : 
     323             : // -------------------------------------------------------------------------
     324             : // Accessors
     325             : 
     326      642126 : Handle<Object> PropertyCallbackArguments::CallAccessorGetter(
     327             :     Handle<AccessorInfo> info, Handle<Name> name) {
     328      642127 :   Isolate* isolate = this->isolate();
     329             :   RuntimeCallTimerScope timer(isolate,
     330      642126 :                               RuntimeCallCounterId::kAccessorGetterCallback);
     331      642127 :   LOG(isolate, ApiNamedPropertyAccess("accessor-getter", holder(), *name));
     332             :   AccessorNameGetterCallback f =
     333      642127 :       ToCData<AccessorNameGetterCallback>(info->getter());
     334             :   return BasicCallNamedGetterCallback(f, name, info,
     335     1284254 :                                       handle(receiver(), isolate));
     336             : }
     337             : 
     338      743588 : Handle<Object> PropertyCallbackArguments::CallAccessorSetter(
     339             :     Handle<AccessorInfo> accessor_info, Handle<Name> name,
     340             :     Handle<Object> value) {
     341     1487217 :   Isolate* isolate = this->isolate();
     342             :   RuntimeCallTimerScope timer(isolate,
     343      743588 :                               RuntimeCallCounterId::kAccessorSetterCallback);
     344             :   AccessorNameSetterCallback f =
     345      743588 :       ToCData<AccessorNameSetterCallback>(accessor_info->setter());
     346     1487217 :   PREPARE_CALLBACK_INFO(isolate, f, Handle<Object>, void, accessor_info,
     347             :                         handle(receiver(), isolate), Setter);
     348      743588 :   LOG(isolate, ApiNamedPropertyAccess("accessor-setter", holder(), *name));
     349      743588 :   f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), callback_info);
     350      743588 :   return GetReturnValue<Object>(isolate);
     351             : }
     352             : 
     353             : #undef PREPARE_CALLBACK_INFO
     354             : #undef PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK
     355             : 
     356             : }  // namespace internal
     357             : }  // namespace v8
     358             : 
     359             : #endif  // V8_API_ARGUMENTS_INL_H_

Generated by: LCOV version 1.10