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

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: blah 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 10 matching lines...) Expand all
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698