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

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: rebase again 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/handle.h" 18 #include "gin/handle.h"
19 #include "gin/public/gin_embedders.h" 19 #include "gin/public/gin_embedders.h"
20 #include "gin/public/wrapper_info.h" 20 #include "gin/public/wrapper_info.h"
21 #include "gin/wrappable.h" 21 #include "gin/wrappable.h"
22 22
23 #include "v8/include/v8.h" 23 #include "v8/include/v8.h"
24 24
25 namespace gin { 25 namespace gin {
26 26
27 class PerIsolateData; 27 class PerIsolateData;
28 28
29 enum CreateFunctionTemplateFlags {
30 HolderIsFirstArgument = 1 << 0,
31 };
32
29 namespace internal { 33 namespace internal {
30 34
31 template<typename T> 35 template<typename T>
32 struct RemoveConstRef { 36 struct CallbackParamTraits {
33 typedef T Type; 37 typedef T LocalType;
34 }; 38 };
35 template<typename T> 39 template<typename T>
36 struct RemoveConstRef<const T&> { 40 struct CallbackParamTraits<const T&> {
37 typedef T Type; 41 typedef T LocalType;
42 };
43 template<typename T>
44 struct CallbackParamTraits<const T*> {
45 typedef T* LocalType;
38 }; 46 };
39 47
40 48
41 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from 49 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from
42 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to 50 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to
43 // DispatchToCallback, where it is invoked. 51 // DispatchToCallback, where it is invoked.
44 // 52 //
45 // v8::FunctionTemplate only supports passing void* as data so how do we know 53 // v8::FunctionTemplate only supports passing void* as data so how do we know
46 // when to delete the base::Callback? That's where CallbackHolderBase comes in. 54 // when to delete the base::Callback? That's where CallbackHolderBase comes in.
47 // It inherits from Wrappable, which delete itself when both (a) the refcount 55 // It inherits from Wrappable, which delete itself when both (a) the refcount
48 // via base::RefCounted has dropped to zero, and (b) there are no more 56 // via base::RefCounted has dropped to zero, and (b) there are no more
49 // JavaScript references in V8. 57 // JavaScript references in V8.
50 class CallbackHolderBase : public Wrappable { 58 class CallbackHolderBase : public Wrappable {
51 public: 59 public:
52 virtual WrapperInfo* GetWrapperInfo() OVERRIDE; 60 virtual WrapperInfo* GetWrapperInfo() OVERRIDE;
53 static WrapperInfo kWrapperInfo; 61 static WrapperInfo kWrapperInfo;
54 protected: 62 protected:
55 virtual ~CallbackHolderBase() {} 63 virtual ~CallbackHolderBase() {}
56 }; 64 };
57 65
58 template<typename Sig> 66 template<typename Sig>
59 class CallbackHolder : public CallbackHolderBase { 67 class CallbackHolder : public CallbackHolderBase {
60 public: 68 public:
61 CallbackHolder(const base::Callback<Sig>& callback) 69 CallbackHolder(const base::Callback<Sig>& callback, int flags)
62 : callback(callback) {} 70 : callback(callback), flags(flags) {}
63 base::Callback<Sig> callback; 71 base::Callback<Sig> callback;
72 int flags;
64 private: 73 private:
65 virtual ~CallbackHolder() {} 74 virtual ~CallbackHolder() {}
66 }; 75 };
67 76
68 77
69 // This set of templates invokes a base::Callback, converts the return type to a 78 // This set of templates invokes a base::Callback, converts the return type to a
70 // JavaScript value, and returns that value to script via the provided 79 // JavaScript value, and returns that value to script via the provided
71 // gin::Arguments object. 80 // gin::Arguments object.
72 // 81 //
73 // In C++, you can declare the function foo(void), but you can't pass a void 82 // 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
173 template<> 182 template<>
174 struct Invoker<void, void, void, void, void> { 183 struct Invoker<void, void, void, void, void> {
175 inline static void Go( 184 inline static void Go(
176 Arguments* args, 185 Arguments* args,
177 const base::Callback<void()>& callback) { 186 const base::Callback<void()>& callback) {
178 callback.Run(); 187 callback.Run();
179 } 188 }
180 }; 189 };
181 190
182 191
192 template<typename T>
193 bool 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.
204 inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
205 Arguments* result) {
206 *result = *args;
207 return true;
208 }
209
210
183 // DispatchToCallback converts all the JavaScript arguments to C++ types and 211 // DispatchToCallback converts all the JavaScript arguments to C++ types and
184 // invokes the base::Callback. 212 // invokes the base::Callback.
213 template<typename Sig>
214 struct Dispatcher {
215 };
216
185 template<typename R> 217 template<typename R>
186 static void DispatchToCallback( 218 struct Dispatcher<R()> {
187 const v8::FunctionCallbackInfo<v8::Value>& info) { 219 static void DispatchToCallback(
188 Arguments args(info); 220 const v8::FunctionCallbackInfo<v8::Value>& info) {
189 CallbackHolderBase* holder_base = NULL; 221 Arguments args(info);
190 CHECK(args.GetData(&holder_base)); 222 CallbackHolderBase* holder_base = NULL;
223 CHECK(args.GetData(&holder_base));
191 224
192 typedef CallbackHolder<R()> HolderT; 225 typedef CallbackHolder<R()> HolderT;
193 HolderT* holder = static_cast<HolderT*>(holder_base); 226 HolderT* holder = static_cast<HolderT*>(holder_base);
194 227
195 Invoker<R>::Go(&args, holder->callback); 228 Invoker<R>::Go(&args, holder->callback);
196 } 229 }
230 };
197 231
198 template<typename R, typename P1> 232 template<typename R, typename P1>
199 static void DispatchToCallback( 233 struct Dispatcher<R(P1)> {
200 const v8::FunctionCallbackInfo<v8::Value>& info) { 234 static void DispatchToCallback(
201 Arguments args(info); 235 const v8::FunctionCallbackInfo<v8::Value>& info) {
202 CallbackHolderBase* holder_base = NULL; 236 Arguments args(info);
203 CHECK(args.GetData(&holder_base)); 237 CallbackHolderBase* holder_base = NULL;
238 CHECK(args.GetData(&holder_base));
204 239
205 typedef CallbackHolder<R(P1)> HolderT; 240 typedef CallbackHolder<R(P1)> HolderT;
206 HolderT* holder = static_cast<HolderT*>(holder_base); 241 HolderT* holder = static_cast<HolderT*>(holder_base);
207 242
208 typename RemoveConstRef<P1>::Type a1; 243 typename CallbackParamTraits<P1>::LocalType a1;
209 if (!args.GetNext(&a1)) { 244 if (!GetNextArgument(&args, holder->flags, true, &a1)) {
210 args.ThrowError(); 245 args.ThrowError();
211 return; 246 return;
247 }
248
249 Invoker<R, P1>::Go(&args, holder->callback, a1);
212 } 250 }
213 251 };
214 Invoker<R, P1>::Go(&args, holder->callback, a1);
215 }
216 252
217 template<typename R, typename P1, typename P2> 253 template<typename R, typename P1, typename P2>
218 static void DispatchToCallback( 254 struct Dispatcher<R(P1, P2)> {
219 const v8::FunctionCallbackInfo<v8::Value>& info) { 255 static void DispatchToCallback(
220 Arguments args(info); 256 const v8::FunctionCallbackInfo<v8::Value>& info) {
221 CallbackHolderBase* holder_base = NULL; 257 Arguments args(info);
222 CHECK(args.GetData(&holder_base)); 258 CallbackHolderBase* holder_base = NULL;
259 CHECK(args.GetData(&holder_base));
223 260
224 typedef CallbackHolder<R(P1, P2)> HolderT; 261 typedef CallbackHolder<R(P1, P2)> HolderT;
225 HolderT* holder = static_cast<HolderT*>(holder_base); 262 HolderT* holder = static_cast<HolderT*>(holder_base);
226 263
227 typename RemoveConstRef<P1>::Type a1; 264 typename CallbackParamTraits<P1>::LocalType a1;
228 typename RemoveConstRef<P2>::Type a2; 265 typename CallbackParamTraits<P2>::LocalType a2;
229 if (!args.GetNext(&a1) || 266 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
230 !args.GetNext(&a2)) { 267 !GetNextArgument(&args, holder->flags, false, &a2)) {
231 args.ThrowError(); 268 args.ThrowError();
232 return; 269 return;
270 }
271
272 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
233 } 273 }
234 274 };
235 Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2);
236 }
237 275
238 template<typename R, typename P1, typename P2, typename P3> 276 template<typename R, typename P1, typename P2, typename P3>
239 static void DispatchToCallback( 277 struct Dispatcher<R(P1, P2, P3)> {
240 const v8::FunctionCallbackInfo<v8::Value>& info) { 278 static void DispatchToCallback(
241 Arguments args(info); 279 const v8::FunctionCallbackInfo<v8::Value>& info) {
242 CallbackHolderBase* holder_base = NULL; 280 Arguments args(info);
243 CHECK(args.GetData(&holder_base)); 281 CallbackHolderBase* holder_base = NULL;
282 CHECK(args.GetData(&holder_base));
244 283
245 typedef CallbackHolder<R(P1, P2, P3)> HolderT; 284 typedef CallbackHolder<R(P1, P2, P3)> HolderT;
246 HolderT* holder = static_cast<HolderT*>(holder_base); 285 HolderT* holder = static_cast<HolderT*>(holder_base);
247 286
248 typename RemoveConstRef<P1>::Type a1; 287 typename CallbackParamTraits<P1>::LocalType a1;
249 typename RemoveConstRef<P2>::Type a2; 288 typename CallbackParamTraits<P2>::LocalType a2;
250 typename RemoveConstRef<P3>::Type a3; 289 typename CallbackParamTraits<P3>::LocalType a3;
251 if (!args.GetNext(&a1) || 290 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
252 !args.GetNext(&a2) || 291 !GetNextArgument(&args, holder->flags, false, &a2) ||
253 !args.GetNext(&a3)) { 292 !GetNextArgument(&args, holder->flags, false, &a3)) {
254 args.ThrowError(); 293 args.ThrowError();
255 return; 294 return;
295 }
296
297 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
256 } 298 }
257 299 };
258 Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3);
259 }
260 300
261 template<typename R, typename P1, typename P2, typename P3, typename P4> 301 template<typename R, typename P1, typename P2, typename P3, typename P4>
262 static void DispatchToCallback( 302 struct Dispatcher<R(P1, P2, P3, P4)> {
263 const v8::FunctionCallbackInfo<v8::Value>& info) { 303 static void DispatchToCallback(
264 Arguments args(info); 304 const v8::FunctionCallbackInfo<v8::Value>& info) {
265 CallbackHolderBase* holder_base = NULL; 305 Arguments args(info);
266 CHECK(args.GetData(&holder_base)); 306 CallbackHolderBase* holder_base = NULL;
307 CHECK(args.GetData(&holder_base));
267 308
268 typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT; 309 typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT;
269 HolderT* holder = static_cast<HolderT*>(holder_base); 310 HolderT* holder = static_cast<HolderT*>(holder_base);
270 311
271 typename RemoveConstRef<P1>::Type a1; 312 typename CallbackParamTraits<P1>::LocalType a1;
272 typename RemoveConstRef<P2>::Type a2; 313 typename CallbackParamTraits<P2>::LocalType a2;
273 typename RemoveConstRef<P3>::Type a3; 314 typename CallbackParamTraits<P3>::LocalType a3;
274 typename RemoveConstRef<P4>::Type a4; 315 typename CallbackParamTraits<P4>::LocalType a4;
275 if (!args.GetNext(&a1) || 316 if (!GetNextArgument(&args, holder->flags, true, &a1) ||
276 !args.GetNext(&a2) || 317 !GetNextArgument(&args, holder->flags, false, &a2) ||
277 !args.GetNext(&a3) || 318 !GetNextArgument(&args, holder->flags, false, &a3) ||
278 !args.GetNext(&a4)) { 319 !GetNextArgument(&args, holder->flags, false, &a4)) {
279 args.ThrowError(); 320 args.ThrowError();
280 return; 321 return;
322 }
323
324 Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
281 } 325 }
282 326 };
283 Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4);
284 }
285 327
286 } // namespace internal 328 } // namespace internal
287 329
288 330
289 // This should be called once per-isolate to initialize the function template 331 // This should be called once per-isolate to initialize the function template
290 // system. 332 // system.
291 void InitFunctionTemplates(PerIsolateData* isolate_data); 333 void InitFunctionTemplates(PerIsolateData* isolate_data);
292 334
293 335
294 // This has to be outside the internal namespace because template 336 // This has to be outside the internal namespace because template
295 // specializations must be declared in the same namespace as the original 337 // specializations must be declared in the same namespace as the original
296 // template. 338 // template.
297 template<> 339 template<>
298 struct Converter<internal::CallbackHolderBase*> 340 struct Converter<internal::CallbackHolderBase*>
299 : public WrappableConverter<internal::CallbackHolderBase> {}; 341 : public WrappableConverter<internal::CallbackHolderBase> {};
300 342
301 343
302 // Creates a v8::FunctionTemplate that will run the provided base::Callback each 344 // CreateFunctionTemplate creates a v8::FunctionTemplate that will create
303 // time it is called. JavaScript arguments and return values are converted via 345 // JavaScript functions that execute a provided C++ function or base::Callback.
304 // gin::Converter. 346 // JavaScript arguments are automatically converted via gin::Converter, as is
305 template<typename R> 347 // the return value of the C++ function, if any.
348 template<typename Sig>
306 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate( 349 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
307 v8::Isolate* isolate, 350 v8::Isolate* isolate, const base::Callback<Sig> callback,
308 const base::Callback<R()> callback) { 351 int callback_flags = 0) {
309 typedef internal::CallbackHolder<R()> HolderT; 352 typedef internal::CallbackHolder<Sig> HolderT;
310 gin::Handle<HolderT> holder = CreateHandle(isolate, new HolderT(callback)); 353 gin::Handle<HolderT> holder = CreateHandle(
354 isolate, new HolderT(callback, callback_flags));
311 return v8::FunctionTemplate::New( 355 return v8::FunctionTemplate::New(
312 isolate, 356 &internal::Dispatcher<Sig>::DispatchToCallback,
313 &internal::DispatchToCallback<R>,
314 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get())); 357 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
315 } 358 }
316 359
317 template<typename R, typename P1>
318 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
319 v8::Isolate* isolate,
320 const base::Callback<R(P1)> callback) {
321 typedef internal::CallbackHolder<R(P1)> HolderT;
322 gin::Handle<HolderT> holder = CreateHandle(isolate, new HolderT(callback));
323 return v8::FunctionTemplate::New(
324 isolate,
325 &internal::DispatchToCallback<R, P1>,
326 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
327 }
328
329 template<typename R, typename P1, typename P2>
330 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
331 v8::Isolate* isolate,
332 const base::Callback<R(P1, P2)> callback) {
333 typedef internal::CallbackHolder<R(P1, P2)> HolderT;
334 gin::Handle<HolderT> holder = CreateHandle(isolate, new HolderT(callback));
335 return v8::FunctionTemplate::New(
336 isolate,
337 &internal::DispatchToCallback<R, P1, P2>,
338 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
339 }
340
341 template<typename R, typename P1, typename P2, typename P3>
342 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
343 v8::Isolate* isolate,
344 const base::Callback<R(P1, P2, P3)> callback) {
345 typedef internal::CallbackHolder<R(P1, P2, P3)> HolderT;
346 gin::Handle<HolderT> holder = CreateHandle(isolate, new HolderT(callback));
347 return v8::FunctionTemplate::New(
348 isolate,
349 &internal::DispatchToCallback<R, P1, P2, P3>,
350 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
351 }
352
353 template<typename R, typename P1, typename P2, typename P3, typename P4>
354 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(
355 v8::Isolate* isolate,
356 const base::Callback<R(P1, P2, P3, P4)> callback) {
357 typedef internal::CallbackHolder<R(P1, P2, P3, P4)> HolderT;
358 gin::Handle<HolderT> holder = CreateHandle(isolate, new HolderT(callback));
359 return v8::FunctionTemplate::New(
360 isolate,
361 &internal::DispatchToCallback<R, P1, P2, P3, P4>,
362 ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get()));
363 }
364
365 } // namespace gin 360 } // namespace gin
366 361
367 #endif // GIN_FUNCTION_TEMPLATE_H_ 362 #endif // GIN_FUNCTION_TEMPLATE_H_
OLDNEW
« no previous file with comments | « gin/arguments.cc ('k') | gin/function_template.h.pump » ('j') | gin/object_template_builder.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698