LCOV - code coverage report
Current view: top level - src - api-arguments.h (source / functions) Hit Total Coverage
Test: app.info Lines: 35 36 97.2 %
Date: 2017-10-20 Functions: 7 18 38.9 %

          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_H_
       6             : #define V8_API_ARGUMENTS_H_
       7             : 
       8             : #include "src/api.h"
       9             : #include "src/isolate.h"
      10             : #include "src/visitors.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : // Custom arguments replicate a small segment of stack that can be
      16             : // accessed through an Arguments object the same way the actual stack
      17             : // can.
      18             : template <int kArrayLength>
      19    17250074 : class CustomArgumentsBase : public Relocatable {
      20             :  public:
      21       47813 :   virtual inline void IterateInstance(RootVisitor* v) {
      22       47813 :     v->VisitRootPointers(Root::kRelocatable, values_, values_ + kArrayLength);
      23       47813 :   }
      24             : 
      25             :  protected:
      26             :   inline Object** begin() { return values_; }
      27             :   explicit inline CustomArgumentsBase(Isolate* isolate)
      28    18712603 :       : Relocatable(isolate) {}
      29             :   Object* values_[kArrayLength];
      30             : };
      31             : 
      32             : template <typename T>
      33             : class CustomArguments : public CustomArgumentsBase<T::kArgsLength> {
      34             :  public:
      35             :   static const int kReturnValueOffset = T::kReturnValueIndex;
      36             : 
      37             :   typedef CustomArgumentsBase<T::kArgsLength> Super;
      38           0 :   ~CustomArguments() {
      39    17250074 :     this->begin()[kReturnValueOffset] =
      40             :         reinterpret_cast<Object*>(kHandleZapValue);
      41    17250074 :   }
      42             : 
      43             :  protected:
      44    17250074 :   explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
      45             : 
      46             :   template <typename V>
      47             :   Handle<V> GetReturnValue(Isolate* isolate);
      48             : 
      49             :   inline Isolate* isolate() {
      50    17249927 :     return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]);
      51             :   }
      52             : };
      53             : 
      54             : template <typename T>
      55             : template <typename V>
      56    16615443 : Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
      57             :   // Check the ReturnValue.
      58    16615443 :   Object** handle = &this->begin()[kReturnValueOffset];
      59             :   // Nothing was set, return empty handle as per previous behaviour.
      60    33230887 :   if ((*handle)->IsTheHole(isolate)) return Handle<V>();
      61             :   Handle<V> result = Handle<V>::cast(Handle<Object>(handle));
      62             :   result->VerifyApiCallResultType();
      63     8670837 :   return result;
      64             : }
      65             : 
      66             : // Note: Calling args.Call() sets the return value on args. For multiple
      67             : // Call()'s, a new args should be used every time.
      68     4285021 : class PropertyCallbackArguments
      69             :     : public CustomArguments<PropertyCallbackInfo<Value> > {
      70             :  public:
      71             :   typedef PropertyCallbackInfo<Value> T;
      72             :   typedef CustomArguments<T> Super;
      73             :   static const int kArgsLength = T::kArgsLength;
      74             :   static const int kThisIndex = T::kThisIndex;
      75             :   static const int kHolderIndex = T::kHolderIndex;
      76             :   static const int kDataIndex = T::kDataIndex;
      77             :   static const int kReturnValueDefaultValueIndex =
      78             :       T::kReturnValueDefaultValueIndex;
      79             :   static const int kIsolateIndex = T::kIsolateIndex;
      80             :   static const int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex;
      81             : 
      82     1462529 :   PropertyCallbackArguments(Isolate* isolate, Object* data, Object* self,
      83             :                             JSObject* holder, Object::ShouldThrow should_throw)
      84     2822492 :       : Super(isolate) {
      85             :     Object** values = this->begin();
      86     2822492 :     values[T::kThisIndex] = self;
      87     2822492 :     values[T::kHolderIndex] = holder;
      88     2822492 :     values[T::kDataIndex] = data;
      89     2822492 :     values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
      90             :     values[T::kShouldThrowOnErrorIndex] =
      91     4820182 :         Smi::FromInt(should_throw == Object::THROW_ON_ERROR ? 1 : 0);
      92             : 
      93             :     // Here the hole is set as default value.
      94             :     // It cannot escape into js as it's removed in Call below.
      95             :     values[T::kReturnValueDefaultValueIndex] =
      96     2822492 :         isolate->heap()->the_hole_value();
      97     2822492 :     values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
      98             :     DCHECK(values[T::kHolderIndex]->IsHeapObject());
      99             :     DCHECK(values[T::kIsolateIndex]->IsSmi());
     100     1462529 :   }
     101             : 
     102             :   /*
     103             :    * The following Call functions wrap the calling of all callbacks to handle
     104             :    * calling either the old or the new style callbacks depending on which one
     105             :    * has been registered.
     106             :    * For old callbacks which return an empty handle, the ReturnValue is checked
     107             :    * and used if it's been set to anything inside the callback.
     108             :    * New style callbacks always use the return value.
     109             :    */
     110             :   Handle<JSObject> Call(IndexedPropertyEnumeratorCallback f);
     111             : 
     112             :   inline Handle<Object> Call(AccessorNameGetterCallback f, Handle<Name> name);
     113             :   inline Handle<Object> Call(GenericNamedPropertyQueryCallback f,
     114             :                              Handle<Name> name);
     115             :   inline Handle<Object> Call(GenericNamedPropertyDeleterCallback f,
     116             :                              Handle<Name> name);
     117             : 
     118             :   inline Handle<Object> Call(IndexedPropertyGetterCallback f, uint32_t index);
     119             :   inline Handle<Object> Call(IndexedPropertyQueryCallback f, uint32_t index);
     120             :   inline Handle<Object> Call(IndexedPropertyDeleterCallback f, uint32_t index);
     121             : 
     122             :   inline Handle<Object> Call(GenericNamedPropertySetterCallback f,
     123             :                              Handle<Name> name, Handle<Object> value);
     124             : 
     125             :   inline Handle<Object> Call(GenericNamedPropertyDefinerCallback f,
     126             :                              Handle<Name> name,
     127             :                              const v8::PropertyDescriptor& desc);
     128             : 
     129             :   inline Handle<Object> Call(IndexedPropertySetterCallback f, uint32_t index,
     130             :                              Handle<Object> value);
     131             : 
     132             :   inline Handle<Object> Call(IndexedPropertyDefinerCallback f, uint32_t index,
     133             :                              const v8::PropertyDescriptor& desc);
     134             : 
     135             :   inline void Call(AccessorNameSetterCallback f, Handle<Name> name,
     136             :                    Handle<Object> value);
     137             : 
     138             :  private:
     139             :   inline JSObject* holder() {
     140          38 :     return JSObject::cast(this->begin()[T::kHolderIndex]);
     141             :   }
     142             : 
     143             :   bool PerformSideEffectCheck(Isolate* isolate, Address function);
     144             : 
     145             :   // Don't copy PropertyCallbackArguments, because they would both have the
     146             :   // same prev_ pointer.
     147             :   DISALLOW_COPY_AND_ASSIGN(PropertyCallbackArguments);
     148             : };
     149             : 
     150    14427582 : class FunctionCallbackArguments
     151             :     : public CustomArguments<FunctionCallbackInfo<Value> > {
     152             :  public:
     153             :   typedef FunctionCallbackInfo<Value> T;
     154             :   typedef CustomArguments<T> Super;
     155             :   static const int kArgsLength = T::kArgsLength;
     156             :   static const int kHolderIndex = T::kHolderIndex;
     157             :   static const int kDataIndex = T::kDataIndex;
     158             :   static const int kReturnValueDefaultValueIndex =
     159             :       T::kReturnValueDefaultValueIndex;
     160             :   static const int kIsolateIndex = T::kIsolateIndex;
     161             :   static const int kCalleeIndex = T::kCalleeIndex;
     162             :   static const int kContextSaveIndex = T::kContextSaveIndex;
     163             :   static const int kNewTargetIndex = T::kNewTargetIndex;
     164             : 
     165             :   FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data,
     166             :                             internal::HeapObject* callee,
     167             :                             internal::Object* holder,
     168             :                             internal::HeapObject* new_target,
     169             :                             internal::Object** argv, int argc)
     170    14427582 :       : Super(isolate), argv_(argv), argc_(argc) {
     171             :     Object** values = begin();
     172    14427582 :     values[T::kDataIndex] = data;
     173    14427582 :     values[T::kCalleeIndex] = callee;
     174    14427582 :     values[T::kHolderIndex] = holder;
     175    14427582 :     values[T::kNewTargetIndex] = new_target;
     176    14427582 :     values[T::kContextSaveIndex] = isolate->heap()->the_hole_value();
     177    14427582 :     values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
     178             :     // Here the hole is set as default value.
     179             :     // It cannot escape into js as it's remove in Call below.
     180             :     values[T::kReturnValueDefaultValueIndex] =
     181    14427582 :         isolate->heap()->the_hole_value();
     182    14427582 :     values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
     183             :     DCHECK(values[T::kCalleeIndex]->IsJSFunction() ||
     184             :            values[T::kCalleeIndex]->IsFunctionTemplateInfo());
     185             :     DCHECK(values[T::kHolderIndex]->IsHeapObject());
     186             :     DCHECK(values[T::kIsolateIndex]->IsSmi());
     187             :   }
     188             : 
     189             :   /*
     190             :    * The following Call function wraps the calling of all callbacks to handle
     191             :    * calling either the old or the new style callbacks depending on which one
     192             :    * has been registered.
     193             :    * For old callbacks which return an empty handle, the ReturnValue is checked
     194             :    * and used if it's been set to anything inside the callback.
     195             :    * New style callbacks always use the return value.
     196             :    */
     197             :   Handle<Object> Call(FunctionCallback f);
     198             : 
     199             :  private:
     200             :   internal::Object** argv_;
     201             :   int argc_;
     202             : };
     203             : 
     204             : }  // namespace internal
     205             : }  // namespace v8
     206             : 
     207             : #endif  // V8_API_ARGUMENTS_H_

Generated by: LCOV version 1.10