OLD | NEW |
---|---|
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 Loading... | |
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_ |
OLD | NEW |