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