result: Add atmosphere result macros

This commit is contained in:
GPUCode 2023-12-04 23:43:02 +02:00
parent 853676d54c
commit 2b27fbc42a
4 changed files with 131 additions and 8 deletions

View File

@ -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(); } \

View File

@ -202,12 +202,10 @@ void KernelSystem::UnregisterKernelObject(KAutoObject* object) {
registered_objects.erase(object);
}
struct KernelSystem::SlabHeapContainer {
};
struct KernelSystem::SlabHeapContainer {};
template <typename T>
KSlabHeap<T>& KernelSystem::SlabHeap() {
}
KSlabHeap<T>& KernelSystem::SlabHeap() {}
SERIALIZE_IMPL(KernelSystem)

View File

@ -8,11 +8,11 @@
#include <atomic>
#include <functional>
#include <memory>
#include <unordered_set>
#include <mutex>
#include <span>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "common/common_types.h"
#include "core/hle/kernel/memory.h"

View File

@ -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<ResultCode>(res).IsSuccess())
#define R_FAILED(res) (!static_cast<ResultCode>(res).IsSuccess())
namespace ResultImpl {
template <auto EvaluateResult, class F>
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 <auto EvaluateResult>
class ResultReferenceForScopedResultGuard {
private:
ResultCode& m_ref;
public:
constexpr ResultReferenceForScopedResultGuard(ResultCode& r) : m_ref(r) {}
constexpr operator ResultCode&() const {
return m_ref;
}
};
template <auto EvaluateResult, typename F>
constexpr ScopedResultGuard<EvaluateResult, F> operator+(
ResultReferenceForScopedResultGuard<EvaluateResult> ref, F&& f) {
return ScopedResultGuard<EvaluateResult, F>(static_cast<ResultCode&>(ref), std::forward<F>(f));
}
constexpr bool EvaluateResultSuccess(const ResultCode& r) {
return R_SUCCEEDED(r);
}
constexpr bool EvaluateResultFailure(const ResultCode& r) {
return R_FAILED(r);
}
template <typename T>
constexpr void UpdateCurrentResultReference(T result_reference, ResultCode result) = delete;
// Intentionally not defined
template <>
constexpr void UpdateCurrentResultReference<ResultCode&>(ResultCode& result_reference,
ResultCode result) {
result_reference = result;
}
template <>
constexpr void UpdateCurrentResultReference<const ResultCode>(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<decltype(__TmpCurrentResultReference), ResultCode&>; \
[[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<decltype(__TmpCurrentResultReference), ResultCode&>); \
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<decltype(__TmpCurrentResultReference)>( \
__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))