| OLD | NEW | 
|    1 $$ This is a pump file for generating file templates.  Pump is a python |    1 $$ This is a pump file for generating file templates.  Pump is a python | 
|    2 $$ script that is part of the Google Test suite of utilities.  Description |    2 $$ script that is part of the Google Test suite of utilities.  Description | 
|    3 $$ can be found here: |    3 $$ can be found here: | 
|    4 $$ |    4 $$ | 
|    5 $$ http://code.google.com/p/googletest/wiki/PumpManual |    5 $$ http://code.google.com/p/googletest/wiki/PumpManual | 
|    6 $$ |    6 $$ | 
|    7  |    7  | 
|    8 #ifndef GIN_FUNCTION_TEMPLATE_H_ |    8 #ifndef GIN_FUNCTION_TEMPLATE_H_ | 
|    9 #define GIN_FUNCTION_TEMPLATE_H_ |    9 #define GIN_FUNCTION_TEMPLATE_H_ | 
|   10  |   10  | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   22 #include "gin/public/gin_embedders.h" |   22 #include "gin/public/gin_embedders.h" | 
|   23 #include "gin/public/wrapper_info.h" |   23 #include "gin/public/wrapper_info.h" | 
|   24 #include "gin/wrappable.h" |   24 #include "gin/wrappable.h" | 
|   25  |   25  | 
|   26 #include "v8/include/v8.h" |   26 #include "v8/include/v8.h" | 
|   27  |   27  | 
|   28 namespace gin { |   28 namespace gin { | 
|   29  |   29  | 
|   30 class PerIsolateData; |   30 class PerIsolateData; | 
|   31  |   31  | 
 |   32 enum CreateFunctionTemplateFlags { | 
 |   33   HolderIsFirstArgument = 1 << 0, | 
 |   34 }; | 
 |   35  | 
|   32 namespace internal { |   36 namespace internal { | 
|   33  |   37  | 
|   34 template<typename T> |   38 template<typename T> | 
|   35 struct RemoveConstRef { |   39 struct CallbackParamTraits { | 
|   36   typedef T Type; |   40   typedef T LocalType; | 
|   37 }; |   41 }; | 
|   38 template<typename T> |   42 template<typename T> | 
|   39 struct RemoveConstRef<const T&> { |   43 struct CallbackParamTraits<const T&> { | 
|   40   typedef T Type; |   44   typedef T LocalType; | 
 |   45 }; | 
 |   46 template<typename T> | 
 |   47 struct CallbackParamTraits<const T*> { | 
 |   48   typedef T* LocalType; | 
|   41 }; |   49 }; | 
|   42  |   50  | 
|   43  |   51  | 
|   44 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from |   52 // CallbackHolder and CallbackHolderBase are used to pass a base::Callback from | 
|   45 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to  |   53 // CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to  | 
|   46 // DispatchToCallback, where it is invoked. |   54 // DispatchToCallback, where it is invoked. | 
|   47 // |   55 // | 
|   48 // v8::FunctionTemplate only supports passing void* as data so how do we know |   56 // v8::FunctionTemplate only supports passing void* as data so how do we know | 
|   49 // when to delete the base::Callback? That's where CallbackHolderBase comes in. |   57 // when to delete the base::Callback? That's where CallbackHolderBase comes in. | 
|   50 // It inherits from Wrappable, which delete itself when both (a) the refcount |   58 // It inherits from Wrappable, which delete itself when both (a) the refcount | 
|   51 // via base::RefCounted has dropped to zero, and (b) there are no more |   59 // via base::RefCounted has dropped to zero, and (b) there are no more | 
|   52 // JavaScript references in V8. |   60 // JavaScript references in V8. | 
|   53 class CallbackHolderBase : public Wrappable { |   61 class CallbackHolderBase : public Wrappable { | 
|   54  public: |   62  public: | 
|   55   virtual WrapperInfo* GetWrapperInfo() OVERRIDE; |   63   virtual WrapperInfo* GetWrapperInfo() OVERRIDE; | 
|   56   static WrapperInfo kWrapperInfo; |   64   static WrapperInfo kWrapperInfo; | 
|   57  protected: |   65  protected: | 
|   58   virtual ~CallbackHolderBase() {} |   66   virtual ~CallbackHolderBase() {} | 
|   59 }; |   67 }; | 
|   60  |   68  | 
|   61 template<typename Sig> |   69 template<typename Sig> | 
|   62 class CallbackHolder : public CallbackHolderBase { |   70 class CallbackHolder : public CallbackHolderBase { | 
|   63  public: |   71  public: | 
|   64   CallbackHolder(const base::Callback<Sig>& callback) |   72   CallbackHolder(const base::Callback<Sig>& callback, int flags) | 
|   65       : callback(callback) {} |   73       : callback(callback), flags(flags) {} | 
|   66   base::Callback<Sig> callback; |   74   base::Callback<Sig> callback; | 
 |   75   int flags; | 
|   67  private: |   76  private: | 
|   68   virtual ~CallbackHolder() {} |   77   virtual ~CallbackHolder() {} | 
|   69 }; |   78 }; | 
|   70  |   79  | 
|   71  |   80  | 
|   72 // This set of templates invokes a base::Callback, converts the return type to a |   81 // This set of templates invokes a base::Callback, converts the return type to a | 
|   73 // JavaScript value, and returns that value to script via the provided |   82 // JavaScript value, and returns that value to script via the provided | 
|   74 // gin::Arguments object. |   83 // gin::Arguments object. | 
|   75 // |   84 // | 
|   76 // In C++, you can declare the function foo(void), but you can't pass a void |   85 // In C++, you can declare the function foo(void), but you can't pass a void | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|  104       Arguments* args, |  113       Arguments* args, | 
|  105       const base::Callback<void($for ARG , [[P$(ARG)]])>& callback$for ARG [[, |  114       const base::Callback<void($for ARG , [[P$(ARG)]])>& callback$for ARG [[, | 
|  106       const P$(ARG)& a$(ARG)]]) { |  115       const P$(ARG)& a$(ARG)]]) { | 
|  107     callback.Run($for ARG, [[a$(ARG)]]); |  116     callback.Run($for ARG, [[a$(ARG)]]); | 
|  108   } |  117   } | 
|  109 }; |  118 }; | 
|  110  |  119  | 
|  111  |  120  | 
|  112 ]] |  121 ]] | 
|  113  |  122  | 
 |  123 template<typename T> | 
 |  124 bool GetNextArgument(Arguments* args, int create_flags, bool is_first, | 
 |  125                      T* result) { | 
 |  126   if (is_first && (create_flags & HolderIsFirstArgument) != 0) { | 
 |  127     return args->GetHolder(result); | 
 |  128   } else { | 
 |  129     return args->GetNext(result); | 
 |  130   } | 
 |  131 } | 
 |  132  | 
 |  133 // For advanced use cases, we allow callers to request the unparsed Arguments | 
 |  134 // object and poke around in it directly. | 
 |  135 inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first, | 
 |  136                             Arguments* result) { | 
 |  137   *result = *args; | 
 |  138   return true; | 
 |  139 } | 
 |  140  | 
 |  141  | 
