Allow RPC arguments w/o default constructor

Fixes #2150
This commit is contained in:
Edgard Schmidt
2016-10-08 04:37:32 +02:00
committed by Christian Helmuth
parent 6a24d70120
commit f97e0f3fa0
8 changed files with 198 additions and 164 deletions

View File

@ -24,6 +24,9 @@ long Test::cap_void_manual(Genode::Native_capability dst,
Genode::Native_capability arg1, Genode::Native_capability arg1,
Genode::addr_t &local_reply) Genode::addr_t &local_reply)
{ {
if (!arg1.valid())
return Genode::Rpc_exception_code::INVALID_OBJECT;
Genode::Thread * myself = Genode::Thread::myself(); Genode::Thread * myself = Genode::Thread::myself();
Nova::Utcb *utcb = reinterpret_cast<Nova::Utcb *>(myself->utcb()); Nova::Utcb *utcb = reinterpret_cast<Nova::Utcb *>(myself->utcb());
@ -38,9 +41,6 @@ long Test::cap_void_manual(Genode::Native_capability dst,
utcb->msg[1] = 0; utcb->msg[1] = 0;
utcb->set_msg_word(2); utcb->set_msg_word(2);
if (!arg1.valid())
return Genode::Rpc_exception_code::INVALID_OBJECT;
Nova::Crd crd = Genode::Capability_space::crd(arg1); Nova::Crd crd = Genode::Capability_space::crd(arg1);
if (!utcb->append_item(crd, 0, false, false, false)) if (!utcb->append_item(crd, 0, false, false, false))
return Genode::Rpc_exception_code::INVALID_OBJECT; return Genode::Rpc_exception_code::INVALID_OBJECT;
@ -50,7 +50,7 @@ long Test::cap_void_manual(Genode::Native_capability dst,
/* restore original receive window */ /* restore original receive window */
utcb->crd_rcv = orig_crd; utcb->crd_rcv = orig_crd;
local_reply = utcb->msg[2]; local_reply = utcb->msg[1];
return (res == Nova::NOVA_OK && utcb->msg_words() == 3) return (res == Nova::NOVA_OK && utcb->msg_words() == 3 && utcb->msg[2])
? utcb->msg[0] : Genode::Rpc_exception_code::INVALID_OBJECT; ? utcb->msg[0] : Genode::Rpc_exception_code::INVALID_OBJECT;
} }

View File

@ -157,10 +157,12 @@ void test_revoke(Genode::Env &env)
Genode::Native_capability copy_session_cap = Capability_space::import(local_name); Genode::Native_capability copy_session_cap = Capability_space::import(local_name);
local_name = Native_thread::INVALID_INDEX;
rpc = Test::cap_void_manual(copy_session_cap, copy_session_cap, local_name); rpc = Test::cap_void_manual(copy_session_cap, copy_session_cap, local_name);
if (rpc != Genode::Rpc_exception_code::SUCCESS || if (rpc != Genode::Rpc_exception_code::SUCCESS ||
local_name == (addr_t)copy_session_cap.local_name() || local_name == (addr_t)copy_session_cap.local_name() ||
local_name == (addr_t)Native_thread::INVALID_INDEX) local_name == (addr_t)Native_thread::INVALID_INDEX ||
local_name == (addr_t)session_cap.local_name())
{ {
failed ++; failed ++;
error("test_revoke ipc call failed ", Hex(rpc)); error("test_revoke ipc call failed ", Hex(rpc));

View File

@ -115,8 +115,7 @@ class Genode::Capability : public Untyped_capability
* Perform RPC call, arguments passed a as nested 'Ref_tuple' object * Perform RPC call, arguments passed a as nested 'Ref_tuple' object
*/ */
template <typename IF> template <typename IF>
void _call(typename IF::Client_args &args, typename IF::Ret_type _call(typename IF::Client_args &args) const;
typename IF::Ret_type &ret) const;
/** /**
* Shortcut for querying argument types used in 'call' methods * Shortcut for querying argument types used in 'call' methods
@ -137,27 +136,6 @@ class Genode::Capability : public Untyped_capability
return cap; return cap;
} }
/**
* Wrapper for the return type instantiated by 'call' overloads
*
* Each 'call' overload creates an instance of the return value
* type as local variable. A reference to this variable is passed
* to the '_call' method, which will assign its value. Even
* though the variable does not need to be initialized prior the
* call of '_call', the GCC will still complain "warning: ret may
* be used uninitialized in this function". Wrapping the return
* value in a struct silences the compiler.
*/
template <typename IF>
struct Return
{
typedef typename Trait::Call_return<typename IF::Ret_type>::Type
Return_type;
volatile Return_type _value;
Return_type &value() { return *(Return_type *)(&_value); }
};
public: public:
typedef RPC_INTERFACE Rpc_interface; typedef RPC_INTERFACE Rpc_interface;
@ -185,9 +163,7 @@ class Genode::Capability : public Untyped_capability
call() const call() const
{ {
Meta::Empty e; Meta::Empty e;
Return<IF> ret; return _call<IF>(e);
_call<IF>(e, ret.value());
return ret.value();
} }
template <typename IF> template <typename IF>
@ -196,9 +172,7 @@ class Genode::Capability : public Untyped_capability
{ {
Meta::Empty e; Meta::Empty e;
typename IF::Client_args args(v1, e); typename IF::Client_args args(v1, e);
Return<IF> ret; return _call<IF>(args);
_call<IF>(args, ret.value());
return ret.value();
} }
template <typename IF> template <typename IF>
@ -207,9 +181,7 @@ class Genode::Capability : public Untyped_capability
{ {
Meta::Empty e; Meta::Empty e;
typename IF::Client_args args(v1, v2, e); typename IF::Client_args args(v1, v2, e);
Return<IF> ret; return _call<IF>(args);
_call<IF>(args, ret.value());
return ret.value();
} }
template <typename IF> template <typename IF>
@ -219,9 +191,7 @@ class Genode::Capability : public Untyped_capability
{ {
Meta::Empty e; Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, e); typename IF::Client_args args(v1, v2, v3, e);
Return<IF> ret; return _call<IF>(args);
_call<IF>(args, ret.value());
return ret.value();
} }
template <typename IF> template <typename IF>
@ -231,9 +201,7 @@ class Genode::Capability : public Untyped_capability
{ {
Meta::Empty e; Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, e); typename IF::Client_args args(v1, v2, v3, v4, e);
Return<IF> ret; return _call<IF>(args);
_call<IF>(args, ret.value());
return ret.value();
} }
template <typename IF> template <typename IF>
@ -244,9 +212,7 @@ class Genode::Capability : public Untyped_capability
{ {
Meta::Empty e; Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, v5, e); typename IF::Client_args args(v1, v2, v3, v4, v5, e);
Return<IF> ret; return _call<IF>(args);
_call<IF>(args, ret.value());
return ret.value();
} }
template <typename IF> template <typename IF>
@ -257,9 +223,7 @@ class Genode::Capability : public Untyped_capability
{ {
Meta::Empty e; Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, v5, v6, e); typename IF::Client_args args(v1, v2, v3, v4, v5, v6, e);
Return<IF> ret; return _call<IF>(args);
_call<IF>(args, ret.value());
return ret.value();
} }
template <typename IF> template <typename IF>
@ -271,9 +235,7 @@ class Genode::Capability : public Untyped_capability
{ {
Meta::Empty e; Meta::Empty e;
typename IF::Client_args args(v1, v2, v3, v4, v5, v6, v7, e); typename IF::Client_args args(v1, v2, v3, v4, v5, v6, v7, e);
Return<IF> ret; return _call<IF>(args);
_call<IF>(args, ret.value());
return ret.value();
} }
}; };

