blob: 9db039dbacf2ed8121fe81f16cdcd6dd4ca65d17 [file] [log] [blame]
[email protected]37dacfa2013-11-26 03:31:041// This file was GENERATED by command:
2// pump.py function_template.h.pump
3// DO NOT EDIT BY HAND!!!
4
5
6
[email protected]b520e132013-11-29 03:21:487#ifndef GIN_FUNCTION_TEMPLATE_H_
8#define GIN_FUNCTION_TEMPLATE_H_
9
[email protected]314cde12013-11-23 20:26:5110// Copyright 2013 The Chromium Authors. All rights reserved.
11// Use of this source code is governed by a BSD-style license that can be
12// found in the LICENSE file.
13
14#include "base/callback.h"
15#include "base/logging.h"
16#include "gin/arguments.h"
17#include "gin/converter.h"
[email protected]d379b0c2013-12-05 05:48:0118#include "gin/handle.h"
[email protected]314cde12013-11-23 20:26:5119#include "gin/public/gin_embedders.h"
20#include "gin/public/wrapper_info.h"
21#include "gin/wrappable.h"
22
23#include "v8/include/v8.h"
24
25namespace gin {
26
27class PerIsolateData;
28
[email protected]bf3dd3c2013-12-06 06:55:2529enum CreateFunctionTemplateFlags {
30 HolderIsFirstArgument = 1 << 0,
31};
32
[email protected]37dacfa2013-11-26 03:31:0433namespace internal {
34
[email protected]314cde12013-11-23 20:26:5135template<typename T>
[email protected]bf3dd3c2013-12-06 06:55:2536struct CallbackParamTraits {
37 typedef T LocalType;
[email protected]314cde12013-11-23 20:26:5138};
39template<typename T>
[email protected]bf3dd3c2013-12-06 06:55:2540struct CallbackParamTraits<const T&> {
41 typedef T LocalType;
42};
43template<typename T>
44struct CallbackParamTraits<const T*> {
45 typedef T* LocalType;
[email protected]314cde12013-11-23 20:26:5146};
47
[email protected]37dacfa2013-11-26 03:31:0448
49// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
50// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
[email protected]81f8b91b2013-11-26 21:02:5151// DispatchToCallback, where it is invoked.
[email protected]37dacfa2013-11-26 03:31:0452//
53// v8::FunctionTemplate only supports passing void* as data so how do we know
54// when to delete the base::Callback? That's where CallbackHolderBase comes in.
55// It inherits from Wrappable, which delete itself when both (a) the refcount
56// via base::RefCounted has dropped to zero, and (b) there are no more
57// JavaScript references in V8.
[email protected]6fe56102013-12-08 07:10:5858
59// This simple base class is used so that we can share a single object template
60// among every CallbackHolder instance.
61class CallbackHolderBase : public Wrappable<CallbackHolderBase> {
[email protected]b4acaf82013-12-12 09:40:5062 public:
63 static WrapperInfo kWrapperInfo;
64
[email protected]314cde12013-11-23 20:26:5165 protected:
[email protected]695af7f52013-12-11 19:41:0166 virtual ~CallbackHolderBase() {}
[email protected]314cde12013-11-23 20:26:5167};
68
[email protected]314cde12013-11-23 20:26:5169template<typename Sig>
70class CallbackHolder : public CallbackHolderBase {
71 public:
[email protected]bf3dd3c2013-12-06 06:55:2572 CallbackHolder(const base::Callback<Sig>& callback, int flags)
73 : callback(callback), flags(flags) {}
[email protected]314cde12013-11-23 20:26:5174 base::Callback<Sig> callback;
[email protected]bf3dd3c2013-12-06 06:55:2575 int flags;
[email protected]314cde12013-11-23 20:26:5176 private:
[email protected]695af7f52013-12-11 19:41:0177 virtual ~CallbackHolder() {}
[email protected]314cde12013-11-23 20:26:5178};
79
[email protected]81f8b91b2013-11-26 21:02:5180
81// This set of templates invokes a base::Callback, converts the return type to a
82// JavaScript value, and returns that value to script via the provided
83// gin::Arguments object.
84//
85// In C++, you can declare the function foo(void), but you can't pass a void
86// expression to foo. As a result, we must specialize the case of Callbacks that
87// have the void return type.
[email protected]7618ebbb2013-11-27 03:38:2688template<typename R, typename P1 = void, typename P2 = void,
89 typename P3 = void, typename P4 = void>
[email protected]81f8b91b2013-11-26 21:02:5190struct Invoker {
91 inline static void Go(
92 Arguments* args,
[email protected]7618ebbb2013-11-27 03:38:2693 const base::Callback<R(P1, P2, P3, P4)>& callback,
94 const P1& a1,
95 const P2& a2,
96 const P3& a3,
97 const P4& a4) {
98 args->Return(callback.Run(a1, a2, a3, a4));
99 }
100};
101template<typename P1, typename P2, typename P3, typename P4>
102struct Invoker<void, P1, P2, P3, P4> {
103 inline static void Go(
104 Arguments* args,
105 const base::Callback<void(P1, P2, P3, P4)>& callback,
106 const P1& a1,
107 const P2& a2,
108 const P3& a3,
109 const P4& a4) {
110 callback.Run(a1, a2, a3, a4);
111 }
112};
113
114template<typename R, typename P1, typename P2, typename P3>
115struct Invoker<R, P1, P2, P3, void> {
116 inline static void Go(
117 Arguments* args,
[email protected]81f8b91b2013-11-26 21:02:51118 const base::Callback<R(P1, P2, P3)>& callback,
119 const P1& a1,
120 const P2& a2,
121 const P3& a3) {
122 args->Return(callback.Run(a1, a2, a3));
123 }
124};
125template<typename P1, typename P2, typename P3>
[email protected]7618ebbb2013-11-27 03:38:26126struct Invoker<void, P1, P2, P3, void> {
[email protected]81f8b91b2013-11-26 21:02:51127 inline static void Go(
128 Arguments* args,
129 const base::Callback<void(P1, P2, P3)>& callback,
130 const P1& a1,
131 const P2& a2,
132 const P3& a3) {
133 callback.Run(a1, a2, a3);
134 }
135};
136
137template<typename R, typename P1, typename P2>
[email protected]7618ebbb2013-11-27 03:38:26138struct Invoker<R, P1, P2, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51139 inline static void Go(
140 Arguments* args,
141 const base::Callback<R(P1, P2)>& callback,
142 const P1& a1,
143 const P2& a2) {
144 args->Return(callback.Run(a1, a2));
145 }
146};
147template<typename P1, typename P2>
[email protected]7618ebbb2013-11-27 03:38:26148struct Invoker<void, P1, P2, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51149 inline static void Go(
150 Arguments* args,
151 const base::Callback<void(P1, P2)>& callback,
152 const P1& a1,
153 const P2& a2) {
154 callback.Run(a1, a2);
155 }
156};
157
158template<typename R, typename P1>
[email protected]7618ebbb2013-11-27 03:38:26159struct Invoker<R, P1, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51160 inline static void Go(
161 Arguments* args,
162 const base::Callback<R(P1)>& callback,
163 const P1& a1) {
164 args->Return(callback.Run(a1));
165 }
166};
167template<typename P1>
[email protected]7618ebbb2013-11-27 03:38:26168struct Invoker<void, P1, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51169 inline static void Go(
170 Arguments* args,
171 const base::Callback<void(P1)>& callback,
172 const P1& a1) {
173 callback.Run(a1);
174 }
175};
176
177template<typename R>
[email protected]7618ebbb2013-11-27 03:38:26178struct Invoker<R, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51179 inline static void Go(
180 Arguments* args,
181 const base::Callback<R()>& callback) {
182 args->Return(callback.Run());
183 }
184};
185template<>
[email protected]7618ebbb2013-11-27 03:38:26186struct Invoker<void, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51187 inline static void Go(
188 Arguments* args,
189 const base::Callback<void()>& callback) {
190 callback.Run();
191 }
192};
193
194
[email protected]bf3dd3c2013-12-06 06:55:25195template<typename T>
196bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
197 T* result) {
198 if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
199 return args->GetHolder(result);
200 } else {
201 return args->GetNext(result);
202 }
203}
204
205// For advanced use cases, we allow callers to request the unparsed Arguments
206// object and poke around in it directly.
207inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
208 Arguments* result) {
209 *result = *args;
210 return true;
211}
212
213
[email protected]81f8b91b2013-11-26 21:02:51214// DispatchToCallback converts all the JavaScript arguments to C++ types and
215// invokes the base::Callback.
[email protected]bf3dd3c2013-12-06 06:55:25216template<typename Sig>
217struct Dispatcher {
218};
219
[email protected]37dacfa2013-11-26 03:31:04220template<typename R>
[email protected]bf3dd3c2013-12-06 06:55:25221struct Dispatcher<R()> {
222 static void DispatchToCallback(
223 const v8::FunctionCallbackInfo<v8::Value>& info) {
224 Arguments args(info);
225 CallbackHolderBase* holder_base = NULL;
226 CHECK(args.GetData(&holder_base));
[email protected]314cde12013-11-23 20:26:51227
[email protected]bf3dd3c2013-12-06 06:55:25228 typedef CallbackHolder<R()> HolderT;
229 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04230
[email protected]bf3dd3c2013-12-06 06:55:25231 Invoker<R>::Go(&args, holder->callback);
232 }
233};
[email protected]37dacfa2013-11-26 03:31:04234
235template<typename R, typename P1>
[email protected]bf3dd3c2013-12-06 06:55:25236struct Dispatcher<R(P1)> {
237 static void DispatchToCallback(
238 const v8::FunctionCallbackInfo<v8::Value>& info) {
239 Arguments args(info);
240 CallbackHolderBase* holder_base = NULL;
241 CHECK(args.GetData(&holder_base));
[email protected]37dacfa2013-11-26 03:31:04242
[email protected]bf3dd3c2013-12-06 06:55:25243 typedef CallbackHolder<R(P1)> HolderT;
244 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04245
[email protected]bf3dd3c2013-12-06 06:55:25246 typename CallbackParamTraits<P1>::LocalType a1;
247 if (!GetNextArgument(&args, holder->flags, true, &a1)) {
248 args.ThrowError();
249 return;
250 }
251
252 Invoker<R, P1>::Go(&args, holder->callback, a1);
[email protected]37dacfa2013-11-26 03:31:04253 }
[email protected]bf3dd3c2013-12-06 06:55:25254};
[email protected]37dacfa2013-11-26 03:31:04255
256template<typename R, typename P1, typename P2>
[email protected]bf3dd3c2013-12-06 06:55:25257struct Dispatcher<R(P1, P2)> {
258 static void DispatchToCallback(
259 const v8::FunctionCallbackInfo<v8::Value>& info) {
260 Arguments args(info);
261 CallbackHolderBase* holder_base = NULL;
262 CHECK(args.GetData(&holder_base));
[email protected]314cde12013-11-23 20:26:51263
[email protected]bf3dd3c2013-12-06 06:55:25264 typedef CallbackHolder<R(P1, P2)> HolderT;
265 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]314cde12013-11-23 20:26:51266
[email protected]bf3dd3c2013-12-06 06:55:25267 typename CallbackParamTraits<P1>::LocalType a1;
268 typename CallbackParamTraits<P2>::LocalType a2;
269 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
270 !GetNextArgument(&args, holder->flags, false, &a2)) {
271 args.ThrowError();
272 return;
273 }
274
275 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
[email protected]314cde12013-11-23 20:26:51276 }
[email protected]bf3dd3c2013-12-06 06:55:25277};
[email protected]37dacfa2013-11-26 03:31:04278
279template<typename R, typename P1, typename P2, typename P3>
[email protected]bf3dd3c2013-12-06 06:55:25280struct Dispatcher<R(P1, P2, P3)> {
281 static void DispatchToCallback(
282 const v8::FunctionCallbackInfo<v8::Value>& info) {
283 Arguments args(info);
284 CallbackHolderBase* holder_base = NULL;
285 CHECK(args.GetData(&holder_base));
[email protected]37dacfa2013-11-26 03:31:04286
[email protected]bf3dd3c2013-12-06 06:55:25287 typedef CallbackHolder<R(P1, P2, P3)> HolderT;
288 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04289
[email protected]bf3dd3c2013-12-06 06:55:25290 typename CallbackParamTraits<P1>::LocalType a1;
291 typename CallbackParamTraits<P2>::LocalType a2;
292 typename CallbackParamTraits<P3>::LocalType a3;
293 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
294 !GetNextArgument(&args, holder->flags, false, &a2) ||
295 !GetNextArgument(&args, holder->flags, false, &a3)) {
296 args.ThrowError();
297 return;
298 }
299
300 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
[email protected]37dacfa2013-11-26 03:31:04301 }
[email protected]bf3dd3c2013-12-06 06:55:25302};
[email protected]81f8b91b2013-11-26 21:02:51303
[email protected]7618ebbb2013-11-27 03:38:26304template<typename R, typename P1, typename P2, typename P3, typename P4>
[email protected]bf3dd3c2013-12-06 06:55:25305struct Dispatcher<R(P1, P2, P3, P4)> {
306 static void DispatchToCallback(
307 const v8::FunctionCallbackInfo<v8::Value>& info) {
308 Arguments args(info);
309 CallbackHolderBase* holder_base = NULL;
310 CHECK(args.GetData(&holder_base));
[email protected]7618ebbb2013-11-27 03:38:26311
[email protected]bf3dd3c2013-12-06 06:55:25312 typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
313 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]7618ebbb2013-11-27 03:38:26314
[email protected]bf3dd3c2013-12-06 06:55:25315 typename CallbackParamTraits<P1>::LocalType a1;
316 typename CallbackParamTraits<P2>::LocalType a2;
317 typename CallbackParamTraits<P3>::LocalType a3;
318 typename CallbackParamTraits<P4>::LocalType a4;
319 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
320 !GetNextArgument(&args, holder->flags, false, &a2) ||
321 !GetNextArgument(&args, holder->flags, false, &a3) ||
322 !GetNextArgument(&args, holder->flags, false, &a4)) {
323 args.ThrowError();
324 return;
325 }
326
327 Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
[email protected]7618ebbb2013-11-27 03:38:26328 }
[email protected]bf3dd3c2013-12-06 06:55:25329};
[email protected]7618ebbb2013-11-27 03:38:26330
[email protected]81f8b91b2013-11-26 21:02:51331} // namespace internal
332
333
334// This should be called once per-isolate to initialize the function template
335// system.
336void InitFunctionTemplates(PerIsolateData* isolate_data);
337
[email protected]7618ebbb2013-11-27 03:38:26338
[email protected]bf3dd3c2013-12-06 06:55:25339// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
340// JavaScript functions that execute a provided C++ function or base::Callback.
341// JavaScript arguments are automatically converted via gin::Converter, as is
342// the return value of the C++ function, if any.
343template<typename Sig>
[email protected]81f8b91b2013-11-26 21:02:51344v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
[email protected]bf3dd3c2013-12-06 06:55:25345 v8::Isolate* isolate, const base::Callback<Sig> callback,
346 int callback_flags = 0) {
347 typedef internal::CallbackHolder<Sig> HolderT;
348 gin::Handle<HolderT> holder = CreateHandle(
349 isolate, new HolderT(callback, callback_flags));
[email protected]81f8b91b2013-11-26 21:02:51350 return v8::FunctionTemplate::New(
[email protected]bf3dd3c2013-12-06 06:55:25351 &internal::Dispatcher<Sig>::DispatchToCallback,
[email protected]7618ebbb2013-11-27 03:38:26352 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
353}
354
[email protected]314cde12013-11-23 20:26:51355} // namespace gin
[email protected]b520e132013-11-29 03:21:48356
357#endif // GIN_FUNCTION_TEMPLATE_H_