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/objects/slots.h" |
12 | #include "src/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 | |
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: |
38 | explicit inline CustomArguments(Isolate* isolate) |
39 | : CustomArgumentsBase(isolate) {} |
40 | |
41 | template <typename V> |
42 | Handle<V> GetReturnValue(Isolate* isolate); |
43 | |
44 | inline Isolate* isolate() { |
45 | return reinterpret_cast<Isolate*>((*slot_at(T::kIsolateIndex)).ptr()); |
46 | } |
47 | |
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 | typedef PropertyCallbackInfo<Value> T; |
64 | typedef CustomArguments<T> Super; |
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 | typedef FunctionCallbackInfo<Value> T; |
154 | typedef CustomArguments<T> Super; |
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(internal::Isolate* isolate, internal::Object data, |
164 | internal::HeapObject callee, |
165 | internal::Object holder, |
166 | internal::HeapObject new_target, |
167 | internal::Address* argv, int argc); |
168 | |
169 | /* |
170 | * The following Call function wraps the calling of all callbacks to handle |
171 | * calling either the old or the new style callbacks depending on which one |
172 | * has been registered. |
173 | * For old callbacks which return an empty handle, the ReturnValue is checked |
174 | * and used if it's been set to anything inside the callback. |
175 | * New style callbacks always use the return value. |
176 | */ |
177 | inline Handle<Object> Call(CallHandlerInfo handler); |
178 | |
179 | private: |
180 | inline JSObject holder(); |
181 | |
182 | internal::Address* argv_; |
183 | int argc_; |
184 | }; |
185 | |
186 | } // namespace internal |
187 | } // namespace v8 |
188 | |
189 | #endif // V8_API_ARGUMENTS_H_ |
190 | |