View File

@ -17,6 +17,7 @@
#include <base/ipc_msgbuf.h> #include <base/ipc_msgbuf.h>
#include <base/rpc_args.h> #include <base/rpc_args.h>
#include <base/log.h> #include <base/log.h>
#include <util/meta.h>
namespace Genode { namespace Genode {
@ -65,9 +66,15 @@ class Genode::Ipc_unmarshaller : Noncopyable
template <typename IT> template <typename IT>
void extract(Capability<IT> &typed_cap) void extract(Capability<IT> &typed_cap)
{ {
Native_capability untyped_cap; typed_cap = extract(Meta::Overload_selector<Capability<IT> >());
extract(untyped_cap); }
typed_cap = reinterpret_cap_cast<IT>(untyped_cap);
template<typename IT>
Capability<IT> extract(Meta::Overload_selector<Capability<IT> >)
{
Native_capability untyped_cap =
extract(Meta::Overload_selector<Native_capability>());
return reinterpret_cap_cast<IT>(untyped_cap);
} }
/** /**
@ -75,9 +82,15 @@ class Genode::Ipc_unmarshaller : Noncopyable
*/ */
void extract(Native_capability &cap) void extract(Native_capability &cap)
{ {
cap = _read_cap_index < _rcv_msg.used_caps() cap = extract(Meta::Overload_selector<Native_capability>());
? _rcv_msg.cap(_read_cap_index) : Native_capability(); }
Native_capability extract(Meta::Overload_selector<Native_capability>)
{
Native_capability cap = _read_cap_index < _rcv_msg.used_caps()
? _rcv_msg.cap(_read_cap_index) : Native_capability();
_read_cap_index++; _read_cap_index++;
return cap;
} }
/** /**
@ -86,8 +99,6 @@ class Genode::Ipc_unmarshaller : Noncopyable
template <size_t SIZE> template <size_t SIZE>
void extract(Rpc_in_buffer<SIZE> &b) void extract(Rpc_in_buffer<SIZE> &b)
{ {
size_t size = 0;
extract(size);
b = Rpc_in_buffer<SIZE>(0, 0); b = Rpc_in_buffer<SIZE>(0, 0);
/* /*
@ -96,13 +107,23 @@ class Genode::Ipc_unmarshaller : Noncopyable
* Note: The addr of the Rpc_in_buffer_base is a null pointer when this * Note: The addr of the Rpc_in_buffer_base is a null pointer when this
* condition triggers. * condition triggers.
*/ */
try {
b = extract(Meta::Overload_selector<Rpc_in_buffer<SIZE> >());
} catch (Ipc_error) { }
}
template<size_t SIZE>
Rpc_in_buffer<SIZE> extract(Meta::Overload_selector<Rpc_in_buffer<SIZE> >)
{
size_t size = extract(Meta::Overload_selector<size_t>());
if (_read_offset + size > _rcv_buf_size) { if (_read_offset + size > _rcv_buf_size) {
error("message buffer overrun"); error("message buffer overrun");
return; throw Ipc_error();
} }
b = Rpc_in_buffer<SIZE>(&_rcv_buf[_read_offset], size); Rpc_in_buffer<SIZE> buf(&_rcv_buf[_read_offset], size);
_read_offset += align_natural(size); _read_offset += align_natural(size);
return buf;
} }
/** /**
@ -110,15 +131,23 @@ class Genode::Ipc_unmarshaller : Noncopyable
*/ */
template <typename T> template <typename T>
void extract(T &value) void extract(T &value)
{
value = extract(Meta::Overload_selector<T>());
}
template <typename T>
T extract(Meta::Overload_selector<T>)
{ {
/* check receive buffer range */ /* check receive buffer range */
if (_read_offset + sizeof(T) > _rcv_buf_size) return; if (_read_offset + sizeof(T) > _rcv_buf_size) throw Ipc_error();
/* return value from receive buffer */ /* return value from receive buffer */
value = *reinterpret_cast<T *>(&_rcv_buf[_read_offset]); T value = *reinterpret_cast<T *>(&_rcv_buf[_read_offset]);
/* increment read pointer to next dword-aligned value */ /* increment read pointer to next dword-aligned value */
_read_offset += align_natural(sizeof(T)); _read_offset += align_natural(sizeof(T));
return value;
} }
Ipc_unmarshaller(Msgbuf_base &rcv_msg) : _rcv_msg(rcv_msg) { } Ipc_unmarshaller(Msgbuf_base &rcv_msg) : _rcv_msg(rcv_msg) { }

