gem5  v20.1.0.0
varargs.hh
Go to the documentation of this file.
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met: redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer;
8  * redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution;
11  * neither the name of the copyright holders nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef __SIM_GUEST_ABI_VARARGS_HH__
29 #define __SIM_GUEST_ABI_VARARGS_HH__
30 
31 #include <memory>
32 #include <sstream>
33 #include <type_traits>
34 
36 
37 class ThreadContext;
38 
39 namespace GuestABI
40 {
41 
42 /*
43  * These templates implement a variadic argument mechanism for guest ABI
44  * functions. A function might be written like this:
45  *
46  * void
47  * func(ThreadContext *tc, VarArgs<Addr, int> varargs)
48  * {
49  * warn("Address = %#x, int = %d.",
50  * varargs.get<Addr>(), varargs.get<int>());
51  * }
52  *
53  * where an object of type VarArgs<...> is its last argument. The types given
54  * to the template specify what types the function might need to retrieve from
55  * varargs. The varargs object will then have get<> methods for each of those
56  * types.
57  *
58  * Note that each get<> will happen live. If you modify values through the
59  * ThreadContext *tc and then run get<>(), you may alter one of your arguments.
60  * If you're going to use tc to modify state, it would be a good idea to use
61  * get<>() as soon as possible to avoid corrupting the functions arguments.
62  */
63 
64 // A recursive template which defines virtual functions to retrieve each of the
65 // requested types. This provides the ABI agnostic interface the function uses.
66 template <typename ...Types>
68 
69 template <typename First, typename ...Types>
70 class VarArgsBase<First, Types...> : public VarArgsBase<Types...>
71 {
72  public:
73  virtual ~VarArgsBase() = default;
74 
75  // The virtual function takes a reference parameter so that the different
76  // _getImpl methods can co-exist through overloading.
77  virtual void _getImpl(First &) = 0;
78 
79  // Make sure base class _getImpl-es aren't hidden by this one.
80  using VarArgsBase<Types...>::_getImpl;
81 };
82 
83 // The base case of the recursion.
84 template <>
85 class VarArgsBase<>
86 {
87  protected:
88  // This just gives the "using" statement in the non base case something to
89  // refer to.
90  void _getImpl();
91 };
92 
93 
94 // A recursive template which defines the ABI specific implementation of the
95 // interface defined above.
96 //
97 // The types in Types are consumed one by one, and by
98 // the time we get down to the base case we'd have lost track of the complete
99 // set we need to know what interface to inherit. The Base parameter keeps
100 // track of that through the recursion.
101 template <typename ABI, typename Base, typename ...Types>
103 
104 template <typename ABI, typename Base, typename First, typename ...Types>
105 class VarArgsImpl<ABI, Base, First, Types...> :
106  public VarArgsImpl<ABI, Base, Types...>
107 {
108  protected:
109  // Bring forward the base class constructor.
110  using VarArgsImpl<ABI, Base, Types...>::VarArgsImpl;
111  // Make sure base class _getImpl-es don't get hidden by ours.
112  using VarArgsImpl<ABI, Base, Types...>::_getImpl;
113 
114  // Implement a version of _getImple, using the ABI specialized version of
115  // the Argument class.
116  void
117  _getImpl(First &first) override
118  {
119  first = Argument<ABI, First>::get(this->tc, this->state);
120  }
121 };
122 
123 // The base case of the recursion, which inherits from the interface class.
124 template <typename ABI, typename Base>
125 class VarArgsImpl<ABI, Base> : public Base
126 {
127  protected:
128  // Declare state to pass to the Argument<>::get methods.
130  typename ABI::State state;
131  // Make sure base class _getImpl-es don't get hidden by ours.
132  using Base::_getImpl;
133 
134  // Give the "using" statement in our subclass something to refer to.
135  void _getImpl();
136 
137  public:
138  VarArgsImpl(ThreadContext *_tc, const typename ABI::State &_state) :
139  tc(_tc), state(_state)
140  {}
141 };
142 
143 // A wrapper which provides a nice interface to the virtual functions, and a
144 // hook for the Argument template mechanism.
145 template <typename ...Types>
146 class VarArgs
147 {
148  private:
149  // This points to the implementation which knows how to read arguments
150  // based on the ABI being used.
151  std::shared_ptr<VarArgsBase<Types...>> _ptr;
152 
153  public:
155 
156  // This template is a friendlier wrapper around the virtual functions the
157  // raw interface provides. This version lets you pick a type which it then
158  // returns, instead of having to pre-declare a variable to pass in.
159  template <typename Arg>
160  Arg
161  get()
162  {
163  Arg arg;
164  _ptr->_getImpl(arg);
165  return arg;
166  }
167 };
168 
169 template <typename T>
170 struct IsVarArgs : public std::false_type {};
171 
172 template <typename ...Types>
173 struct IsVarArgs<VarArgs<Types...>> : public std::true_type {};
174 
175 template <typename ...Types>
176 std::ostream &
177 operator << (std::ostream &os, const VarArgs<Types...> &va)
178 {
179  os << "...";
180  return os;
181 }
182 
183 // The ABI independent hook which tells the GuestABI mechanism what to do with
184 // a VarArgs argument. It constructs the underlying implementation which knows
185 // about the ABI, and installs it in the VarArgs wrapper to give to the
186 // function.
187 template <typename ABI, typename ...Types>
188 struct Argument<ABI, VarArgs<Types...>>
189 {
190  static VarArgs<Types...>
191  get(ThreadContext *tc, typename ABI::State &state)
192  {
193  using Base = VarArgsBase<Types...>;
194  using Impl = VarArgsImpl<ABI, Base, Types...>;
195  return VarArgs<Types...>(new Impl(tc, state));
196  }
197 };
198 
199 } // namespace GuestABI
200 
201 #endif // __SIM_GUEST_ABI_VARARGS_HH__
GuestABI::VarArgsImpl< ABI, Base >::VarArgsImpl
VarArgsImpl(ThreadContext *_tc, const typename ABI::State &_state)
Definition: varargs.hh:138
X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:803
GuestABI::IsVarArgs
Definition: varargs.hh:170
definition.hh
GuestABI::VarArgsImpl< ABI, Base, First, Types... >::_getImpl
void _getImpl(First &first) override
Definition: varargs.hh:117
GuestABI::VarArgs::VarArgs
VarArgs(VarArgsBase< Types... > *ptr)
Definition: varargs.hh:154
GuestABI::operator<<
std::ostream & operator<<(std::ostream &os, const VarArgs< Types... > &va)
Definition: varargs.hh:177
GuestABI::VarArgsImpl< ABI, Base >::state
ABI::State state
Definition: varargs.hh:130
GuestABI::Argument< ABI, VarArgs< Types... > >::get
static VarArgs< Types... > get(ThreadContext *tc, typename ABI::State &state)
Definition: varargs.hh:191
GuestABI::VarArgs::get
Arg get()
Definition: varargs.hh:161
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
GuestABI::VarArgs
Definition: varargs.hh:146
GuestABI
Definition: aapcs32.hh:66
GuestABI::Argument
Definition: definition.hh:93
GuestABI::VarArgsImpl
Definition: varargs.hh:102
GuestABI::VarArgs::_ptr
std::shared_ptr< VarArgsBase< Types... > > _ptr
Definition: varargs.hh:151
GuestABI::VarArgsBase
Definition: varargs.hh:67
GuestABI::VarArgsImpl< ABI, Base >::tc
ThreadContext * tc
Definition: varargs.hh:129
ArmISA::va
Bitfield< 8 > va
Definition: miscregs_types.hh:272

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17