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