diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 040a081de..eae7159b8 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -49,9 +49,7 @@ public: CITRA_NON_MOVEABLE(CLASS); \ \ using BaseClass = BASE_CLASS; \ - static constexpr TypeObj GetStaticTypeObj() { \ - return TypeObj(TypeName, ClassToken); \ - } \ + static constexpr TypeObj GetStaticTypeObj() { return TypeObj(TypeName, ClassToken); } \ static constexpr const char* GetStaticTypeName() { return TypeName; } \ virtual TypeObj GetTypeObj() ATTRIBUTE { return GetStaticTypeObj(); } \ virtual const char* GetTypeName() ATTRIBUTE { return GetStaticTypeName(); } \ diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 5276841b7..737c73520 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -202,12 +202,10 @@ void KernelSystem::UnregisterKernelObject(KAutoObject* object) { registered_objects.erase(object); } -struct KernelSystem::SlabHeapContainer { -}; +struct KernelSystem::SlabHeapContainer {}; template -KSlabHeap& KernelSystem::SlabHeap() { -} +KSlabHeap& KernelSystem::SlabHeap() {} SERIALIZE_IMPL(KernelSystem) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index b26379692..928bbecb0 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -8,11 +8,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include "common/common_types.h" #include "core/hle/kernel/memory.h" diff --git a/src/core/hle/result.h b/src/core/hle/result.h index a1adaeeaa..115c766ea 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -408,3 +408,130 @@ private: auto CONCAT2(check_result_L, __LINE__) = source; \ if (CONCAT2(check_result_L, __LINE__).IsError()) \ return CONCAT2(check_result_L, __LINE__); + +#define R_SUCCEEDED(res) (static_cast(res).IsSuccess()) +#define R_FAILED(res) (!static_cast(res).IsSuccess()) + +namespace ResultImpl { +template +class ScopedResultGuard { +private: + ResultCode& m_ref; + F m_f; + +public: + constexpr ScopedResultGuard(ResultCode& ref, F f) : m_ref(ref), m_f(std::move(f)) {} + constexpr ~ScopedResultGuard() { + if (EvaluateResult(m_ref)) { + m_f(); + } + } +}; + +template +class ResultReferenceForScopedResultGuard { +private: + ResultCode& m_ref; + +public: + constexpr ResultReferenceForScopedResultGuard(ResultCode& r) : m_ref(r) {} + constexpr operator ResultCode&() const { + return m_ref; + } +}; + +template +constexpr ScopedResultGuard operator+( + ResultReferenceForScopedResultGuard ref, F&& f) { + return ScopedResultGuard(static_cast(ref), std::forward(f)); +} + +constexpr bool EvaluateResultSuccess(const ResultCode& r) { + return R_SUCCEEDED(r); +} +constexpr bool EvaluateResultFailure(const ResultCode& r) { + return R_FAILED(r); +} + +template +constexpr void UpdateCurrentResultReference(T result_reference, ResultCode result) = delete; +// Intentionally not defined + +template <> +constexpr void UpdateCurrentResultReference(ResultCode& result_reference, + ResultCode result) { + result_reference = result; +} + +template <> +constexpr void UpdateCurrentResultReference(ResultCode result_reference, + ResultCode result) {} +} // namespace ResultImpl + +#define DECLARE_CURRENT_RESULT_REFERENCE_AND_STORAGE(COUNTER_VALUE) \ + [[maybe_unused]] constexpr bool CONCAT2(HasPrevRef_, COUNTER_VALUE) = \ + std::same_as; \ + [[maybe_unused]] Result CONCAT2(PrevRef_, COUNTER_VALUE) = __TmpCurrentResultReference; \ + [[maybe_unused]] Result CONCAT2(__tmp_result_, COUNTER_VALUE) = ResultSuccess; \ + Result& __TmpCurrentResultReference = CONCAT2(HasPrevRef_, COUNTER_VALUE) \ + ? CONCAT2(PrevRef_, COUNTER_VALUE) \ + : CONCAT2(__tmp_result_, COUNTER_VALUE) + +#define ON_RESULT_RETURN_IMPL(...) \ + static_assert(std::same_as); \ + auto CONCAT2(RESULT_GUARD_STATE_, __COUNTER__) = \ + ResultImpl::ResultReferenceForScopedResultGuard<__VA_ARGS__>( \ + __TmpCurrentResultReference) + \ + [&]() + +#define ON_RESULT_FAILURE_2 ON_RESULT_RETURN_IMPL(ResultImpl::EvaluateResultFailure) + +#define ON_RESULT_FAILURE \ + DECLARE_CURRENT_RESULT_REFERENCE_AND_STORAGE(__COUNTER__); \ + ON_RESULT_FAILURE_2 + +#define ON_RESULT_SUCCESS_2 ON_RESULT_RETURN_IMPL(ResultImpl::EvaluateResultSuccess) + +#define ON_RESULT_SUCCESS \ + DECLARE_CURRENT_RESULT_REFERENCE_AND_STORAGE(__COUNTER__); \ + ON_RESULT_SUCCESS_2 + +constexpr inline ResultCode __TmpCurrentResultReference = RESULT_SUCCESS; + +/// Returns a result. +#define R_RETURN(res_expr) \ + { \ + const ResultCode _tmp_r_throw_rc = (res_expr); \ + ResultImpl::UpdateCurrentResultReference( \ + __TmpCurrentResultReference, _tmp_r_throw_rc); \ + return _tmp_r_throw_rc; \ + } + +/// Returns ResultSuccess() +#define R_SUCCEED() R_RETURN(RESULT_SUCCESS) + +/// Throws a result. +#define R_THROW(res_expr) R_RETURN(res_expr) + +/// Evaluates a boolean expression, and returns a result unless that expression is true. +#define R_UNLESS(expr, res) \ + { \ + if (!(expr)) { \ + R_THROW(res); \ + } \ + } + +/// Evaluates an expression that returns a result, and returns the result if it would fail. +#define R_TRY(res_expr) \ + { \ + const auto _tmp_r_try_rc = (res_expr); \ + if (R_FAILED(_tmp_r_try_rc)) { \ + R_THROW(_tmp_r_try_rc); \ + } \ + } + +/// Evaluates a boolean expression, and succeeds if that expression is true. +#define R_SUCCEED_IF(expr) R_UNLESS(!(expr), RESULT_SUCCESS) + +/// Evaluates a boolean expression, and asserts if that expression is false. +#define R_ASSERT(expr) ASSERT(R_SUCCEEDED(expr))