Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: gin/function_template.h

Issue 103703002: Gin: Add support for binding JS methods to C++ instance methods. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: blah Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // This file was GENERATED by command: 1 // This file was GENERATED by command:
2 // pump.py function_template.h.pump 2 // pump.py function_template.h.pump
3 // DO NOT EDIT BY HAND!!! 3 // DO NOT EDIT BY HAND!!!
4 4
5 5
6 6
7 #ifndef GIN_FUNCTION_TEMPLATE_H_ 7 #ifndef GIN_FUNCTION_TEMPLATE_H_
8 #define GIN_FUNCTION_TEMPLATE_H_ 8 #define GIN_FUNCTION_TEMPLATE_H_
9 9
10 // Copyright 2013 The Chromium Authors. All rights reserved. 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 11 // Use of this source code is governed by a BSD-style license that can be
12 // found in the LICENSE file. 12 // found in the LICENSE file.
13 13
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "gin/arguments.h" 16 #include "gin/arguments.h"
17 #include "gin/converter.h" 17 #include "gin/converter.h"
18 #include "gin/public/gin_embedders.h" 18 #include "gin/public/gin_embedders.h"
19 #include "gin/public/wrapper_info.h" 19 #include "gin/public/wrapper_info.h"
20 #include "gin/wrappable.h" 20 #include "gin/wrappable.h"
21 21
22 #include "v8/include/v8.h" 22 #include "v8/include/v8.h"
23 23
24 namespace gin { 24 namespace gin {
25 25
26 class PerIsolateData; 26 class PerIsolateData;
27 27
28 enum CreateFunctionTemplateFlags {
29 HolderIsFirstArgument = 1 << 0,
30 };
31
28 namespace internal { 32 namespace internal {
29 33
30 template<typename T> 34 template<typename T>
31 struct RemoveConstRef { 35 struct RemoveConstRef {
32 typedef T Type; 36 typedef T Type;
33 }; 37 };
34 template<typename T> 38 template<typename T>
35 struct RemoveConstRef<const T&> { 39 struct RemoveConstRef<const T&> {
36 typedef T Type; 40 typedef T Type;
37 }; 41 };
42 template<typename T>
43 struct RemoveConstRef<const T*> {
abarth-chromium 2013/12/04 16:27:55 This seems like a slight misnomer. Maybe we shoul
44 typedef T* Type;
45 };
38 46
39 47
40 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from 48 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
41 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to 49 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
42 // DispatchToCallback, where it is invoked. 50 // DispatchToCallback, where it is invoked.
43 // 51 //
44 // v8::FunctionTemplate only supports passing void* as data so how do we know 52 // v8::FunctionTemplate only supports passing void* as data so how do we know
45 // when to delete the base::Callback? That's where CallbackHolderBase comes in. 53 // when to delete the base::Callback? That's where CallbackHolderBase comes in.
46 // It inherits from Wrappable, which delete itself when both (a) the refcount 54 // It inherits from Wrappable, which delete itself when both (a) the refcount
47 // via base::RefCounted has dropped to zero, and (b) there are no more 55 // via base::RefCounted has dropped to zero, and (b) there are no more
48 // JavaScript references in V8. 56 // JavaScript references in V8.
49 class CallbackHolderBase : public Wrappable { 57 class CallbackHolderBase : public Wrappable {
50 public: 58 public:
51 virtual WrapperInfo* GetWrapperInfo() OVERRIDE; 59 virtual WrapperInfo* GetWrapperInfo() OVERRIDE;
52 static WrapperInfo kWrapperInfo; 60 static WrapperInfo kWrapperInfo;
53 protected: 61 protected:
54 virtual ~CallbackHolderBase() {} 62 virtual ~CallbackHolderBase() {}
55 }; 63 };
56 64
57 template<typename Sig> 65 template<typename Sig>
58 class CallbackHolder : public CallbackHolderBase { 66 class CallbackHolder : public CallbackHolderBase {
59 public: 67 public:
60 CallbackHolder(const base::Callback<Sig>& callback) 68 CallbackHolder(const base::Callback<Sig>& callback, int flags)
61 : callback(callback) {} 69 : callback(callback), flags(flags) {}
62 base::Callback<Sig> callback; 70 base::Callback<Sig> callback;
71 int flags;
63 private: 72 private:
64 virtual ~CallbackHolder() {} 73 virtual ~CallbackHolder() {}
65 }; 74 };
66 75
67 76
68 // This set of templates invokes a base::Callback, converts the return type to a 77 // This set of templates invokes a base::Callback, converts the return type to a
69 // JavaScript value, and returns that value to script via the provided 78 // JavaScript value, and returns that value to script via the provided
70 // gin::Arguments object. 79 // gin::Arguments object.
71 // 80 //
72 // In C++, you can declare the function foo(void), but you can't pass a void 81 // In C++, you can declare the function foo(void), but you can't pass a void
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 template<> 181 template<>
173 struct Invoker<void, void, void, void, void> { 182 struct Invoker<void, void, void, void, void> {
174 inline static void Go( 183 inline static void Go(
175 Arguments* args, 184 Arguments* args,
176 const base::Callback<void()>& callback) { 185 const base::Callback<void()>& callback) {
177 callback.Run(); 186 callback.Run();
178 } 187 }
179 }; 188 };
180 189
181 190
191 template<typename T>
192 bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
193 T* result) {
194 if (is_first && (create_flags & HolderIsFirstArgument) != 0) {
195 return args->GetHolder(result);
196 } else {
197 return args->GetNext(result);
198 }
199 }
200
201 // For advanced use cases, we allow callers to request the unparsed Arguments
202 // object and poke around in it directly.
203 inline bool GetNextArgument(Arguments* args, int flags, bool is_first,
abarth-chromium 2013/12/04 16:27:55 |flags| is slightly inconsistent with the name |cr
204 Arguments* result) {
205 *result = *args;
206 return true;
207 }
208
209
182 // DispatchToCallback converts all the JavaScript arguments to C++ types and 210 // DispatchToCallback converts all the JavaScript arguments to C++ types and
183 // invokes the base::Callback. 211 // invokes the base::Callback.
212 template<typename Sig>
213 struct Dispatcher {
214 };
215
184 template<typename R> 216 template<typename R>
185 static void DispatchToCallback( 217 struct Dispatcher<R()> {
186 const v8::FunctionCallbackInfo<v8::Value>& info) { 218 static void DispatchToCallback(
187 Arguments args(info); 219 const v8::FunctionCallbackInfo<v8::Value>& info) {
188 CallbackHolderBase* holder_base = NULL; 220 Arguments args(info);
189 CHECK(args.GetData(&holder_base)); 221 CallbackHolderBase* holder_base = NULL;
222 CHECK(args.GetData(&holder_base));
190 223
191 typedef CallbackHolder<R()> HolderT; 224 typedef CallbackHolder<R()> HolderT;
192 HolderT* holder = static_cast<HolderT*>(holder_base); 225 HolderT* holder = static_cast<HolderT*>(holder_base);
193 226
194 Invoker<R>::Go(&args, holder->callback); 227 Invoker<R>::Go(&args, holder->callback);
195 } 228 }
229 };
196 230
197 template<typename R, typename P1> 231 template<typename R, typename P1>
198 static void DispatchToCallback( 232 struct Dispatcher<R(P1)> {
199 const v8::FunctionCallbackInfo<v8::Value>& info) { 233 static void DispatchToCallback(
200 Arguments args(info); 234 const v8::FunctionCallbackInfo<v8::Value>& info) {
201 CallbackHolderBase* holder_base = NULL; 235 Arguments args(info);
202 CHECK(args.GetData(&holder_base)); 236 CallbackHolderBase* holder_base = NULL;
237 CHECK(args.GetData(&holder_base));
203 238
204 typedef CallbackHolder<R(P1)> HolderT; 239 typedef CallbackHolder<R(P1)> HolderT;
205 HolderT* holder = static_cast<HolderT*>(holder_base); 240 HolderT* holder = static_cast<HolderT*>(holder_base);
206 241
207 typename RemoveConstRef<P1>::Type a1; 242 typename RemoveConstRef<P1>::Type a1;
208 if (!args.GetNext(&a1)) { 243 if (!GetNextArgument(&args, holder->flags, true, &a1)) {
209 args.ThrowError(); 244 args.ThrowError();
210 return; 245 return;
246 }
247
248 Invoker<R, P1>::Go(&args, holder->callback, a1);
211 } 249 }
212 250 };
213 Invoker<R, P1>::Go(&args, holder->callback, a1);
214 }
215 251
216 template<typename R, typename P1, typename P2> 252 template<typename R, typename P1, typename P2>
217 static void DispatchToCallback( 253 struct Dispatcher<R(P1, P2)> {
218 const v8::FunctionCallbackInfo<v8::Value>& info) { 254 static void DispatchToCallback(
219 Arguments args(info); 255 const v8::FunctionCallbackInfo<v8::Value>& info) {
220 CallbackHolderBase* holder_base = NULL; 256 Arguments args(info);
221 CHECK(args.GetData(&holder_base)); 257 CallbackHolderBase* holder_base = NULL;
258 CHECK(args.GetData(&holder_base));
222 259
223 typedef CallbackHolder<R(P1, P2)> HolderT; 260 typedef CallbackHolder<R(P1, P2)> HolderT;
224 HolderT* holder = static_cast<HolderT*>(holder_base); 261 HolderT* holder = static_cast<HolderT*>(holder_base);
225 262
226 typename RemoveConstRef<P1>::Type a1; 263 typename RemoveConstRef<P1>::Type a1;
227 typename RemoveConstRef<P2>::Type a2; 264 typename RemoveConstRef<P2>::Type a2;
228 if (!args.GetNext(&a1) || 265 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
229 !args.GetNext(&a2)) { 266 !GetNextArgument(&args, holder->flags, false, &a2)) {
230 args.ThrowError(); 267 args.ThrowError();
231 return; 268 return;
269 }
270
271 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
232 } 272 }
233 273 };
234 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
235 }
236 274
237 template<typename R, typename P1, typename P2, typename P3> 275 template<typename R, typename P1, typename P2, typename P3>
238 static void DispatchToCallback( 276 struct Dispatcher<R(P1, P2, P3)> {
239 const v8::FunctionCallbackInfo<v8::Value>& info) { 277 static void DispatchToCallback(
240 Arguments args(info); 278 const v8::FunctionCallbackInfo<v8::Value>& info) {
241 CallbackHolderBase* holder_base = NULL; 279 Arguments args(info);
242 CHECK(args.GetData(&holder_base)); 280 CallbackHolderBase* holder_base = NULL;
281 CHECK(args.GetData(&holder_base));
243 282
244 typedef CallbackHolder<R(P1, P2, P3)> HolderT; 283 typedef CallbackHolder<R(P1, P2, P3)> HolderT;
245 HolderT* holder = static_cast<HolderT*>(holder_base); 284 HolderT* holder = static_cast<HolderT*>(holder_base);
246 285
247 typename RemoveConstRef<P1>::Type a1; 286 typename RemoveConstRef<P1>::Type a1;
248 typename RemoveConstRef<P2>::Type a2; 287 typename RemoveConstRef<P2>::Type a2;
249 typename RemoveConstRef<P3>::Type a3; 288 typename RemoveConstRef<P3>::Type a3;
250 if (!args.GetNext(&a1) || 289 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
251 !args.GetNext(&a2) || 290 !GetNextArgument(&args, holder->flags, false, &a2) ||
252 !args.GetNext(&a3)) { 291 !GetNextArgument(&args, holder->flags, false, &a3)) {
253 args.ThrowError(); 292 args.ThrowError();
254 return; 293 return;
294 }
295
296 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
255 } 297 }
256 298 };
257 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
258 }
259 299
260 template<typename R, typename P1, typename P2, typename P3, typename P4> 300 template<typename R, typename P1, typename P2, typename P3, typename P4>
261 static void DispatchToCallback( 301 struct Dispatcher<R(P1, P2, P3, P4)> {
262 const v8::FunctionCallbackInfo<v8::Value>& info) { 302 static void DispatchToCallback(
263 Arguments args(info); 303 const v8::FunctionCallbackInfo<v8::Value>& info) {
264 CallbackHolderBase* holder_base = NULL; 304 Arguments args(info);
265 CHECK(args.GetData(&holder_base)); 305 CallbackHolderBase* holder_base = NULL;
306 CHECK(args.GetData(&holder_base));
266 307
267 typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT; 308 typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
268 HolderT* holder = static_cast<HolderT*>(holder_base); 309 HolderT* holder = static_cast<HolderT*>(holder_base);
269 310
270 typename RemoveConstRef<P1>::Type a1; 311 typename RemoveConstRef<P1>::Type a1;
271 typename RemoveConstRef<P2>::Type a2; 312 typename RemoveConstRef<P2>::Type a2;
272 typename RemoveConstRef<P3>::Type a3; 313 typename RemoveConstRef<P3>::Type a3;
273 typename RemoveConstRef<P4>::Type a4; 314 typename RemoveConstRef<P4>::Type a4;
274 if (!args.GetNext(&a1) || 315 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
275 !args.GetNext(&a2) || 316 !GetNextArgument(&args, holder->flags, false, &a2) ||
276 !args.GetNext(&a3) || 317 !GetNextArgument(&args, holder->flags, false, &a3) ||
277 !args.GetNext(&a4)) { 318 !GetNextArgument(&args, holder->flags, false, &a4)) {
278 args.ThrowError(); 319 args.ThrowError();
279 return; 320 return;
321 }
322
323 Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
280 } 324 }
281 325 };
282 Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
283 }
284 326
285 } // namespace internal 327 } // namespace internal
286 328
287 329
288 // This should be called once per-isolate to initialize the function template 330 // This should be called once per-isolate to initialize the function template
289 // system. 331 // system.
290 void InitFunctionTemplates(PerIsolateData* isolate_data); 332 void InitFunctionTemplates(PerIsolateData* isolate_data);
291 333
292 334
293 // This has to be outside the internal namespace because template 335 // This has to be outside the internal namespace because template
294 // specializations must be declared in the same namespace as the original 336 // specializations must be declared in the same namespace as the original
295 // template. 337 // template.
296 template<> 338 template<>
297 struct Converter<internal::CallbackHolderBase*> 339 struct Converter<internal::CallbackHolderBase*>
298 : public WrappableConverter<internal::CallbackHolderBase> {}; 340 : public WrappableConverter<internal::CallbackHolderBase> {};
299 341
300 342
301 // Creates a v8::FunctionTemplate that will run the provided base::Callback each 343 // CreateFunctionTemplate creates a v8::FunctionTemplate that will create
302 // time it is called. JavaScript arguments and return values are converted via 344 // JavaScript functions that execute a provided C++ function or base::Callback.
303 // gin::Converter. 345 // JavaScript arguments are automatically converted via gin::Converter, as is
304 template<typename R> 346 // the return value of the C++ function, if any.
347 template<typename Sig>
305 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate( 348 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
306 v8::Isolate* isolate, 349 v8::Isolate* isolate,
307 const base::Callback<R()> callback) { 350 const base::Callback<Sig> callback,
308 typedef internal::CallbackHolder<R()> HolderT; 351 int flags = 0) {
309 scoped_refptr<HolderT> holder(new HolderT(callback)); 352 typedef internal::CallbackHolder<Sig> HolderT;
353 scoped_refptr<HolderT> holder(new HolderT(callback, flags));
310 return v8::FunctionTemplate::New( 354 return v8::FunctionTemplate::New(
311 &internal::DispatchToCallback<R>, 355 &internal::Dispatcher<Sig>::DispatchToCallback,
312 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get())); 356 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
313 } 357 }
314 358
315 template<typename R, typename P1>
316 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
317 v8::Isolate* isolate,
318 const base::Callback<R(P1)> callback) {
319 typedef internal::CallbackHolder<R(P1)> HolderT;
320 scoped_refptr<HolderT> holder(new HolderT(callback));
321 return v8::FunctionTemplate::New(
322 &internal::DispatchToCallback<R, P1>,
323 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
324 }
325
326 template<typename R, typename P1, typename P2>
327 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
328 v8::Isolate* isolate,
329 const base::Callback<R(P1, P2)> callback) {
330 typedef internal::CallbackHolder<R(P1, P2)> HolderT;
331 scoped_refptr<HolderT> holder(new HolderT(callback));
332 return v8::FunctionTemplate::New(
333 &internal::DispatchToCallback<R, P1, P2>,
334 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
335 }
336
337 template<typename R, typename P1, typename P2, typename P3>
338 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
339 v8::Isolate* isolate,
340 const base::Callback<R(P1, P2, P3)> callback) {
341 typedef internal::CallbackHolder<R(P1, P2, P3)> HolderT;
342 scoped_refptr<HolderT> holder(new HolderT(callback));
343 return v8::FunctionTemplate::New(
344 &internal::DispatchToCallback<R, P1, P2, P3>,
345 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
346 }
347
348 template<typename R, typename P1, typename P2, typename P3, typename P4>
349 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
350 v8::Isolate* isolate,
351 const base::Callback<R(P1, P2, P3, P4)> callback) {
352 typedef internal::CallbackHolder<R(P1, P2, P3, P4)> HolderT;
353 scoped_refptr<HolderT> holder(new HolderT(callback));
354 return v8::FunctionTemplate::New(
355 &internal::DispatchToCallback<R, P1, P2, P3, P4>,
356 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
357 }
358
359 } // namespace gin 359 } // namespace gin
360 360
361 #endif // GIN_FUNCTION_TEMPLATE_H_ 361 #endif // GIN_FUNCTION_TEMPLATE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698