|  114 // DispatchToCallback converts all the JavaScript arguments to C++ types and |  142 // DispatchToCallback converts all the JavaScript arguments to C++ types and | 
|  115 // invokes the base::Callback. |  143 // invokes the base::Callback. | 
 |  144 template<typename Sig> | 
 |  145 struct Dispatcher { | 
 |  146 }; | 
 |  147  | 
|  116 $range ARITY 0..MAX_ARITY |  148 $range ARITY 0..MAX_ARITY | 
|  117 $for ARITY [[ |  149 $for ARITY [[ | 
|  118 $range ARG 1..ARITY |  150 $range ARG 1..ARITY | 
|  119  |  151  | 
|  120 template<typename R$for ARG [[, typename P$(ARG)]]> |  152 template<typename R$for ARG [[, typename P$(ARG)]]> | 
|  121 static void DispatchToCallback( |  153 struct Dispatcher<R($for ARG , [[P$(ARG)]])> { | 
|  122     const v8::FunctionCallbackInfo<v8::Value>& info) { |  154   static void DispatchToCallback( | 
|  123   Arguments args(info); |  155       const v8::FunctionCallbackInfo<v8::Value>& info) { | 
|  124   CallbackHolderBase* holder_base = NULL; |  156     Arguments args(info); | 
|  125   CHECK(args.GetData(&holder_base)); |  157     CallbackHolderBase* holder_base = NULL; | 
 |  158     CHECK(args.GetData(&holder_base)); | 
|  126  |  159  | 
|  127   typedef CallbackHolder<R($for ARG , [[P$(ARG)]])> HolderT; |  160     typedef CallbackHolder<R($for ARG , [[P$(ARG)]])> HolderT; | 
|  128   HolderT* holder = static_cast<HolderT*>(holder_base); |  161     HolderT* holder = static_cast<HolderT*>(holder_base); | 
|  129  |  162  | 
|  130 $if ARITY != 0 [[ |  163 $if ARITY != 0 [[ | 
|  131  |  164  | 
|  132  |  165  | 
|  133 $for ARG [[  typename RemoveConstRef<P$(ARG)>::Type a$(ARG); |  166 $for ARG [[    typename CallbackParamTraits<P$(ARG)>::LocalType a$(ARG); | 
|  134  |  167  | 
|  135 ]] |  168 ]] | 
|  136   if ( |  169     if ($for ARG  || | 
|  137 $for ARG  || |  170         [[!GetNextArgument(&args, holder->flags, $if ARG == 1 [[true]] $else [[f
     alse]], &a$(ARG))]]) { | 
|  138       [[!args.GetNext(&a$(ARG))]]) { |  171       args.ThrowError(); | 
|  139     args.ThrowError(); |  172       return; | 
|  140     return; |  173     } | 
|  141   } |  | 
|  142  |  174  | 
|  143 ]] |  175 ]] | 
|  144  |  176  | 
|  145   Invoker<R$for ARG [[, P$(ARG)]]>::Go(&args, holder->callback$for ARG [[, a$(AR
     G)]]); |  177     Invoker<R$for ARG [[, P$(ARG)]]>::Go(&args, holder->callback$for ARG [[, a$(
     ARG)]]); | 
|  146 } |  178   } | 
 |  179 }; | 
|  147  |  180  | 
|  148 ]] |  181 ]] | 
|  149  |  182  | 
|  150 }  // namespace internal |  183 }  // namespace internal | 
|  151  |  184  | 
|  152  |  185  | 
|  153 // This should be called once per-isolate to initialize the function template |  186 // This should be called once per-isolate to initialize the function template | 
|  154 // system. |  187 // system. | 
|  155 void InitFunctionTemplates(PerIsolateData* isolate_data); |  188 void InitFunctionTemplates(PerIsolateData* isolate_data); | 
|  156  |  189  | 
|  157  |  190  | 
|  158 // This has to be outside the internal namespace because template |  191 // This has to be outside the internal namespace because template | 
|  159 // specializations must be declared in the same namespace as the original |  192 // specializations must be declared in the same namespace as the original | 
|  160 // template. |  193 // template. | 
|  161 template<> |  194 template<> | 
|  162 struct Converter<internal::CallbackHolderBase*> |  195 struct Converter<internal::CallbackHolderBase*> | 
|  163     : public WrappableConverter<internal::CallbackHolderBase> {}; |  196     : public WrappableConverter<internal::CallbackHolderBase> {}; | 
|  164  |  197  | 
|  165  |  198  | 
|  166 // Creates a v8::FunctionTemplate that will run the provided base::Callback each |  199 // CreateFunctionTemplate creates a v8::FunctionTemplate that will create | 
|  167 // time it is called. JavaScript arguments and return values are converted via |  200 // JavaScript functions that execute a provided C++ function or base::Callback. | 
|  168 // gin::Converter. |  201 // JavaScript arguments are automatically converted via gin::Converter, as is | 
|  169 $range ARITY 0..MAX_ARITY |  202 // the return value of the C++ function, if any. | 
|  170 $for ARITY [[ |  203 template<typename Sig> | 
|  171 $range ARG 1..ARITY |  | 
|  172  |  | 
|  173 template<typename R$for ARG [[, typename P$(ARG)]]> |  | 
|  174 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate( |  204 v8::Local<v8::FunctionTemplate> CreateFunctionTemplate( | 
|  175     v8::Isolate* isolate, |  205     v8::Isolate* isolate, const base::Callback<Sig> callback, | 
|  176     const base::Callback<R($for ARG , [[P$(ARG)]])> callback) { |  206     int callback_flags = 0) { | 
|  177   typedef internal::CallbackHolder<R($for ARG , [[P$(ARG)]])> HolderT; |  207   typedef internal::CallbackHolder<Sig> HolderT; | 
|  178   gin::Handle<HolderT> holder = CreateHandle(isolate, new HolderT(callback)); |  208   gin::Handle<HolderT> holder = CreateHandle( | 
 |  209       isolate, new HolderT(callback, callback_flags)); | 
|  179   return v8::FunctionTemplate::New( |  210   return v8::FunctionTemplate::New( | 
|  180       isolate, |  211       &internal::Dispatcher<Sig>::DispatchToCallback, | 
|  181       &internal::DispatchToCallback<R$for ARG [[, P$(ARG)]]>, |  | 
|  182       ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get())); |  212       ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get())); | 
|  183 } |  213 } | 
|  184  |  214  | 
|  185 ]] |  | 
|  186  |  | 
|  187 }  // namespace gin |  215 }  // namespace gin | 
|  188  |  216  | 
|  189 #endif  // GIN_FUNCTION_TEMPLATE_H_ |  217 #endif  // GIN_FUNCTION_TEMPLATE_H_ | 
| OLD | NEW |