Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / gin / function_template.h
blob7ba54b5910ef4ffcb032deba86a8490a0fba72ef
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"
21 namespace gin {
23 class PerIsolateData;
25 enum CreateFunctionTemplateFlags {
26 HolderIsFirstArgument = 1 << 0,
29 namespace internal {
31 template<typename T>
32 struct CallbackParamTraits {
33 typedef T LocalType;
35 template<typename T>
36 struct CallbackParamTraits<const T&> {
37 typedef T LocalType;
39 template<typename T>
40 struct CallbackParamTraits<const T*> {
41 typedef T* LocalType;
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 {
52 public:
53 v8::Handle<v8::External> GetHandle(v8::Isolate* isolate);
55 protected:
56 explicit CallbackHolderBase(v8::Isolate* isolate);
57 virtual ~CallbackHolderBase();
59 private:
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 {
70 public:
71 CallbackHolder(v8::Isolate* isolate,
72 const base::Callback<Sig>& callback,
73 int flags)
74 : CallbackHolderBase(isolate), callback(callback), flags(flags) {}
75 base::Callback<Sig> callback;
76 int flags;
77 private:
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,
93 typename P6 = void>
94 struct Invoker {
95 inline static void Go(
96 Arguments* args,
97 const base::Callback<R(P1, P2, P3, P4, P5, P6)>& callback,
98 const P1& a1,
99 const P2& a2,
100 const P3& a3,
101 const P4& a4,
102 const P5& a5,
103 const P6& a6) {
104 args->Return(callback.Run(a1, a2, a3, a4, a5, a6));
107 template<typename P1, typename P2, typename P3, typename P4, typename P5,
108 typename P6>
109 struct Invoker<void, P1, P2, P3, P4, P5, P6> {
110 inline static void Go(
111 Arguments* args,
112 const base::Callback<void(P1, P2, P3, P4, P5, P6)>& callback,
113 const P1& a1,
114 const P2& a2,
115 const P3& a3,
116 const P4& a4,
117 const P5& a5,
118 const P6& a6) {
119 callback.Run(a1, a2, a3, a4, a5, a6);
123 template<typename R, typename P1, typename P2, typename P3, typename P4,
124 typename P5>
125 struct Invoker<R, P1, P2, P3, P4, P5, void> {
126 inline static void Go(
127 Arguments* args,
128 const base::Callback<R(P1, P2, P3, P4, P5)>& callback,
129 const P1& a1,
130 const P2& a2,
131 const P3& a3,
132 const P4& a4,
133 const P5& a5) {
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(
140 Arguments* args,
141 const base::Callback<void(P1, P2, P3, P4, P5)>& callback,
142 const P1& a1,
143 const P2& a2,
144 const P3& a3,
145 const P4& a4,
146 const P5& a5) {
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(
154 Arguments* args,
155 const base::Callback<R(P1, P2, P3, P4)>& callback,
156 const P1& a1,
157 const P2& a2,
158 const P3& a3,
159 const P4& a4) {
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(
166 Arguments* args,
167 const base::Callback<void(P1, P2, P3, P4)>& callback,
168 const P1& a1,
169 const P2& a2,
170 const P3& a3,
171 const P4& a4) {
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(
179 Arguments* args,
180 const base::Callback<R(P1, P2, P3)>& callback,
181 const P1& a1,
182 const P2& a2,
183 const P3& a3) {
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(
190 Arguments* args,
191 const base::Callback<void(P1, P2, P3)>& callback,
192 const P1& a1,
193 const P2& a2,
194 const P3& a3) {
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(
202 Arguments* args,
203 const base::Callback<R(P1, P2)>& callback,
204 const P1& a1,
205 const P2& a2) {
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(
212 Arguments* args,
213 const base::Callback<void(P1, P2)>& callback,
214 const P1& a1,
215 const P2& a2) {
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(
223 Arguments* args,
224 const base::Callback<R(P1)>& callback,
225 const P1& a1) {
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(
232 Arguments* args,
233 const base::Callback<void(P1)>& callback,
234 const P1& a1) {
235 callback.Run(a1);
239 template<typename R>
240 struct Invoker<R, void, void, void, void, void, void> {
241 inline static void Go(
242 Arguments* args,
243 const base::Callback<R()>& callback) {
244 args->Return(callback.Run());
247 template<>
248 struct Invoker<void, void, void, void, void, void, void> {
249 inline static void Go(
250 Arguments* args,
251 const base::Callback<void()>& callback) {
252 callback.Run();
257 template<typename T>
258 bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
259 T* result) {
260 if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
261 return args->GetHolder(result);
262 } else {
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,
270 Arguments* result) {
271 *result = *args;
272 return true;
274 inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
275 Arguments** result) {
276 *result = args;
277 return true;
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();
284 return true;
288 // DispatchToCallback converts all the JavaScript arguments to C++ types and
289 // invokes the base::Callback.
290 template<typename Sig>
291 struct Dispatcher {
294 template<typename R>
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*>(
302 v8_holder->Value());
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*>(
319 v8_holder->Value());
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)) {
326 args.ThrowError();
327 return;
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*>(
342 v8_holder->Value());
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)) {
351 args.ThrowError();
352 return;
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*>(
367 v8_holder->Value());
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)) {
378 args.ThrowError();
379 return;
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*>(
394 v8_holder->Value());
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)) {
407 args.ThrowError();
408 return;
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,
416 typename P5>
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*>(
424 v8_holder->Value());
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)) {
439 args.ThrowError();
440 return;
443 Invoker<R, P1, P2, P3, P4, P5>::Go(&args, holder->callback, a1, a2, a3, a4,
444 a5);
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*>(
457 v8_holder->Value());
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)) {
474 args.ThrowError();
475 return;
478 Invoker<R, P1, P2, P3, P4, P5, P6>::Go(&args, holder->callback, a1, a2, a3,
479 a4, a5, a6);
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(
498 isolate,
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)));
518 } // namespace gin
520 #endif // GIN_FUNCTION_TEMPLATE_H_