blob: 0685c1b4c2b4ad5d49ff18dbe46cebd2ac52655a [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]314cde12013-11-23 20:26:517// Copyright 2013 The Chromium Authors. All rights reserved.
8// Use of this source code is governed by a BSD-style license that can be
9// found in the LICENSE file.
10
11#include "base/callback.h"
12#include "base/logging.h"
13#include "gin/arguments.h"
14#include "gin/converter.h"
15#include "gin/public/gin_embedders.h"
16#include "gin/public/wrapper_info.h"
17#include "gin/wrappable.h"
18
19#include "v8/include/v8.h"
20
21namespace gin {
22
23class PerIsolateData;
24
[email protected]37dacfa2013-11-26 03:31:0425namespace internal {
26
[email protected]314cde12013-11-23 20:26:5127template<typename T>
28struct RemoveConstRef {
29 typedef T Type;
30};
31template<typename T>
32struct RemoveConstRef<const T&> {
33 typedef T Type;
34};
35
[email protected]37dacfa2013-11-26 03:31:0436
37// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
38// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
[email protected]81f8b91b2013-11-26 21:02:5139// DispatchToCallback, where it is invoked.
[email protected]37dacfa2013-11-26 03:31:0440//
41// v8::FunctionTemplate only supports passing void* as data so how do we know
42// when to delete the base::Callback? That's where CallbackHolderBase comes in.
43// It inherits from Wrappable, which delete itself when both (a) the refcount
44// via base::RefCounted has dropped to zero, and (b) there are no more
45// JavaScript references in V8.
[email protected]314cde12013-11-23 20:26:5146class CallbackHolderBase : public Wrappable {
47 public:
[email protected]314cde12013-11-23 20:26:5148 virtual WrapperInfo* GetWrapperInfo() OVERRIDE;
49 static WrapperInfo kWrapperInfo;
50 protected:
51 virtual ~CallbackHolderBase() {}
52};
53
[email protected]314cde12013-11-23 20:26:5154template<typename Sig>
55class CallbackHolder : public CallbackHolderBase {
56 public:
57 CallbackHolder(const base::Callback<Sig>& callback)
58 : callback(callback) {}
59 base::Callback<Sig> callback;
60 private:
61 virtual ~CallbackHolder() {}
62};
63
[email protected]81f8b91b2013-11-26 21:02:5164
65// This set of templates invokes a base::Callback, converts the return type to a
66// JavaScript value, and returns that value to script via the provided
67// gin::Arguments object.
68//
69// In C++, you can declare the function foo(void), but you can't pass a void
70// expression to foo. As a result, we must specialize the case of Callbacks that
71// have the void return type.
72template<typename R, typename P1 = void, typename P2 = void, typename P3 = void>
73struct Invoker {
74 inline static void Go(
75 Arguments* args,
76 const base::Callback<R(P1, P2, P3)>& callback,
77 const P1& a1,
78 const P2& a2,
79 const P3& a3) {
80 args->Return(callback.Run(a1, a2, a3));
81 }
82};
83template<typename P1, typename P2, typename P3>
84struct Invoker<void, P1, P2, P3> {
85 inline static void Go(
86 Arguments* args,
87 const base::Callback<void(P1, P2, P3)>& callback,
88 const P1& a1,
89 const P2& a2,
90 const P3& a3) {
91 callback.Run(a1, a2, a3);
92 }
93};
94
95template<typename R, typename P1, typename P2>
96struct Invoker<R, P1, P2, void> {
97 inline static void Go(
98 Arguments* args,
99 const base::Callback<R(P1, P2)>& callback,
100 const P1& a1,
101 const P2& a2) {
102 args->Return(callback.Run(a1, a2));
103 }
104};
105template<typename P1, typename P2>
106struct Invoker<void, P1, P2, void> {
107 inline static void Go(
108 Arguments* args,
109 const base::Callback<void(P1, P2)>& callback,
110 const P1& a1,
111 const P2& a2) {
112 callback.Run(a1, a2);
113 }
114};
115
116template<typename R, typename P1>
117struct Invoker<R, P1, void, void> {
118 inline static void Go(
119 Arguments* args,
120 const base::Callback<R(P1)>& callback,
121 const P1& a1) {
122 args->Return(callback.Run(a1));
123 }
124};
125template<typename P1>
126struct Invoker<void, P1, void, void> {
127 inline static void Go(
128 Arguments* args,
129 const base::Callback<void(P1)>& callback,
130 const P1& a1) {
131 callback.Run(a1);
132 }
133};
134
135template<typename R>
136struct Invoker<R, void, void, void> {
137 inline static void Go(
138 Arguments* args,
139 const base::Callback<R()>& callback) {
140 args->Return(callback.Run());
141 }
142};
143template<>
144struct Invoker<void, void, void, void> {
145 inline static void Go(
146 Arguments* args,
147 const base::Callback<void()>& callback) {
148 callback.Run();
149 }
150};
151
152
153// DispatchToCallback converts all the JavaScript arguments to C++ types and
154// invokes the base::Callback.
[email protected]37dacfa2013-11-26 03:31:04155template<typename R>
156static void DispatchToCallback(
157 const v8::FunctionCallbackInfo<v8::Value>& info) {
158 Arguments args(info);
159 CallbackHolderBase* holder_base = NULL;
160 CHECK(args.GetData(&holder_base));
[email protected]314cde12013-11-23 20:26:51161
[email protected]81f8b91b2013-11-26 21:02:51162 typedef CallbackHolder<R()> HolderT;
[email protected]37dacfa2013-11-26 03:31:04163 HolderT* holder = static_cast<HolderT*>(holder_base);
164
[email protected]81f8b91b2013-11-26 21:02:51165 Invoker<R>::Go(&args, holder->callback);
[email protected]37dacfa2013-11-26 03:31:04166}
167
168template<typename R, typename P1>
169static void DispatchToCallback(
170 const v8::FunctionCallbackInfo<v8::Value>& info) {
171 Arguments args(info);
172 CallbackHolderBase* holder_base = NULL;
173 CHECK(args.GetData(&holder_base));
174
[email protected]81f8b91b2013-11-26 21:02:51175 typedef CallbackHolder<R(P1)> HolderT;
[email protected]37dacfa2013-11-26 03:31:04176 HolderT* holder = static_cast<HolderT*>(holder_base);
177
[email protected]81f8b91b2013-11-26 21:02:51178 typename RemoveConstRef<P1>::Type a1;
[email protected]37dacfa2013-11-26 03:31:04179 if (!args.GetNext(&a1)) {
180 args.ThrowError();
181 return;
182 }
183
[email protected]81f8b91b2013-11-26 21:02:51184 Invoker<R, P1>::Go(&args, holder->callback, a1);
[email protected]37dacfa2013-11-26 03:31:04185}
186
187template<typename R, typename P1, typename P2>
[email protected]314cde12013-11-23 20:26:51188static void DispatchToCallback(
189 const v8::FunctionCallbackInfo<v8::Value>& info) {
190 Arguments args(info);
191 CallbackHolderBase* holder_base = NULL;
192 CHECK(args.GetData(&holder_base));
193
[email protected]81f8b91b2013-11-26 21:02:51194 typedef CallbackHolder<R(P1, P2)> HolderT;
[email protected]314cde12013-11-23 20:26:51195 HolderT* holder = static_cast<HolderT*>(holder_base);
196
[email protected]81f8b91b2013-11-26 21:02:51197 typename RemoveConstRef<P1>::Type a1;
198 typename RemoveConstRef<P2>::Type a2;
[email protected]314cde12013-11-23 20:26:51199 if (!args.GetNext(&a1) ||
200 !args.GetNext(&a2)) {
201 args.ThrowError();
202 return;
203 }
204
[email protected]81f8b91b2013-11-26 21:02:51205 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
[email protected]37dacfa2013-11-26 03:31:04206}
207
208template<typename R, typename P1, typename P2, typename P3>
209static void DispatchToCallback(
210 const v8::FunctionCallbackInfo<v8::Value>& info) {
211 Arguments args(info);
212 CallbackHolderBase* holder_base = NULL;
213 CHECK(args.GetData(&holder_base));
214
[email protected]81f8b91b2013-11-26 21:02:51215 typedef CallbackHolder<R(P1, P2, P3)> HolderT;
[email protected]37dacfa2013-11-26 03:31:04216 HolderT* holder = static_cast<HolderT*>(holder_base);
217
[email protected]81f8b91b2013-11-26 21:02:51218 typename RemoveConstRef<P1>::Type a1;
219 typename RemoveConstRef<P2>::Type a2;
220 typename RemoveConstRef<P3>::Type a3;
[email protected]37dacfa2013-11-26 03:31:04221 if (!args.GetNext(&a1) ||
222 !args.GetNext(&a2) ||
223 !args.GetNext(&a3)) {
224 args.ThrowError();
225 return;
226 }
227
[email protected]81f8b91b2013-11-26 21:02:51228 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
229}
230
231} // namespace internal
232
233
234// This should be called once per-isolate to initialize the function template
235// system.
236void InitFunctionTemplates(PerIsolateData* isolate_data);
237
238// This has to be outside the internal namespace because template
239// specializations must be declared in the same namespace as the original
240// template.
241template<>
242struct Converter<internal::CallbackHolderBase*>
243 : public WrappableConverter<internal::CallbackHolderBase> {};
244
245
246// Creates a v8::FunctionTemplate that will run the provided base::Callback each
247// time it is called. JavaScript arguments and return values are converted via
248// gin::Converter.
249template<typename R>
250v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
251 v8::Isolate* isolate,
252 const base::Callback<R()> callback) {
253 typedef internal::CallbackHolder<R()> HolderT;
254 scoped_refptr<HolderT> holder(new HolderT(callback));
255 return v8::FunctionTemplate::New(
256 &internal::DispatchToCallback<R>,
257 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
258}
259
260template<typename R, typename P1>
261v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
262 v8::Isolate* isolate,
263 const base::Callback<R(P1)> callback) {
264 typedef internal::CallbackHolder<R(P1)> HolderT;
265 scoped_refptr<HolderT> holder(new HolderT(callback));
266 return v8::FunctionTemplate::New(
267 &internal::DispatchToCallback<R, P1>,
268 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
269}
270
271template<typename R, typename P1, typename P2>
272v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
273 v8::Isolate* isolate,
274 const base::Callback<R(P1, P2)> callback) {
275 typedef internal::CallbackHolder<R(P1, P2)> HolderT;
276 scoped_refptr<HolderT> holder(new HolderT(callback));
277 return v8::FunctionTemplate::New(
278 &internal::DispatchToCallback<R, P1, P2>,
279 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
[email protected]37dacfa2013-11-26 03:31:04280}
281
282template<typename R, typename P1, typename P2, typename P3>
[email protected]81f8b91b2013-11-26 21:02:51283v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
[email protected]37dacfa2013-11-26 03:31:04284 v8::Isolate* isolate,
285 const base::Callback<R(P1, P2, P3)> callback) {
[email protected]81f8b91b2013-11-26 21:02:51286 typedef internal::CallbackHolder<R(P1, P2, P3)> HolderT;
[email protected]37dacfa2013-11-26 03:31:04287 scoped_refptr<HolderT> holder(new HolderT(callback));
288 return v8::FunctionTemplate::New(
[email protected]81f8b91b2013-11-26 21:02:51289 &internal::DispatchToCallback<R, P1, P2, P3>,
290 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
[email protected]314cde12013-11-23 20:26:51291}
292
293} // namespace gin