diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /security/sandbox/chromium/base/bind_internal.h | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'security/sandbox/chromium/base/bind_internal.h')
-rw-r--r-- | security/sandbox/chromium/base/bind_internal.h | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/security/sandbox/chromium/base/bind_internal.h b/security/sandbox/chromium/base/bind_internal.h new file mode 100644 index 000000000..ac7cd0098 --- /dev/null +++ b/security/sandbox/chromium/base/bind_internal.h @@ -0,0 +1,425 @@ +// Copyright (c) 2011 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. + +#ifndef BASE_BIND_INTERNAL_H_ +#define BASE_BIND_INTERNAL_H_ + +#include <stddef.h> + +#include <type_traits> + +#include "base/bind_helpers.h" +#include "base/callback_internal.h" +#include "base/memory/raw_scoped_refptr_mismatch_checker.h" +#include "base/memory/weak_ptr.h" +#include "base/template_util.h" +#include "base/tuple.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +#include "base/bind_internal_win.h" +#endif + +namespace base { +namespace internal { + +// See base/callback.h for user documentation. +// +// +// CONCEPTS: +// Runnable -- A type (really a type class) that has a single Run() method +// and a RunType typedef that corresponds to the type of Run(). +// A Runnable can declare that it should treated like a method +// call by including a typedef named IsMethod. The value of +// this typedef is NOT inspected, only the existence. When a +// Runnable declares itself a method, Bind() will enforce special +// refcounting + WeakPtr handling semantics for the first +// parameter which is expected to be an object. +// Functor -- A copyable type representing something that should be called. +// All function pointers, Callback<>, and Runnables are functors +// even if the invocation syntax differs. +// RunType -- A function type (as opposed to function _pointer_ type) for +// a Run() function. Usually just a convenience typedef. +// (Bound)Args -- A set of types that stores the arguments. +// +// Types: +// RunnableAdapter<> -- Wraps the various "function" pointer types into an +// object that adheres to the Runnable interface. +// ForceVoidReturn<> -- Helper class for translating function signatures to +// equivalent forms with a "void" return type. +// FunctorTraits<> -- Type traits used determine the correct RunType and +// RunnableType for a Functor. This is where function +// signature adapters are applied. +// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable +// type class that represents the underlying Functor. +// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it. +// Handle the differing syntaxes needed for WeakPtr<> +// support, and for ignoring return values. This is separate +// from Invoker to avoid creating multiple version of +// Invoker<>. +// Invoker<> -- Unwraps the curried parameters and executes the Runnable. +// BindState<> -- Stores the curried parameters, and is the main entry point +// into the Bind() system, doing most of the type resolution. +// There are ARITY BindState types. + +// HasNonConstReferenceParam selects true_type when any of the parameters in +// |Sig| is a non-const reference. +// Implementation note: This non-specialized case handles zero-arity case only. +// Non-zero-arity cases should be handled by the specialization below. +template <typename List> +struct HasNonConstReferenceItem : false_type {}; + +// Implementation note: Select true_type if the first parameter is a non-const +// reference. Otherwise, skip the first parameter and check rest of parameters +// recursively. +template <typename T, typename... Args> +struct HasNonConstReferenceItem<TypeList<T, Args...>> + : std::conditional<is_non_const_reference<T>::value, + true_type, + HasNonConstReferenceItem<TypeList<Args...>>>::type {}; + +// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw +// pointer to a RefCounted type. +// Implementation note: This non-specialized case handles zero-arity case only. +// Non-zero-arity cases should be handled by the specialization below. +template <typename... Args> +struct HasRefCountedTypeAsRawPtr : false_type {}; + +// Implementation note: Select true_type if the first parameter is a raw pointer +// to a RefCounted type. Otherwise, skip the first parameter and check rest of +// parameters recursively. +template <typename T, typename... Args> +struct HasRefCountedTypeAsRawPtr<T, Args...> + : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value, + true_type, + HasRefCountedTypeAsRawPtr<Args...>>::type {}; + +// BindsArrayToFirstArg selects true_type when |is_method| is true and the first +// item of |Args| is an array type. +// Implementation note: This non-specialized case handles !is_method case and +// zero-arity case only. Other cases should be handled by the specialization +// below. +template <bool is_method, typename... Args> +struct BindsArrayToFirstArg : false_type {}; + +template <typename T, typename... Args> +struct BindsArrayToFirstArg<true, T, Args...> : is_array<T> {}; + +// HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except +// when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument. +// Implementation note: This non-specialized case handles !is_method case and +// zero-arity case only. Other cases should be handled by the specialization +// below. +template <bool is_method, typename... Args> +struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {}; + +template <typename T, typename... Args> +struct HasRefCountedParamAsRawPtr<true, T, Args...> + : HasRefCountedTypeAsRawPtr<Args...> {}; + +// RunnableAdapter<> +// +// The RunnableAdapter<> templates provide a uniform interface for invoking +// a function pointer, method pointer, or const method pointer. The adapter +// exposes a Run() method with an appropriate signature. Using this wrapper +// allows for writing code that supports all three pointer types without +// undue repetition. Without it, a lot of code would need to be repeated 3 +// times. +// +// For method pointers and const method pointers the first argument to Run() +// is considered to be the received of the method. This is similar to STL's +// mem_fun(). +// +// This class also exposes a RunType typedef that is the function type of the +// Run() function. +// +// If and only if the wrapper contains a method or const method pointer, an +// IsMethod typedef is exposed. The existence of this typedef (NOT the value) +// marks that the wrapper should be considered a method wrapper. + +template <typename Functor> +class RunnableAdapter; + +// Function. +template <typename R, typename... Args> +class RunnableAdapter<R(*)(Args...)> { + public: + // MSVC 2013 doesn't support Type Alias of function types. + // Revisit this after we update it to newer version. + typedef R RunType(Args...); + + explicit RunnableAdapter(R(*function)(Args...)) + : function_(function) { + } + + R Run(typename CallbackParamTraits<Args>::ForwardType... args) { + return function_(CallbackForward(args)...); + } + + private: + R (*function_)(Args...); +}; + +// Method. +template <typename R, typename T, typename... Args> +class RunnableAdapter<R(T::*)(Args...)> { + public: + // MSVC 2013 doesn't support Type Alias of function types. + // Revisit this after we update it to newer version. + typedef R RunType(T*, Args...); + using IsMethod = true_type; + + explicit RunnableAdapter(R(T::*method)(Args...)) + : method_(method) { + } + + R Run(T* object, typename CallbackParamTraits<Args>::ForwardType... args) { + return (object->*method_)(CallbackForward(args)...); + } + + private: + R (T::*method_)(Args...); +}; + +// Const Method. +template <typename R, typename T, typename... Args> +class RunnableAdapter<R(T::*)(Args...) const> { + public: + using RunType = R(const T*, Args...); + using IsMethod = true_type; + + explicit RunnableAdapter(R(T::*method)(Args...) const) + : method_(method) { + } + + R Run(const T* object, + typename CallbackParamTraits<Args>::ForwardType... args) { + return (object->*method_)(CallbackForward(args)...); + } + + private: + R (T::*method_)(Args...) const; +}; + + +// ForceVoidReturn<> +// +// Set of templates that support forcing the function return type to void. +template <typename Sig> +struct ForceVoidReturn; + +template <typename R, typename... Args> +struct ForceVoidReturn<R(Args...)> { + // MSVC 2013 doesn't support Type Alias of function types. + // Revisit this after we update it to newer version. + typedef void RunType(Args...); +}; + + +// FunctorTraits<> +// +// See description at top of file. +template <typename T> +struct FunctorTraits { + using RunnableType = RunnableAdapter<T>; + using RunType = typename RunnableType::RunType; +}; + +template <typename T> +struct FunctorTraits<IgnoreResultHelper<T>> { + using RunnableType = typename FunctorTraits<T>::RunnableType; + using RunType = + typename ForceVoidReturn<typename RunnableType::RunType>::RunType; +}; + +template <typename T> +struct FunctorTraits<Callback<T>> { + using RunnableType = Callback<T> ; + using RunType = typename Callback<T>::RunType; +}; + + +// MakeRunnable<> +// +// Converts a passed in functor to a RunnableType using type inference. + +template <typename T> +typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) { + return RunnableAdapter<T>(t); +} + +template <typename T> +typename FunctorTraits<T>::RunnableType +MakeRunnable(const IgnoreResultHelper<T>& t) { + return MakeRunnable(t.functor_); +} + +template <typename T> +const typename FunctorTraits<Callback<T>>::RunnableType& +MakeRunnable(const Callback<T>& t) { + DCHECK(!t.is_null()); + return t; +} + + +// InvokeHelper<> +// +// There are 3 logical InvokeHelper<> specializations: normal, void-return, +// WeakCalls. +// +// The normal type just calls the underlying runnable. +// +// We need a InvokeHelper to handle void return types in order to support +// IgnoreResult(). Normally, if the Runnable's RunType had a void return, +// the template system would just accept "return functor.Run()" ignoring +// the fact that a void function is being used with return. This piece of +// sugar breaks though when the Runnable's RunType is not void. Thus, we +// need a partial specialization to change the syntax to drop the "return" +// from the invocation call. +// +// WeakCalls similarly need special syntax that is applied to the first +// argument to check if they should no-op themselves. +template <bool IsWeakCall, typename ReturnType, typename Runnable, + typename ArgsType> +struct InvokeHelper; + +template <typename ReturnType, typename Runnable, typename... Args> +struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> { + static ReturnType MakeItSo(Runnable runnable, Args... args) { + return runnable.Run(CallbackForward(args)...); + } +}; + +template <typename Runnable, typename... Args> +struct InvokeHelper<false, void, Runnable, TypeList<Args...>> { + static void MakeItSo(Runnable runnable, Args... args) { + runnable.Run(CallbackForward(args)...); + } +}; + +template <typename Runnable, typename BoundWeakPtr, typename... Args> +struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> { + static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) { + if (!weak_ptr.get()) { + return; + } + runnable.Run(weak_ptr.get(), CallbackForward(args)...); + } +}; + +#if !defined(_MSC_VER) + +template <typename ReturnType, typename Runnable, typename ArgsType> +struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { + // WeakCalls are only supported for functions with a void return type. + // Otherwise, the function result would be undefined if the the WeakPtr<> + // is invalidated. + static_assert(is_void<ReturnType>::value, + "weak_ptrs can only bind to methods without return values"); +}; + +#endif + +// Invoker<> +// +// See description at the top of the file. +template <typename BoundIndices, + typename StorageType, typename Unwrappers, + typename InvokeHelperType, typename UnboundForwardRunType> +struct Invoker; + +template <size_t... bound_indices, + typename StorageType, + typename... Unwrappers, + typename InvokeHelperType, + typename R, + typename... UnboundForwardArgs> +struct Invoker<IndexSequence<bound_indices...>, + StorageType, TypeList<Unwrappers...>, + InvokeHelperType, R(UnboundForwardArgs...)> { + static R Run(BindStateBase* base, + UnboundForwardArgs... unbound_args) { + StorageType* storage = static_cast<StorageType*>(base); + // Local references to make debugger stepping easier. If in a debugger, + // you really want to warp ahead and step through the + // InvokeHelper<>::MakeItSo() call below. + return InvokeHelperType::MakeItSo( + storage->runnable_, + Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))..., + CallbackForward(unbound_args)...); + } +}; + + +// BindState<> +// +// This stores all the state passed into Bind() and is also where most +// of the template resolution magic occurs. +// +// Runnable is the functor we are binding arguments to. +// RunType is type of the Run() function that the Invoker<> should use. +// Normally, this is the same as the RunType of the Runnable, but it can +// be different if an adapter like IgnoreResult() has been used. +// +// BoundArgs contains the storage type for all the bound arguments. +template <typename Runnable, typename RunType, typename... BoundArgs> +struct BindState; + +template <typename Runnable, + typename R, + typename... Args, + typename... BoundArgs> +struct BindState<Runnable, R(Args...), BoundArgs...> final + : public BindStateBase { + private: + using StorageType = BindState<Runnable, R(Args...), BoundArgs...>; + using RunnableType = Runnable; + + // true_type if Runnable is a method invocation and the first bound argument + // is a WeakPtr. + using IsWeakCall = + IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>; + + using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; + using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>; + using UnboundForwardArgs = DropTypeListItem< + sizeof...(BoundArgs), + TypeList<typename CallbackParamTraits<Args>::ForwardType...>>; + using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>; + + using InvokeHelperArgs = ConcatTypeLists< + TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>, + UnboundForwardArgs>; + using InvokeHelperType = + InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>; + + using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; + + public: + using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers, + InvokeHelperType, UnboundForwardRunType>; + using UnboundRunType = MakeFunctionType<R, UnboundArgs>; + + BindState(const Runnable& runnable, const BoundArgs&... bound_args) + : BindStateBase(&Destroy), + runnable_(runnable), + ref_(bound_args...), + bound_args_(bound_args...) {} + + RunnableType runnable_; + MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_; + Tuple<BoundArgs...> bound_args_; + + private: + ~BindState() {} + + static void Destroy(BindStateBase* self) { + delete static_cast<BindState*>(self); + } +}; + +} // namespace internal +} // namespace base + +#endif // BASE_BIND_INTERNAL_H_ |