• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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