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