strat: use sf::NativeHandle for ipc templating
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
#include <stratosphere/sf/sf_service_object.hpp>
|
||||
#include <stratosphere/sf/sf_out.hpp>
|
||||
#include <stratosphere/sf/sf_buffers.hpp>
|
||||
#include <stratosphere/sf/sf_handles.hpp>
|
||||
#include <stratosphere/sf/sf_native_handle.hpp>
|
||||
#include <stratosphere/sf/cmif/sf_cmif_pointer_and_size.hpp>
|
||||
#include <stratosphere/sf/cmif/sf_cmif_service_dispatch.hpp>
|
||||
#include <stratosphere/sf/cmif/sf_cmif_service_object_holder.hpp>
|
||||
@@ -199,15 +199,18 @@ namespace ams::sf::impl {
|
||||
|
||||
template<typename T>
|
||||
constexpr inline ArgumentType GetArgumentType = [] {
|
||||
static_assert(!std::same_as<T, sf::NativeHandle>);
|
||||
static_assert(!std::same_as<T, sf::Out<sf::NativeHandle>>);
|
||||
|
||||
if constexpr (sf::IsBuffer<T>) {
|
||||
return ArgumentType::Buffer;
|
||||
} else if constexpr (IsInObject<T>::value) {
|
||||
return ArgumentType::InObject;
|
||||
} else if constexpr (std::is_base_of<sf::impl::OutObjectTag, T>::value) {
|
||||
return ArgumentType::OutObject;
|
||||
} else if constexpr (std::is_base_of<sf::impl::InHandleTag, T>::value) {
|
||||
} else if constexpr (std::same_as<T, sf::CopyHandle> || std::same_as<T, sf::MoveHandle>) {
|
||||
return ArgumentType::InHandle;
|
||||
} else if constexpr (std::is_base_of<sf::impl::OutHandleTag, T>::value) {
|
||||
} else if constexpr (std::same_as<T, sf::OutCopyHandle> || std::same_as<T, sf::OutMoveHandle>) {
|
||||
return ArgumentType::OutHandle;
|
||||
} else if constexpr (std::is_base_of<sf::impl::OutBaseTag, T>::value) {
|
||||
return ArgumentType::OutData;
|
||||
@@ -413,7 +416,7 @@ namespace ams::sf::impl {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using DecayForCommandMetaArguments = typename std::conditional<sf::IsLargeData<typename std::decay<T>::type> && !std::is_base_of<impl::OutBaseTag, typename std::decay<T>::type>::value, T, typename std::decay<T>::type>::type;
|
||||
using DecayForCommandMetaArguments = typename std::conditional<(sf::IsLargeData<typename std::decay<T>::type> && !std::is_base_of<impl::OutBaseTag, typename std::decay<T>::type>::value), T, typename std::conditional<(std::same_as<T, sf::MoveHandle &&> || std::same_as<T, sf::CopyHandle &&>), typename std::decay<T>::type &, typename std::decay<T>::type>::type>::type;
|
||||
|
||||
template<typename... Arguments>
|
||||
struct CommandMetaInfo {
|
||||
@@ -625,38 +628,57 @@ namespace ams::sf::impl {
|
||||
};
|
||||
|
||||
template<size_t _NumMove, size_t _NumCopy>
|
||||
class OutHandleHolder {
|
||||
class InHandleHolder {
|
||||
public:
|
||||
static constexpr size_t NumMove = _NumMove;
|
||||
static constexpr size_t NumCopy = _NumCopy;
|
||||
private:
|
||||
MoveHandle move_handles[NumMove];
|
||||
CopyHandle copy_handles[NumCopy];
|
||||
bool copy_managed[NumCopy];
|
||||
public:
|
||||
constexpr OutHandleHolder() : move_handles(), copy_handles(), copy_managed() { /* ... */ }
|
||||
constexpr InHandleHolder() : move_handles(), copy_handles() { /* ... */ }
|
||||
|
||||
template<size_t Index>
|
||||
constexpr inline MoveHandle *GetMoveHandlePointer() {
|
||||
constexpr inline MoveHandle &SetMoveHandle(os::NativeHandle os_handle) {
|
||||
static_assert(Index < NumMove);
|
||||
move_handles[Index] = sf::NativeHandle(os_handle, true);
|
||||
return move_handles[Index];
|
||||
}
|
||||
|
||||
template<size_t Index>
|
||||
constexpr inline CopyHandle &SetCopyHandle(os::NativeHandle os_handle) {
|
||||
static_assert(Index < NumCopy);
|
||||
copy_handles[Index] = sf::NativeHandle(os_handle, true);
|
||||
return copy_handles[Index];
|
||||
}
|
||||
};
|
||||
|
||||
template<size_t _NumMove, size_t _NumCopy>
|
||||
class OutHandleHolder {
|
||||
public:
|
||||
static constexpr size_t NumMove = _NumMove;
|
||||
static constexpr size_t NumCopy = _NumCopy;
|
||||
private:
|
||||
NativeHandle move_handles[NumMove];
|
||||
NativeHandle copy_handles[NumCopy];
|
||||
public:
|
||||
constexpr OutHandleHolder() : move_handles(), copy_handles() { /* ... */ }
|
||||
|
||||
template<size_t Index>
|
||||
constexpr inline NativeHandle *GetMoveHandlePointer() {
|
||||
static_assert(Index < NumMove, "Index < NumMove");
|
||||
return &move_handles[Index];
|
||||
return move_handles + Index;
|
||||
}
|
||||
|
||||
template<size_t Index>
|
||||
constexpr inline CopyHandle *GetCopyHandlePointer() {
|
||||
constexpr inline NativeHandle *GetCopyHandlePointer() {
|
||||
static_assert(Index < NumCopy, "Index < NumCopy");
|
||||
return ©_handles[Index];
|
||||
}
|
||||
|
||||
template<size_t Index>
|
||||
constexpr inline bool *GetCopyHandleManagedPointer() {
|
||||
static_assert(Index < NumCopy, "Index < NumCopy");
|
||||
return ©_managed[Index];
|
||||
return copy_handles + Index;
|
||||
}
|
||||
|
||||
constexpr inline void CopyTo(const cmif::ServiceDispatchContext &ctx, const HipcRequest &response, const size_t num_out_object_handles) {
|
||||
ctx.handles_to_close->num_handles = 0;
|
||||
#define _SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(n) do { if constexpr (NumCopy > n) { const auto handle = copy_handles[n].GetValue(); response.copy_handles[n] = handle; if (copy_managed[n]) { ctx.handles_to_close->handles[ctx.handles_to_close->num_handles++] = handle; } } } while (0)
|
||||
#define _SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(n) do { if constexpr (NumCopy > n) { const auto handle = copy_handles[n].GetOsHandle(); response.copy_handles[n] = handle; if (copy_handles[n].IsManaged()) { ctx.handles_to_close->handles[ctx.handles_to_close->num_handles++] = handle; } copy_handles[n].Detach(); } } while (0)
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(0);
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(1);
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(2);
|
||||
@@ -666,7 +688,7 @@ namespace ams::sf::impl {
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(6);
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(7);
|
||||
#undef _SF_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE
|
||||
#define _SF_OUT_HANDLE_HOLDER_WRITE_MOVE_HANDLE(n) do { if constexpr (NumMove > n) { response.move_handles[n + num_out_object_handles] = move_handles[n].GetValue(); } } while (0)
|
||||
#define _SF_OUT_HANDLE_HOLDER_WRITE_MOVE_HANDLE(n) do { if constexpr (NumMove > n) { response.move_handles[n + num_out_object_handles] = move_handles[n].GetOsHandle(); move_handles[n].Detach(); } } while (0)
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_MOVE_HANDLE(0);
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_MOVE_HANDLE(1);
|
||||
_SF_OUT_HANDLE_HOLDER_WRITE_MOVE_HANDLE(2);
|
||||
@@ -830,6 +852,7 @@ namespace ams::sf::impl {
|
||||
using ArgsType = typename CommandMeta::ArgsType;
|
||||
using BufferArrayType = std::array<cmif::PointerAndSize, CommandMeta::NumBuffers>;
|
||||
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
||||
using InHandleHolderType = InHandleHolder<CommandMeta::NumInMoveHandles, CommandMeta::NumInCopyHandles>;
|
||||
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
||||
using InOutObjectHolderType = InOutObjectHolder<CommandMeta::NumInObjects, CommandMeta::NumOutObjects>;
|
||||
|
||||
@@ -1014,7 +1037,7 @@ namespace ams::sf::impl {
|
||||
/* Argument deserialization. */
|
||||
private:
|
||||
template<size_t Index, typename T = typename std::tuple_element<Index, ArgsType>::type>
|
||||
NX_CONSTEXPR typename std::tuple_element<Index, ArgsTypeForInvoke>::type DeserializeArgumentImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) {
|
||||
NX_CONSTEXPR typename std::tuple_element<Index, ArgsTypeForInvoke>::type DeserializeArgumentImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, InHandleHolderType &in_handles_holder, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) {
|
||||
constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index];
|
||||
if constexpr (Info.arg_type == ArgumentType::InData) {
|
||||
/* New in rawdata. */
|
||||
@@ -1031,19 +1054,22 @@ namespace ams::sf::impl {
|
||||
return T(out_raw_holder.template GetAddress<Offset, T::TypeSize>());
|
||||
} else if constexpr (Info.arg_type == ArgumentType::InHandle) {
|
||||
/* New InHandle. */
|
||||
using InvokeType = typename std::tuple_element<Index, ArgsTypeForInvoke>::type;
|
||||
if constexpr (std::is_same<T, sf::MoveHandle>::value) {
|
||||
return T(ctx.request.data.move_handles[Info.in_move_handle_index]);
|
||||
static_assert(std::same_as<InvokeType, sf::MoveHandle &>);
|
||||
return in_handles_holder.template SetMoveHandle<Info.in_move_handle_index>(ctx.request.data.move_handles[Info.in_move_handle_index]);
|
||||
} else if constexpr (std::is_same<T, sf::CopyHandle>::value) {
|
||||
return T(ctx.request.data.copy_handles[Info.in_copy_handle_index]);
|
||||
static_assert(std::same_as<InvokeType, sf::CopyHandle &>);
|
||||
return in_handles_holder.template SetCopyHandle<Info.in_copy_handle_index>(ctx.request.data.copy_handles[Info.in_copy_handle_index]);
|
||||
} else {
|
||||
static_assert(!std::is_same<T, T>::value, "Invalid InHandle kind");
|
||||
}
|
||||
} else if constexpr (Info.arg_type == ArgumentType::OutHandle) {
|
||||
/* New OutHandle. */
|
||||
if constexpr (std::is_same<T, sf::Out<sf::MoveHandle>>::value) {
|
||||
if constexpr (std::is_same<T, sf::OutMoveHandle>::value) {
|
||||
return T(out_handles_holder.template GetMoveHandlePointer<Info.out_move_handle_index>());
|
||||
} else if constexpr (std::is_same<T, sf::Out<sf::CopyHandle>>::value) {
|
||||
return T(out_handles_holder.template GetCopyHandlePointer<Info.out_copy_handle_index>(), out_handles_holder.template GetCopyHandleManagedPointer<Info.out_copy_handle_index>());
|
||||
} else if constexpr (std::is_same<T, sf::OutCopyHandle>::value) {
|
||||
return T(out_handles_holder.template GetCopyHandlePointer<Info.out_copy_handle_index>());
|
||||
} else {
|
||||
static_assert(!std::is_same<T, T>::value, "Invalid OutHandle kind");
|
||||
}
|
||||
@@ -1078,12 +1104,12 @@ namespace ams::sf::impl {
|
||||
}
|
||||
|
||||
template<size_t... Is>
|
||||
NX_CONSTEXPR ArgsTypeForInvoke DeserializeArgumentsImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder, std::index_sequence<Is...>) {
|
||||
return ArgsTypeForInvoke { DeserializeArgumentImpl<Is>(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder)..., };
|
||||
NX_CONSTEXPR ArgsTypeForInvoke DeserializeArgumentsImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, InHandleHolderType &in_handles_holder, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder, std::index_sequence<Is...>) {
|
||||
return ArgsTypeForInvoke { DeserializeArgumentImpl<Is>(ctx, in_raw_data, out_raw_holder, buffers, in_handles_holder, out_handles_holder, in_out_objects_holder)..., };
|
||||
}
|
||||
public:
|
||||
NX_CONSTEXPR ArgsTypeForInvoke DeserializeArguments(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) {
|
||||
return DeserializeArgumentsImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder, std::make_index_sequence<std::tuple_size<ArgsTypeForInvoke>::value>{});
|
||||
NX_CONSTEXPR ArgsTypeForInvoke DeserializeArguments(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, InHandleHolderType &in_handles_holder, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) {
|
||||
return DeserializeArgumentsImpl(ctx, in_raw_data, out_raw_holder, buffers, in_handles_holder, out_handles_holder, in_out_objects_holder, std::make_index_sequence<std::tuple_size<ArgsTypeForInvoke>::value>{});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1099,6 +1125,7 @@ namespace ams::sf::impl {
|
||||
constexpr Result InvokeServiceCommandImplCommon(CmifOutHeader **out_header_ptr, cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, Result (*invoke_impl)(sf::IServiceObject *, Arguments &&...)) {
|
||||
using ImplProcessorType = HipcCommandProcessor<CommandMeta>;
|
||||
using BufferArrayType = std::array<cmif::PointerAndSize, CommandMeta::NumBuffers>;
|
||||
using InHandleHolderType = InHandleHolder<CommandMeta::NumInMoveHandles, CommandMeta::NumInCopyHandles>;
|
||||
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
||||
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
||||
using InOutObjectHolderType = InOutObjectHolder<CommandMeta::NumInObjects, CommandMeta::NumOutObjects>;
|
||||
@@ -1133,39 +1160,43 @@ namespace ams::sf::impl {
|
||||
|
||||
/* Decoding/Invocation. */
|
||||
{
|
||||
typename CommandMeta::ArgsTypeForInvoke args_tuple = ImplProcessorType::DeserializeArguments(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder);
|
||||
Result command_result;
|
||||
{
|
||||
InHandleHolderType in_handles_holder;
|
||||
typename CommandMeta::ArgsTypeForInvoke args_tuple = ImplProcessorType::DeserializeArguments(ctx, in_raw_data, out_raw_holder, buffers, in_handles_holder, out_handles_holder, in_out_objects_holder);
|
||||
|
||||
/* Handle in process ID holder if relevant. */
|
||||
if constexpr (CommandMeta::HasInProcessIdHolder) {
|
||||
/* TODO: More precise value than 32? */
|
||||
static_assert(std::tuple_size<typename CommandMeta::ArgsTypeForInvoke>::value <= 32, "Commands must have <= 32 arguments");
|
||||
os::ProcessId process_id{ctx.request.pid};
|
||||
#define _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(n) do { \
|
||||
using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke; \
|
||||
if constexpr (n < std::tuple_size<ArgsTypeForInvoke>::value) { \
|
||||
if constexpr (CommandMeta::template IsInProcessIdHolderIndex<n>) { \
|
||||
R_TRY(MarshalProcessId(std::get<n>(args_tuple), process_id)); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x00); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x01); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x02); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x03);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x04); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x05); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x06); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x07);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x08); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x09); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0a); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0b);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0c); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0d); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0e); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0f);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x10); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x11); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x12); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x13);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x14); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x15); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x16); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x17);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x18); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x19); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1a); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1b);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1c); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1d); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1e); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1f);
|
||||
#undef _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID
|
||||
/* Handle in process ID holder if relevant. */
|
||||
if constexpr (CommandMeta::HasInProcessIdHolder) {
|
||||
/* TODO: More precise value than 32? */
|
||||
static_assert(std::tuple_size<typename CommandMeta::ArgsTypeForInvoke>::value <= 32, "Commands must have <= 32 arguments");
|
||||
const os::ProcessId process_id{ctx.request.pid};
|
||||
#define _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(n) do { \
|
||||
using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke; \
|
||||
if constexpr (n < std::tuple_size<ArgsTypeForInvoke>::value) { \
|
||||
if constexpr (CommandMeta::template IsInProcessIdHolderIndex<n>) { \
|
||||
R_TRY(MarshalProcessId(std::get<n>(args_tuple), process_id)); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x00); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x01); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x02); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x03);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x04); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x05); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x06); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x07);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x08); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x09); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0a); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0b);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0c); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0d); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0e); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x0f);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x10); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x11); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x12); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x13);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x14); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x15); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x16); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x17);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x18); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x19); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1a); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1b);
|
||||
_SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1c); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1d); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1e); _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID(0x1f);
|
||||
#undef _SF_IMPL_PROCESSOR_MARSHAL_PROCESS_ID
|
||||
}
|
||||
|
||||
using TrueArgumentsTuple = std::tuple<Arguments...>;
|
||||
|
||||
sf::IServiceObject * const this_ptr = ctx.srv_obj;
|
||||
command_result = [this_ptr, invoke_impl, &args_tuple]<size_t ...Ix>(std::index_sequence<Ix...>) ALWAYS_INLINE_LAMBDA {
|
||||
return invoke_impl(this_ptr, std::forward<typename std::tuple_element<Ix, TrueArgumentsTuple>::type>(std::get<Ix>(args_tuple))...);
|
||||
}(std::make_index_sequence<std::tuple_size<typename CommandMeta::ArgsTypeForInvoke>::value>());
|
||||
}
|
||||
|
||||
using TrueArgumentsTuple = std::tuple<Arguments...>;
|
||||
|
||||
sf::IServiceObject * const this_ptr = ctx.srv_obj;
|
||||
const auto command_result = [this_ptr, invoke_impl, &args_tuple]<size_t ...Ix>(std::index_sequence<Ix...>) ALWAYS_INLINE_LAMBDA {
|
||||
return invoke_impl(this_ptr, std::forward<typename std::tuple_element<Ix, TrueArgumentsTuple>::type>(std::get<Ix>(args_tuple))...);
|
||||
}(std::make_index_sequence<std::tuple_size<typename CommandMeta::ArgsTypeForInvoke>::value>());
|
||||
|
||||
if (R_FAILED(command_result)) {
|
||||
cmif::PointerAndSize out_raw_data;
|
||||
ctx.processor->PrepareForErrorReply(ctx, out_raw_data, runtime_metadata);
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere/sf/sf_common.hpp>
|
||||
#include <stratosphere/sf/sf_out.hpp>
|
||||
#include <stratosphere/sf/cmif/sf_cmif_pointer_and_size.hpp>
|
||||
|
||||
namespace ams::sf {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct InHandleTag{};
|
||||
struct OutHandleTag{};
|
||||
|
||||
template<u32 Attribute>
|
||||
struct InHandle : public InHandleTag {
|
||||
os::NativeHandle handle;
|
||||
|
||||
constexpr InHandle() : handle(os::InvalidNativeHandle) { /* ... */ }
|
||||
constexpr InHandle(os::NativeHandle h) : handle(h) { /* ... */ }
|
||||
constexpr InHandle(const InHandle &o) : handle(o.handle) { /* ... */ }
|
||||
|
||||
constexpr void operator=(const os::NativeHandle &h) { this->handle = h; }
|
||||
constexpr void operator=(const InHandle &o) { this->handle = o.handle; }
|
||||
|
||||
constexpr /* TODO: explicit? */ operator os::NativeHandle() const { return this->handle; }
|
||||
constexpr os::NativeHandle GetValue() const { return this->handle; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class OutHandleImpl : public OutHandleTag {
|
||||
static_assert(std::is_base_of<InHandleTag, T>::value, "OutHandleImpl requires InHandle base");
|
||||
private:
|
||||
T *ptr;
|
||||
public:
|
||||
constexpr OutHandleImpl(T *p) : ptr(p) { /* ... */ }
|
||||
|
||||
constexpr void SetValue(const os::NativeHandle &value) {
|
||||
*this->ptr = value;
|
||||
}
|
||||
|
||||
constexpr void SetValue(const T &value) {
|
||||
*this->ptr = value;
|
||||
}
|
||||
|
||||
constexpr const T &GetValue() const {
|
||||
return *this->ptr;
|
||||
}
|
||||
|
||||
constexpr T *GetPointer() const {
|
||||
return this->ptr;
|
||||
}
|
||||
|
||||
constexpr os::NativeHandle *GetHandlePointer() const {
|
||||
return &this->ptr->handle;
|
||||
}
|
||||
|
||||
constexpr T &operator *() const {
|
||||
return *this->ptr;
|
||||
}
|
||||
|
||||
constexpr T *operator ->() const {
|
||||
return this->ptr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using MoveHandle = typename impl::InHandle<SfOutHandleAttr_HipcMove>;
|
||||
using CopyHandle = typename impl::InHandle<SfOutHandleAttr_HipcCopy>;
|
||||
|
||||
static_assert(sizeof(MoveHandle) == sizeof(os::NativeHandle), "sizeof(MoveHandle)");
|
||||
static_assert(sizeof(CopyHandle) == sizeof(os::NativeHandle), "sizeof(CopyHandle)");
|
||||
|
||||
template<>
|
||||
class IsOutForceEnabled<MoveHandle> : public std::true_type{};
|
||||
template<>
|
||||
class IsOutForceEnabled<CopyHandle> : public std::true_type{};
|
||||
|
||||
template<>
|
||||
class Out<MoveHandle> : public impl::OutHandleImpl<MoveHandle> {
|
||||
private:
|
||||
using T = MoveHandle;
|
||||
using Base = impl::OutHandleImpl<T>;
|
||||
public:
|
||||
constexpr Out<T>(T *p) : Base(p) { /* ... */ }
|
||||
|
||||
constexpr void SetValue(const os::NativeHandle &value) {
|
||||
Base::SetValue(value);
|
||||
}
|
||||
|
||||
constexpr void SetValue(const T &value) {
|
||||
Base::SetValue(value);
|
||||
}
|
||||
|
||||
constexpr const T &GetValue() const {
|
||||
return Base::GetValue();
|
||||
}
|
||||
|
||||
constexpr T *GetPointer() const {
|
||||
return Base::GetPointer();
|
||||
}
|
||||
|
||||
constexpr os::NativeHandle *GetHandlePointer() const {
|
||||
return Base::GetHandlePointer();
|
||||
}
|
||||
|
||||
constexpr T &operator *() const {
|
||||
return Base::operator*();
|
||||
}
|
||||
|
||||
constexpr T *operator ->() const {
|
||||
return Base::operator->();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Out<CopyHandle> : public impl::OutHandleImpl<CopyHandle> {
|
||||
private:
|
||||
using T = CopyHandle;
|
||||
using Base = impl::OutHandleImpl<T>;
|
||||
private:
|
||||
bool *m_managed;
|
||||
public:
|
||||
constexpr Out<T>(T *p) : Base(p), m_managed(nullptr) { /* ... */ }
|
||||
constexpr Out<T>(T *p, bool *m) : Base(p), m_managed(m) { /* ... */ }
|
||||
|
||||
constexpr void SetValue(const os::NativeHandle &value) {
|
||||
Base::SetValue(value);
|
||||
}
|
||||
|
||||
constexpr void SetValue(const T &value) {
|
||||
Base::SetValue(value);
|
||||
}
|
||||
|
||||
constexpr void SetManaged(bool m) {
|
||||
AMS_ASSERT(m_managed != nullptr);
|
||||
*m_managed = m;
|
||||
}
|
||||
|
||||
constexpr const T &GetValue() const {
|
||||
return Base::GetValue();
|
||||
}
|
||||
|
||||
constexpr T *GetPointer() const {
|
||||
return Base::GetPointer();
|
||||
}
|
||||
|
||||
constexpr os::NativeHandle *GetHandlePointer() const {
|
||||
return Base::GetHandlePointer();
|
||||
}
|
||||
|
||||
constexpr T &operator *() const {
|
||||
return Base::operator*();
|
||||
}
|
||||
|
||||
constexpr T *operator ->() const {
|
||||
return Base::operator->();
|
||||
}
|
||||
};
|
||||
|
||||
using OutMoveHandle = sf::Out<sf::MoveHandle>;
|
||||
using OutCopyHandle = sf::Out<sf::CopyHandle>;
|
||||
|
||||
}
|
||||
@@ -21,7 +21,8 @@
|
||||
namespace ams::sf {
|
||||
|
||||
class NativeHandle {
|
||||
NON_COPYABLE(NativeHandle);
|
||||
protected:
|
||||
NON_COPYABLE(NativeHandle);
|
||||
private:
|
||||
os::NativeHandle m_handle;
|
||||
bool m_managed;
|
||||
@@ -77,12 +78,24 @@ namespace ams::sf {
|
||||
}
|
||||
};
|
||||
|
||||
ALWAYS_INLINE void swap(NativeHandle &lhs, NativeHandle &rhs) {
|
||||
class CopyHandle : public NativeHandle {
|
||||
public:
|
||||
using NativeHandle::NativeHandle;
|
||||
using NativeHandle::operator=;
|
||||
};
|
||||
|
||||
class MoveHandle : public NativeHandle {
|
||||
public:
|
||||
using NativeHandle::NativeHandle;
|
||||
using NativeHandle::operator=;
|
||||
};
|
||||
|
||||
constexpr ALWAYS_INLINE void swap(NativeHandle &lhs, NativeHandle &rhs) {
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
template<>
|
||||
class Out<NativeHandle> {
|
||||
class Out<CopyHandle> {
|
||||
private:
|
||||
NativeHandle *m_ptr;
|
||||
public:
|
||||
@@ -92,9 +105,36 @@ namespace ams::sf {
|
||||
*m_ptr = std::move(v);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void SetValue(os::NativeHandle os_handle, bool managed) const {
|
||||
return this->SetValue(NativeHandle(os_handle, managed));
|
||||
}
|
||||
|
||||
NativeHandle &operator*() const {
|
||||
return *m_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Out<MoveHandle> {
|
||||
private:
|
||||
NativeHandle *m_ptr;
|
||||
public:
|
||||
Out(NativeHandle *p) : m_ptr(p) { /* ... */ }
|
||||
|
||||
void SetValue(NativeHandle v) const {
|
||||
*m_ptr = std::move(v);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void SetValue(os::NativeHandle os_handle, bool managed) const {
|
||||
return this->SetValue(NativeHandle(os_handle, managed));
|
||||
}
|
||||
|
||||
NativeHandle &operator*() const {
|
||||
return *m_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
using OutCopyHandle = Out<CopyHandle>;
|
||||
using OutMoveHandle = Out<MoveHandle>;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user