Przeglądaj źródła

Merge pull request #2210 from lioncash/optional

kernel/hle_ipc: Convert std::shared_ptr IPC header instances to std::optional
bunnei 7 lat temu
rodzic
commit
9909d40530

+ 1 - 1
.travis.yml

@@ -24,7 +24,7 @@ matrix:
     - os: osx
     - os: osx
       env: NAME="macos build"
       env: NAME="macos build"
       sudo: false
       sudo: false
-      osx_image: xcode10
+      osx_image: xcode10.1
       install: "./.travis/macos/deps.sh"
       install: "./.travis/macos/deps.sh"
       script: "./.travis/macos/build.sh"
       script: "./.travis/macos/build.sh"
       after_success: "./.travis/macos/upload.sh"
       after_success: "./.travis/macos/upload.sh"

+ 1 - 1
.travis/macos/build.sh

@@ -2,7 +2,7 @@
 
 
 set -o pipefail
 set -o pipefail
 
 
-export MACOSX_DEPLOYMENT_TARGET=10.13
+export MACOSX_DEPLOYMENT_TARGET=10.14
 export Qt5_DIR=$(brew --prefix)/opt/qt5
 export Qt5_DIR=$(brew --prefix)/opt/qt5
 export UNICORNDIR=$(pwd)/externals/unicorn
 export UNICORNDIR=$(pwd)/externals/unicorn
 export PATH="/usr/local/opt/ccache/libexec:$PATH"
 export PATH="/usr/local/opt/ccache/libexec:$PATH"

+ 7 - 9
src/common/bit_field.h

@@ -111,12 +111,6 @@
 template <std::size_t Position, std::size_t Bits, typename T>
 template <std::size_t Position, std::size_t Bits, typename T>
 struct BitField {
 struct BitField {
 private:
 private:
-    // We hide the copy assigment operator here, because the default copy
-    // assignment would copy the full storage value, rather than just the bits
-    // relevant to this particular bit field.
-    // We don't delete it because we want BitField to be trivially copyable.
-    constexpr BitField& operator=(const BitField&) = default;
-
     // UnderlyingType is T for non-enum types and the underlying type of T if
     // UnderlyingType is T for non-enum types and the underlying type of T if
     // T is an enumeration. Note that T is wrapped within an enable_if in the
     // T is an enumeration. Note that T is wrapped within an enable_if in the
     // former case to workaround compile errors which arise when using
     // former case to workaround compile errors which arise when using
@@ -163,9 +157,13 @@ public:
     BitField(T val) = delete;
     BitField(T val) = delete;
     BitField& operator=(T val) = delete;
     BitField& operator=(T val) = delete;
 
 
-    // Force default constructor to be created
-    // so that we can use this within unions
-    constexpr BitField() = default;
+    constexpr BitField() noexcept = default;
+
+    constexpr BitField(const BitField&) noexcept = default;
+    constexpr BitField& operator=(const BitField&) noexcept = default;
+
+    constexpr BitField(BitField&&) noexcept = default;
+    constexpr BitField& operator=(BitField&&) noexcept = default;
 
 
     constexpr FORCE_INLINE operator T() const {
     constexpr FORCE_INLINE operator T() const {
         return Value();
         return Value();

+ 1 - 1
src/core/hle/ipc_helpers.h

@@ -350,7 +350,7 @@ public:
     template <class T>
     template <class T>
     std::shared_ptr<T> PopIpcInterface() {
     std::shared_ptr<T> PopIpcInterface() {
         ASSERT(context->Session()->IsDomain());
         ASSERT(context->Session()->IsDomain());
-        ASSERT(context->GetDomainMessageHeader()->input_object_count > 0);
+        ASSERT(context->GetDomainMessageHeader().input_object_count > 0);
         return context->GetDomainRequestHandler<T>(Pop<u32>() - 1);
         return context->GetDomainRequestHandler<T>(Pop<u32>() - 1);
     }
     }
 };
 };

+ 6 - 8
src/core/hle/kernel/hle_ipc.cpp

@@ -86,7 +86,7 @@ HLERequestContext::~HLERequestContext() = default;
 void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf,
 void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf,
                                            bool incoming) {
                                            bool incoming) {
     IPC::RequestParser rp(src_cmdbuf);
     IPC::RequestParser rp(src_cmdbuf);
-    command_header = std::make_shared<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>());
+    command_header = rp.PopRaw<IPC::CommandHeader>();
 
 
     if (command_header->type == IPC::CommandType::Close) {
     if (command_header->type == IPC::CommandType::Close) {
         // Close does not populate the rest of the IPC header
         // Close does not populate the rest of the IPC header
@@ -95,8 +95,7 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
 
 
     // If handle descriptor is present, add size of it
     // If handle descriptor is present, add size of it
     if (command_header->enable_handle_descriptor) {
     if (command_header->enable_handle_descriptor) {
-        handle_descriptor_header =
-            std::make_shared<IPC::HandleDescriptorHeader>(rp.PopRaw<IPC::HandleDescriptorHeader>());
+        handle_descriptor_header = rp.PopRaw<IPC::HandleDescriptorHeader>();
         if (handle_descriptor_header->send_current_pid) {
         if (handle_descriptor_header->send_current_pid) {
             rp.Skip(2, false);
             rp.Skip(2, false);
         }
         }
@@ -140,16 +139,15 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
         // If this is an incoming message, only CommandType "Request" has a domain header
         // If this is an incoming message, only CommandType "Request" has a domain header
         // All outgoing domain messages have the domain header, if only incoming has it
         // All outgoing domain messages have the domain header, if only incoming has it
         if (incoming || domain_message_header) {
         if (incoming || domain_message_header) {
-            domain_message_header =
-                std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
+            domain_message_header = rp.PopRaw<IPC::DomainMessageHeader>();
         } else {
         } else {
-            if (Session()->IsDomain())
+            if (Session()->IsDomain()) {
                 LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
                 LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
+            }
         }
         }
     }
     }
 
 
-    data_payload_header =
-        std::make_shared<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
+    data_payload_header = rp.PopRaw<IPC::DataPayloadHeader>();
 
 
     data_payload_offset = rp.GetCurrentOffset();
     data_payload_offset = rp.GetCurrentOffset();
 
 

+ 8 - 7
src/core/hle/kernel/hle_ipc.h

@@ -6,6 +6,7 @@
 
 
 #include <array>
 #include <array>
 #include <memory>
 #include <memory>
+#include <optional>
 #include <string>
 #include <string>
 #include <type_traits>
 #include <type_traits>
 #include <vector>
 #include <vector>
@@ -168,12 +169,12 @@ public:
         return buffer_c_desciptors;
         return buffer_c_desciptors;
     }
     }
 
 
-    const IPC::DomainMessageHeader* GetDomainMessageHeader() const {
-        return domain_message_header.get();
+    const IPC::DomainMessageHeader& GetDomainMessageHeader() const {
+        return domain_message_header.value();
     }
     }
 
 
     bool HasDomainMessageHeader() const {
     bool HasDomainMessageHeader() const {
-        return domain_message_header != nullptr;
+        return domain_message_header.has_value();
     }
     }
 
 
     /// Helper function to read a buffer using the appropriate buffer descriptor
     /// Helper function to read a buffer using the appropriate buffer descriptor
@@ -272,10 +273,10 @@ private:
     boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
     boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
     boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
     boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
 
 
-    std::shared_ptr<IPC::CommandHeader> command_header;
-    std::shared_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header;
-    std::shared_ptr<IPC::DataPayloadHeader> data_payload_header;
-    std::shared_ptr<IPC::DomainMessageHeader> domain_message_header;
+    std::optional<IPC::CommandHeader> command_header;
+    std::optional<IPC::HandleDescriptorHeader> handle_descriptor_header;
+    std::optional<IPC::DataPayloadHeader> data_payload_header;
+    std::optional<IPC::DomainMessageHeader> domain_message_header;
     std::vector<IPC::BufferDescriptorX> buffer_x_desciptors;
     std::vector<IPC::BufferDescriptorX> buffer_x_desciptors;
     std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
     std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
     std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;
     std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;

+ 32 - 31
src/core/hle/kernel/server_session.cpp

@@ -92,41 +92,42 @@ std::size_t ServerSession::NumDomainRequestHandlers() const {
 }
 }
 
 
 ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
 ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
