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 "v8/include/v8.h"
25 enum CreateFunctionTemplateFlags
{
26 HolderIsFirstArgument
= 1 << 0,
32 struct CallbackParamTraits
{
36 struct CallbackParamTraits
<const T
&> {
40 struct CallbackParamTraits
<const T
*> {
45 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
46 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
47 // DispatchToCallback, where it is invoked.
49 // This simple base class is used so that we can share a single object template
50 // among every CallbackHolder instance.
51 class GIN_EXPORT CallbackHolderBase
{
53 v8::Handle
<v8::External
> GetHandle(v8::Isolate
* isolate
);
56 explicit CallbackHolderBase(v8::Isolate
* isolate
);
57 virtual ~CallbackHolderBase();
60 static void WeakCallback(
61 const v8::WeakCallbackData
<v8::External
, CallbackHolderBase
>& data
);
63 v8::Persistent
<v8::External
> v8_ref_
;
65 DISALLOW_COPY_AND_ASSIGN(CallbackHolderBase
);
68 template<typename Sig
>
69 class CallbackHolder
: public CallbackHolderBase
{
71 CallbackHolder(v8::Isolate
* isolate
,
72 const base::Callback
<Sig
>& callback
,
74 : CallbackHolderBase(isolate
), callback(callback
), flags(flags
) {}
75 base::Callback
<Sig
> callback
;
78 virtual ~CallbackHolder() {}
80 DISALLOW_COPY_AND_ASSIGN(CallbackHolder
);
84 // This set of templates invokes a base::Callback, converts the return type to a
85 // JavaScript value, and returns that value to script via the provided
86 // gin::Arguments object.
88 // In C++, you can declare the function foo(void), but you can't pass a void
89 // expression to foo. As a result, we must specialize the case of Callbacks that
90 // have the void return type.
91 template<typename R
, typename P1
= void, typename P2
= void,
92 typename P3
= void, typename P4
= void, typename P5
= void,
95 inline static void Go(
97 const base::Callback
<R(P1
, P2
, P3
, P4
, P5
, P6
)>& callback
,
104 args
->Return(callback
.Run(a1
, a2
, a3
, a4
, a5
, a6
));
107 template<typename P1
, typename P2
, typename P3
, typename P4
, typename P5
,
109 struct Invoker
<void, P1
, P2
, P3
, P4
, P5
, P6
> {
110 inline static void Go(
112 const base::Callback
<void(P1
, P2
, P3
, P4
, P5
, P6
)>& callback
,
119 callback
.Run(a1
, a2
, a3
, a4
, a5
, a6
);
123 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
,
125 struct Invoker
<R
, P1
, P2
, P3
, P4
, P5
, void> {
126 inline static void Go(
128 const base::Callback
<R(P1
, P2
, P3
, P4
, P5
)>& callback
,
134 args
->Return(callback
.Run(a1
, a2
, a3
, a4
, a5
));
137 template<typename P1
, typename P2
, typename P3
, typename P4
, typename P5
>
138 struct Invoker
<void, P1
, P2
, P3
, P4
, P5
, void> {
139 inline static void Go(
141 const base::Callback
<void(P1
, P2
, P3
, P4
, P5
)>& callback
,
147 callback
.Run(a1
, a2
, a3
, a4
, a5
);
151 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
>
152 struct Invoker
<R
, P1
, P2
, P3
, P4
, void, void> {
153 inline static void Go(
155 const base::Callback
<R(P1
, P2
, P3
, P4
)>& callback
,
160 args
->Return(callback
.Run(a1
, a2
, a3
, a4
));
163 template<typename P1
, typename P2
, typename P3
, typename P4
>
164 struct Invoker
<void, P1
, P2
, P3
, P4
, void, void> {
165 inline static void Go(
167 const base::Callback
<void(P1
, P2
, P3
, P4
)>& callback
,
172 callback
.Run(a1
, a2
, a3
, a4
);
176 template<typename R
, typename P1
, typename P2
, typename P3
>
177 struct Invoker
<R
, P1
, P2
, P3
, void, void, void> {
178 inline static void Go(
180 const base::Callback
<R(P1
, P2
, P3
)>& callback
,
184 args
->Return(callback
.Run(a1
, a2
, a3
));
187 template<typename P1
, typename P2
, typename P3
>
188 struct Invoker
<void, P1
, P2
, P3
, void, void, void> {
189 inline static void Go(
191 const base::Callback
<void(P1
, P2
, P3
)>& callback
,
195 callback
.Run(a1
, a2
, a3
);
199 template<typename R
, typename P1
, typename P2
>
200 struct Invoker
<R
, P1
, P2
, void, void, void, void> {
201 inline static void Go(
203 const base::Callback
<R(P1
, P2
)>& callback
,
206 args
->Return(callback
.Run(a1
, a2
));
209 template<typename P1
, typename P2
>
210 struct Invoker
<void, P1
, P2
, void, void, void, void> {
211 inline static void Go(
213 const base::Callback
<void(P1
, P2
)>& callback
,
216 callback
.Run(a1
, a2
);
220 template<typename R
, typename P1
>
221 struct Invoker
<R
, P1
, void, void, void, void, void> {
222 inline static void Go(
224 const base::Callback
<R(P1
)>& callback
,
226 args
->Return(callback
.Run(a1
));
229 template<typename P1
>
230 struct Invoker
<void, P1
, void, void, void, void, void> {
231 inline static void Go(
233 const base::Callback
<void(P1
)>& callback
,
240 struct Invoker
<R
, void, void, void, void, void, void> {
241 inline static void Go(
243 const base::Callback
<R()>& callback
) {
244 args
->Return(callback
.Run());
248 struct Invoker
<void, void, void, void, void, void, void> {
249 inline static void Go(
251 const base::Callback
<void()>& callback
) {
258 bool GetNextArgument(Arguments
* args
, int create_flags
, bool is_first
,
260 if (is_first
&& (create_flags
& HolderIsFirstArgument
) != 0) {
261 return args
->GetHolder(result
);
263 return args
->GetNext(result
);
267 // For advanced use cases, we allow callers to request the unparsed Arguments
268 // object and poke around in it directly.
269 inline bool GetNextArgument(Arguments
* args
, int create_flags
, bool is_first
,
274 inline bool GetNextArgument(Arguments
* args
, int create_flags
, bool is_first
,
275 Arguments
** result
) {
280 // It's common for clients to just need the isolate, so we make that easy.
281 inline bool GetNextArgument(Arguments
* args
, int create_flags
,
282 bool is_first
, v8::Isolate
** result
) {
283 *result
= args
->isolate();
288 // DispatchToCallback converts all the JavaScript arguments to C++ types and
289 // invokes the base::Callback.
290 template<typename Sig
>
295 struct Dispatcher
<R()> {
296 static void DispatchToCallback(
297 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
298 Arguments
args(info
);
299 v8::Handle
<v8::External
> v8_holder
;
300 CHECK(args
.GetData(&v8_holder
));
301 CallbackHolderBase
* holder_base
= reinterpret_cast<CallbackHolderBase
*>(
304 typedef CallbackHolder
<R()> HolderT
;
305 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
307 Invoker
<R
>::Go(&args
, holder
->callback
);
311 template<typename R
, typename P1
>
312 struct Dispatcher
<R(P1
)> {
313 static void DispatchToCallback(
314 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
315 Arguments
args(info
);
316 v8::Handle
<v8::External
> v8_holder
;
317 CHECK(args
.GetData(&v8_holder
));
318 CallbackHolderBase
* holder_base
= reinterpret_cast<CallbackHolderBase
*>(
321 typedef CallbackHolder
<R(P1
)> HolderT
;
322 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
324 typename CallbackParamTraits
<P1
>::LocalType a1
;
325 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
)) {
330 Invoker
<R
, P1
>::Go(&args
, holder
->callback
, a1
);
334 template<typename R
, typename P1
, typename P2
>
335 struct Dispatcher
<R(P1
, P2
)> {
336 static void DispatchToCallback(
337 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
338 Arguments
args(info
);
339 v8::Handle
<v8::External
> v8_holder
;
340 CHECK(args
.GetData(&v8_holder
));
341 CallbackHolderBase
* holder_base
= reinterpret_cast<CallbackHolderBase
*>(
344 typedef CallbackHolder
<R(P1
, P2
)> HolderT
;
345 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
347 typename CallbackParamTraits
<P1
>::LocalType a1
;
348 typename CallbackParamTraits
<P2
>::LocalType a2
;
349 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
350 !GetNextArgument(&args
, holder
->flags
, false, &a2
)) {
355 Invoker
<R
, P1
, P2
>::Go(&args
, holder
->callback
, a1
, a2
);
359 template<typename R
, typename P1
, typename P2
, typename P3
>
360 struct Dispatcher
<R(P1
, P2
, P3
)> {
361 static void DispatchToCallback(
362 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
363 Arguments
args(info
);
364 v8::Handle
<v8::External
> v8_holder
;
365 CHECK(args
.GetData(&v8_holder
));
366 CallbackHolderBase
* holder_base
= reinterpret_cast<CallbackHolderBase
*>(
369 typedef CallbackHolder
<R(P1
, P2
, P3
)> HolderT
;
370 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
372 typename CallbackParamTraits
<P1
>::LocalType a1
;
373 typename CallbackParamTraits
<P2
>::LocalType a2
;
374 typename CallbackParamTraits
<P3
>::LocalType a3
;
375 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
376 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
377 !GetNextArgument(&args
, holder
->flags
, false, &a3
)) {
382 Invoker
<R
, P1
, P2
, P3
>::Go(&args
, holder
->callback
, a1
, a2
, a3
);
386 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
>
387 struct Dispatcher
<R(P1
, P2
, P3
, P4
)> {
388 static void DispatchToCallback(
389 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
390 Arguments
args(info
);
391 v8::Handle
<v8::External
> v8_holder
;
392 CHECK(args
.GetData(&v8_holder
));
393 CallbackHolderBase
* holder_base
= reinterpret_cast<CallbackHolderBase
*>(
396 typedef CallbackHolder
<R(P1
, P2
, P3
, P4
)> HolderT
;
397 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
399 typename CallbackParamTraits
<P1
>::LocalType a1
;
400 typename CallbackParamTraits
<P2
>::LocalType a2
;
401 typename CallbackParamTraits
<P3
>::LocalType a3
;
402 typename CallbackParamTraits
<P4
>::LocalType a4
;
403 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
404 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
405 !GetNextArgument(&args
, holder
->flags
, false, &a3
) ||
406 !GetNextArgument(&args
, holder
->flags
, false, &a4
)) {
411 Invoker
<R
, P1
, P2
, P3
, P4
>::Go(&args
, holder
->callback
, a1
, a2
, a3
, a4
);
415 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
,
417 struct Dispatcher
<R(P1
, P2
, P3
, P4
, P5
)> {
418 static void DispatchToCallback(
419 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
420 Arguments
args(info
);
421 v8::Handle
<v8::External
> v8_holder
;
422 CHECK(args
.GetData(&v8_holder
));
423 CallbackHolderBase
* holder_base
= reinterpret_cast<CallbackHolderBase
*>(
426 typedef CallbackHolder
<R(P1
, P2
, P3
, P4
, P5
)> HolderT
;
427 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
429 typename CallbackParamTraits
<P1
>::LocalType a1
;
430 typename CallbackParamTraits
<P2
>::LocalType a2
;
431 typename CallbackParamTraits
<P3
>::LocalType a3
;
432 typename CallbackParamTraits
<P4
>::LocalType a4
;
433 typename CallbackParamTraits
<P5
>::LocalType a5
;
434 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
435 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
436 !GetNextArgument(&args
, holder
->flags
, false, &a3
) ||
437 !GetNextArgument(&args
, holder
->flags
, false, &a4
) ||
438 !GetNextArgument(&args
, holder
->flags
, false, &a5
)) {
443 Invoker
<R
, P1
, P2
, P3
, P4
, P5
>::Go(&args
, holder
->callback
, a1
, a2
, a3
, a4
,
448 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
,
449 typename P5
, typename P6
>
450 struct Dispatcher
<R(P1
, P2
, P3
, P4
, P5
, P6
)> {
451 static void DispatchToCallback(
452 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
453 Arguments
args(info
);
454 v8::Handle
<v8::External
> v8_holder
;
455 CHECK(args
.GetData(&v8_holder
));
456 CallbackHolderBase
* holder_base
= reinterpret_cast<CallbackHolderBase
*>(
459 typedef CallbackHolder
<R(P1
, P2
, P3
, P4
, P5
, P6
)> HolderT
;
460 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
462 typename CallbackParamTraits
<P1
>::LocalType a1
;
463 typename CallbackParamTraits
<P2
>::LocalType a2
;
464 typename CallbackParamTraits
<P3
>::LocalType a3
;
465 typename CallbackParamTraits
<P4
>::LocalType a4
;
466 typename CallbackParamTraits
<P5
>::LocalType a5
;
467 typename CallbackParamTraits
<P6
>::LocalType a6
;
468 if (!GetNextArgument(&args
, holder
->flags
, true, &a1
) ||
469 !GetNextArgument(&args
, holder
->flags
, false, &a2
) ||
470 !GetNextArgument(&args
, holder
->flags
, false, &a3
) ||
471 !GetNextArgument(&args
, holder
->flags
, false, &a4
) ||
472 !GetNextArgument(&args
, holder
->flags
, false, &a5
) ||
473 !GetNextArgument(&args
, holder
->flags
, false, &a6
)) {
478 Invoker
<R
, P1
, P2
, P3
, P4
, P5
, P6
>::Go(&args
, holder
->callback
, a1
, a2
, a3
,
483 } // namespace internal
486 // CreateFunctionTemplate creates a v8::FunctionTemplate that will create
487 // JavaScript functions that execute a provided C++ function or base::Callback.
488 // JavaScript arguments are automatically converted via gin::Converter, as is
489 // the return value of the C++ function, if any.
490 template<typename Sig
>
491 v8::Local
<v8::FunctionTemplate
> CreateFunctionTemplate(
492 v8::Isolate
* isolate
, const base::Callback
<Sig
> callback
,
493 int callback_flags
= 0) {
494 typedef internal::CallbackHolder
<Sig
> HolderT
;
495 HolderT
* holder
= new HolderT(isolate
, callback
, callback_flags
);
497 return v8::FunctionTemplate::New(
499 &internal::Dispatcher
<Sig
>::DispatchToCallback
,
500 ConvertToV8
<v8::Handle
<v8::External
> >(isolate
,
501 holder
->GetHandle(isolate
)));
504 // CreateFunctionHandler installs a CallAsFunction handler on the given
505 // object template that forwards to a provided C++ function or base::Callback.
506 template<typename Sig
>
507 void CreateFunctionHandler(v8::Isolate
* isolate
,
508 v8::Local
<v8::ObjectTemplate
> tmpl
,
509 const base::Callback
<Sig
> callback
,
510 int callback_flags
= 0) {
511 typedef internal::CallbackHolder
<Sig
> HolderT
;
512 HolderT
* holder
= new HolderT(isolate
, callback
, callback_flags
);
513 tmpl
->SetCallAsFunctionHandler(&internal::Dispatcher
<Sig
>::DispatchToCallback
,
514 ConvertToV8
<v8::Handle
<v8::External
> >(
515 isolate
, holder
->GetHandle(isolate
)));
520 #endif // GIN_FUNCTION_TEMPLATE_H_