Chromium Code Reviews| 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 |