blob: 31f67fa3b3d97bff6b147b2002e761956e429b4b [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]48c21632013-12-12 21:32:3418#include "gin/gin_export.h"
[email protected]d379b0c2013-12-05 05:48:0119#include "gin/handle.h"
[email protected]314cde12013-11-23 20:26:5120#include "gin/public/gin_embedders.h"
21#include "gin/public/wrapper_info.h"
22#include "gin/wrappable.h"
23
24#include "v8/include/v8.h"
25
26namespace gin {
27
28class PerIsolateData;
29
[email protected]bf3dd3c2013-12-06 06:55:2530enum CreateFunctionTemplateFlags {
31 HolderIsFirstArgument = 1 << 0,
32};
33
[email protected]37dacfa2013-11-26 03:31:0434namespace internal {
35
[email protected]314cde12013-11-23 20:26:5136template<typename T>
[email protected]bf3dd3c2013-12-06 06:55:2537struct CallbackParamTraits {
38 typedef T LocalType;
[email protected]314cde12013-11-23 20:26:5139};
40template<typename T>
[email protected]bf3dd3c2013-12-06 06:55:2541struct CallbackParamTraits<const T&> {
42 typedef T LocalType;
43};
44template<typename T>
45struct CallbackParamTraits<const T*> {
46 typedef T* LocalType;
[email protected]314cde12013-11-23 20:26:5147};
48
[email protected]37dacfa2013-11-26 03:31:0449
50// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
51// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
[email protected]81f8b91b2013-11-26 21:02:5152// DispatchToCallback, where it is invoked.
[email protected]37dacfa2013-11-26 03:31:0453//
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.
[email protected]6fe56102013-12-08 07:10:5859
60// This simple base class is used so that we can share a single object template
61// among every CallbackHolder instance.
[email protected]48c21632013-12-12 21:32:3462class GIN_EXPORT CallbackHolderBase : public Wrappable<CallbackHolderBase> {
[email protected]b4acaf82013-12-12 09:40:5063 public:
64 static WrapperInfo kWrapperInfo;
[email protected]d73341d12013-12-21 00:48:4665
[email protected]314cde12013-11-23 20:26:5166 protected:
[email protected]695af7f52013-12-11 19:41:0167 virtual ~CallbackHolderBase() {}
[email protected]314cde12013-11-23 20:26:5168};
69
[email protected]314cde12013-11-23 20:26:5170template<typename Sig>
71class CallbackHolder : public CallbackHolderBase {
72 public:
[email protected]bf3dd3c2013-12-06 06:55:2573 CallbackHolder(const base::Callback<Sig>& callback, int flags)
74 : callback(callback), flags(flags) {}
[email protected]314cde12013-11-23 20:26:5175 base::Callback<Sig> callback;
[email protected]bf3dd3c2013-12-06 06:55:2576 int flags;
[email protected]314cde12013-11-23 20:26:5177 private:
[email protected]695af7f52013-12-11 19:41:0178 virtual ~CallbackHolder() {}
[email protected]314cde12013-11-23 20:26:5179};
80
[email protected]81f8b91b2013-11-26 21:02:5181
82// This set of templates invokes a base::Callback, converts the return type to a
83// JavaScript value, and returns that value to script via the provided
84// gin::Arguments object.
85//
86// In C++, you can declare the function foo(void), but you can't pass a void
87// expression to foo. As a result, we must specialize the case of Callbacks that
88// have the void return type.
[email protected]7618ebbb2013-11-27 03:38:2689template<typename R, typename P1 = void, typename P2 = void,
[email protected]d73341d12013-12-21 00:48:4690 typename P3 = void, typename P4 = void, typename P5 = void,
91 typename P6 = void>
[email protected]81f8b91b2013-11-26 21:02:5192struct Invoker {
93 inline static void Go(
94 Arguments* args,
[email protected]d73341d12013-12-21 00:48:4695 const base::Callback<R(P1, P2, P3, P4, P5, P6)>& callback,
96 const P1& a1,
97 const P2& a2,
98 const P3& a3,
99 const P4& a4,
100 const P5& a5,
101 const P6& a6) {
102 args->Return(callback.Run(a1, a2, a3, a4, a5, a6));
103 }
104};
105template<typename P1, typename P2, typename P3, typename P4, typename P5,
106 typename P6>
107struct Invoker<void, P1, P2, P3, P4, P5, P6> {
108 inline static void Go(
109 Arguments* args,
110 const base::Callback<void(P1, P2, P3, P4, P5, P6)>& callback,
111 const P1& a1,
112 const P2& a2,
113 const P3& a3,
114 const P4& a4,
115 const P5& a5,
116 const P6& a6) {
117 callback.Run(a1, a2, a3, a4, a5, a6);
118 }
119};
120
121template<typename R, typename P1, typename P2, typename P3, typename P4,
122 typename P5>
123struct Invoker<R, P1, P2, P3, P4, P5, void> {
124 inline static void Go(
125 Arguments* args,
126 const base::Callback<R(P1, P2, P3, P4, P5)>& callback,
127 const P1& a1,
128 const P2& a2,
129 const P3& a3,
130 const P4& a4,
131 const P5& a5) {
132 args->Return(callback.Run(a1, a2, a3, a4, a5));
133 }
134};
135template<typename P1, typename P2, typename P3, typename P4, typename P5>
136struct Invoker<void, P1, P2, P3, P4, P5, void> {
137 inline static void Go(
138 Arguments* args,
139 const base::Callback<void(P1, P2, P3, P4, P5)>& callback,
140 const P1& a1,
141 const P2& a2,
142 const P3& a3,
143 const P4& a4,
144 const P5& a5) {
145 callback.Run(a1, a2, a3, a4, a5);
146 }
147};
148
149template<typename R, typename P1, typename P2, typename P3, typename P4>
150struct Invoker<R, P1, P2, P3, P4, void, void> {
151 inline static void Go(
152 Arguments* args,
[email protected]7618ebbb2013-11-27 03:38:26153 const base::Callback<R(P1, P2, P3, P4)>& callback,
154 const P1& a1,
155 const P2& a2,
156 const P3& a3,
157 const P4& a4) {
158 args->Return(callback.Run(a1, a2, a3, a4));
159 }
160};
161template<typename P1, typename P2, typename P3, typename P4>
[email protected]d73341d12013-12-21 00:48:46162struct Invoker<void, P1, P2, P3, P4, void, void> {
[email protected]7618ebbb2013-11-27 03:38:26163 inline static void Go(
164 Arguments* args,
165 const base::Callback<void(P1, P2, P3, P4)>& callback,
166 const P1& a1,
167 const P2& a2,
168 const P3& a3,
169 const P4& a4) {
170 callback.Run(a1, a2, a3, a4);
171 }
172};
173
174template<typename R, typename P1, typename P2, typename P3>
[email protected]d73341d12013-12-21 00:48:46175struct Invoker<R, P1, P2, P3, void, void, void> {
[email protected]7618ebbb2013-11-27 03:38:26176 inline static void Go(
177 Arguments* args,
[email protected]81f8b91b2013-11-26 21:02:51178 const base::Callback<R(P1, P2, P3)>& callback,
179 const P1& a1,
180 const P2& a2,
181 const P3& a3) {
182 args->Return(callback.Run(a1, a2, a3));
183 }
184};
185template<typename P1, typename P2, typename P3>
[email protected]d73341d12013-12-21 00:48:46186struct Invoker<void, P1, P2, P3, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51187 inline static void Go(
188 Arguments* args,
189 const base::Callback<void(P1, P2, P3)>& callback,
190 const P1& a1,
191 const P2& a2,
192 const P3& a3) {
193 callback.Run(a1, a2, a3);
194 }
195};
196
197template<typename R, typename P1, typename P2>
[email protected]d73341d12013-12-21 00:48:46198struct Invoker<R, P1, P2, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51199 inline static void Go(
200 Arguments* args,
201 const base::Callback<R(P1, P2)>& callback,
202 const P1& a1,
203 const P2& a2) {
204 args->Return(callback.Run(a1, a2));
205 }
206};
207template<typename P1, typename P2>
[email protected]d73341d12013-12-21 00:48:46208struct Invoker<void, P1, P2, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51209 inline static void Go(
210 Arguments* args,
211 const base::Callback<void(P1, P2)>& callback,
212 const P1& a1,
213 const P2& a2) {
214 callback.Run(a1, a2);
215 }
216};
217
218template<typename R, typename P1>
[email protected]d73341d12013-12-21 00:48:46219struct Invoker<R, P1, void, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51220 inline static void Go(
221 Arguments* args,
222 const base::Callback<R(P1)>& callback,
223 const P1& a1) {
224 args->Return(callback.Run(a1));
225 }
226};
227template<typename P1>
[email protected]d73341d12013-12-21 00:48:46228struct Invoker<void, P1, void, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51229 inline static void Go(
230 Arguments* args,
231 const base::Callback<void(P1)>& callback,
232 const P1& a1) {
233 callback.Run(a1);
234 }
235};
236
237template<typename R>
[email protected]d73341d12013-12-21 00:48:46238struct Invoker<R, void, void, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51239 inline static void Go(
240 Arguments* args,
241 const base::Callback<R()>& callback) {
242 args->Return(callback.Run());
243 }
244};
245template<>
[email protected]d73341d12013-12-21 00:48:46246struct Invoker<void, void, void, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51247 inline static void Go(
248 Arguments* args,
249 const base::Callback<void()>& callback) {
250 callback.Run();
251 }
252};
253
254
[email protected]bf3dd3c2013-12-06 06:55:25255template<typename T>
256bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
257 T* result) {
258 if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
259 return args->GetHolder(result);
260 } else {
261 return args->GetNext(result);
262 }
263}
264
265// For advanced use cases, we allow callers to request the unparsed Arguments
266// object and poke around in it directly.
267inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
268 Arguments* result) {
269 *result = *args;
270 return true;
271}
272
[email protected]2491f142013-12-21 17:54:37273// It's common for clients to just need the isolate, so we make that easy.
274inline bool GetNextArgument(Arguments* args, int create_flags,
275 bool is_first, v8::Isolate** result) {
276 *result = args->isolate();
277 return true;
278}
279
[email protected]bf3dd3c2013-12-06 06:55:25280
[email protected]81f8b91b2013-11-26 21:02:51281// DispatchToCallback converts all the JavaScript arguments to C++ types and
282// invokes the base::Callback.
[email protected]bf3dd3c2013-12-06 06:55:25283template<typename Sig>
284struct Dispatcher {
285};
286
[email protected]37dacfa2013-11-26 03:31:04287template<typename R>
[email protected]bf3dd3c2013-12-06 06:55:25288struct Dispatcher<R()> {
289 static void DispatchToCallback(
290 const v8::FunctionCallbackInfo<v8::Value>& info) {
291 Arguments args(info);
292 CallbackHolderBase* holder_base = NULL;
293 CHECK(args.GetData(&holder_base));
[email protected]314cde12013-11-23 20:26:51294
[email protected]bf3dd3c2013-12-06 06:55:25295 typedef CallbackHolder<R()> HolderT;
296 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04297
[email protected]bf3dd3c2013-12-06 06:55:25298 Invoker<R>::Go(&args, holder->callback);
299 }
300};
[email protected]37dacfa2013-11-26 03:31:04301
302template<typename R, typename P1>
[email protected]bf3dd3c2013-12-06 06:55:25303struct Dispatcher<R(P1)> {
304 static void DispatchToCallback(
305 const v8::FunctionCallbackInfo<v8::Value>& info) {
306 Arguments args(info);
307 CallbackHolderBase* holder_base = NULL;
308 CHECK(args.GetData(&holder_base));
[email protected]37dacfa2013-11-26 03:31:04309
[email protected]bf3dd3c2013-12-06 06:55:25310 typedef CallbackHolder<R(P1)> HolderT;
311 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04312
[email protected]bf3dd3c2013-12-06 06:55:25313 typename CallbackParamTraits<P1>::LocalType a1;
314 if (!GetNextArgument(&args, holder->flags, true, &a1)) {
315 args.ThrowError();
316 return;
317 }
318
319 Invoker<R, P1>::Go(&args, holder->callback, a1);
[email protected]37dacfa2013-11-26 03:31:04320 }
[email protected]bf3dd3c2013-12-06 06:55:25321};
[email protected]37dacfa2013-11-26 03:31:04322
323template<typename R, typename P1, typename P2>
[email protected]bf3dd3c2013-12-06 06:55:25324struct Dispatcher<R(P1, P2)> {
325 static void DispatchToCallback(
326 const v8::FunctionCallbackInfo<v8::Value>& info) {
327 Arguments args(info);
328 CallbackHolderBase* holder_base = NULL;
329 CHECK(args.GetData(&holder_base));
[email protected]314cde12013-11-23 20:26:51330
[email protected]bf3dd3c2013-12-06 06:55:25331 typedef CallbackHolder<R(P1, P2)> HolderT;
332 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]314cde12013-11-23 20:26:51333
[email protected]bf3dd3c2013-12-06 06:55:25334 typename CallbackParamTraits<P1>::LocalType a1;
335 typename CallbackParamTraits<P2>::LocalType a2;
336 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
337 !GetNextArgument(&args, holder->flags, false, &a2)) {
338 args.ThrowError();
339 return;
340 }
341
342 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
[email protected]314cde12013-11-23 20:26:51343 }
[email protected]bf3dd3c2013-12-06 06:55:25344};
[email protected]37dacfa2013-11-26 03:31:04345
346template<typename R, typename P1, typename P2, typename P3>
[email protected]bf3dd3c2013-12-06 06:55:25347struct Dispatcher<R(P1, P2, P3)> {
348 static void DispatchToCallback(
349 const v8::FunctionCallbackInfo<v8::Value>& info) {
350 Arguments args(info);
351 CallbackHolderBase* holder_base = NULL;
352 CHECK(args.GetData(&holder_base));
[email protected]37dacfa2013-11-26 03:31:04353
[email protected]bf3dd3c2013-12-06 06:55:25354 typedef CallbackHolder<R(P1, P2, P3)> HolderT;
355 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04356
[email protected]bf3dd3c2013-12-06 06:55:25357 typename CallbackParamTraits<P1>::LocalType a1;
358 typename CallbackParamTraits<P2>::LocalType a2;
359 typename CallbackParamTraits<P3>::LocalType a3;
360 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
361 !GetNextArgument(&args, holder->flags, false, &a2) ||
362 !GetNextArgument(&args, holder->flags, false, &a3)) {
363 args.ThrowError();
364 return;
365 }
366
367 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
[email protected]37dacfa2013-11-26 03:31:04368 }
[email protected]bf3dd3c2013-12-06 06:55:25369};
[email protected]81f8b91b2013-11-26 21:02:51370
[email protected]7618ebbb2013-11-27 03:38:26371template<typename R, typename P1, typename P2, typename P3, typename P4>
[email protected]bf3dd3c2013-12-06 06:55:25372struct Dispatcher<R(P1, P2, P3, P4)> {
373 static void DispatchToCallback(
374 const v8::FunctionCallbackInfo<v8::Value>& info) {
375 Arguments args(info);
376 CallbackHolderBase* holder_base = NULL;
377 CHECK(args.GetData(&holder_base));
[email protected]7618ebbb2013-11-27 03:38:26378
[email protected]bf3dd3c2013-12-06 06:55:25379 typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
380 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]7618ebbb2013-11-27 03:38:26381
[email protected]bf3dd3c2013-12-06 06:55:25382 typename CallbackParamTraits<P1>::LocalType a1;
383 typename CallbackParamTraits<P2>::LocalType a2;
384 typename CallbackParamTraits<P3>::LocalType a3;
385 typename CallbackParamTraits<P4>::LocalType a4;
386 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
387 !GetNextArgument(&args, holder->flags, false, &a2) ||
388 !GetNextArgument(&args, holder->flags, false, &a3) ||
389 !GetNextArgument(&args, holder->flags, false, &a4)) {
390 args.ThrowError();
391 return;
392 }
393
394 Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
[email protected]7618ebbb2013-11-27 03:38:26395 }
[email protected]bf3dd3c2013-12-06 06:55:25396};
[email protected]7618ebbb2013-11-27 03:38:26397
[email protected]d73341d12013-12-21 00:48:46398template<typename R, typename P1, typename P2, typename P3, typename P4,
399 typename P5>
400struct Dispatcher<R(P1, P2, P3, P4, P5)> {
401 static void DispatchToCallback(
402 const v8::FunctionCallbackInfo<v8::Value>& info) {
403 Arguments args(info);
404 CallbackHolderBase* holder_base = NULL;
405 CHECK(args.GetData(&holder_base));
406
407 typedef CallbackHolder<R(P1, P2, P3, P4, P5)> HolderT;
408 HolderT* holder = static_cast<HolderT*>(holder_base);
409
410 typename CallbackParamTraits<P1>::LocalType a1;
411 typename CallbackParamTraits<P2>::LocalType a2;
412 typename CallbackParamTraits<P3>::LocalType a3;
413 typename CallbackParamTraits<P4>::LocalType a4;
414 typename CallbackParamTraits<P5>::LocalType a5;
415 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
416 !GetNextArgument(&args, holder->flags, false, &a2) ||
417 !GetNextArgument(&args, holder->flags, false, &a3) ||
418 !GetNextArgument(&args, holder->flags, false, &a4) ||
419 !GetNextArgument(&args, holder->flags, false, &a5)) {
420 args.ThrowError();
421 return;
422 }
423
424 Invoker<R, P1, P2, P3, P4, P5>::Go(&args, holder->callback, a1, a2, a3, a4,
425 a5);
426 }
427};
428
429template<typename R, typename P1, typename P2, typename P3, typename P4,
430 typename P5, typename P6>
431struct Dispatcher<R(P1, P2, P3, P4, P5, P6)> {
432 static void DispatchToCallback(
433 const v8::FunctionCallbackInfo<v8::Value>& info) {
434 Arguments args(info);
435 CallbackHolderBase* holder_base = NULL;
436 CHECK(args.GetData(&holder_base));
437
438 typedef CallbackHolder<R(P1, P2, P3, P4, P5, P6)> HolderT;
439 HolderT* holder = static_cast<HolderT*>(holder_base);
440
441 typename CallbackParamTraits<P1>::LocalType a1;
442 typename CallbackParamTraits<P2>::LocalType a2;
443 typename CallbackParamTraits<P3>::LocalType a3;
444 typename CallbackParamTraits<P4>::LocalType a4;
445 typename CallbackParamTraits<P5>::LocalType a5;
446 typename CallbackParamTraits<P6>::LocalType a6;
447 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
448 !GetNextArgument(&args, holder->flags, false, &a2) ||
449 !GetNextArgument(&args, holder->flags, false, &a3) ||
450 !GetNextArgument(&args, holder->flags, false, &a4) ||
451 !GetNextArgument(&args, holder->flags, false, &a5) ||
452 !GetNextArgument(&args, holder->flags, false, &a6)) {
453 args.ThrowError();
454 return;
455 }
456
457 Invoker<R, P1, P2, P3, P4, P5, P6>::Go(&args, holder->callback, a1, a2, a3,
458 a4, a5, a6);
459 }
460};
461
[email protected]81f8b91b2013-11-26 21:02:51462} // namespace internal
463
464
[email protected]bf3dd3c2013-12-06 06:55:25465// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
466// JavaScript functions that execute a provided C++ function or base::Callback.
467// JavaScript arguments are automatically converted via gin::Converter, as is
468// the return value of the C++ function, if any.
469template<typename Sig>
[email protected]81f8b91b2013-11-26 21:02:51470v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
[email protected]bf3dd3c2013-12-06 06:55:25471 v8::Isolate* isolate, const base::Callback<Sig> callback,
472 int callback_flags = 0) {
473 typedef internal::CallbackHolder<Sig> HolderT;
474 gin::Handle<HolderT> holder = CreateHandle(
475 isolate, new HolderT(callback, callback_flags));
[email protected]81f8b91b2013-11-26 21:02:51476 return v8::FunctionTemplate::New(
[email protected]505ffde2013-12-19 15:47:13477 isolate,
[email protected]bf3dd3c2013-12-06 06:55:25478 &internal::Dispatcher<Sig>::DispatchToCallback,
[email protected]7618ebbb2013-11-27 03:38:26479 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
480}
481
[email protected]314cde12013-11-23 20:26:51482} // namespace gin
[email protected]b520e132013-11-29 03:21:48483
484#endif // GIN_FUNCTION_TEMPLATE_H_