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
14namespace v8 {
15namespace 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.
20class CustomArgumentsBase : public Relocatable {
21 protected:
22 explicit inline CustomArgumentsBase(Isolate* isolate);
23};
24
25template <typename T>
26class 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.
60class 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
150class 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