• 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 "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