[Telemetry]: Fix v8_object_stats metric to avoid having a '.' in trace names
[chromium-blink-merge.git] / gin / function_template.h
blob29cb336391ca50fdfbbb05ae2ef351a1c04ac6c3
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"
26 namespace gin {
28 class PerIsolateData;
30 enum CreateFunctionTemplateFlags {
31 HolderIsFirstArgument = 1 << 0,
34 namespace internal {
36 template<typename T>
37 struct CallbackParamTraits {
38 typedef T LocalType;
40 template<typename T>
41 struct CallbackParamTraits<const T&> {
42 typedef T LocalType;
44 template<typename T>
45 struct CallbackParamTraits<const T*> {
46 typedef T* LocalType;
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> {
63 public:
64 static WrapperInfo kWrapperInfo;
65 protected:
66 virtual ~CallbackHolderBase() {}
69 template<typename Sig>
70 class CallbackHolder : public CallbackHolderBase {
71 public:
72 CallbackHolder(const base::Callback<Sig>& callback, int flags)
73 : callback(callback), flags(flags) {}
74 base::Callback<Sig> callback;
75 int flags;
76 private:
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,
90 typename P6 = void>
91 struct Invoker {
92 inline static void Go(
93 Arguments* args,
94 const base::Callback<R(P1, P2, P3, P4, P5, P6)>& callback,
95 const P1& a1,
96 const P2& a2,
97 const P3& a3,
98 const P4& a4,
99 const P5& a5,
100 const P6& a6) {
101 args->Return(callback.Run(a1, a2, a3, a4, a5, a6));
104 template<typename P1, typename P2, typename P3, typename P4, typename P5,
105 typename P6>
106 struct Invoker<void, P1, P2, P3, P4, P5, P6> {
107 inline static void Go(
108 Arguments* args,
109 const base::Callback<void(P1, P2, P3, P4, P5, P6)>& callback,
110 const P1& a1,
111 const P2& a2,
112 const P3& a3,
113 const P4& a4,
114 const P5& a5,
115 const P6& a6) {
116 callback.Run(a1, a2, a3, a4, a5, a6);
120 template<typename R, typename P1, typename P2, typename P3, typename P4,
121 typename P5>
122 struct Invoker<R, P1, P2, P3, P4, P5, void> {
123 inline static void Go(
124 Arguments* args,
125 const base::Callback<R(P1, P2, P3, P4, P5)>& callback,
126 const P1& a1,
127 const P2& a2,
128 const P3& a3,
129 const P4& a4,
130 const P5& a5) {
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(
137 Arguments* args,
138 const base::Callback<void(P1, P2, P3, P4, P5)>& callback,
139 const P1& a1,
140 const P2& a2,
141 const P3& a3,
142 const P4& a4,
143 const P5& a5) {
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(
151 Arguments* args,
152 const base::Callback<R(P1, P2, P3, P4)>& callback,
153 const P1& a1,
154 const P2& a2,
155 const P3& a3,
156 const P4& a4) {
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(
163 Arguments* args,
164 const base::Callback<void(P1, P2, P3, P4)>& callback,
165 const P1& a1,
166 const P2& a2,
167 const P3& a3,
168 const P4& a4) {
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(
176 Arguments* args,
177 const base::Callback<R(P1, P2, P3)>& callback,
178 const P1& a1,
179 const P2& a2,
180 const P3& a3) {
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(
187 Arguments* args,
188 const base::Callback<void(P1, P2, P3)>& callback,
189 const P1& a1,
190 const P2& a2,
191 const P3& a3) {
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(
199 Arguments* args,
200 const base::Callback<R(P1, P2)>& callback,
201 const P1& a1,
202 const P2& a2) {
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(
209 Arguments* args,
210 const base::Callback<void(P1, P2)>& callback,
211 const P1& a1,
212 const P2& a2) {
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(
220 Arguments* args,
221 const base::Callback<R(P1)>& callback,
222 const P1& a1) {
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(
229 Arguments* args,
230 const base::Callback<void(P1)>& callback,
231 const P1& a1) {
232 callback.Run(a1);
236 template<typename R>
237 struct Invoker<R, void, void, void, void, void, void> {
238 inline static void Go(
239 Arguments* args,
240 const base::Callback<R()>& callback) {
241 args->Return(callback.Run());
244 template<>
245 struct Invoker<void, void, void, void, void, void, void> {
246 inline static void Go(
247 Arguments* args,
248 const base::Callback<void()>& callback) {
249 callback.Run();
254 template<typename T>
255 bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
256 T* result) {
257 if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
258 return args->GetHolder(result);
259 } else {
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,
267 Arguments* result) {
268 *result = *args;
269 return true;
271 inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
272 Arguments** result) {
273 *result = args;
274 return true;
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();
281 return true;
285 // DispatchToCallback converts all the JavaScript arguments to C++ types and
286 // invokes the base::Callback.
287 template<typename Sig>
288 struct Dispatcher {
291 template<typename R>
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)) {
319 args.ThrowError();
320 return;
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)) {
342 args.ThrowError();
343 return;
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)) {
367 args.ThrowError();
368 return;
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)) {
394 args.ThrowError();
395 return;
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,
403 typename P5>
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)) {
424 args.ThrowError();
425 return;
428 Invoker<R, P1, P2, P3, P4, P5>::Go(&args, holder->callback, a1, a2, a3, a4,
429 a5);
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)) {
457 args.ThrowError();
458 return;
461 Invoker<R, P1, P2, P3, P4, P5, P6>::Go(&args, holder->callback, a1, a2, a3,
462 a4, a5, a6);
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(
481 isolate,
482 &internal::Dispatcher<Sig>::DispatchToCallback,
483 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
486 } // namespace gin
488 #endif // GIN_FUNCTION_TEMPLATE_H_