1 // This file was GENERATED by command:
2 // pump.py function_template.h.pump
3 // DO NOT EDIT BY HAND!!!
7 #ifndef GIN_FUNCTION_TEMPLATE_H_
8 #define GIN_FUNCTION_TEMPLATE_H_
10 // 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.
14 #include "base/callback.h"
15 #include "base/logging.h"
16 #include "gin/arguments.h"
17 #include "gin/converter.h"
18 #include "gin/gin_export.h"
19 #include "gin/handle.h"
20 #include "gin/public/gin_embedders.h"
21 #include "gin/public/wrapper_info.h"
22 #include "gin/wrappable.h"
24 #include "v8/include/v8.h"
30 enum CreateFunctionTemplateFlags
{
31 HolderIsFirstArgument
= 1 << 0,
37 struct CallbackParamTraits
{
41 struct CallbackParamTraits
<const T
&> {
45 struct CallbackParamTraits
<const T
*> {
50 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
51 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
52 // DispatchToCallback, where it is invoked.
54 // v8::FunctionTemplate only supports passing void* as data so how do we know
55 // when to delete the base::Callback? That's where CallbackHolderBase comes in.
56 // It inherits from Wrappable, which delete itself when both (a) the refcount
57 // via base::RefCounted has dropped to zero, and (b) there are no more
58 // JavaScript references in V8.
60 // This simple base class is used so that we can share a single object template
61 // among every CallbackHolder instance.
62 class GIN_EXPORT CallbackHolderBase
: public Wrappable
<CallbackHolderBase
> {
64 static WrapperInfo kWrapperInfo
;
66 virtual ~CallbackHolderBase() {}
69 template<typename Sig
>
70 class CallbackHolder
: public CallbackHolderBase
{
72 CallbackHolder(const base::Callback
<Sig
>& callback
, int flags
)
73 : callback(callback
), flags(flags
) {}
74 base::Callback
<Sig
> callback
;
77 virtual ~CallbackHolder() {}
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.
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.
88 template<typename R
, typename P1
= void, typename P2
= void,
89 typename P3
= void, typename P4
= void, typename P5
= void,
92 inline static void Go(
94 const base::Callback
<R(P1
, P2
, P3
, P4
, P5
, P6
)>& callback
,
101 args
->Return(callback
.Run(a1
, a2
, a3
, a4
, a5
, a6
));
104 template<typename P1
, typename P2
, typename P3
, typename P4
, typename P5
,
106 struct Invoker
<void, P1
, P2
, P3
, P4
, P5
, P6
> {
107 inline static void Go(
109 const base::Callback
<void(P1
, P2
, P3
, P4
, P5
, P6
)>& callback
,
116 callback
.Run(a1
, a2
, a3
, a4
, a5
, a6
);
120 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
,
122 struct Invoker
<R
, P1
, P2
, P3
, P4
, P5
, void> {
123 inline static void Go(
125 const base::Callback
<R(P1
, P2
, P3
, P4
, P5
)>& callback
,
131 args
->Return(callback
.Run(a1
, a2
, a3
, a4
, a5
));
134 template<typename P1
, typename P2
, typename P3
, typename P4
, typename P5
>
135 struct Invoker
<void, P1
, P2
, P3
, P4
, P5
, void> {
136 inline static void Go(
138 const base::Callback
<void(P1
, P2
, P3
, P4
, P5
)>& callback
,
144 callback
.Run(a1
, a2
, a3
, a4
, a5
);
148 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
>
149 struct Invoker
<R
, P1
, P2
, P3
, P4
, void, void> {
150 inline static void Go(
152 const base::Callback
<R(P1
, P2
, P3
, P4
)>& callback
,
157 args
->Return(callback
.Run(a1
, a2
, a3
, a4
));
160 template<typename P1
, typename P2
, typename P3
, typename P4
>
161 struct Invoker
<void, P1
, P2
, P3
, P4
, void, void> {
162 inline static void Go(
164 const base::Callback
<void(P1
, P2
, P3
, P4
)>& callback
,
169 callback
.Run(a1
, a2
, a3
, a4
);
173 template<typename R
, typename P1
, typename P2
, typename P3
>
174 struct Invoker
<R
, P1
, P2
, P3
, void, void, void> {
175 inline static void Go(
177 const base::Callback
<R(P1
, P2
, P3
)>& callback
,
181 args
->Return(callback
.Run(a1
, a2
, a3
));
184 template<typename P1
, typename P2
, typename P3
>
185 struct Invoker
<void, P1
, P2
, P3
, void, void, void> {
186 inline static void Go(
188 const base::Callback
<void(P1
, P2
, P3
)>& callback
,
192 callback
.Run(a1
, a2
, a3
);
196 template<typename R
, typename P1
, typename P2
>
197 struct Invoker
<R
, P1
, P2
, void, void, void, void> {
198 inline static void Go(
200 const base::Callback
<R(P1
, P2
)>& callback
,
203 args
->Return(callback
.Run(a1
, a2
));
206 template<typename P1
, typename P2
>
207 struct Invoker
<void, P1
, P2
, void, void, void, void> {
208 inline static void Go(
210 const base::Callback
<void(P1
, P2
)>& callback
,
213 callback
.Run(a1
, a2
);
217 template<typename R
, typename P1
>
218 struct Invoker
<R
, P1
, void, void, void, void, void> {
219 inline static void Go(
221 const base::Callback
<R(P1
)>& callback
,
223 args
->Return(callback
.Run(a1
));
226 template<typename P1
>
227 struct Invoker
<void, P1
, void, void, void, void, void> {
228 inline static void Go(
230 const base::Callback
<void(P1
)>& callback
,
237 struct Invoker
<R
, void, void, void, void, void, void> {
238 inline static void Go(
240 const base::Callback
<R()>& callback
) {
241 args
->Return(callback
.Run());
245 struct Invoker
<void, void, void, void, void, void, void> {
246 inline static void Go(
248 const base::Callback
<void()>& callback
) {
255 bool GetNextArgument(Arguments
* args
, int create_flags
, bool is_first
,
257 if (is_first
&& (create_flags
& HolderIsFirstArgument
) != 0) {
258 return args
->GetHolder(result
);
260 return args
->GetNext(result
);
264 // For advanced use cases, we allow callers to request the unparsed Arguments
265 // object and poke around in it directly.
266 inline bool GetNextArgument(Arguments
* args
, int create_flags
, bool is_first
,
271 inline bool GetNextArgument(Arguments
* args
, int create_flags
, bool is_first
,
272 Arguments
** result
) {
277 // It's common for clients to just need the isolate, so we make that easy.
278 inline bool GetNextArgument(Arguments
* args
, int create_flags
,
279 bool is_first
, v8::Isolate
** result
) {
280 *result
= args
->isolate();
285 // DispatchToCallback converts all the JavaScript arguments to C++ types and
286 // invokes the base::Callback.
287 template<typename Sig
>
292 struct Dispatcher
<R()> {
293 static void DispatchToCallback(
294 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
295 Arguments
args(info
);
296 CallbackHolderBase
* holder_base
= NULL
;
297 CHECK(args
.GetData(&holder_base
));
299 typedef CallbackHolder
<R()> HolderT
;
300 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
302 Invoker
<R
>::Go(&args
, holder
->callback
);
306 template<typename R
, typename P1
>
307 struct Dispatcher
<R(P1
)> {
308 static void DispatchToCallback(
309 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
310 Arguments
args(info
);
311 CallbackHolderBase
* holder_base
= NULL
;
312 CHECK(args
.GetData(&holder_base
));
314 typedef CallbackHolder
<R(P1
)> HolderT
;
315 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
317 typename CallbackParamTraits
<P1
>::LocalType a1
;
318 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
)) {
323 Invoker
<R
, P1
>::Go(&args
, holder
->callback
, a1
);
327 template<typename R
, typename P1
, typename P2
>
328 struct Dispatcher
<R(P1
, P2
)> {
329 static void DispatchToCallback(
330 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
331 Arguments
args(info
);
332 CallbackHolderBase
* holder_base
= NULL
;
333 CHECK(args
.GetData(&holder_base
));
335 typedef CallbackHolder
<R(P1
, P2
)> HolderT
;
336 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
338 typename CallbackParamTraits
<P1
>::LocalType a1
;
339 typename CallbackParamTraits
<P2
>::LocalType a2
;
340 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
341 !GetNextArgument(&args
, holder
->flags
, false, &a2
)) {
346 Invoker
<R
, P1
, P2
>::Go(&args
, holder
->callback
, a1
, a2
);
350 template<typename R
, typename P1
, typename P2
, typename P3
>
351 struct Dispatcher
<R(P1
, P2
, P3
)> {
352 static void DispatchToCallback(
353 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
354 Arguments
args(info
);
355 CallbackHolderBase
* holder_base
= NULL
;
356 CHECK(args
.GetData(&holder_base
));
358 typedef CallbackHolder
<R(P1
, P2
, P3
)> HolderT
;
359 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
361 typename CallbackParamTraits
<P1
>::LocalType a1
;
362 typename CallbackParamTraits
<P2
>::LocalType a2
;
363 typename CallbackParamTraits
<P3
>::LocalType a3
;
364 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
365 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
366 !GetNextArgument(&args
, holder
->flags
, false, &a3
)) {
371 Invoker
<R
, P1
, P2
, P3
>::Go(&args
, holder
->callback
, a1
, a2
, a3
);
375 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
>
376 struct Dispatcher
<R(P1
, P2
, P3
, P4
)> {
377 static void DispatchToCallback(
378 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
379 Arguments
args(info
);
380 CallbackHolderBase
* holder_base
= NULL
;
381 CHECK(args
.GetData(&holder_base
));
383 typedef CallbackHolder
<R(P1
, P2
, P3
, P4
)> HolderT
;
384 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
386 typename CallbackParamTraits
<P1
>::LocalType a1
;
387 typename CallbackParamTraits
<P2
>::LocalType a2
;
388 typename CallbackParamTraits
<P3
>::LocalType a3
;
389 typename CallbackParamTraits
<P4
>::LocalType a4
;
390 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
391 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
392 !GetNextArgument(&args
, holder
->flags
, false, &a3
) ||
393 !GetNextArgument(&args
, holder
->flags
, false, &a4
)) {
398 Invoker
<R
, P1
, P2
, P3
, P4
>::Go(&args
, holder
->callback
, a1
, a2
, a3
, a4
);
402 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
,
404 struct Dispatcher
<R(P1
, P2
, P3
, P4
, P5
)> {
405 static void DispatchToCallback(
406 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
407 Arguments
args(info
);
408 CallbackHolderBase
* holder_base
= NULL
;
409 CHECK(args
.GetData(&holder_base
));
411 typedef CallbackHolder
<R(P1
, P2
, P3
, P4
, P5
)> HolderT
;
412 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
414 typename CallbackParamTraits
<P1
>::LocalType a1
;
415 typename CallbackParamTraits
<P2
>::LocalType a2
;
416 typename CallbackParamTraits
<P3
>::LocalType a3
;
417 typename CallbackParamTraits
<P4
>::LocalType a4
;
418 typename CallbackParamTraits
<P5
>::LocalType a5
;
419 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
420 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
421 !GetNextArgument(&args
, holder
->flags
, false, &a3
) ||
422 !GetNextArgument(&args
, holder
->flags
, false, &a4
) ||
423 !GetNextArgument(&args
, holder
->flags
, false, &a5
)) {
428 Invoker
<R
, P1
, P2
, P3
, P4
, P5
>::Go(&args
, holder
->callback
, a1
, a2
, a3
, a4
,
433 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
,
434 typename P5
, typename P6
>
435 struct Dispatcher
<R(P1
, P2
, P3
, P4
, P5
, P6
)> {
436 static void DispatchToCallback(
437 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
438 Arguments
args(info
);
439 CallbackHolderBase
* holder_base
= NULL
;
440 CHECK(args
.GetData(&holder_base
));
442 typedef CallbackHolder
<R(P1
, P2
, P3
, P4
, P5
, P6
)> HolderT
;
443 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
445 typename CallbackParamTraits
<P1
>::LocalType a1
;
446 typename CallbackParamTraits
<P2
>::LocalType a2
;
447 typename CallbackParamTraits
<P3
>::LocalType a3
;
448 typename CallbackParamTraits
<P4
>::LocalType a4
;
449 typename CallbackParamTraits
<P5
>::LocalType a5
;
450 typename CallbackParamTraits
<P6
>::LocalType a6
;
451 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
452 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
453 !GetNextArgument(&args
, holder
->flags
, false, &a3
) ||
454 !GetNextArgument(&args
, holder
->flags
, false, &a4
) ||
455 !GetNextArgument(&args
, holder
->flags
, false, &a5
) ||
456 !GetNextArgument(&args
, holder
->flags
, false, &a6
)) {
461 Invoker
<R
, P1
, P2
, P3
, P4
, P5
, P6
>::Go(&args
, holder
->callback
, a1
, a2
, a3
,
466 } // namespace internal
469 // CreateFunctionTemplate creates a v8::FunctionTemplate that will create
470 // JavaScript functions that execute a provided C++ function or base::Callback.
471 // JavaScript arguments are automatically converted via gin::Converter, as is
472 // the return value of the C++ function, if any.
473 template<typename Sig
>
474 v8::Local
<v8::FunctionTemplate
> CreateFunctionTemplate(
475 v8::Isolate
* isolate
, const base::Callback
<Sig
> callback
,
476 int callback_flags
= 0) {
477 typedef internal::CallbackHolder
<Sig
> HolderT
;
478 gin::Handle
<HolderT
> holder
= CreateHandle(
479 isolate
, new HolderT(callback
, callback_flags
));
480 return v8::FunctionTemplate::New(
482 &internal::Dispatcher
<Sig
>::DispatchToCallback
,
483 ConvertToV8
<internal::CallbackHolderBase
*>(isolate
, holder
.get()));
488 #endif // GIN_FUNCTION_TEMPLATE_H_