cmif_types: improve ergonomics of types
This commit is contained in:
		| @@ -150,7 +150,7 @@ void ReadInArgument(CallArguments& args, const u8* raw_data, HLERequestContext& | ||||
|  | ||||
|             return ReadInArgument<Domain, MethodArguments, CallArguments, ArgAlign, ArgEnd, HandleIndex, InBufferIndex, OutBufferIndex, true, ArgIndex + 1>(args, raw_data, ctx, temp); | ||||
|         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InCopyHandle) { | ||||
|             std::get<ArgIndex>(args) = std::move(ctx.GetObjectFromHandle<typename ArgType::Type>(ctx.GetCopyHandle(HandleIndex))); | ||||
|             std::get<ArgIndex>(args) = ctx.GetObjectFromHandle<typename ArgType::Type>(ctx.GetCopyHandle(HandleIndex)).GetPointerUnsafe(); | ||||
|  | ||||
|             return ReadInArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, HandleIndex + 1, InBufferIndex, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); | ||||
|         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::InLargeData) { | ||||
| @@ -253,11 +253,11 @@ void WriteOutArgument(CallArguments& args, u8* raw_data, HLERequestContext& ctx, | ||||
|  | ||||
|             return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(args, raw_data, ctx, temp); | ||||
|         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutCopyHandle) { | ||||
|             ctx.AddCopyObject(std::get<ArgIndex>(args).GetPointerUnsafe()); | ||||
|             ctx.AddCopyObject(std::get<ArgIndex>(args)); | ||||
|  | ||||
|             return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); | ||||
|         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutMoveHandle) { | ||||
|             ctx.AddMoveObject(std::get<ArgIndex>(args).GetPointerUnsafe()); | ||||
|             ctx.AddMoveObject(std::get<ArgIndex>(args)); | ||||
|  | ||||
|             return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp); | ||||
|         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) { | ||||
|   | ||||
| @@ -15,19 +15,21 @@ namespace Service { | ||||
| template <typename T> | ||||
| class Out { | ||||
| public: | ||||
|     /* implicit */ Out(T& t) : raw(&t) {} | ||||
|     using Type = T; | ||||
|  | ||||
|     /* implicit */ Out(Type& t) : raw(&t) {} | ||||
|     ~Out() = default; | ||||
|  | ||||
|     T* Get() const { | ||||
|     Type* Get() const { | ||||
|         return raw; | ||||
|     } | ||||
|  | ||||
|     T& operator*() { | ||||
|     Type& operator*() { | ||||
|         return *raw; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     T* raw; | ||||
|     Type* raw; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| @@ -45,51 +47,93 @@ struct ClientProcessId { | ||||
|     u64 pid; | ||||
| }; | ||||
|  | ||||
| struct ProcessId { | ||||
|     explicit operator bool() const { | ||||
|         return pid != 0; | ||||
|     } | ||||
|  | ||||
|     const u64& operator*() const { | ||||
|         return pid; | ||||
|     } | ||||
|  | ||||
|     u64 pid; | ||||
| }; | ||||
|  | ||||
| using ClientAppletResourceUserId = ClientProcessId; | ||||
| using AppletResourceUserId = ProcessId; | ||||
|  | ||||
| template <typename T> | ||||
| class InCopyHandle : public Kernel::KScopedAutoObject<T> { | ||||
| class InCopyHandle { | ||||
| public: | ||||
|     using Type = T; | ||||
|  | ||||
|     template <typename... Args> | ||||
|     /* implicit */ InCopyHandle(Args&&... args) : Kernel::KScopedAutoObject<T>(std::forward<Args...>(args)...) {} | ||||
|     /* implicit */ InCopyHandle(Type* t) : raw(t) {} | ||||
|     /* implicit */ InCopyHandle() : raw() {} | ||||
|     ~InCopyHandle() = default; | ||||
|  | ||||
|     InCopyHandle& operator=(InCopyHandle&& rhs) { | ||||
|         Kernel::KScopedAutoObject<T>::operator=(std::move(rhs)); | ||||
|     InCopyHandle& operator=(Type* rhs) { | ||||
|         raw = rhs; | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     Type* Get() const { | ||||
|         return raw; | ||||
|     } | ||||
|  | ||||
|     Type& operator*() const { | ||||
|         return *raw; | ||||
|     } | ||||
|  | ||||
|     Type* operator->() const { | ||||
|         return raw; | ||||
|     } | ||||
|  | ||||
|     explicit operator bool() const { | ||||
|         return raw != nullptr; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     Type* raw; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| class OutCopyHandle : public Kernel::KScopedAutoObject<T> { | ||||
| class OutCopyHandle { | ||||
| public: | ||||
|     using Type = T; | ||||
|     using Type = T*; | ||||
|  | ||||
|     template <typename... Args> | ||||
|     /* implicit */ OutCopyHandle(Args&&... args) : Kernel::KScopedAutoObject<T>(std::forward<Args...>(args)...) {} | ||||
|     /* implicit */ OutCopyHandle(Type& t) : raw(&t) {} | ||||
|     ~OutCopyHandle() = default; | ||||
|  | ||||
|     OutCopyHandle& operator=(OutCopyHandle&& rhs) { | ||||
|         Kernel::KScopedAutoObject<T>::operator=(std::move(rhs)); | ||||
|         return *this; | ||||
|     Type* Get() const { | ||||
|         return raw; | ||||
|     } | ||||
|  | ||||
|     Type& operator*() { | ||||
|         return *raw; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     Type* raw; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| class OutMoveHandle : public Kernel::KScopedAutoObject<T> { | ||||
| class OutMoveHandle { | ||||
| public: | ||||
|     using Type = T; | ||||
|     using Type = T*; | ||||
|  | ||||
|     template <typename... Args> | ||||
|     /* implicit */ OutMoveHandle(Args&&... args) : Kernel::KScopedAutoObject<T>(std::forward<Args...>(args)...) {} | ||||
|     /* implicit */ OutMoveHandle(Type& t) : raw(&t) {} | ||||
|     ~OutMoveHandle() = default; | ||||
|  | ||||
|     OutMoveHandle& operator=(OutMoveHandle&& rhs) { | ||||
|         Kernel::KScopedAutoObject<T>::operator=(std::move(rhs)); | ||||
|         return *this; | ||||
|     Type* Get() const { | ||||
|         return raw; | ||||
|     } | ||||
|  | ||||
|     Type& operator*() { | ||||
|         return *raw; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     Type* raw; | ||||
| }; | ||||
|  | ||||
| enum BufferAttr : int { | ||||
| @@ -105,12 +149,15 @@ enum BufferAttr : int { | ||||
|  | ||||
| template <typename T, int A> | ||||
| struct Buffer : public std::span<T> { | ||||
|     static_assert(std::is_trivial_v<T>, "Buffer type must be trivial"); | ||||
|     static_assert(std::is_trivially_copyable_v<T>, "Buffer type must be trivially copyable"); | ||||
|     static_assert((A & BufferAttr_FixedSize) == 0, "Buffer attr must not contain FixedSize"); | ||||
|     static_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "Buffer attr must be In or Out"); | ||||
|     static constexpr BufferAttr Attr = static_cast<BufferAttr>(A); | ||||
|     using Type = T; | ||||
|  | ||||
|     /* implicit */ Buffer(const std::span<T>& rhs) : std::span<T>(rhs) {} | ||||
|     /* implicit */ Buffer() = default; | ||||
|  | ||||
|     Buffer& operator=(const std::span<T>& rhs) { | ||||
|         std::span<T>::operator=(rhs); | ||||
|         return *this; | ||||
| @@ -139,11 +186,14 @@ using OutArray = Buffer<T, BufferAttr_Out | A>; | ||||
|  | ||||
| template <typename T, int A> | ||||
| struct LargeData : public T { | ||||
|     static_assert(std::is_trivial_v<T>, "LargeData type must be trivial"); | ||||
|     static_assert(std::is_trivially_copyable_v<T>, "LargeData type must be trivially copyable"); | ||||
|     static_assert((A & BufferAttr_FixedSize) != 0, "LargeData attr must contain FixedSize"); | ||||
|     static_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "LargeData attr must be In or Out"); | ||||
|     static constexpr BufferAttr Attr = static_cast<BufferAttr>(A); | ||||
|     using Type = T; | ||||
|  | ||||
|     /* implicit */ LargeData(const T& rhs) : T(rhs) {} | ||||
|     /* implicit */ LargeData() = default; | ||||
| }; | ||||
|  | ||||
| template <typename T, BufferAttr A> | ||||
| @@ -159,7 +209,17 @@ struct RemoveOut { | ||||
|  | ||||
| template <typename T> | ||||
| struct RemoveOut<Out<T>> { | ||||
|     using Type = T; | ||||
|     using Type = typename Out<T>::Type; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| struct RemoveOut<OutCopyHandle<T>> { | ||||
|     using Type = typename OutCopyHandle<T>::Type; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| struct RemoveOut<OutMoveHandle<T>> { | ||||
|     using Type = typename OutMoveHandle<T>::Type; | ||||
| }; | ||||
|  | ||||
| enum class ArgumentType { | ||||
|   | ||||
| @@ -27,7 +27,7 @@ static_assert(sizeof(Struct32) == 32, "Struct32 has wrong size"); | ||||
| class IJitEnvironment final : public ServiceFramework<IJitEnvironment> { | ||||
| public: | ||||
|     explicit IJitEnvironment(Core::System& system_, | ||||
|                              Kernel::KScopedAutoObject<Kernel::KProcess>&& process_, | ||||
|                              Kernel::KScopedAutoObject<Kernel::KProcess> process_, | ||||
|                              CodeMemory&& user_rx_, CodeMemory&& user_ro_) | ||||
|         : ServiceFramework{system_, "IJitEnvironment"}, process{std::move(process_)}, | ||||
|           user_rx{std::move(user_rx_)}, user_ro{std::move(user_ro_)}, | ||||
| @@ -129,7 +129,7 @@ public: | ||||
|     Result LoadPlugin(u64 tmem_size, InCopyHandle<Kernel::KTransferMemory>& tmem, | ||||
|                       InBuffer<BufferAttr_HipcMapAlias> nrr, | ||||
|                       InBuffer<BufferAttr_HipcMapAlias> nro) { | ||||
|         if (tmem.IsNull()) { | ||||
|         if (!tmem) { | ||||
|             LOG_ERROR(Service_JIT, "Invalid transfer memory handle!"); | ||||
|             R_THROW(ResultUnknown); | ||||
|         } | ||||
| @@ -271,15 +271,15 @@ private: | ||||
|                                 u64 rx_size, u64 ro_size, InCopyHandle<Kernel::KProcess>& process, | ||||
|                                 InCopyHandle<Kernel::KCodeMemory>& rx_mem, | ||||
|                                 InCopyHandle<Kernel::KCodeMemory>& ro_mem) { | ||||
|         if (process.IsNull()) { | ||||
|         if (!process) { | ||||
|             LOG_ERROR(Service_JIT, "process is null"); | ||||
|             R_THROW(ResultUnknown); | ||||
|         } | ||||
|         if (rx_mem.IsNull()) { | ||||
|         if (!rx_mem) { | ||||
|             LOG_ERROR(Service_JIT, "rx_mem is null"); | ||||
|             R_THROW(ResultUnknown); | ||||
|         } | ||||
|         if (rx_mem.IsNull()) { | ||||
|         if (!ro_mem) { | ||||
|             LOG_ERROR(Service_JIT, "ro_mem is null"); | ||||
|             R_THROW(ResultUnknown); | ||||
|         } | ||||
| @@ -291,8 +291,8 @@ private: | ||||
|         R_TRY(ro.Initialize(*process, *ro_mem, ro_size, Kernel::Svc::MemoryPermission::Read, | ||||
|                             generate_random)); | ||||
|  | ||||
|         *out_jit_environment = std::make_shared<IJitEnvironment>(system, std::move(process), | ||||
|                                                                  std::move(rx), std::move(ro)); | ||||
|         *out_jit_environment = | ||||
|             std::make_shared<IJitEnvironment>(system, process.Get(), std::move(rx), std::move(ro)); | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -551,8 +551,7 @@ public: | ||||
|     Result RegisterProcessHandle(ClientProcessId client_pid, | ||||
|                                  InCopyHandle<Kernel::KProcess>& process) { | ||||
|         // Register the process. | ||||
|         R_RETURN(m_ro->RegisterProcess(std::addressof(m_context_id), process.GetPointerUnsafe(), | ||||
|                                        *client_pid)); | ||||
|         R_RETURN(m_ro->RegisterProcess(std::addressof(m_context_id), process.Get(), *client_pid)); | ||||
|     } | ||||
|  | ||||
|     Result RegisterProcessModuleInfo(ClientProcessId client_pid, u64 nrr_address, u64 nrr_size, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user