View File

@ -43,9 +43,9 @@
typedef ::Genode::Trait::Call_return<ret_type>::Type Ret_type; \ typedef ::Genode::Trait::Call_return<ret_type>::Type Ret_type; \
\ \
template <typename SERVER, typename RET> \ template <typename SERVER, typename RET> \
static void serve(SERVER &server, Server_args &args, RET &ret) { \ static RET serve(SERVER &server, Server_args &args) { \
::Genode::Meta::call_member<RET, SERVER, Server_args> \ return ::Genode::Meta::call_member<RET, SERVER, Server_args> \
(ret, server, args, &SERVER::func_name); } \ (server, args, &SERVER::func_name); } \
\ \
static const char* name() { return #func_name; } \ static const char* name() { return #func_name; } \
}; };

View File

@ -107,8 +107,8 @@ namespace Genode {
template <typename RPC_INTERFACE> template <typename RPC_INTERFACE>
template <typename IF> template <typename IF>
void Capability<RPC_INTERFACE>:: typename IF::Ret_type Capability<RPC_INTERFACE>::
_call(typename IF::Client_args &args, typename IF::Ret_type &ret) const _call(typename IF::Client_args &args) const
{ {
/** /**
* Message buffer for RPC message * Message buffer for RPC message
@ -144,7 +144,6 @@ namespace Genode {
throw Ipc_error(); throw Ipc_error();
Ipc_unmarshaller unmarshaller(reply_buf); Ipc_unmarshaller unmarshaller(reply_buf);
unmarshaller.extract(ret);
{ {
Trace::Rpc_returned trace_event(IF::name(), reply_buf); Trace::Rpc_returned trace_event(IF::name(), reply_buf);
@ -156,6 +155,10 @@ namespace Genode {
/* reflect callee-side exception at the caller */ /* reflect callee-side exception at the caller */
_check_for_exceptions(exception_code, _check_for_exceptions(exception_code,
Meta::Overload_selector<typename IF::Exceptions>()); Meta::Overload_selector<typename IF::Exceptions>());
/* the return value does only exist if no exception was thrown */
Meta::Overload_selector<typename IF::Ret_type> ret_overloader;
return unmarshaller.extract(ret_overloader);
} }
} }

