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 94528890 : class CustomArgumentsBase : public Relocatable {
20 : public:
21 41800 : virtual inline void IterateInstance(RootVisitor* v) {
22 41800 : v->VisitRootPointers(Root::kRelocatable, values_, values_ + kArrayLength);
23 41800 : }
24 :
25 : protected:
26 : inline Object** begin() { return values_; }
27 : explicit inline CustomArgumentsBase(Isolate* isolate)
28 134016638 : : 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 94528890 : this->begin()[kReturnValueOffset] =
40 : reinterpret_cast<Object*>(kHandleZapValue);
41 94528890 : }
42 :
43 : protected:
44 94528890 : explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
45 :
46 : template <typename V>
47 : Handle<V> GetReturnValue(Isolate* isolate);
48 :
49 : inline Isolate* isolate() {
50 94528783 : return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]);
51 : }
52 : };
53 :
54 : template <typename T>
55 : template <typename V>
56 55975768 : Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
57 : // Check the ReturnValue.
58 55975768 : Object** handle = &this->begin()[kReturnValueOffset];
59 : // Nothing was set, return empty handle as per previous behaviour.
60 111951539 : if ((*handle)->IsTheHole(isolate)) return Handle<V>();
61 : Handle<V> result = Handle<V>::cast(Handle<Object>(handle));
62 : result->VerifyApiCallResultType();
63 15028052 : return result;
64 : }
65 :
66 82149992 : class PropertyCallbackArguments
67 : : public CustomArguments<PropertyCallbackInfo<Value> > {
68 : public:
69 : typedef PropertyCallbackInfo<Value> T;
70 : typedef CustomArguments<T> Super;
71 : static const int kArgsLength = T::kArgsLength;
72 : static const int kThisIndex = T::kThisIndex;
73 : static const int kHolderIndex = T::kHolderIndex;
74 : static const int kDataIndex = T::kDataIndex;
75 : static const int kReturnValueDefaultValueIndex =
76 : T::kReturnValueDefaultValueIndex;
77 : static const int kIsolateIndex = T::kIsolateIndex;
78 : static const int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex;
79 :
80 39487748 : PropertyCallbackArguments(Isolate* isolate, Object* data, Object* self,
81 : JSObject* holder, Object::ShouldThrow should_throw)
82 42662243 : : Super(isolate) {
83 : Object** values = this->begin();
84 42662243 : values[T::kThisIndex] = self;
85 42662243 : values[T::kHolderIndex] = holder;
86 42662243 : values[T::kDataIndex] = data;
87 42662243 : values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
88 : values[T::kShouldThrowOnErrorIndex] =
89 84150575 : Smi::FromInt(should_throw == Object::THROW_ON_ERROR ? 1 : 0);
90 :
91 : // Here the hole is set as default value.
92 : // It cannot escape into js as it's removed in Call below.
93 : values[T::kReturnValueDefaultValueIndex] =
94 42662243 : isolate->heap()->the_hole_value();
95 42662243 : values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
96 : DCHECK(values[T::kHolderIndex]->IsHeapObject());
97 : DCHECK(values[T::kIsolateIndex]->IsSmi());
98 39487748 : }
99 :
100 : /*
101 : * The following Call functions wrap the calling of all callbacks to handle
102 : * calling either the old or the new style callbacks depending on which one
103 : * has been registered.
104 : * For old callbacks which return an empty handle, the ReturnValue is checked
105 : * and used if it's been set to anything inside the callback.
106 : * New style callbacks always use the return value.
107 : */
108 : Handle<JSObject> Call(IndexedPropertyEnumeratorCallback f);
109 :
110 : inline Handle<Object> Call(AccessorNameGetterCallback f, Handle<Name> name);
111 : inline Handle<Object> Call(GenericNamedPropertyQueryCallback f,
112 : Handle<Name> name);
113 : inline Handle<Object> Call(GenericNamedPropertyDeleterCallback f,
114 : Handle<Name> name);
115 :
116 : inline Handle<Object> Call(IndexedPropertyGetterCallback f, uint32_t index);
117 : inline Handle<Object> Call(IndexedPropertyQueryCallback f, uint32_t index);
118 : inline Handle<Object> Call(IndexedPropertyDeleterCallback f, uint32_t index);
119 :
120 : inline Handle<Object> Call(GenericNamedPropertySetterCallback f,
121 : Handle<Name> name, Handle<Object> value);
122 :
123 : inline Handle<Object> Call(GenericNamedPropertyDefinerCallback f,
124 : Handle<Name> name,
125 : const v8::PropertyDescriptor& desc);
126 :
127 : inline Handle<Object> Call(IndexedPropertySetterCallback f, uint32_t index,
128 : Handle<Object> value);
129 :
130 : inline Handle<Object> Call(IndexedPropertyDefinerCallback f, uint32_t index,
131 : const v8::PropertyDescriptor& desc);
132 :
133 : inline void Call(AccessorNameSetterCallback f, Handle<Name> name,
134 : Handle<Object> value);
135 :
136 : private:
137 : inline JSObject* holder() {
138 336 : return JSObject::cast(this->begin()[T::kHolderIndex]);
139 : }
140 :
141 : bool PerformSideEffectCheck(Isolate* isolate, Address function);
142 : };
143 :
144 51866646 : class FunctionCallbackArguments
145 : : public CustomArguments<FunctionCallbackInfo<Value> > {
146 : public:
147 : typedef FunctionCallbackInfo<Value> T;
148 : typedef CustomArguments<T> Super;
149 : static const int kArgsLength = T::kArgsLength;
150 : static const int kHolderIndex = T::kHolderIndex;
151 : static const int kDataIndex = T::kDataIndex;
152 : static const int kReturnValueDefaultValueIndex =
153 : T::kReturnValueDefaultValueIndex;
154 : static const int kIsolateIndex = T::kIsolateIndex;
155 : static const int kCalleeIndex = T::kCalleeIndex;
156 : static const int kContextSaveIndex = T::kContextSaveIndex;
157 : static const int kNewTargetIndex = T::kNewTargetIndex;
158 :
159 : FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data,
160 : internal::HeapObject* callee,
161 : internal::Object* holder,
162 : internal::HeapObject* new_target,
163 : internal::Object** argv, int argc)
164 51866647 : : Super(isolate), argv_(argv), argc_(argc) {
165 : Object** values = begin();
166 51866647 : values[T::kDataIndex] = data;
167 51866647 : values[T::kCalleeIndex] = callee;
168 51866647 : values[T::kHolderIndex] = holder;
169 51866647 : values[T::kNewTargetIndex] = new_target;
170 51866647 : values[T::kContextSaveIndex] = isolate->heap()->the_hole_value();
171 51866647 : values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
172 : // Here the hole is set as default value.
173 : // It cannot escape into js as it's remove in Call below.
174 : values[T::kReturnValueDefaultValueIndex] =
175 51866647 : isolate->heap()->the_hole_value();
176 51866647 : values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
177 : DCHECK(values[T::kCalleeIndex]->IsJSFunction() ||
178 : values[T::kCalleeIndex]->IsFunctionTemplateInfo());
179 : DCHECK(values[T::kHolderIndex]->IsHeapObject());
180 : DCHECK(values[T::kIsolateIndex]->IsSmi());
181 : }
182 :
183 : /*
184 : * The following Call function wraps the calling of all callbacks to handle
185 : * calling either the old or the new style callbacks depending on which one
186 : * has been registered.
187 : * For old callbacks which return an empty handle, the ReturnValue is checked
188 : * and used if it's been set to anything inside the callback.
189 : * New style callbacks always use the return value.
190 : */
191 : Handle<Object> Call(FunctionCallback f);
192 :
193 : private:
194 : internal::Object** argv_;
195 : int argc_;
196 : };
197 :
198 : } // namespace internal
199 : } // namespace v8
200 :
201 : #endif // V8_API_ARGUMENTS_H_
|