diff options
author | Andras Becsi <andras.becsi@digia.com> | 2014-03-18 13:16:26 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-03-20 15:55:39 +0100 |
commit | 3f0f86b0caed75241fa71c95a5d73bc0164348c5 (patch) | |
tree | 92b9fb00f2e9e90b0be2262093876d4f43b6cd13 /chromium/gin/function_template.h | |
parent | e90d7c4b152c56919d963987e2503f9909a666d2 (diff) | |
download | qtwebengine-chromium-3f0f86b0caed75241fa71c95a5d73bc0164348c5.tar.gz |
Update to new stable branch 1750
This also includes an updated ninja and chromium dependencies
needed on Windows.
Change-Id: Icd597d80ed3fa4425933c9f1334c3c2e31291c42
Reviewed-by: Zoltan Arvai <zarvai@inf.u-szeged.hu>
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'chromium/gin/function_template.h')
-rw-r--r-- | chromium/gin/function_template.h | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/chromium/gin/function_template.h b/chromium/gin/function_template.h new file mode 100644 index 00000000000..14f6e78fe2f --- /dev/null +++ b/chromium/gin/function_template.h @@ -0,0 +1,357 @@ +// This file was GENERATED by command: +// pump.py function_template.h.pump +// DO NOT EDIT BY HAND!!! + + + +#ifndef GIN_FUNCTION_TEMPLATE_H_ +#define GIN_FUNCTION_TEMPLATE_H_ + +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/callback.h" +#include "base/logging.h" +#include "gin/arguments.h" +#include "gin/converter.h" +#include "gin/gin_export.h" +#include "gin/handle.h" +#include "gin/public/gin_embedders.h" +#include "gin/public/wrapper_info.h" +#include "gin/wrappable.h" + +#include "v8/include/v8.h" + +namespace gin { + +class PerIsolateData; + +enum CreateFunctionTemplateFlags { + HolderIsFirstArgument = 1 << 0, +}; + +namespace internal { + +template<typename T> +struct CallbackParamTraits { + typedef T LocalType; +}; +template<typename T> +struct CallbackParamTraits<const T&> { + typedef T LocalType; +}; +template<typename T> +struct CallbackParamTraits<const T*> { + typedef T* LocalType; +}; + + +// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from +// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to +// DispatchToCallback, where it is invoked. +// +// v8::FunctionTemplate only supports passing void* as data so how do we know +// when to delete the base::Callback? That's where CallbackHolderBase comes in. +// It inherits from Wrappable, which delete itself when both (a) the refcount +// via base::RefCounted has dropped to zero, and (b) there are no more +// JavaScript references in V8. + +// This simple base class is used so that we can share a single object template +// among every CallbackHolder instance. +class GIN_EXPORT CallbackHolderBase : public Wrappable<CallbackHolderBase> { + public: + static WrapperInfo kWrapperInfo; + protected: + virtual ~CallbackHolderBase() {} +}; + +template<typename Sig> +class CallbackHolder : public CallbackHolderBase { + public: + CallbackHolder(const base::Callback<Sig>& callback, int flags) + : callback(callback), flags(flags) {} + base::Callback<Sig> callback; + int flags; + private: + virtual ~CallbackHolder() {} +}; + + +// This set of templates invokes a base::Callback, converts the return type to a +// JavaScript value, and returns that value to script via the provided +// gin::Arguments object. +// +// 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, 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, + const P3& a3) { + args->Return(callback.Run(a1, a2, a3)); + } +}; +template<typename P1, typename P2, typename P3> +struct Invoker<void, P1, P2, P3, void> { + inline static void Go( + Arguments* args, + const base::Callback<void(P1, P2, P3)>& callback, + const P1& a1, + const P2& a2, + const P3& a3) { + callback.Run(a1, a2, a3); + } +}; + +template<typename R, typename P1, typename P2> +struct Invoker<R, P1, P2, void, void> { + inline static void Go( + Arguments* args, + const base::Callback<R(P1, P2)>& callback, + const P1& a1, + const P2& a2) { + args->Return(callback.Run(a1, a2)); + } +}; +template<typename P1, typename P2> +struct Invoker<void, P1, P2, void, void> { + inline static void Go( + Arguments* args, + const base::Callback<void(P1, P2)>& callback, + const P1& a1, + const P2& a2) { + callback.Run(a1, a2); + } +}; + +template<typename R, typename P1> +struct Invoker<R, P1, void, void, void> { + inline static void Go( + Arguments* args, + const base::Callback<R(P1)>& callback, + const P1& a1) { + args->Return(callback.Run(a1)); + } +}; +template<typename P1> +struct Invoker<void, P1, void, void, void> { + inline static void Go( + Arguments* args, + const base::Callback<void(P1)>& callback, + const P1& a1) { + callback.Run(a1); + } +}; + +template<typename R> +struct Invoker<R, void, void, void, void> { + inline static void Go( + Arguments* args, + const base::Callback<R()>& callback) { + args->Return(callback.Run()); + } +}; +template<> +struct Invoker<void, void, void, void, void> { + inline static void Go( + Arguments* args, + const base::Callback<void()>& callback) { + callback.Run(); + } +}; + + +template<typename T> +bool GetNextArgument(Arguments* args, int create_flags, bool is_first, + T* result) { + if (is_first && (create_flags & HolderIsFirstArgument) != 0) { + return args->GetHolder(result); + } else { + return args->GetNext(result); + } +} + +// For advanced use cases, we allow callers to request the unparsed Arguments +// object and poke around in it directly. +inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first, + Arguments* result) { + *result = *args; + return true; +} + + +// DispatchToCallback converts all the JavaScript arguments to C++ types and +// invokes the base::Callback. +template<typename Sig> +struct Dispatcher { +}; + +template<typename R> +struct Dispatcher<R()> { + static void DispatchToCallback( + const v8::FunctionCallbackInfo<v8::Value>& info) { + Arguments args(info); + CallbackHolderBase* holder_base = NULL; + CHECK(args.GetData(&holder_base)); + + typedef CallbackHolder<R()> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + Invoker<R>::Go(&args, holder->callback); + } +}; + +template<typename R, typename P1> +struct Dispatcher<R(P1)> { + 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)> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + typename CallbackParamTraits<P1>::LocalType a1; + if (!GetNextArgument(&args, holder->flags, true, &a1)) { + args.ThrowError(); + return; + } + + Invoker<R, P1>::Go(&args, holder->callback, a1); + } +}; + +template<typename R, typename P1, typename P2> +struct Dispatcher<R(P1, P2)> { + 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)> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + typename CallbackParamTraits<P1>::LocalType a1; + typename CallbackParamTraits<P2>::LocalType a2; + if (!GetNextArgument(&args, holder->flags, true, &a1) || + !GetNextArgument(&args, holder->flags, false, &a2)) { + args.ThrowError(); + return; + } + + Invoker<R, P1, P2>::Go(&args, holder->callback, a1, a2); + } +}; + +template<typename R, typename P1, typename P2, typename P3> +struct Dispatcher<R(P1, P2, P3)> { + 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)> HolderT; + HolderT* holder = static_cast<HolderT*>(holder_base); + + typename CallbackParamTraits<P1>::LocalType a1; + typename CallbackParamTraits<P2>::LocalType a2; + typename CallbackParamTraits<P3>::LocalType a3; + if (!GetNextArgument(&args, holder->flags, true, &a1) || + !GetNextArgument(&args, holder->flags, false, &a2) || + !GetNextArgument(&args, holder->flags, false, &a3)) { + args.ThrowError(); + return; + } + + Invoker<R, P1, P2, P3>::Go(&args, holder->callback, a1, a2, a3); + } +}; + +template<typename R, typename P1, typename P2, typename P3, typename P4> +struct Dispatcher<R(P1, P2, P3, 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 CallbackParamTraits<P1>::LocalType a1; + typename CallbackParamTraits<P2>::LocalType a2; + typename CallbackParamTraits<P3>::LocalType a3; + typename CallbackParamTraits<P4>::LocalType a4; + if (!GetNextArgument(&args, holder->flags, true, &a1) || + !GetNextArgument(&args, holder->flags, false, &a2) || + !GetNextArgument(&args, holder->flags, false, &a3) || + !GetNextArgument(&args, holder->flags, false, &a4)) { + args.ThrowError(); + return; + } + + Invoker<R, P1, P2, P3, P4>::Go(&args, holder->callback, a1, a2, a3, a4); + } +}; + +} // namespace internal + + +// This should be called once per-isolate to initialize the function template +// system. +GIN_EXPORT void InitFunctionTemplates(PerIsolateData* isolate_data); + + +// CreateFunctionTemplate creates a v8::FunctionTemplate that will create +// JavaScript functions that execute a provided C++ function or base::Callback. +// JavaScript arguments are automatically converted via gin::Converter, as is +// the return value of the C++ function, if any. +template<typename Sig> +v8::Local<v8::FunctionTemplate> CreateFunctionTemplate( + v8::Isolate* isolate, const base::Callback<Sig> callback, + int callback_flags = 0) { + typedef internal::CallbackHolder<Sig> HolderT; + gin::Handle<HolderT> holder = CreateHandle( + isolate, new HolderT(callback, callback_flags)); + return v8::FunctionTemplate::New( + &internal::Dispatcher<Sig>::DispatchToCallback, + ConvertToV8<internal::CallbackHolderBase*>(isolate, holder.get())); +} + +} // namespace gin + +#endif // GIN_FUNCTION_TEMPLATE_H_ |