OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_API_ARGUMENTS_H_ | 5 #ifndef V8_API_ARGUMENTS_H_ |
6 #define V8_API_ARGUMENTS_H_ | 6 #define V8_API_ARGUMENTS_H_ |
7 | 7 |
8 #include "src/api.h" | |
8 #include "src/isolate.h" | 9 #include "src/isolate.h" |
9 #include "src/tracing/trace-event.h" | 10 #include "src/tracing/trace-event.h" |
11 #include "src/vm-state-inl.h" | |
10 | 12 |
11 namespace v8 { | 13 namespace v8 { |
12 namespace internal { | 14 namespace internal { |
13 | 15 |
14 // For each type of callback, we have a list of arguments | |
15 // They are used to generate the Call() functions below | |
16 // These aren't included in the list as they have duplicate signatures | |
17 // F(GenericNamedPropertyEnumeratorCallback, ...) | |
18 // F(GenericNamedPropertyGetterCallback, ...) | |
19 | |
20 #define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \ | |
21 F(IndexedPropertyEnumeratorCallback, v8::Array) | |
22 | |
23 #define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \ | |
24 F(AccessorNameGetterCallback, v8::Value, v8::Local<v8::Name>) \ | |
25 F(GenericNamedPropertyQueryCallback, v8::Integer, v8::Local<v8::Name>) \ | |
26 F(GenericNamedPropertyDeleterCallback, v8::Boolean, v8::Local<v8::Name>) \ | |
27 F(IndexedPropertyGetterCallback, v8::Value, uint32_t) \ | |
28 F(IndexedPropertyQueryCallback, v8::Integer, uint32_t) \ | |
29 F(IndexedPropertyDeleterCallback, v8::Boolean, uint32_t) | |
30 | |
31 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \ | |
32 F(GenericNamedPropertySetterCallback, v8::Value, v8::Local<v8::Name>, \ | |
33 v8::Local<v8::Value>) \ | |
34 F(IndexedPropertySetterCallback, v8::Value, uint32_t, v8::Local<v8::Value>) | |
35 | |
36 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \ | |
37 F(AccessorNameSetterCallback, void, v8::Local<v8::Name>, v8::Local<v8::Value>) | |
38 | |
39 // Custom arguments replicate a small segment of stack that can be | 16 // Custom arguments replicate a small segment of stack that can be |
40 // accessed through an Arguments object the same way the actual stack | 17 // accessed through an Arguments object the same way the actual stack |
41 // can. | 18 // can. |
42 template <int kArrayLength> | 19 template <int kArrayLength> |
43 class CustomArgumentsBase : public Relocatable { | 20 class CustomArgumentsBase : public Relocatable { |
44 public: | 21 public: |
45 virtual inline void IterateInstance(ObjectVisitor* v) { | 22 virtual inline void IterateInstance(ObjectVisitor* v) { |
46 v->VisitPointers(values_, values_ + kArrayLength); | 23 v->VisitPointers(values_, values_ + kArrayLength); |
47 } | 24 } |
48 | 25 |
(...skipping 12 matching lines...) Expand all Loading... | |
61 typedef CustomArgumentsBase<T::kArgsLength> Super; | 38 typedef CustomArgumentsBase<T::kArgsLength> Super; |
62 ~CustomArguments() { | 39 ~CustomArguments() { |
63 this->begin()[kReturnValueOffset] = | 40 this->begin()[kReturnValueOffset] = |
64 reinterpret_cast<Object*>(kHandleZapValue); | 41 reinterpret_cast<Object*>(kHandleZapValue); |
65 } | 42 } |
66 | 43 |
67 protected: | 44 protected: |
68 explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {} | 45 explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {} |
69 | 46 |
70 template <typename V> | 47 template <typename V> |
71 v8::Local<V> GetReturnValue(Isolate* isolate); | 48 Handle<V> GetReturnValue(Isolate* isolate); |
72 | 49 |
73 inline Isolate* isolate() { | 50 inline Isolate* isolate() { |
74 return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]); | 51 return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]); |
75 } | 52 } |
76 }; | 53 }; |
77 | 54 |
55 template <typename T> | |
56 template <typename V> | |
57 Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) { | |
58 // Check the ReturnValue. | |
59 Object** handle = &this->begin()[kReturnValueOffset]; | |
60 // Nothing was set, return empty handle as per previous behaviour. | |
61 if ((*handle)->IsTheHole()) return Handle<V>(); | |
62 Handle<V> result = Handle<V>::cast(Handle<Object>(handle)); | |
63 result->VerifyApiCallResultType(); | |
64 return result; | |
65 } | |
66 | |
78 class PropertyCallbackArguments | 67 class PropertyCallbackArguments |
79 : public CustomArguments<PropertyCallbackInfo<Value> > { | 68 : public CustomArguments<PropertyCallbackInfo<Value> > { |
80 public: | 69 public: |
81 typedef PropertyCallbackInfo<Value> T; | 70 typedef PropertyCallbackInfo<Value> T; |
82 typedef CustomArguments<T> Super; | 71 typedef CustomArguments<T> Super; |
83 static const int kArgsLength = T::kArgsLength; | 72 static const int kArgsLength = T::kArgsLength; |
84 static const int kThisIndex = T::kThisIndex; | 73 static const int kThisIndex = T::kThisIndex; |
85 static const int kHolderIndex = T::kHolderIndex; | 74 static const int kHolderIndex = T::kHolderIndex; |
86 static const int kDataIndex = T::kDataIndex; | 75 static const int kDataIndex = T::kDataIndex; |
87 static const int kReturnValueDefaultValueIndex = | 76 static const int kReturnValueDefaultValueIndex = |
(...skipping 22 matching lines...) Expand all Loading... | |
110 } | 99 } |
111 | 100 |
112 /* | 101 /* |
113 * The following Call functions wrap the calling of all callbacks to handle | 102 * The following Call functions wrap the calling of all callbacks to handle |
114 * calling either the old or the new style callbacks depending on which one | 103 * calling either the old or the new style callbacks depending on which one |
115 * has been registered. | 104 * has been registered. |
116 * For old callbacks which return an empty handle, the ReturnValue is checked | 105 * For old callbacks which return an empty handle, the ReturnValue is checked |
117 * and used if it's been set to anything inside the callback. | 106 * and used if it's been set to anything inside the callback. |
118 * New style callbacks always use the return value. | 107 * New style callbacks always use the return value. |
119 */ | 108 */ |
120 #define WRITE_CALL_0(Function, ReturnValue) \ | 109 Handle<JSObject> Call(IndexedPropertyEnumeratorCallback f); |
121 v8::Local<ReturnValue> Call(Function f); | |
122 | 110 |
123 #define WRITE_CALL_1(Function, ReturnValue, Arg1) \ | 111 #define FOR_EACH_CALLBACK_TABLE_MAPPING_1_NAME(F) \ |
124 v8::Local<ReturnValue> Call(Function f, Arg1 arg1); | 112 F(AccessorNameGetterCallback, "get", v8::Value, Object) \ |
113 F(GenericNamedPropertyQueryCallback, "has", v8::Integer, Object) \ | |
114 F(GenericNamedPropertyDeleterCallback, "delete", v8::Boolean, Object) | |
125 | 115 |
126 #define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2) \ | 116 #define WRITE_CALL_1_NAME(Function, type, ApiReturn, InternalReturn) \ |
127 v8::Local<ReturnValue> Call(Function f, Arg1 arg1, Arg2 arg2); | 117 Handle<InternalReturn> Call(Function f, Handle<Name> name) { \ |
118 Isolate* isolate = this->isolate(); \ | |
Jakob Kummerow
2016/03/10 15:04:27
Does it matter for performance to have all these i
| |
119 VMState<EXTERNAL> state(isolate); \ | |
120 ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \ | |
121 PropertyCallbackInfo<ApiReturn> info(begin()); \ | |
122 LOG(isolate, \ | |
123 ApiNamedPropertyAccess("interceptor-named-" type, holder(), *name)); \ | |
124 f(v8::Utils::ToLocal(name), info); \ | |
125 return GetReturnValue<InternalReturn>(isolate); \ | |
126 } | |
128 | 127 |
129 #define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \ | 128 FOR_EACH_CALLBACK_TABLE_MAPPING_1_NAME(WRITE_CALL_1_NAME) |
130 void Call(Function f, Arg1 arg1, Arg2 arg2); | |
131 | 129 |
132 FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0) | 130 #undef FOR_EACH_CALLBACK_TABLE_MAPPING_1_NAME |
133 FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1) | 131 #undef WRITE_CALL_1_NAME |
134 FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2) | |
135 FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(WRITE_CALL_2_VOID) | |
136 | 132 |
137 #undef WRITE_CALL_0 | 133 #define FOR_EACH_CALLBACK_TABLE_MAPPING_1_INDEX(F) \ |
138 #undef WRITE_CALL_1 | 134 F(IndexedPropertyGetterCallback, "get", v8::Value, Object) \ |
139 #undef WRITE_CALL_2 | 135 F(IndexedPropertyQueryCallback, "has", v8::Integer, Object) \ |
140 #undef WRITE_CALL_2_VOID | 136 F(IndexedPropertyDeleterCallback, "delete", v8::Boolean, Object) |
137 | |
138 #define WRITE_CALL_1_INDEX(Function, type, ApiReturn, InternalReturn) \ | |
139 Handle<InternalReturn> Call(Function f, uint32_t index) { \ | |
140 Isolate* isolate = this->isolate(); \ | |
141 VMState<EXTERNAL> state(isolate); \ | |
142 ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \ | |
143 PropertyCallbackInfo<ApiReturn> info(begin()); \ | |
144 LOG(isolate, ApiIndexedPropertyAccess("interceptor-indexed-" type, \ | |
145 holder(), index)); \ | |
146 f(index, info); \ | |
147 return GetReturnValue<InternalReturn>(isolate); \ | |
148 } | |
149 | |
150 FOR_EACH_CALLBACK_TABLE_MAPPING_1_INDEX(WRITE_CALL_1_INDEX) | |
151 | |
152 #undef FOR_EACH_CALLBACK_TABLE_MAPPING_1_INDEX | |
153 #undef WRITE_CALL_1_INDEX | |
154 | |
155 Handle<Object> Call(GenericNamedPropertySetterCallback f, Handle<Name> name, | |
156 Handle<Object> value) { | |
157 Isolate* isolate = this->isolate(); | |
158 VMState<EXTERNAL> state(isolate); | |
159 ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); | |
160 PropertyCallbackInfo<v8::Value> info(begin()); | |
161 LOG(isolate, | |
162 ApiNamedPropertyAccess("interceptor-named-set", holder(), *name)); | |
163 f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); | |
164 return GetReturnValue<Object>(isolate); | |
165 } | |
166 | |
167 Handle<Object> Call(IndexedPropertySetterCallback f, uint32_t index, | |
168 Handle<Object> value) { | |
169 Isolate* isolate = this->isolate(); | |
170 VMState<EXTERNAL> state(isolate); | |
171 ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); | |
172 PropertyCallbackInfo<v8::Value> info(begin()); | |
173 LOG(isolate, | |
174 ApiIndexedPropertyAccess("interceptor-indexed-set", holder(), index)); | |
175 f(index, v8::Utils::ToLocal(value), info); | |
176 return GetReturnValue<Object>(isolate); | |
177 } | |
178 | |
179 void Call(AccessorNameSetterCallback f, Handle<Name> name, | |
180 Handle<Object> value) { | |
181 Isolate* isolate = this->isolate(); | |
182 VMState<EXTERNAL> state(isolate); | |
183 ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); | |
184 PropertyCallbackInfo<void> info(begin()); | |
185 LOG(isolate, | |
186 ApiNamedPropertyAccess("interceptor-named-set", holder(), *name)); | |
187 f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); | |
188 } | |
189 | |
190 private: | |
191 inline JSObject* holder() { | |
192 return JSObject::cast(this->begin()[T::kHolderIndex]); | |
193 } | |
141 }; | 194 }; |
142 | 195 |
143 class FunctionCallbackArguments | 196 class FunctionCallbackArguments |
144 : public CustomArguments<FunctionCallbackInfo<Value> > { | 197 : public CustomArguments<FunctionCallbackInfo<Value> > { |
145 public: | 198 public: |
146 typedef FunctionCallbackInfo<Value> T; | 199 typedef FunctionCallbackInfo<Value> T; |
147 typedef CustomArguments<T> Super; | 200 typedef CustomArguments<T> Super; |
148 static const int kArgsLength = T::kArgsLength; | 201 static const int kArgsLength = T::kArgsLength; |
149 static const int kHolderIndex = T::kHolderIndex; | 202 static const int kHolderIndex = T::kHolderIndex; |
150 static const int kDataIndex = T::kDataIndex; | 203 static const int kDataIndex = T::kDataIndex; |
(...skipping 29 matching lines...) Expand all Loading... | |
180 } | 233 } |
181 | 234 |
182 /* | 235 /* |
183 * The following Call function wraps the calling of all callbacks to handle | 236 * The following Call function wraps the calling of all callbacks to handle |
184 * calling either the old or the new style callbacks depending on which one | 237 * calling either the old or the new style callbacks depending on which one |
185 * has been registered. | 238 * has been registered. |
186 * For old callbacks which return an empty handle, the ReturnValue is checked | 239 * For old callbacks which return an empty handle, the ReturnValue is checked |
187 * and used if it's been set to anything inside the callback. | 240 * and used if it's been set to anything inside the callback. |
188 * New style callbacks always use the return value. | 241 * New style callbacks always use the return value. |
189 */ | 242 */ |
190 v8::Local<v8::Value> Call(FunctionCallback f); | 243 Handle<Object> Call(FunctionCallback f); |
191 | 244 |
192 private: | 245 private: |
193 internal::Object** argv_; | 246 internal::Object** argv_; |
194 int argc_; | 247 int argc_; |
195 bool is_construct_call_; | 248 bool is_construct_call_; |
196 }; | 249 }; |
197 | 250 |
198 } // namespace internal | 251 } // namespace internal |
199 } // namespace v8 | 252 } // namespace v8 |
200 | 253 |
201 #endif // V8_API_ARGUMENTS_H_ | 254 #endif // V8_API_ARGUMENTS_H_ |
OLD | NEW |