Ver Fonte

cmif_types: improve ergonomics of types

Liam há 2 anos atrás
pai
commit
431df5ae93

+ 3 - 3
src/core/hle/service/cmif_serialization.h

@@ -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);
             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) {
         } 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);
             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) {
         } 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);
             return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, true, ArgIndex + 1>(args, raw_data, ctx, temp);
         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutCopyHandle) {
         } 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);
             return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutMoveHandle) {
         } 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);
             return WriteOutArgument<Domain, MethodArguments, CallArguments, PrevAlign, DataOffset, OutBufferIndex, RawDataFinished, ArgIndex + 1>(args, raw_data, ctx, temp);
         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {
         } else if constexpr (ArgumentTraits<ArgType>::Type == ArgumentType::OutLargeData) {

+ 86 - 26
src/core/hle/service/cmif_types.h

@@ -15,19 +15,21 @@ namespace Service {
 template <typename T>
 template <typename T>
 class Out {
 class Out {
 public:
 public:
-    /* implicit */ Out(T& t) : raw(&t) {}
+    using Type = T;
+
+    /* implicit */ Out(Type& t) : raw(&t) {}
     ~Out() = default;
     ~Out() = default;
 
 
-    T* Get() const {
+    Type* Get() const {
         return raw;
         return raw;
     }
     }
 
 
-    T& operator*() {
+    Type& operator*() {
         return *raw;
         return *raw;
     }
     }
 
 
 private:
 private:
-    T* raw;
+    Type* raw;
 };
 };
 
 
 template <typename T>
 template <typename T>
@@ -45,51 +47,93 @@ struct ClientProcessId {
     u64 pid;
     u64 pid;
 };
 };
 
 
+struct ProcessId {
+    explicit operator bool() const {
+        return pid != 0;
+    }
+
+    const u64& operator*() const {
+        return pid;
+    }
+
+    u64 pid;
+};
+
 using ClientAppletResourceUserId = ClientProcessId;
 using ClientAppletResourceUserId = ClientProcessId;
+using AppletResourceUserId = ProcessId;
 
 
 template <typename T>
 template <typename T>
-class InCopyHandle : public Kernel::KScopedAutoObject<T> {
+class InCopyHandle {
 public:
 public:
     using Type = T;
     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() = default;
 
 
-    InCopyHandle& operator=(InCopyHandle&& rhs) {
-        Kernel::KScopedAutoObject<T>::operator=(std::move(rhs));
+    InCopyHandle& operator=(Type* rhs) {
+        raw = rhs;
         return *this;
         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>
 template <typename T>
-class OutCopyHandle : public Kernel::KScopedAutoObject<T> {
+class OutCopyHandle {
 public:
 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() = 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>
 template <typename T>
-class OutMoveHandle : public Kernel::KScopedAutoObject<T> {
+class OutMoveHandle {
 public:
 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() = 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 {
 enum BufferAttr : int {
@@ -105,12 +149,15 @@ enum BufferAttr : int {
 
 
 template <typename T, int A>
 template <typename T, int A>
 struct Buffer : public std::span<T> {
 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_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_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "Buffer attr must be In or Out");
     static constexpr BufferAttr Attr = static_cast<BufferAttr>(A);
     static constexpr BufferAttr Attr = static_cast<BufferAttr>(A);
     using Type = T;
     using Type = T;
 
 
+    /* implicit */ Buffer(const std::span<T>& rhs) : std::span<T>(rhs) {}
+    /* implicit */ Buffer() = default;
+
     Buffer& operator=(const std::span<T>& rhs) {
     Buffer& operator=(const std::span<T>& rhs) {
         std::span<T>::operator=(rhs);
         std::span<T>::operator=(rhs);
         return *this;
         return *this;
@@ -139,11 +186,14 @@ using OutArray = Buffer<T, BufferAttr_Out | A>;
 
 
 template <typename T, int A>
 template <typename T, int A>
 struct LargeData : public T {
 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_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_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "LargeData attr must be In or Out");
     static constexpr BufferAttr Attr = static_cast<BufferAttr>(A);
     static constexpr BufferAttr Attr = static_cast<BufferAttr>(A);
     using Type = T;
     using Type = T;
+
+    /* implicit */ LargeData(const T& rhs) : T(rhs) {}
+    /* implicit */ LargeData() = default;
 };
 };
 
 
 template <typename T, BufferAttr A>
 template <typename T, BufferAttr A>
@@ -159,7 +209,17 @@ struct RemoveOut {
 
 
 template <typename T>
 template <typename T>
 struct RemoveOut<Out<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 {
 enum class ArgumentType {

+ 7 - 7
src/core/hle/service/jit/jit.cpp

@@ -27,7 +27,7 @@ static_assert(sizeof(Struct32) == 32, "Struct32 has wrong size");
 class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
 class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
 public:
 public:
     explicit IJitEnvironment(Core::System& system_,
     explicit IJitEnvironment(Core::System& system_,
-                             Kernel::KScopedAutoObject<Kernel::KProcess>&& process_,
+                             Kernel::KScopedAutoObject<Kernel::KProcess> process_,
                              CodeMemory&& user_rx_, CodeMemory&& user_ro_)
                              CodeMemory&& user_rx_, CodeMemory&& user_ro_)
         : ServiceFramework{system_, "IJitEnvironment"}, process{std::move(process_)},
         : ServiceFramework{system_, "IJitEnvironment"}, process{std::move(process_)},
           user_rx{std::move(user_rx_)}, user_ro{std::move(user_ro_)},
           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,
     Result LoadPlugin(u64 tmem_size, InCopyHandle<Kernel::KTransferMemory>& tmem,
                       InBuffer<BufferAttr_HipcMapAlias> nrr,
                       InBuffer<BufferAttr_HipcMapAlias> nrr,
                       InBuffer<BufferAttr_HipcMapAlias> nro) {
                       InBuffer<BufferAttr_HipcMapAlias> nro) {
-        if (tmem.IsNull()) {
+        if (!tmem) {
             LOG_ERROR(Service_JIT, "Invalid transfer memory handle!");
             LOG_ERROR(Service_JIT, "Invalid transfer memory handle!");
             R_THROW(ResultUnknown);
             R_THROW(ResultUnknown);
         }
         }
@@ -271,15 +271,15 @@ private:
                                 u64 rx_size, u64 ro_size, InCopyHandle<Kernel::KProcess>& process,
                                 u64 rx_size, u64 ro_size, InCopyHandle<Kernel::KProcess>& process,
                                 InCopyHandle<Kernel::KCodeMemory>& rx_mem,
                                 InCopyHandle<Kernel::KCodeMemory>& rx_mem,
                                 InCopyHandle<Kernel::KCodeMemory>& ro_mem) {
                                 InCopyHandle<Kernel::KCodeMemory>& ro_mem) {
-        if (process.IsNull()) {
+        if (!process) {
             LOG_ERROR(Service_JIT, "process is null");
             LOG_ERROR(Service_JIT, "process is null");
             R_THROW(ResultUnknown);
             R_THROW(ResultUnknown);
         }
         }
-        if (rx_mem.IsNull()) {
+        if (!rx_mem) {
             LOG_ERROR(Service_JIT, "rx_mem is null");
             LOG_ERROR(Service_JIT, "rx_mem is null");
             R_THROW(ResultUnknown);
             R_THROW(ResultUnknown);
         }
         }
-        if (rx_mem.IsNull()) {
+        if (!ro_mem) {
             LOG_ERROR(Service_JIT, "ro_mem is null");
             LOG_ERROR(Service_JIT, "ro_mem is null");
             R_THROW(ResultUnknown);
             R_THROW(ResultUnknown);
         }
         }
@@ -291,8 +291,8 @@ private:
         R_TRY(ro.Initialize(*process, *ro_mem, ro_size, Kernel::Svc::MemoryPermission::Read,
         R_TRY(ro.Initialize(*process, *ro_mem, ro_size, Kernel::Svc::MemoryPermission::Read,
                             generate_random));
                             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();
         R_SUCCEED();
     }
     }
 
 

+ 1 - 2
src/core/hle/service/ro/ro.cpp

@@ -551,8 +551,7 @@ public:
     Result RegisterProcessHandle(ClientProcessId client_pid,
     Result RegisterProcessHandle(ClientProcessId client_pid,
                                  InCopyHandle<Kernel::KProcess>& process) {
                                  InCopyHandle<Kernel::KProcess>& process) {
         // Register the 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,
     Result RegisterProcessModuleInfo(ClientProcessId client_pid, u64 nrr_address, u64 nrr_size,