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/public/gin_embedders.h"
19 #include "gin/public/wrapper_info.h"
20 #include "gin/wrappable.h"
22 #include "v8/include/v8.h"
31 struct RemoveConstRef
{
35 struct RemoveConstRef
<const T
&> {
40 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
41 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
42 // DispatchToCallback, where it is invoked.
44 // v8::FunctionTemplate only supports passing void* as data so how do we know
45 // when to delete the base::Callback? That's where CallbackHolderBase comes in.
46 // It inherits from Wrappable, which delete itself when both (a) the refcount
47 // via base::RefCounted has dropped to zero, and (b) there are no more
48 // JavaScript references in V8.
49 class CallbackHolderBase
: public Wrappable
{
51 virtual WrapperInfo
* GetWrapperInfo() OVERRIDE
;
52 static WrapperInfo kWrapperInfo
;
54 virtual ~CallbackHolderBase() {}
57 template<typename Sig
>
58 class CallbackHolder
: public CallbackHolderBase
{
60 CallbackHolder(const base::Callback
<Sig
>& callback
)
61 : callback(callback
) {}
62 base::Callback
<Sig
> callback
;
64 virtual ~CallbackHolder() {}
68 // This set of templates invokes a base::Callback, converts the return type to a
69 // JavaScript value, and returns that value to script via the provided
70 // gin::Arguments object.
72 // In C++, you can declare the function foo(void), but you can't pass a void
73 // expression to foo. As a result, we must specialize the case of Callbacks that
74 // have the void return type.
75 template<typename R
, typename P1
= void, typename P2
= void,
76 typename P3
= void, typename P4
= void>
78 inline static void Go(
80 const base::Callback
<R(P1
, P2
, P3
, P4
)>& callback
,
85 args
->Return(callback
.Run(a1
, a2
, a3
, a4
));
88 template<typename P1
, typename P2
, typename P3
, typename P4
>
89 struct Invoker
<void, P1
, P2
, P3
, P4
> {
90 inline static void Go(
92 const base::Callback
<void(P1
, P2
, P3
, P4
)>& callback
,
97 callback
.Run(a1
, a2
, a3
, a4
);
101 template<typename R
, typename P1
, typename P2
, typename P3
>
102 struct Invoker
<R
, P1
, P2
, P3
, void> {
103 inline static void Go(
105 const base::Callback
<R(P1
, P2
, P3
)>& callback
,
109 args
->Return(callback
.Run(a1
, a2
, a3
));
112 template<typename P1
, typename P2
, typename P3
>
113 struct Invoker
<void, P1
, P2
, P3
, void> {
114 inline static void Go(
116 const base::Callback
<void(P1
, P2
, P3
)>& callback
,
120 callback
.Run(a1
, a2
, a3
);
124 template<typename R
, typename P1
, typename P2
>
125 struct Invoker
<R
, P1
, P2
, void, void> {
126 inline static void Go(
128 const base::Callback
<R(P1
, P2
)>& callback
,
131 args
->Return(callback
.Run(a1
, a2
));
134 template<typename P1
, typename P2
>
135 struct Invoker
<void, P1
, P2
, void, void> {
136 inline static void Go(
138 const base::Callback
<void(P1
, P2
)>& callback
,
141 callback
.Run(a1
, a2
);
145 template<typename R
, typename P1
>
146 struct Invoker
<R
, P1
, void, void, void> {
147 inline static void Go(
149 const base::Callback
<R(P1
)>& callback
,
151 args
->Return(callback
.Run(a1
));
154 template<typename P1
>
155 struct Invoker
<void, P1
, void, void, void> {
156 inline static void Go(
158 const base::Callback
<void(P1
)>& callback
,
165 struct Invoker
<R
, void, void, void, void> {
166 inline static void Go(
168 const base::Callback
<R()>& callback
) {
169 args
->Return(callback
.Run());
173 struct Invoker
<void, void, void, void, void> {
174 inline static void Go(
176 const base::Callback
<void()>& callback
) {
182 // DispatchToCallback converts all the JavaScript arguments to C++ types and
183 // invokes the base::Callback.
185 static void DispatchToCallback(
186 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
187 Arguments
args(info
);
188 CallbackHolderBase
* holder_base
= NULL
;
189 CHECK(args
.GetData(&holder_base
));
191 typedef CallbackHolder
<R()> HolderT
;
192 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
194 Invoker
<R
>::Go(&args
, holder
->callback
);
197 template<typename R
, typename P1
>
198 static void DispatchToCallback(
199 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
200 Arguments
args(info
);
201 CallbackHolderBase
* holder_base
= NULL
;
202 CHECK(args
.GetData(&holder_base
));
204 typedef CallbackHolder
<R(P1
)> HolderT
;
205 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
207 typename RemoveConstRef
<P1
>::Type a1
;
208 if (!args
.GetNext(&a1
)) {
213 Invoker
<R
, P1
>::Go(&args
, holder
->callback
, a1
);
216 template<typename R
, typename P1
, typename P2
>
217 static void DispatchToCallback(
218 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
219 Arguments
args(info
);
220 CallbackHolderBase
* holder_base
= NULL
;
221 CHECK(args
.GetData(&holder_base
));
223 typedef CallbackHolder
<R(P1
, P2
)> HolderT
;
224 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
226 typename RemoveConstRef
<P1
>::Type a1
;
227 typename RemoveConstRef
<P2
>::Type a2
;
228 if (!args
.GetNext(&a1
) ||
229 !args
.GetNext(&a2
)) {
234 Invoker
<R
, P1
, P2
>::Go(&args
, holder
->callback
, a1
, a2
);
237 template<typename R
, typename P1
, typename P2
, typename P3
>
238 static void DispatchToCallback(
239 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
240 Arguments
args(info
);
241 CallbackHolderBase
* holder_base
= NULL
;
242 CHECK(args
.GetData(&holder_base
));
244 typedef CallbackHolder
<R(P1
, P2
, P3
)> HolderT
;
245 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
247 typename RemoveConstRef
<P1
>::Type a1
;
248 typename RemoveConstRef
<P2
>::Type a2
;
249 typename RemoveConstRef
<P3
>::Type a3
;
250 if (!args
.GetNext(&a1
) ||
251 !args
.GetNext(&a2
) ||
252 !args
.GetNext(&a3
)) {
257 Invoker
<R
, P1
, P2
, P3
>::Go(&args
, holder
->callback
, a1
, a2
, a3
);
260 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
>
261 static void DispatchToCallback(
262 const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
263 Arguments
args(info
);
264 CallbackHolderBase
* holder_base
= NULL
;
265 CHECK(args
.GetData(&holder_base
));
267 typedef CallbackHolder
<R(P1
, P2
, P3
, P4
)> HolderT
;
268 HolderT
* holder
= static_cast<HolderT
*>(holder_base
);
270 typename RemoveConstRef
<P1
>::Type a1
;
271 typename RemoveConstRef
<P2
>::Type a2
;
272 typename RemoveConstRef
<P3
>::Type a3
;
273 typename RemoveConstRef
<P4
>::Type a4
;
274 if (!args
.GetNext(&a1
) ||
275 !args
.GetNext(&a2
) ||
276 !args
.GetNext(&a3
) ||
277 !args
.GetNext(&a4
)) {
282 Invoker
<R
, P1
, P2
, P3
, P4
>::Go(&args
, holder
->callback
, a1
, a2
, a3
, a4
);
285 } // namespace internal
288 // This should be called once per-isolate to initialize the function template
290 void InitFunctionTemplates(PerIsolateData
* isolate_data
);
293 // This has to be outside the internal namespace because template
294 // specializations must be declared in the same namespace as the original
297 struct Converter
<internal::CallbackHolderBase
*>
298 : public WrappableConverter
<internal::CallbackHolderBase
> {};
301 // Creates a v8::FunctionTemplate that will run the provided base::Callback each
302 // time it is called. JavaScript arguments and return values are converted via
305 v8::Local
<v8::FunctionTemplate
> CreateFunctionTemplate(
306 v8::Isolate
* isolate
,
307 const base::Callback
<R()> callback
) {
308 typedef internal::CallbackHolder
<R()> HolderT
;
309 scoped_refptr
<HolderT
> holder(new HolderT(callback
));
310 return v8::FunctionTemplate::New(
311 &internal::DispatchToCallback
<R
>,
312 ConvertToV8
<internal::CallbackHolderBase
*>(isolate
, holder
.get()));
315 template<typename R
, typename P1
>
316 v8::Local
<v8::FunctionTemplate
> CreateFunctionTemplate(
317 v8::Isolate
* isolate
,
318 const base::Callback
<R(P1
)> callback
) {
319 typedef internal::CallbackHolder
<R(P1
)> HolderT
;
320 scoped_refptr
<HolderT
> holder(new HolderT(callback
));
321 return v8::FunctionTemplate::New(
322 &internal::DispatchToCallback
<R
, P1
>,
323 ConvertToV8
<internal::CallbackHolderBase
*>(isolate
, holder
.get()));
326 template<typename R
, typename P1
, typename P2
>
327 v8::Local
<v8::FunctionTemplate
> CreateFunctionTemplate(
328 v8::Isolate
* isolate
,
329 const base::Callback
<R(P1
, P2
)> callback
) {
330 typedef internal::CallbackHolder
<R(P1
, P2
)> HolderT
;
331 scoped_refptr
<HolderT
> holder(new HolderT(callback
));
332 return v8::FunctionTemplate::New(
333 &internal::DispatchToCallback
<R
, P1
, P2
>,
334 ConvertToV8
<internal::CallbackHolderBase
*>(isolate
, holder
.get()));
337 template<typename R
, typename P1
, typename P2
, typename P3
>
338 v8::Local
<v8::FunctionTemplate
> CreateFunctionTemplate(
339 v8::Isolate
* isolate
,
340 const base::Callback
<R(P1
, P2
, P3
)> callback
) {
341 typedef internal::CallbackHolder
<R(P1
, P2
, P3
)> HolderT
;
342 scoped_refptr
<HolderT
> holder(new HolderT(callback
));
343 return v8::FunctionTemplate::New(
344 &internal::DispatchToCallback
<R
, P1
, P2
, P3
>,
345 ConvertToV8
<internal::CallbackHolderBase
*>(isolate
, holder
.get()));
348 template<typename R
, typename P1
, typename P2
, typename P3
, typename P4
>
349 v8::Local
<v8::FunctionTemplate
> CreateFunctionTemplate(
350 v8::Isolate
* isolate
,
351 const base::Callback
<R(P1
, P2
, P3
, P4
)> callback
) {
352 typedef internal::CallbackHolder
<R(P1
, P2
, P3
, P4
)> HolderT
;
353 scoped_refptr
<HolderT
> holder(new HolderT(callback
));
354 return v8::FunctionTemplate::New(
355 &internal::DispatchToCallback
<R
, P1
, P2
, P3
, P4
>,
356 ConvertToV8
<internal::CallbackHolderBase
*>(isolate
, holder
.get()));
361 #endif // GIN_FUNCTION_TEMPLATE_H_