Line data Source code
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/isolate.h"
10 : #include "src/visitors.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : // Custom arguments replicate a small segment of stack that can be
16 : // accessed through an Arguments object the same way the actual stack
17 : // can.
18 : template <int kArrayLength>
19 17250074 : class CustomArgumentsBase : public Relocatable {
20 : public:
21 47813 : virtual inline void IterateInstance(RootVisitor* v) {
22 47813 : v->VisitRootPointers(Root::kRelocatable, values_, values_ + kArrayLength);
23 47813 : }
24 :
25 : protected:
26 : inline Object** begin() { return values_; }
27 : explicit inline CustomArgumentsBase(Isolate* isolate)
28 18712603 : : Relocatable(isolate) {}
29 : Object* values_[kArrayLength];
30 : };
31 :
32 : template <typename T>
33 : class CustomArguments : public CustomArgumentsBase<T::kArgsLength> {
34 : public:
35 : static const int kReturnValueOffset = T::kReturnValueIndex;
36 :
37 : typedef CustomArgumentsBase<T::kArgsLength> Super;
38 0 : ~CustomArguments() {
39 17250074 : this->begin()[kReturnValueOffset] =
40 : reinterpret_cast<Object*>(kHandleZapValue);
41 17250074 : }
42 :
43 : protected:
44 17250074 : explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
45 :
46 : template <typename V>
47 : Handle<V> GetReturnValue(Isolate* isolate);
48 :
49 : inline Isolate* isolate() {
50 17249927 : return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]);
51 : }
52 : };
53 :
54 : template <typename T>
55 : template <typename V>
56 16615443 : Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
57 : // Check the ReturnValue.
58 16615443 : Object** handle = &this->begin()[kReturnValueOffset];
59 : // Nothing was set, return empty handle as per previous behaviour.
60 33230887 : if ((*handle)->IsTheHole(isolate)) return Handle<V>();
61 : Handle<V> result = Handle<V>::cast(Handle<Object>(handle));
62 : result->VerifyApiCallResultType();
63 8670837 : return result;
64 : }
65 :
66 : // Note: Calling args.Call() sets the return value on args. For multiple
67 : // Call()'s, a new args should be used every time.
68 4285021 : class PropertyCallbackArguments
69 : : public CustomArguments<PropertyCallbackInfo<Value> > {
70 : public:
71 : typedef PropertyCallbackInfo<Value> T;
72 : typedef CustomArguments<T> Super;
73 : static const int kArgsLength = T::kArgsLength;
74 : static const int kThisIndex = T::kThisIndex;
75 : static const int kHolderIndex = T::kHolderIndex;
76 : static const int kDataIndex = T::kDataIndex;
77 : static const int kReturnValueDefaultValueIndex =
78 : T::kReturnValueDefaultValueIndex;
79 : static const int kIsolateIndex = T::kIsolateIndex;
80 : static const int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex;
81 :
82 1462529 : PropertyCallbackArguments(Isolate* isolate, Object* data, Object* self,
83 : JSObject* holder, Object::ShouldThrow should_throw)
84 2822492 : : Super(isolate) {
85 : Object** values = this->begin();
86 2822492 : values[T::kThisIndex] = self;
87 2822492 : values[T::kHolderIndex] = holder;
88 2822492 : values[T::kDataIndex] = data;
89 2822492 : values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
90 : values[T::kShouldThrowOnErrorIndex] =
91 4820182 : Smi::FromInt(should_throw == Object::THROW_ON_ERROR ? 1 : 0);
92 :
93 : // Here the hole is set as default value.
94 : // It cannot escape into js as it's removed in Call below.
95 : values[T::kReturnValueDefaultValueIndex] =
96 2822492 : isolate->heap()->the_hole_value();
97 2822492 : values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
98 : DCHECK(values[T::kHolderIndex]->IsHeapObject());
99 : DCHECK(values[T::kIsolateIndex]->IsSmi());
100 1462529 : }
101 :
102 : /*
103 : * The following Call functions wrap the calling of all callbacks to handle
104 : * calling either the old or the new style callbacks depending on which one
105 : * has been registered.
106 : * For old callbacks which return an empty handle, the ReturnValue is checked
107 : * and used if it's been set to anything inside the callback.
108 : * New style callbacks always use the return value.
109 : */
110 : Handle<JSObject> Call(IndexedPropertyEnumeratorCallback f);
111 :
112 : inline Handle<Object> Call(AccessorNameGetterCallback f, Handle<Name> name);
113 : inline Handle<Object> Call(GenericNamedPropertyQueryCallback f,
114 : Handle<Name> name);
115 : inline Handle<Object> Call(GenericNamedPropertyDeleterCallback f,
116 : Handle<Name> name);
117 :
118 : inline Handle<Object> Call(IndexedPropertyGetterCallback f, uint32_t index);
119 : inline Handle<Object> Call(IndexedPropertyQueryCallback f, uint32_t index);
120 : inline Handle<Object> Call(IndexedPropertyDeleterCallback f, uint32_t index);
121 :
122 : inline Handle<Object> Call(GenericNamedPropertySetterCallback f,
123 : Handle<Name> name, Handle<Object> value);
124 :
125 : inline Handle<Object> Call(GenericNamedPropertyDefinerCallback f,
126 : Handle<Name> name,
127 : const v8::PropertyDescriptor& desc);
128 :
129 : inline Handle<Object> Call(IndexedPropertySetterCallback f, uint32_t index,
130 : Handle<Object> value);
131 :
132 : inline Handle<Object> Call(IndexedPropertyDefinerCallback f, uint32_t index,
133 : const v8::PropertyDescriptor& desc);
134 :
135 : inline void Call(AccessorNameSetterCallback f, Handle<Name> name,
136 : Handle<Object> value);
137 :
138 : private:
139 : inline JSObject* holder() {
140 38 : return JSObject::cast(this->begin()[T::kHolderIndex]);
141 : }
142 :
143 : bool PerformSideEffectCheck(Isolate* isolate, Address function);
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 14427582 : 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 kCalleeIndex = T::kCalleeIndex;
162 : static const int kContextSaveIndex = T::kContextSaveIndex;
163 : static const int kNewTargetIndex = T::kNewTargetIndex;
164 :
165 : FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data,
166 : internal::HeapObject* callee,
167 : internal::Object* holder,
168 : internal::HeapObject* new_target,
169 : internal::Object** argv, int argc)
170 14427582 : : Super(isolate), argv_(argv), argc_(argc) {
171 : Object** values = begin();
172 14427582 : values[T::kDataIndex] = data;
173 14427582 : values[T::kCalleeIndex] = callee;
174 14427582 : values[T::kHolderIndex] = holder;
175 14427582 : values[T::kNewTargetIndex] = new_target;
176 14427582 : values[T::kContextSaveIndex] = isolate->heap()->the_hole_value();
177 14427582 : values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
178 : // Here the hole is set as default value.
179 : // It cannot escape into js as it's remove in Call below.
180 : values[T::kReturnValueDefaultValueIndex] =
181 14427582 : isolate->heap()->the_hole_value();
182 14427582 : values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
183 : DCHECK(values[T::kCalleeIndex]->IsJSFunction() ||
184 : values[T::kCalleeIndex]->IsFunctionTemplateInfo());
185 : DCHECK(values[T::kHolderIndex]->IsHeapObject());
186 : DCHECK(values[T::kIsolateIndex]->IsSmi());
187 : }
188 :
189 : /*
190 : * The following Call function wraps the calling of all callbacks to handle
191 : * calling either the old or the new style callbacks depending on which one
192 : * has been registered.
193 : * For old callbacks which return an empty handle, the ReturnValue is checked
194 : * and used if it's been set to anything inside the callback.
195 : * New style callbacks always use the return value.
196 : */
197 : Handle<Object> Call(FunctionCallback f);
198 :
199 : private:
200 : internal::Object** argv_;
201 : int argc_;
202 : };
203 :
204 : } // namespace internal
205 : } // namespace v8
206 :
207 : #endif // V8_API_ARGUMENTS_H_
|