View File

@ -63,15 +63,44 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE
protected: protected:
template <typename ARG_LIST> template <typename ARG_LIST>
void _read_args(Ipc_unmarshaller &msg, ARG_LIST &args) ARG_LIST _read_args(Ipc_unmarshaller &msg,
Meta::Overload_selector<ARG_LIST>)
{ {
if (Trait::Rpc_direction<typename ARG_LIST::Head>::Type::IN) typename Trait::Rpc_direction<typename ARG_LIST::Head>::Type direction;
msg.extract(args._1); typedef typename ARG_LIST::Stored_head Arg;
Arg arg = _read_arg<Arg>(msg, direction);
_read_args(msg, args._2); Meta::Overload_selector<typename ARG_LIST::Tail> tail_selector;
typename ARG_LIST::Tail subsequent_args = _read_args(msg,
tail_selector);
ARG_LIST args { arg, subsequent_args };
return args;
} }
void _read_args(Ipc_unmarshaller &, Meta::Empty) { } Meta::Empty _read_args(Ipc_unmarshaller &msg,
Meta::Overload_selector<Meta::Empty>)
{
return Meta::Empty();
}
template <typename ARG>
ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_in)
{
return msg.extract(Meta::Overload_selector<ARG>());
}
template <typename ARG>
ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_inout)
{
return _read_arg<ARG>(msg, Rpc_arg_in());
}
template <typename ARG>
ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_out)
{
return ARG();
}
template <typename ARG_LIST> template <typename ARG_LIST>
void _write_results(Msgbuf_base &msg, ARG_LIST &args) void _write_results(Msgbuf_base &msg, ARG_LIST &args)
@ -85,28 +114,34 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE
void _write_results(Msgbuf_base &, Meta::Empty) { } void _write_results(Msgbuf_base &, Meta::Empty) { }
template <typename RPC_FUNCTION, typename EXC_TL> template <typename RPC_FUNCTION, typename EXC_TL>
Rpc_exception_code _do_serve(typename RPC_FUNCTION::Server_args &args, typename RPC_FUNCTION::Ret_type
typename RPC_FUNCTION::Ret_type &ret, _do_serve(typename RPC_FUNCTION::Server_args &args,
Meta::Overload_selector<RPC_FUNCTION, EXC_TL>) Meta::Overload_selector<RPC_FUNCTION, EXC_TL>)
{ {
enum { EXCEPTION_CODE = Rpc_exception_code::EXCEPTION_BASE enum { EXCEPTION_CODE = Rpc_exception_code::EXCEPTION_BASE
- Meta::Length<EXC_TL>::Value }; - Meta::Length<EXC_TL>::Value };
try { try {
typedef typename EXC_TL::Tail Exc_tail; typedef typename EXC_TL::Tail Exc_tail;
return _do_serve(args, ret, return _do_serve(args,
Meta::Overload_selector<RPC_FUNCTION, Exc_tail>()); Meta::Overload_selector<RPC_FUNCTION, Exc_tail>());
} catch (typename EXC_TL::Head) { } catch (typename EXC_TL::Head) {
return Rpc_exception_code(EXCEPTION_CODE); /**
* By passing the exception code through an exception we ensure that
* a return value is only returned if it exists. This way, the return
* type does not have to be default-constructible.
*/
throw Rpc_exception_code(EXCEPTION_CODE);
} }
} }
template <typename RPC_FUNCTION> template <typename RPC_FUNCTION>
Rpc_exception_code _do_serve(typename RPC_FUNCTION::Server_args &args, typename RPC_FUNCTION::Ret_type
typename RPC_FUNCTION::Ret_type &ret, _do_serve(typename RPC_FUNCTION::Server_args &args,
Meta::Overload_selector<RPC_FUNCTION, Meta::Empty>) Meta::Overload_selector<RPC_FUNCTION, Meta::Empty>)
{ {
RPC_FUNCTION::serve(*static_cast<SERVER *>(this), args, ret); typedef typename RPC_FUNCTION::Ret_type Ret_type;
return Rpc_exception_code(Rpc_exception_code::SUCCESS); SERVER *me = static_cast<SERVER *>(this);
return RPC_FUNCTION::template serve<SERVER, Ret_type>(*me, args);
} }
template <typename RPC_FUNCTIONS_TO_CHECK> template <typename RPC_FUNCTIONS_TO_CHECK>
@ -120,10 +155,10 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE
if (opcode.value == Index_of<Rpc_functions, This_rpc_function>::Value) { if (opcode.value == Index_of<Rpc_functions, This_rpc_function>::Value) {
typename This_rpc_function::Server_args args{};
/* read arguments from incoming message */ /* read arguments from incoming message */
_read_args(in, args); typedef typename This_rpc_function::Server_args Server_args;
Meta::Overload_selector<Server_args> arg_selector;
Server_args args = _read_args(in, arg_selector);
{ {
Trace::Rpc_dispatch trace_event(This_rpc_function::name()); Trace::Rpc_dispatch trace_event(This_rpc_function::name());
@ -134,22 +169,29 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE
* 'This_rpc_function' and the list of its exceptions to * 'This_rpc_function' and the list of its exceptions to
* select the overload. * select the overload.
*/ */
typedef typename This_rpc_function::Exceptions Exceptions;
typename This_rpc_function::Ret_type ret { }; typedef typename This_rpc_function::Ret_type Ret_type;
Rpc_exception_code Rpc_exception_code exc(Rpc_exception_code::SUCCESS);
exc(_do_serve(args, ret, try {
Overload_selector<This_rpc_function, Exceptions>())); typedef typename This_rpc_function::Exceptions Exceptions;
Overload_selector<This_rpc_function, Exceptions> overloader;
Ret_type ret = _do_serve(args, overloader);
out.insert(ret); _write_results(out, args);
out.insert(ret);
} catch (Rpc_exception_code thrown) {
/**
* Output arguments may be modified although an exception was thrown.
* However, a return value does not exist. So we do not insert one.
*/
_write_results(out, args);
exc = thrown;
}
{ {
Trace::Rpc_reply trace_event(This_rpc_function::name()); Trace::Rpc_reply trace_event(This_rpc_function::name());
} }
/* write results to outgoing message */
_write_results(out, args);
return exc; return exc;
} }

View File

@ -291,17 +291,26 @@ namespace Genode {
/** /**
* Tuple holding raw (plain old) data * Tuple holding raw (plain old) data
*
* Has to be an aggregate type to allow non-default-constructible RPC
* arguments. But aggregate types must not derive from a base class in
* C++11. So we do not derive from Meta::Type_tuple although it is an
* empty class.
*/ */
template <typename HEAD, typename TAIL> template <typename HEAD, typename TAIL>
struct Pod_tuple : public Type_tuple<HEAD, TAIL> struct Pod_tuple
{ {
typename Trait::Pod<HEAD>::Type _1; typedef typename Trait::Pod<HEAD>::Type Stored_head;
typename Trait::Pod<TAIL>::Type _2; Stored_head _1;
TAIL _2;
typedef HEAD Head;
typedef TAIL Tail;
/** /**
* Accessor for requesting the data reference to '_1' * Accessor for requesting the data reference to '_1'
*/ */
typename Trait::Pod<HEAD>::Type &get() { return _1; } Stored_head &get() { return _1; }
}; };
/** /**
@ -313,32 +322,18 @@ namespace Genode {
* function returns a pointer to the stored copy. * function returns a pointer to the stored copy.
*/ */
template <typename HEAD, typename TAIL> template <typename HEAD, typename TAIL>
struct Pod_tuple<HEAD *, TAIL> : public Type_tuple<HEAD *, TAIL> struct Pod_tuple<HEAD *, TAIL>
{ {
typename Trait::Non_reference<HEAD>::Type _1; typedef typename Trait::Non_reference<HEAD>::Type Stored_head;
typename Trait::Non_reference<TAIL>::Type _2; Stored_head _1;
TAIL _2;
typedef HEAD* Head;
typedef TAIL Tail;
HEAD *get() { return &_1; } HEAD *get() { return &_1; }
}; };
template <typename T1, typename T2, typename T3>
struct Pod_tuple_3 : public Pod_tuple<T1, Pod_tuple<T2, T3> > { };
template <typename T1, typename T2, typename T3, typename T4>
struct Pod_tuple_4 : public Pod_tuple<T1, Pod_tuple_3<T2, T3, T4> > { };
template <typename T1, typename T2, typename T3, typename T4, typename T5>
struct Pod_tuple_5 : public Pod_tuple<T1, Pod_tuple_4<T2, T3, T4, T5> > { };
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
struct Pod_tuple_6 : public Pod_tuple<T1, Pod_tuple_5<T2, T3, T4, T5, T6> > { };
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
struct Pod_tuple_7 : public Pod_tuple<T1, Pod_tuple_6<T2, T3, T4, T5, T6, T7> > { };
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
struct Pod_tuple_8 : public Pod_tuple<T1, Pod_tuple_7<T2, T3, T4, T5, T6, T7, T8> > { };
/************************************************************************* /*************************************************************************
** Support for representing function arguments in a normalized fashion ** ** Support for representing function arguments in a normalized fashion **
@ -409,22 +404,23 @@ namespace Genode {
struct Pod_args<T1, Void> { typedef Pod_tuple<T1, Empty> Type; }; struct Pod_args<T1, Void> { typedef Pod_tuple<T1, Empty> Type; };
template <typename T1, typename T2> template <typename T1, typename T2>
struct Pod_args<T1, T2, Void> { typedef Pod_tuple_3<T1, T2, Empty> Type; }; struct Pod_args<T1, T2, Void> { typedef Pod_tuple<T1, typename Pod_args<T2, Void>::Type> Type; };
template <typename T1, typename T2, typename T3> template <typename T1, typename T2, typename T3>
struct Pod_args<T1, T2, T3, Void> { typedef Pod_tuple_4<T1, T2, T3, Empty> Type; }; struct Pod_args<T1, T2, T3, Void> { typedef Pod_tuple<T1, typename Pod_args<T2, T3, Void>::Type> Type; };
template <typename T1, typename T2, typename T3, typename T4> template <typename T1, typename T2, typename T3, typename T4>
struct Pod_args<T1, T2, T3, T4, Void> { typedef Pod_tuple_5<T1, T2, T3, T4, Empty> Type; }; struct Pod_args<T1, T2, T3, T4, Void> { typedef Pod_tuple<T1, typename Pod_args<T2, T3, T4, Void>::Type> Type; };
template <typename T1, typename T2, typename T3, typename T4, typename T5> template <typename T1, typename T2, typename T3, typename T4, typename T5>
struct Pod_args<T1, T2, T3, T4, T5, Void> { typedef Pod_tuple_6<T1, T2, T3, T4, T5, Empty> Type; }; struct Pod_args<T1, T2, T3, T4, T5, Void> { typedef Pod_tuple<T1, typename Pod_args<T2, T3, T4, T5, Void>::Type> Type; };
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
struct Pod_args<T1, T2, T3, T4, T5, T6, Void> { typedef Pod_tuple_7<T1, T2, T3, T4, T5, T6, Empty> Type; }; struct Pod_args<T1, T2, T3, T4, T5, T6, Void> { typedef Pod_tuple<T1, typename Pod_args<T2, T3, T4, T5, T6, Void>::Type> Type; };
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
struct Pod_args<T1, T2, T3, T4, T5, T6, T7, Void> { typedef Pod_tuple_8<T1, T2, T3, T4, T5, T6, T7, Empty> Type; }; struct Pod_args<T1, T2, T3, T4, T5, T6, T7, Void> { typedef Pod_tuple<T1, typename Pod_args<T2, T3, T4, T5, T6, T7, Void>::Type> Type; };
/** /**
* Helper for calling member functions via a uniform interface * Helper for calling member functions via a uniform interface
@ -453,114 +449,114 @@ namespace Genode {
*/ */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &, static inline RET_TYPE call_member(SERVER &server, ARGS &,
RET_TYPE (SERVER::*func)()) RET_TYPE (SERVER::*func)())
{ ret = (server.*func)(); } { return (server.*func)(); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &, static inline RET_TYPE call_member(SERVER &server, ARGS &,
RET_TYPE (SERVER::*func)() const) RET_TYPE (SERVER::*func)() const)
{ ret = (server.*func)(); } { return (server.*func)(); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &, static inline RET_TYPE call_member(SERVER &server, ARGS &,
void (SERVER::*func)()) void (SERVER::*func)())
{ (server.*func)(); } { (server.*func)(); return Empty(); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &, static inline RET_TYPE call_member(SERVER &server, ARGS &,
void (SERVER::*func)() const) void (SERVER::*func)() const)
{ (server.*func)(); } { (server.*func)(); return Empty(); }
/* 1 */ /* 1 */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type)) RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type))
{ ret = (server.*func)(args.get()); } { return (server.*func)(args.get()); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
void (SERVER::*func)(typename Type_at<ARGS, 0>::Type)) void (SERVER::*func)(typename Type_at<ARGS, 0>::Type))
{ (server.*func)(args.get()); } { (server.*func)(args.get()); return Empty(); }
/* 2 */ /* 2 */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type, RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type)) typename Type_at<ARGS, 1>::Type))
{ ret = (server.*func)(args.get(), args._2.get()); } { return (server.*func)(args.get(), args._2.get()); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
void (SERVER::*func)(typename Type_at<ARGS, 0>::Type, void (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type)) typename Type_at<ARGS, 1>::Type))
{ (server.*func)(args.get(), args._2.get()); } { (server.*func)(args.get(), args._2.get()); return Empty(); }
/* 3 */ /* 3 */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type, RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type)) typename Type_at<ARGS, 2>::Type))
{ ret = (server.*func)(args.get(), args._2.get(), args._2._2.get()); } { return (server.*func)(args.get(), args._2.get(), args._2._2.get()); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
void (SERVER::*func)(typename Type_at<ARGS, 0>::Type, void (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type)) typename Type_at<ARGS, 2>::Type))
{ (server.*func)(args.get(), args._2.get(), args._2._2.get()); } { (server.*func)(args.get(), args._2.get(), args._2._2.get()); return Empty(); }
/* 4 */ /* 4 */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type, RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
typename Type_at<ARGS, 3>::Type)) typename Type_at<ARGS, 3>::Type))
{ ret = (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get()); } { return (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get()); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
void (SERVER::*func)(typename Type_at<ARGS, 0>::Type, void (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
typename Type_at<ARGS, 3>::Type)) typename Type_at<ARGS, 3>::Type))
{ (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get()); } { (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get()); return Empty(); }
/* 5 */ /* 5 */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type, RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
typename Type_at<ARGS, 3>::Type, typename Type_at<ARGS, 3>::Type,
typename Type_at<ARGS, 4>::Type)) typename Type_at<ARGS, 4>::Type))
{ ret = (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), args._2._2._2._2.get()); } { return (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), args._2._2._2._2.get()); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
void (SERVER::*func)(typename Type_at<ARGS, 0>::Type, void (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
typename Type_at<ARGS, 3>::Type, typename Type_at<ARGS, 3>::Type,
typename Type_at<ARGS, 4>::Type)) typename Type_at<ARGS, 4>::Type))
{ (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), args._2._2._2._2.get()); } { (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), args._2._2._2._2.get()); return Empty(); }
/* 6 */ /* 6 */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type, RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
typename Type_at<ARGS, 3>::Type, typename Type_at<ARGS, 3>::Type,
typename Type_at<ARGS, 4>::Type, typename Type_at<ARGS, 4>::Type,
typename Type_at<ARGS, 5>::Type)) typename Type_at<ARGS, 5>::Type))
{ ret = (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), { return (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(),
args._2._2._2._2.get(), args._2._2._2._2._2.get()); } args._2._2._2._2.get(), args._2._2._2._2._2.get()); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
void (SERVER::*func)(typename Type_at<ARGS, 0>::Type, void (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
@ -568,11 +564,11 @@ namespace Genode {
typename Type_at<ARGS, 4>::Type, typename Type_at<ARGS, 4>::Type,
typename Type_at<ARGS, 5>::Type)) typename Type_at<ARGS, 5>::Type))
{ (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), { (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(),
args._2._2._2._2.get(), args._2._2._2._2._2.get()); } args._2._2._2._2.get(), args._2._2._2._2._2.get()); return Empty(); }
/* 7 */ /* 7 */
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(RET_TYPE &ret, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type, RET_TYPE (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
@ -580,11 +576,11 @@ namespace Genode {
typename Type_at<ARGS, 4>::Type, typename Type_at<ARGS, 4>::Type,
typename Type_at<ARGS, 5>::Type, typename Type_at<ARGS, 5>::Type,
typename Type_at<ARGS, 6>::Type)) typename Type_at<ARGS, 6>::Type))
{ ret = (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), { return (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(),
args._2._2._2._2.get(), args._2._2._2._2._2.get(), args._2._2._2._2._2._2.get()); } args._2._2._2._2.get(), args._2._2._2._2._2.get(), args._2._2._2._2._2._2.get()); }
template <typename RET_TYPE, typename SERVER, typename ARGS> template <typename RET_TYPE, typename SERVER, typename ARGS>
static inline void call_member(Meta::Empty &, SERVER &server, ARGS &args, static inline RET_TYPE call_member(SERVER &server, ARGS &args,
void (SERVER::*func)(typename Type_at<ARGS, 0>::Type, void (SERVER::*func)(typename Type_at<ARGS, 0>::Type,
typename Type_at<ARGS, 1>::Type, typename Type_at<ARGS, 1>::Type,
typename Type_at<ARGS, 2>::Type, typename Type_at<ARGS, 2>::Type,
@ -593,7 +589,7 @@ namespace Genode {
typename Type_at<ARGS, 5>::Type, typename Type_at<ARGS, 5>::Type,
typename Type_at<ARGS, 6>::Type)) typename Type_at<ARGS, 6>::Type))
{ (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(), { (server.*func)(args.get(), args._2.get(), args._2._2.get(), args._2._2._2.get(),
args._2._2._2._2.get(), args._2._2._2._2._2.get(), args._2._2._2._2._2._2.get()); } args._2._2._2._2.get(), args._2._2._2._2._2.get(), args._2._2._2._2._2._2.get()); return Empty(); }
/******************** /********************