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/debug/debug.h" 10 #include "src/isolate.h" 11 #include "src/visitors.h" 12 13 namespace v8 { 14 namespace internal { 15 16 // Custom arguments replicate a small segment of stack that can be 17 // accessed through an Arguments object the same way the actual stack 18 // can. 19 class CustomArgumentsBase : public Relocatable { 20 protected: 21 explicit inline CustomArgumentsBase(Isolate* isolate); 22 }; 23 24 template <typename T> 25 class CustomArguments : public CustomArgumentsBase { 26 public: 27 static const int kReturnValueOffset = T::kReturnValueIndex; 28 ~CustomArguments()29 ~CustomArguments() { 30 this->begin()[kReturnValueOffset] = 31 reinterpret_cast<Object*>(kHandleZapValue); 32 } 33 IterateInstance(RootVisitor * v)34 virtual inline void IterateInstance(RootVisitor* v) { 35 v->VisitRootPointers(Root::kRelocatable, nullptr, values_, 36 values_ + T::kArgsLength); 37 } 38 39 protected: CustomArguments(Isolate * isolate)40 explicit inline CustomArguments(Isolate* isolate) 41 : CustomArgumentsBase(isolate) {} 42 43 template <typename V> 44 Handle<V> GetReturnValue(Isolate* isolate); 45 isolate()46 inline Isolate* isolate() { 47 return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]); 48 } 49 begin()50 inline Object** begin() { return values_; } 51 Object* values_[T::kArgsLength]; 52 }; 53 54 // Note: Calling args.Call() sets the return value on args. For multiple 55 // Call()'s, a new args should be used every time. 56 class PropertyCallbackArguments 57 : public CustomArguments<PropertyCallbackInfo<Value> > { 58 public: 59 typedef PropertyCallbackInfo<Value> T; 60 typedef CustomArguments<T> Super; 61 static const int kArgsLength = T::kArgsLength; 62 static const int kThisIndex = T::kThisIndex; 63 static const int kHolderIndex = T::kHolderIndex; 64 static const int kDataIndex = T::kDataIndex; 65 static const int kReturnValueDefaultValueIndex = 66 T::kReturnValueDefaultValueIndex; 67 static const int kIsolateIndex = T::kIsolateIndex; 68 static const int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex; 69 70 PropertyCallbackArguments(Isolate* isolate, Object* data, Object* self, 71 JSObject* holder, ShouldThrow should_throw); 72 73 // ------------------------------------------------------------------------- 74 // Accessor Callbacks 75 // Also used for AccessorSetterCallback. 76 inline Handle<Object> CallAccessorSetter(Handle<AccessorInfo> info, 77 Handle<Name> name, 78 Handle<Object> value); 79 // Also used for AccessorGetterCallback, AccessorNameGetterCallback. 80 inline Handle<Object> CallAccessorGetter(Handle<AccessorInfo> info, 81 Handle<Name> name); 82 83 // ------------------------------------------------------------------------- 84 // Named Interceptor Callbacks 85 inline Handle<Object> CallNamedQuery(Handle<InterceptorInfo> interceptor, 86 Handle<Name> name); 87 inline Handle<Object> CallNamedGetter(Handle<InterceptorInfo> interceptor, 88 Handle<Name> name); 89 inline Handle<Object> CallNamedSetter(Handle<InterceptorInfo> interceptor, 90 Handle<Name> name, 91 Handle<Object> value); 92 inline Handle<Object> CallNamedDefiner(Handle<InterceptorInfo> interceptor, 93 Handle<Name> name, 94 const v8::PropertyDescriptor& desc); 95 inline Handle<Object> CallNamedDeleter(Handle<InterceptorInfo> interceptor, 96 Handle<Name> name); 97 inline Handle<Object> CallNamedDescriptor(Handle<InterceptorInfo> interceptor, 98 Handle<Name> name); 99 inline Handle<JSObject> CallNamedEnumerator( 100 Handle<InterceptorInfo> interceptor); 101 102 // ------------------------------------------------------------------------- 103 // Indexed Interceptor Callbacks 104 inline Handle<Object> CallIndexedQuery(Handle<InterceptorInfo> interceptor, 105 uint32_t index); 106 inline Handle<Object> CallIndexedGetter(Handle<InterceptorInfo> interceptor, 107 uint32_t index); 108 inline Handle<Object> CallIndexedSetter(Handle<InterceptorInfo> interceptor, 109 uint32_t index, Handle<Object> value); 110 inline Handle<Object> CallIndexedDefiner(Handle<InterceptorInfo> interceptor, 111 uint32_t index, 112 const v8::PropertyDescriptor& desc); 113 inline Handle<Object> CallIndexedDeleter(Handle<InterceptorInfo> interceptor, 114 uint32_t index); 115 inline Handle<Object> CallIndexedDescriptor( 116 Handle<InterceptorInfo> interceptor, uint32_t index); 117 inline Handle<JSObject> CallIndexedEnumerator( 118 Handle<InterceptorInfo> interceptor); 119 120 private: 121 /* 122 * The following Call functions wrap the calling of all callbacks to handle 123 * calling either the old or the new style callbacks depending on which one 124 * has been registered. 125 * For old callbacks which return an empty handle, the ReturnValue is checked 126 * and used if it's been set to anything inside the callback. 127 * New style callbacks always use the return value. 128 */ 129 inline Handle<JSObject> CallPropertyEnumerator( 130 Handle<InterceptorInfo> interceptor); 131 132 inline Handle<Object> BasicCallIndexedGetterCallback( 133 IndexedPropertyGetterCallback f, uint32_t index, Handle<Object> info); 134 inline Handle<Object> BasicCallNamedGetterCallback( 135 GenericNamedPropertyGetterCallback f, Handle<Name> name, 136 Handle<Object> info); 137 138 inline JSObject* holder(); 139 140 // Don't copy PropertyCallbackArguments, because they would both have the 141 // same prev_ pointer. 142 DISALLOW_COPY_AND_ASSIGN(PropertyCallbackArguments); 143 }; 144 145 class FunctionCallbackArguments 146 : public CustomArguments<FunctionCallbackInfo<Value> > { 147 public: 148 typedef FunctionCallbackInfo<Value> T; 149 typedef CustomArguments<T> Super; 150 static const int kArgsLength = T::kArgsLength; 151 static const int kHolderIndex = T::kHolderIndex; 152 static const int kDataIndex = T::kDataIndex; 153 static const int kReturnValueDefaultValueIndex = 154 T::kReturnValueDefaultValueIndex; 155 static const int kIsolateIndex = T::kIsolateIndex; 156 static const int kNewTargetIndex = T::kNewTargetIndex; 157 158 FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data, 159 internal::HeapObject* callee, 160 internal::Object* holder, 161 internal::HeapObject* new_target, 162 internal::Object** argv, int argc); 163 164 /* 165 * The following Call function wraps the calling of all callbacks to handle 166 * calling either the old or the new style callbacks depending on which one 167 * has been registered. 168 * For old callbacks which return an empty handle, the ReturnValue is checked 169 * and used if it's been set to anything inside the callback. 170 * New style callbacks always use the return value. 171 */ 172 inline Handle<Object> Call(CallHandlerInfo* handler); 173 174 private: 175 inline JSObject* holder(); 176 177 internal::Object** argv_; 178 int argc_; 179 }; 180 181 } // namespace internal 182 } // namespace v8 183 184 #endif // V8_API_ARGUMENTS_H_ 185