diff --git a/repos/base-nova/src/test/platform/ipc.cc b/repos/base-nova/src/test/platform/ipc.cc index a4d20b2d0..f6b3deb2c 100644 --- a/repos/base-nova/src/test/platform/ipc.cc +++ b/repos/base-nova/src/test/platform/ipc.cc @@ -24,6 +24,9 @@ long Test::cap_void_manual(Genode::Native_capability dst, Genode::Native_capability arg1, Genode::addr_t &local_reply) { + if (!arg1.valid()) + return Genode::Rpc_exception_code::INVALID_OBJECT; + Genode::Thread * myself = Genode::Thread::myself(); Nova::Utcb *utcb = reinterpret_cast(myself->utcb()); @@ -38,9 +41,6 @@ long Test::cap_void_manual(Genode::Native_capability dst, utcb->msg[1] = 0; utcb->set_msg_word(2); - if (!arg1.valid()) - return Genode::Rpc_exception_code::INVALID_OBJECT; - Nova::Crd crd = Genode::Capability_space::crd(arg1); if (!utcb->append_item(crd, 0, false, false, false)) return Genode::Rpc_exception_code::INVALID_OBJECT; @@ -50,7 +50,7 @@ long Test::cap_void_manual(Genode::Native_capability dst, /* restore original receive window */ utcb->crd_rcv = orig_crd; - local_reply = utcb->msg[2]; - return (res == Nova::NOVA_OK && utcb->msg_words() == 3) + local_reply = utcb->msg[1]; + return (res == Nova::NOVA_OK && utcb->msg_words() == 3 && utcb->msg[2]) ? utcb->msg[0] : Genode::Rpc_exception_code::INVALID_OBJECT; } diff --git a/repos/base-nova/src/test/platform/main.cc b/repos/base-nova/src/test/platform/main.cc index 0c337fcb6..a23684bba 100644 --- a/repos/base-nova/src/test/platform/main.cc +++ b/repos/base-nova/src/test/platform/main.cc @@ -157,10 +157,12 @@ void test_revoke(Genode::Env &env) 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); if (rpc != Genode::Rpc_exception_code::SUCCESS || 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 ++; error("test_revoke ipc call failed ", Hex(rpc)); diff --git a/repos/base/include/base/capability.h b/repos/base/include/base/capability.h index 3afb315c2..f3c6ce88d 100644 --- a/repos/base/include/base/capability.h +++ b/repos/base/include/base/capability.h @@ -115,8 +115,7 @@ class Genode::Capability : public Untyped_capability * Perform RPC call, arguments passed a as nested 'Ref_tuple' object */ template - void _call(typename IF::Client_args &args, - typename IF::Ret_type &ret) const; + typename IF::Ret_type _call(typename IF::Client_args &args) const; /** * Shortcut for querying argument types used in 'call' methods @@ -137,27 +136,6 @@ class Genode::Capability : public Untyped_capability 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 - struct Return - { - typedef typename Trait::Call_return::Type - Return_type; - - volatile Return_type _value; - Return_type &value() { return *(Return_type *)(&_value); } - }; - public: typedef RPC_INTERFACE Rpc_interface; @@ -185,9 +163,7 @@ class Genode::Capability : public Untyped_capability call() const { Meta::Empty e; - Return ret; - _call(e, ret.value()); - return ret.value(); + return _call(e); } template @@ -196,9 +172,7 @@ class Genode::Capability : public Untyped_capability { Meta::Empty e; typename IF::Client_args args(v1, e); - Return ret; - _call(args, ret.value()); - return ret.value(); + return _call(args); } template @@ -207,9 +181,7 @@ class Genode::Capability : public Untyped_capability { Meta::Empty e; typename IF::Client_args args(v1, v2, e); - Return ret; - _call(args, ret.value()); - return ret.value(); + return _call(args); } template @@ -219,9 +191,7 @@ class Genode::Capability : public Untyped_capability { Meta::Empty e; typename IF::Client_args args(v1, v2, v3, e); - Return ret; - _call(args, ret.value()); - return ret.value(); + return _call(args); } template @@ -231,9 +201,7 @@ class Genode::Capability : public Untyped_capability { Meta::Empty e; typename IF::Client_args args(v1, v2, v3, v4, e); - Return ret; - _call(args, ret.value()); - return ret.value(); + return _call(args); } template @@ -244,9 +212,7 @@ class Genode::Capability : public Untyped_capability { Meta::Empty e; typename IF::Client_args args(v1, v2, v3, v4, v5, e); - Return ret; - _call(args, ret.value()); - return ret.value(); + return _call(args); } template @@ -257,9 +223,7 @@ class Genode::Capability : public Untyped_capability { Meta::Empty e; typename IF::Client_args args(v1, v2, v3, v4, v5, v6, e); - Return ret; - _call(args, ret.value()); - return ret.value(); + return _call(args); } template @@ -271,9 +235,7 @@ class Genode::Capability : public Untyped_capability { Meta::Empty e; typename IF::Client_args args(v1, v2, v3, v4, v5, v6, v7, e); - Return ret; - _call(args, ret.value()); - return ret.value(); + return _call(args); } }; diff --git a/repos/base/include/base/ipc.h b/repos/base/include/base/ipc.h index 798933fb6..b5a9cf38a 100644 --- a/repos/base/include/base/ipc.h +++ b/repos/base/include/base/ipc.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace Genode { @@ -65,9 +66,15 @@ class Genode::Ipc_unmarshaller : Noncopyable template void extract(Capability &typed_cap) { - Native_capability untyped_cap; - extract(untyped_cap); - typed_cap = reinterpret_cap_cast(untyped_cap); + typed_cap = extract(Meta::Overload_selector >()); + } + + template + Capability extract(Meta::Overload_selector >) + { + Native_capability untyped_cap = + extract(Meta::Overload_selector()); + return reinterpret_cap_cast(untyped_cap); } /** @@ -75,9 +82,15 @@ class Genode::Ipc_unmarshaller : Noncopyable */ void extract(Native_capability &cap) { - cap = _read_cap_index < _rcv_msg.used_caps() - ? _rcv_msg.cap(_read_cap_index) : Native_capability(); + cap = extract(Meta::Overload_selector()); + } + + Native_capability extract(Meta::Overload_selector) + { + Native_capability cap = _read_cap_index < _rcv_msg.used_caps() + ? _rcv_msg.cap(_read_cap_index) : Native_capability(); _read_cap_index++; + return cap; } /** @@ -86,8 +99,6 @@ class Genode::Ipc_unmarshaller : Noncopyable template void extract(Rpc_in_buffer &b) { - size_t size = 0; - extract(size); b = Rpc_in_buffer(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 * condition triggers. */ + try { + b = extract(Meta::Overload_selector >()); + } catch (Ipc_error) { } + } + + template + Rpc_in_buffer extract(Meta::Overload_selector >) + { + size_t size = extract(Meta::Overload_selector()); if (_read_offset + size > _rcv_buf_size) { error("message buffer overrun"); - return; + throw Ipc_error(); } - b = Rpc_in_buffer(&_rcv_buf[_read_offset], size); + Rpc_in_buffer buf(&_rcv_buf[_read_offset], size); _read_offset += align_natural(size); + return buf; } /** @@ -110,15 +131,23 @@ class Genode::Ipc_unmarshaller : Noncopyable */ template void extract(T &value) + { + value = extract(Meta::Overload_selector()); + } + + template + T extract(Meta::Overload_selector) { /* 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 */ - value = *reinterpret_cast(&_rcv_buf[_read_offset]); + T value = *reinterpret_cast(&_rcv_buf[_read_offset]); /* increment read pointer to next dword-aligned value */ _read_offset += align_natural(sizeof(T)); + + return value; } Ipc_unmarshaller(Msgbuf_base &rcv_msg) : _rcv_msg(rcv_msg) { } diff --git a/repos/base/include/base/rpc.h b/repos/base/include/base/rpc.h index 6ce8d18af..75c3cd917 100644 --- a/repos/base/include/base/rpc.h +++ b/repos/base/include/base/rpc.h @@ -43,9 +43,9 @@ typedef ::Genode::Trait::Call_return::Type Ret_type; \ \ template \ - static void serve(SERVER &server, Server_args &args, RET &ret) { \ - ::Genode::Meta::call_member \ - (ret, server, args, &SERVER::func_name); } \ + static RET serve(SERVER &server, Server_args &args) { \ + return ::Genode::Meta::call_member \ + (server, args, &SERVER::func_name); } \ \ static const char* name() { return #func_name; } \ }; diff --git a/repos/base/include/base/rpc_client.h b/repos/base/include/base/rpc_client.h index bac73ec9f..6dce72462 100644 --- a/repos/base/include/base/rpc_client.h +++ b/repos/base/include/base/rpc_client.h @@ -107,8 +107,8 @@ namespace Genode { template template - void Capability:: - _call(typename IF::Client_args &args, typename IF::Ret_type &ret) const + typename IF::Ret_type Capability:: + _call(typename IF::Client_args &args) const { /** * Message buffer for RPC message @@ -144,7 +144,6 @@ namespace Genode { throw Ipc_error(); Ipc_unmarshaller unmarshaller(reply_buf); - unmarshaller.extract(ret); { Trace::Rpc_returned trace_event(IF::name(), reply_buf); @@ -156,6 +155,10 @@ namespace Genode { /* reflect callee-side exception at the caller */ _check_for_exceptions(exception_code, Meta::Overload_selector()); + + /* the return value does only exist if no exception was thrown */ + Meta::Overload_selector ret_overloader; + return unmarshaller.extract(ret_overloader); } } diff --git a/repos/base/include/base/rpc_server.h b/repos/base/include/base/rpc_server.h index 1a29d94f4..04ad43853 100644 --- a/repos/base/include/base/rpc_server.h +++ b/repos/base/include/base/rpc_server.h @@ -63,15 +63,44 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE protected: template - void _read_args(Ipc_unmarshaller &msg, ARG_LIST &args) + ARG_LIST _read_args(Ipc_unmarshaller &msg, + Meta::Overload_selector) { - if (Trait::Rpc_direction::Type::IN) - msg.extract(args._1); + typename Trait::Rpc_direction::Type direction; + typedef typename ARG_LIST::Stored_head Arg; + Arg arg = _read_arg(msg, direction); - _read_args(msg, args._2); + Meta::Overload_selector 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) + { + return Meta::Empty(); + } + + template + ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_in) + { + return msg.extract(Meta::Overload_selector()); + } + + template + ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_inout) + { + return _read_arg(msg, Rpc_arg_in()); + } + + template + ARG _read_arg(Ipc_unmarshaller &msg, Rpc_arg_out) + { + return ARG(); + } template 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) { } template - Rpc_exception_code _do_serve(typename RPC_FUNCTION::Server_args &args, - typename RPC_FUNCTION::Ret_type &ret, - Meta::Overload_selector) + typename RPC_FUNCTION::Ret_type + _do_serve(typename RPC_FUNCTION::Server_args &args, + Meta::Overload_selector) { enum { EXCEPTION_CODE = Rpc_exception_code::EXCEPTION_BASE - Meta::Length::Value }; try { typedef typename EXC_TL::Tail Exc_tail; - return _do_serve(args, ret, + return _do_serve(args, Meta::Overload_selector()); } 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 - Rpc_exception_code _do_serve(typename RPC_FUNCTION::Server_args &args, - typename RPC_FUNCTION::Ret_type &ret, - Meta::Overload_selector) + typename RPC_FUNCTION::Ret_type + _do_serve(typename RPC_FUNCTION::Server_args &args, + Meta::Overload_selector) { - RPC_FUNCTION::serve(*static_cast(this), args, ret); - return Rpc_exception_code(Rpc_exception_code::SUCCESS); + typedef typename RPC_FUNCTION::Ret_type Ret_type; + SERVER *me = static_cast(this); + return RPC_FUNCTION::template serve(*me, args); } template @@ -120,10 +155,10 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE if (opcode.value == Index_of::Value) { - typename This_rpc_function::Server_args args{}; - /* read arguments from incoming message */ - _read_args(in, args); + typedef typename This_rpc_function::Server_args Server_args; + Meta::Overload_selector arg_selector; + Server_args args = _read_args(in, arg_selector); { 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 * select the overload. */ - typedef typename This_rpc_function::Exceptions Exceptions; - typename This_rpc_function::Ret_type ret { }; - Rpc_exception_code - exc(_do_serve(args, ret, - Overload_selector())); + typedef typename This_rpc_function::Ret_type Ret_type; + Rpc_exception_code exc(Rpc_exception_code::SUCCESS); + try { + typedef typename This_rpc_function::Exceptions Exceptions; + Overload_selector 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()); } - /* write results to outgoing message */ - _write_results(out, args); - return exc; } diff --git a/repos/base/include/util/meta.h b/repos/base/include/util/meta.h index 53256f75c..5e9d98695 100644 --- a/repos/base/include/util/meta.h +++ b/repos/base/include/util/meta.h @@ -291,17 +291,26 @@ namespace Genode { /** * 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 - struct Pod_tuple : public Type_tuple + struct Pod_tuple { - typename Trait::Pod::Type _1; - typename Trait::Pod::Type _2; + typedef typename Trait::Pod::Type Stored_head; + Stored_head _1; + TAIL _2; + + typedef HEAD Head; + typedef TAIL Tail; /** * Accessor for requesting the data reference to '_1' */ - typename Trait::Pod::Type &get() { return _1; } + Stored_head &get() { return _1; } }; /** @@ -313,32 +322,18 @@ namespace Genode { * function returns a pointer to the stored copy. */ template - struct Pod_tuple : public Type_tuple + struct Pod_tuple { - typename Trait::Non_reference::Type _1; - typename Trait::Non_reference::Type _2; + typedef typename Trait::Non_reference::Type Stored_head; + Stored_head _1; + TAIL _2; + + typedef HEAD* Head; + typedef TAIL Tail; HEAD *get() { return &_1; } }; - template - struct Pod_tuple_3 : public Pod_tuple > { }; - - template - struct Pod_tuple_4 : public Pod_tuple > { }; - - template - struct Pod_tuple_5 : public Pod_tuple > { }; - - template - struct Pod_tuple_6 : public Pod_tuple > { }; - - template - struct Pod_tuple_7 : public Pod_tuple > { }; - - template - struct Pod_tuple_8 : public Pod_tuple > { }; - /************************************************************************* ** Support for representing function arguments in a normalized fashion ** @@ -409,22 +404,23 @@ namespace Genode { struct Pod_args { typedef Pod_tuple Type; }; template - struct Pod_args { typedef Pod_tuple_3 Type; }; + struct Pod_args { typedef Pod_tuple::Type> Type; }; template - struct Pod_args { typedef Pod_tuple_4 Type; }; + struct Pod_args { typedef Pod_tuple::Type> Type; }; template - struct Pod_args { typedef Pod_tuple_5 Type; }; + struct Pod_args { typedef Pod_tuple::Type> Type; }; template - struct Pod_args { typedef Pod_tuple_6 Type; }; + struct Pod_args { typedef Pod_tuple::Type> Type; }; template - struct Pod_args { typedef Pod_tuple_7 Type; }; + struct Pod_args { typedef Pod_tuple::Type> Type; }; template - struct Pod_args { typedef Pod_tuple_8 Type; }; + struct Pod_args { typedef Pod_tuple::Type> Type; }; + /** * Helper for calling member functions via a uniform interface @@ -453,114 +449,114 @@ namespace Genode { */ template - 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 = (server.*func)(); } + { return (server.*func)(); } template - 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 = (server.*func)(); } + { return (server.*func)(); } template - static inline void call_member(Meta::Empty &, SERVER &server, ARGS &, + static inline RET_TYPE call_member(SERVER &server, ARGS &, void (SERVER::*func)()) - { (server.*func)(); } + { (server.*func)(); return Empty(); } template - static inline void call_member(Meta::Empty &, SERVER &server, ARGS &, + static inline RET_TYPE call_member(SERVER &server, ARGS &, void (SERVER::*func)() const) - { (server.*func)(); } + { (server.*func)(); return Empty(); } /* 1 */ template - 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::Type)) - { ret = (server.*func)(args.get()); } + { return (server.*func)(args.get()); } template - 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::Type)) - { (server.*func)(args.get()); } + { (server.*func)(args.get()); return Empty(); } /* 2 */ template - 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::Type, typename Type_at::Type)) - { ret = (server.*func)(args.get(), args._2.get()); } + { return (server.*func)(args.get(), args._2.get()); } template - 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::Type, typename Type_at::Type)) - { (server.*func)(args.get(), args._2.get()); } + { (server.*func)(args.get(), args._2.get()); return Empty(); } /* 3 */ template - 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::Type, typename Type_at::Type, typename Type_at::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 - 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::Type, typename Type_at::Type, typename Type_at::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 */ template - 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::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::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 - 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::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::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 */ template - 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::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::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 - 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::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::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 */ template - 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::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::Type, typename Type_at::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()); } template - 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::Type, typename Type_at::Type, typename Type_at::Type, @@ -568,11 +564,11 @@ namespace Genode { typename Type_at::Type, typename Type_at::Type)) { (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 */ template - 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::Type, typename Type_at::Type, typename Type_at::Type, @@ -580,11 +576,11 @@ namespace Genode { typename Type_at::Type, typename Type_at::Type, typename Type_at::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()); } template - 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::Type, typename Type_at::Type, typename Type_at::Type, @@ -593,7 +589,7 @@ namespace Genode { typename Type_at::Type, typename Type_at::Type)) { (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(); } /********************