blob: 86ca1a6235cf3c0780eecfce866eceef1a845f69 [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]d379b0c2013-12-05 05:48:0118#include "gin/handle.h"
[email protected]314cde12013-11-23 20:26:5119#include "gin/public/gin_embedders.h"
20#include "gin/public/wrapper_info.h"
21#include "gin/wrappable.h"
22
23#include "v8/include/v8.h"
24
25namespace gin {
26
27class PerIsolateData;
28
[email protected]bf3dd3c2013-12-06 06:55:2529enum CreateFunctionTemplateFlags {
30 HolderIsFirstArgument = 1 << 0,
31};
32
[email protected]37dacfa2013-11-26 03:31:0433namespace internal {
34
[email protected]314cde12013-11-23 20:26:5135template<typename T>
[email protected]bf3dd3c2013-12-06 06:55:2536struct CallbackParamTraits {
37 typedef T LocalType;
[email protected]314cde12013-11-23 20:26:5138};
39template<typename T>
[email protected]bf3dd3c2013-12-06 06:55:2540struct CallbackParamTraits<const T&> {
41 typedef T LocalType;
42};
43template<typename T>
44struct CallbackParamTraits<const T*> {
45 typedef T* LocalType;
[email protected]314cde12013-11-23 20:26:5146};
47
[email protected]37dacfa2013-11-26 03:31:0448
49// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
50// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
[email protected]81f8b91b2013-11-26 21:02:5151// DispatchToCallback, where it is invoked.
[email protected]37dacfa2013-11-26 03:31:0452//
53// v8::FunctionTemplate only supports passing void* as data so how do we know
54// when to delete the base::Callback? That's where CallbackHolderBase comes in.
55// It inherits from Wrappable, which delete itself when both (a) the refcount
56// via base::RefCounted has dropped to zero, and (b) there are no more
57// JavaScript references in V8.
[email protected]6fe56102013-12-08 07:10:5858
59// This simple base class is used so that we can share a single object template
60// among every CallbackHolder instance.
61class CallbackHolderBase : public Wrappable<CallbackHolderBase> {
[email protected]314cde12013-11-23 20:26:5162 protected:
[email protected]6fe56102013-12-08 07:10:5863 ~CallbackHolderBase() {}
[email protected]314cde12013-11-23 20:26:5164};
65
[email protected]314cde12013-11-23 20:26:5166template<typename Sig>
67class CallbackHolder : public CallbackHolderBase {
68 public:
[email protected]bf3dd3c2013-12-06 06:55:2569 CallbackHolder(const base::Callback<Sig>& callback, int flags)
70 : callback(callback), flags(flags) {}
[email protected]314cde12013-11-23 20:26:5171 base::Callback<Sig> callback;
[email protected]bf3dd3c2013-12-06 06:55:2572 int flags;
[email protected]314cde12013-11-23 20:26:5173 private:
[email protected]6fe56102013-12-08 07:10:5874 ~CallbackHolder() {}
[email protected]314cde12013-11-23 20:26:5175};
76
[email protected]81f8b91b2013-11-26 21:02:5177
78// This set of templates invokes a base::Callback, converts the return type to a
79// JavaScript value, and returns that value to script via the provided
80// gin::Arguments object.
81//
82// In C++, you can declare the function foo(void), but you can't pass a void
83// expression to foo. As a result, we must specialize the case of Callbacks that
84// have the void return type.
[email protected]7618ebbb2013-11-27 03:38:2685template<typename R, typename P1 = void, typename P2 = void,
86 typename P3 = void, typename P4 = void>
[email protected]81f8b91b2013-11-26 21:02:5187struct Invoker {
88 inline static void Go(
89 Arguments* args,
[email protected]7618ebbb2013-11-27 03:38:2690 const base::Callback<R(P1, P2, P3, P4)>& callback,
91 const P1& a1,
92 const P2& a2,
93 const P3& a3,
94 const P4& a4) {
95 args->Return(callback.Run(a1, a2, a3, a4));
96 }
97};
98template<typename P1, typename P2, typename P3, typename P4>
99struct Invoker<void, P1, P2, P3, P4> {
100 inline static void Go(
101 Arguments* args,
102 const base::Callback<void(P1, P2, P3, P4)>& callback,
103 const P1& a1,
104 const P2& a2,
105 const P3& a3,
106 const P4& a4) {
107 callback.Run(a1, a2, a3, a4);
108 }
109};
110
111template<typename R, typename P1, typename P2, typename P3>
112struct Invoker<R, P1, P2, P3, void> {
113 inline static void Go(
114 Arguments* args,
[email protected]81f8b91b2013-11-26 21:02:51115 const base::Callback<R(P1, P2, P3)>& callback,
116 const P1& a1,
117 const P2& a2,
118 const P3& a3) {
119 args->Return(callback.Run(a1, a2, a3));
120 }
121};
122template<typename P1, typename P2, typename P3>
[email protected]7618ebbb2013-11-27 03:38:26123struct Invoker<void, P1, P2, P3, void> {
[email protected]81f8b91b2013-11-26 21:02:51124 inline static void Go(
125 Arguments* args,
126 const base::Callback<void(P1, P2, P3)>& callback,
127 const P1& a1,
128 const P2& a2,
129 const P3& a3) {
130 callback.Run(a1, a2, a3);
131 }
132};
133
134template<typename R, typename P1, typename P2>
[email protected]7618ebbb2013-11-27 03:38:26135struct Invoker<R, P1, P2, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51136 inline static void Go(
137 Arguments* args,
138 const base::Callback<R(P1, P2)>& callback,
139 const P1& a1,
140 const P2& a2) {
141 args->Return(callback.Run(a1, a2));
142 }
143};
144template<typename P1, typename P2>
[email protected]7618ebbb2013-11-27 03:38:26145struct Invoker<void, P1, P2, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51146 inline static void Go(
147 Arguments* args,
148 const base::Callback<void(P1, P2)>& callback,
149 const P1& a1,
150 const P2& a2) {
151 callback.Run(a1, a2);
152 }
153};
154
155template<typename R, typename P1>
[email protected]7618ebbb2013-11-27 03:38:26156struct Invoker<R, P1, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51157 inline static void Go(
158 Arguments* args,
159 const base::Callback<R(P1)>& callback,
160 const P1& a1) {
161 args->Return(callback.Run(a1));
162 }
163};
164template<typename P1>
[email protected]7618ebbb2013-11-27 03:38:26165struct Invoker<void, P1, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51166 inline static void Go(
167 Arguments* args,
168 const base::Callback<void(P1)>& callback,
169 const P1& a1) {
170 callback.Run(a1);
171 }
172};
173
174template<typename R>
[email protected]7618ebbb2013-11-27 03:38:26175struct Invoker<R, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51176 inline static void Go(
177 Arguments* args,
178 const base::Callback<R()>& callback) {
179 args->Return(callback.Run());
180 }
181};
182template<>
[email protected]7618ebbb2013-11-27 03:38:26183struct Invoker<void, void, void, void, void> {
[email protected]81f8b91b2013-11-26 21:02:51184 inline static void Go(
185 Arguments* args,
186 const base::Callback<void()>& callback) {
187 callback.Run();
188 }
189};
190
191
[email protected]bf3dd3c2013-12-06 06:55:25192template<typename T>
193bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
194 T* result) {
195 if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
196 return args->GetHolder(result);
197 } else {
198 return args->GetNext(result);
199 }
200}
201
202// For advanced use cases, we allow callers to request the unparsed Arguments
203// object and poke around in it directly.
204inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
205 Arguments* result) {
206 *result = *args;
207 return true;
208}
209
210
[email protected]81f8b91b2013-11-26 21:02:51211// DispatchToCallback converts all the JavaScript arguments to C++ types and
212// invokes the base::Callback.
[email protected]bf3dd3c2013-12-06 06:55:25213template<typename Sig>
214struct Dispatcher {
215};
216
[email protected]37dacfa2013-11-26 03:31:04217template<typename R>
[email protected]bf3dd3c2013-12-06 06:55:25218struct Dispatcher<R()> {
219 static void DispatchToCallback(
220 const v8::FunctionCallbackInfo<v8::Value>& info) {
221 Arguments args(info);
222 CallbackHolderBase* holder_base = NULL;
223 CHECK(args.GetData(&holder_base));
[email protected]314cde12013-11-23 20:26:51224
[email protected]bf3dd3c2013-12-06 06:55:25225 typedef CallbackHolder<R()> HolderT;
226 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04227
[email protected]bf3dd3c2013-12-06 06:55:25228 Invoker<R>::Go(&args, holder->callback);
229 }
230};
[email protected]37dacfa2013-11-26 03:31:04231
232template<typename R, typename P1>
[email protected]bf3dd3c2013-12-06 06:55:25233struct Dispatcher<R(P1)> {
234 static void DispatchToCallback(
235 const v8::FunctionCallbackInfo<v8::Value>& info) {
236 Arguments args(info);
237 CallbackHolderBase* holder_base = NULL;
238 CHECK(args.GetData(&holder_base));
[email protected]37dacfa2013-11-26 03:31:04239
[email protected]bf3dd3c2013-12-06 06:55:25240 typedef CallbackHolder<R(P1)> HolderT;
241 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04242
[email protected]bf3dd3c2013-12-06 06:55:25243 typename CallbackParamTraits<P1>::LocalType a1;
244 if (!GetNextArgument(&args, holder->flags, true, &a1)) {
245 args.ThrowError();
246 return;
247 }
248
249 Invoker<R, P1>::Go(&args, holder->callback, a1);
[email protected]37dacfa2013-11-26 03:31:04250 }
[email protected]bf3dd3c2013-12-06 06:55:25251};
[email protected]37dacfa2013-11-26 03:31:04252
253template<typename R, typename P1, typename P2>
[email protected]bf3dd3c2013-12-06 06:55:25254struct Dispatcher<R(P1, P2)> {
255 static void DispatchToCallback(
256 const v8::FunctionCallbackInfo<v8::Value>& info) {
257 Arguments args(info);
258 CallbackHolderBase* holder_base = NULL;
259 CHECK(args.GetData(&holder_base));
[email protected]314cde12013-11-23 20:26:51260
[email protected]bf3dd3c2013-12-06 06:55:25261 typedef CallbackHolder<R(P1, P2)> HolderT;
262 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]314cde12013-11-23 20:26:51263
[email protected]bf3dd3c2013-12-06 06:55:25264 typename CallbackParamTraits<P1>::LocalType a1;
265 typename CallbackParamTraits<P2>::LocalType a2;
266 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
267 !GetNextArgument(&args, holder->flags, false, &a2)) {
268 args.ThrowError();
269 return;
270 }
271
272 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
[email protected]314cde12013-11-23 20:26:51273 }
[email protected]bf3dd3c2013-12-06 06:55:25274};
[email protected]37dacfa2013-11-26 03:31:04275
276template<typename R, typename P1, typename P2, typename P3>
[email protected]bf3dd3c2013-12-06 06:55:25277struct Dispatcher<R(P1, P2, P3)> {
278 static void DispatchToCallback(
279 const v8::FunctionCallbackInfo<v8::Value>& info) {
280 Arguments args(info);
281 CallbackHolderBase* holder_base = NULL;
282 CHECK(args.GetData(&holder_base));
[email protected]37dacfa2013-11-26 03:31:04283
[email protected]bf3dd3c2013-12-06 06:55:25284 typedef CallbackHolder<R(P1, P2, P3)> HolderT;
285 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]37dacfa2013-11-26 03:31:04286
[email protected]bf3dd3c2013-12-06 06:55:25287 typename CallbackParamTraits<P1>::LocalType a1;
288 typename CallbackParamTraits<P2>::LocalType a2;
289 typename CallbackParamTraits<P3>::LocalType a3;
290 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
291 !GetNextArgument(&args, holder->flags, false, &a2) ||
292 !GetNextArgument(&args, holder->flags, false, &a3)) {
293 args.ThrowError();
294 return;
295 }
296
297 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
[email protected]37dacfa2013-11-26 03:31:04298 }
[email protected]bf3dd3c2013-12-06 06:55:25299};
[email protected]81f8b91b2013-11-26 21:02:51300
[email protected]7618ebbb2013-11-27 03:38:26301template<typename R, typename P1, typename P2, typename P3, typename P4>
[email protected]bf3dd3c2013-12-06 06:55:25302struct Dispatcher<R(P1, P2, P3, P4)> {
303 static void DispatchToCallback(
304 const v8::FunctionCallbackInfo<v8::Value>& info) {
305 Arguments args(info);
306 CallbackHolderBase* holder_base = NULL;
307 CHECK(args.GetData(&holder_base));
[email protected]7618ebbb2013-11-27 03:38:26308
[email protected]bf3dd3c2013-12-06 06:55:25309 typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
310 HolderT* holder = static_cast<HolderT*>(holder_base);
[email protected]7618ebbb2013-11-27 03:38:26311
[email protected]bf3dd3c2013-12-06 06:55:25312 typename CallbackParamTraits<P1>::LocalType a1;
313 typename CallbackParamTraits<P2>::LocalType a2;
314 typename CallbackParamTraits<P3>::LocalType a3;
315 typename CallbackParamTraits<P4>::LocalType a4;
316 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
317 !GetNextArgument(&args, holder->flags, false, &a2) ||
318 !GetNextArgument(&args, holder->flags, false, &a3) ||
319 !GetNextArgument(&args, holder->flags, false, &a4)) {
320 args.ThrowError();
321 return;
322 }
323
324 Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
[email protected]7618ebbb2013-11-27 03:38:26325 }
[email protected]bf3dd3c2013-12-06 06:55:25326};
[email protected]7618ebbb2013-11-27 03:38:26327
[email protected]81f8b91b2013-11-26 21:02:51328} // namespace internal
329
330
331// This should be called once per-isolate to initialize the function template
332// system.
333void InitFunctionTemplates(PerIsolateData* isolate_data);
334
[email protected]7618ebbb2013-11-27 03:38:26335
[email protected]bf3dd3c2013-12-06 06:55:25336// CreateFunctionTemplate creates a v8::FunctionTemplate that will create
337// JavaScript functions that execute a provided C++ function or base::Callback.
338// JavaScript arguments are automatically converted via gin::Converter, as is
339// the return value of the C++ function, if any.
340template<typename Sig>
[email protected]81f8b91b2013-11-26 21:02:51341v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
[email protected]bf3dd3c2013-12-06 06:55:25342 v8::Isolate* isolate, const base::Callback<Sig> callback,
343 int callback_flags = 0) {
344 typedef internal::CallbackHolder<Sig> HolderT;
345 gin::Handle<HolderT> holder = CreateHandle(
346 isolate, new HolderT(callback, callback_flags));
[email protected]81f8b91b2013-11-26 21:02:51347 return v8::FunctionTemplate::New(
[email protected]bf3dd3c2013-12-06 06:55:25348 &internal::Dispatcher<Sig>::DispatchToCallback,
[email protected]7618ebbb2013-11-27 03:38:26349 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
350}
351
[email protected]314cde12013-11-23 20:26:51352} // namespace gin
[email protected]b520e132013-11-29 03:21:48353
354#endif // GIN_FUNCTION_TEMPLATE_H_