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

Side by Side Diff: gin/function_template.h.pump

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 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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698