summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium/base/bind_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium/base/bind_internal.h')
-rw-r--r--security/sandbox/chromium/base/bind_internal.h425
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_