-    auto* const domain_message_header = context.GetDomainMessageHeader();
-    if (domain_message_header) {
-        // Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
-        context.SetDomainRequestHandlers(domain_request_handlers);
-
-        // If there is a DomainMessageHeader, then this is CommandType "Request"
-        const u32 object_id{context.GetDomainMessageHeader()->object_id};
-        switch (domain_message_header->command) {
-        case IPC::DomainMessageHeader::CommandType::SendMessage:
-            if (object_id > domain_request_handlers.size()) {
-                LOG_CRITICAL(IPC,
-                             "object_id {} is too big! This probably means a recent service call "
-                             "to {} needed to return a new interface!",
-                             object_id, name);
-                UNREACHABLE();
-                return RESULT_SUCCESS; // Ignore error if asserts are off
-            }
-            return domain_request_handlers[object_id - 1]->HandleSyncRequest(context);
-
-        case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
-            LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
-
-            domain_request_handlers[object_id - 1] = nullptr;
-
-            IPC::ResponseBuilder rb{context, 2};
-            rb.Push(RESULT_SUCCESS);
-            return RESULT_SUCCESS;
-        }
+    if (!context.HasDomainMessageHeader()) {
+        return RESULT_SUCCESS;
+    }
+
+    // Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
+    context.SetDomainRequestHandlers(domain_request_handlers);
+
+    // If there is a DomainMessageHeader, then this is CommandType "Request"
+    const auto& domain_message_header = context.GetDomainMessageHeader();
+    const u32 object_id{domain_message_header.object_id};
+    switch (domain_message_header.command) {
+    case IPC::DomainMessageHeader::CommandType::SendMessage:
+        if (object_id > domain_request_handlers.size()) {
+            LOG_CRITICAL(IPC,
+                         "object_id {} is too big! This probably means a recent service call "
+                         "to {} needed to return a new interface!",
+                         object_id, name);
+            UNREACHABLE();
+            return RESULT_SUCCESS; // Ignore error if asserts are off
         }
         }
+        return domain_request_handlers[object_id - 1]->HandleSyncRequest(context);
 
 
-        LOG_CRITICAL(IPC, "Unknown domain command={}",
-                     static_cast<int>(domain_message_header->command.Value()));
-        ASSERT(false);
+    case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
+        LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
+
+        domain_request_handlers[object_id - 1] = nullptr;
+
+        IPC::ResponseBuilder rb{context, 2};
+        rb.Push(RESULT_SUCCESS);
+        return RESULT_SUCCESS;
+    }
     }
     }
 
 
+    LOG_CRITICAL(IPC, "Unknown domain command={}",
+                 static_cast<int>(domain_message_header.command.Value()));
+    ASSERT(false);
     return RESULT_SUCCESS;
     return RESULT_SUCCESS;
 }
 }