Index: gin/function_template.h |
diff --git a/gin/function_template.h b/gin/function_template.h |
index 0685c1b4c2b4ad5d49ff18dbe46cebd2ac52655a..99165f55606fbc93478cd2934d4a15a6f15b0796 100644 |
--- a/gin/function_template.h |
+++ b/gin/function_template.h |
@@ -69,10 +69,36 @@ class CallbackHolder : public CallbackHolderBase { |
// In C++, you can declare the function foo(void), but you can't pass a void |
// expression to foo. As a result, we must specialize the case of Callbacks that |
// have the void return type. |
-template<typename R, typename P1 = void, typename P2 = void, typename P3 = void> |
+template<typename R, typename P1 = void, typename P2 = void, |
+ typename P3 = void, typename P4 = void> |
struct Invoker { |
inline static void Go( |
Arguments* args, |
+ const base::Callback<R(P1, P2, P3, P4)>& callback, |
+ const P1& a1, |
+ const P2& a2, |
+ const P3& a3, |
+ const P4& a4) { |
+ args->Return(callback.Run(a1, a2, a3, a4)); |
+ } |
+}; |
+template<typename P1, typename P2, typename P3, typename P4> |
+struct Invoker<void, P1, P2, P3, P4> { |
+ inline static void Go( |
+ Arguments* args, |
+ const base::Callback<void(P1, P2, P3, P4)>& callback, |
+ const P1& a1, |
+ const P2& a2, |
+ const P3& a3, |
+ const P4& a4) { |
+ callback.Run(a1, a2, a3, a4); |
+ } |
+}; |
+ |
+template<typename R, typename P1, typename P2, typename P3> |
+struct Invoker<R, P1, P2, P3, void> { |
+ inline static void Go( |
+ Arguments* args, |
const base::Callback<R(P1, P2, P3)>& callback, |
const P1& a1, |
const P2& a2, |
@@ -81,7 +107,7 @@ struct Invoker { |
} |
}; |
template<typename P1, typename P2, typename P3> |
-struct Invoker<void, P1, P2, P3> { |
+struct Invoker<void, P1, P2, P3, void> { |
inline static void Go( |
Arguments* args, |
const base::Callback<void(P1, P2, P3)>& callback, |
@@ -93,7 +119,7 @@ struct Invoker<void, P1, P2, P3> { |
}; |
template<typename R, typename P1, typename P2> |
-struct Invoker<R, P1, P2, void> { |
+struct Invoker<R, P1, P2, void, void> { |
inline static void Go( |
Arguments* args, |
const base::Callback<R(P1, P2)>& callback, |
@@ -103,7 +129,7 @@ struct Invoker<R, P1, P2, void> { |
} |
}; |
template<typename P1, typename P2> |
-struct Invoker<void, P1, P2, void> { |
+struct Invoker<void, P1, P2, void, void> { |
inline static void Go( |
Arguments* args, |
const base::Callback<void(P1, P2)>& callback, |
@@ -114,7 +140,7 @@ struct Invoker<void, P1, P2, void> { |
}; |
template<typename R, typename P1> |
-struct Invoker<R, P1, void, void> { |
+struct Invoker<R, P1, void, void, void> { |
inline static void Go( |
Arguments* args, |
const base::Callback<R(P1)>& callback, |
@@ -123,7 +149,7 @@ struct Invoker<R, P1, void, void> { |
} |
}; |
template<typename P1> |
-struct Invoker<void, P1, void, void> { |
+struct Invoker<void, P1, void, void, void> { |
inline static void Go( |
Arguments* args, |
const base::Callback<void(P1)>& callback, |
@@ -133,7 +159,7 @@ struct Invoker<void, P1, void, void> { |
}; |
template<typename R> |
-struct Invoker<R, void, void, void> { |
+struct Invoker<R, void, void, void, void> { |
inline static void Go( |
Arguments* args, |
const base::Callback<R()>& callback) { |
@@ -141,7 +167,7 @@ struct Invoker<R, void, void, void> { |
} |
}; |
template<> |
-struct Invoker<void, void, void, void> { |
+struct Invoker<void, void, void, void, void> { |
inline static void Go( |
Arguments* args, |
const base::Callback<void()>& callback) { |
@@ -228,6 +254,31 @@ static void DispatchToCallback( |
Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3); |
} |
+template<typename R, typename P1, typename P2, typename P3, typename P4> |
+static void DispatchToCallback( |
+ const v8::FunctionCallbackInfo<v8::Value>& info) { |
+ Arguments args(info); |
+ CallbackHolderBase* holder_base = NULL; |
+ CHECK(args.GetData(&holder_base)); |
+ |
+ typedef CallbackHolder<R(P1, P2, P3, P4)> HolderT; |
+ HolderT* holder = static_cast<HolderT*>(holder_base); |
+ |
+ typename RemoveConstRef<P1>::Type a1; |
+ typename RemoveConstRef<P2>::Type a2; |
+ typename RemoveConstRef<P3>::Type a3; |
+ typename RemoveConstRef<P4>::Type a4; |
+ if (!args.GetNext(&a1) || |
+ !args.GetNext(&a2) || |
+ !args.GetNext(&a3) || |
+ !args.GetNext(&a4)) { |
+ args.ThrowError(); |
+ return; |
+ } |
+ |
+ Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4); |
+} |
+ |
} // namespace internal |
@@ -235,6 +286,7 @@ static void DispatchToCallback( |
// system. |
void InitFunctionTemplates(PerIsolateData* isolate_data); |
+ |
// This has to be outside the internal namespace because template |
// specializations must be declared in the same namespace as the original |
// template. |
@@ -290,4 +342,15 @@ v8::Local<v8::FunctionTemplate> CreateFunctionTemplate( |
ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get())); |
} |
+template<typename R, typename P1, typename P2, typename P3, typename P4> |
+v8::Local<v8::FunctionTemplate> CreateFunctionTemplate( |
+ v8::Isolate* isolate, |
+ const base::Callback<R(P1, P2, P3, P4)> callback) { |
+ typedef internal::CallbackHolder<R(P1, P2, P3, P4)> HolderT; |
+ scoped_refptr<HolderT> holder(new HolderT(callback)); |
+ return v8::FunctionTemplate::New( |
+ &internal::DispatchToCallback<R, P1, P2, P3, P4>, |
+ ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get())); |
+} |
+ |
} // namespace gin |