mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-08 21:47:57 +00:00
Result: Refactor to have compiletime defs
This commit is contained in:
parent
be17f1f494
commit
edcd4cbc26
2 changed files with 127 additions and 73 deletions
|
@ -5,83 +5,137 @@
|
||||||
namespace mesosphere
|
namespace mesosphere
|
||||||
{
|
{
|
||||||
|
|
||||||
class Result final {
|
enum class ResultModule : uint {
|
||||||
|
None = 0,
|
||||||
|
Kernel = 1,
|
||||||
|
/* Other modules not included. */
|
||||||
|
};
|
||||||
|
|
||||||
|
class ResultHelper {
|
||||||
public:
|
public:
|
||||||
enum class Module : uint {
|
using BaseType = uint;
|
||||||
None = 0,
|
static constexpr BaseType SuccessValue = BaseType();
|
||||||
Kernel = 1,
|
static constexpr BaseType ModuleBits = 9;
|
||||||
/* Other modules not included. */
|
static constexpr BaseType DescriptionBits = 13;
|
||||||
|
|
||||||
|
template<ResultModule module, BaseType description>
|
||||||
|
struct MakeResult : public std::integral_constant<BaseType, ((static_cast<BaseType>(module)) | (description << ModuleBits))> {
|
||||||
|
static_assert(static_cast<BaseType>(module) < 1 << (ModuleBits + 1), "Invalid Module");
|
||||||
|
static_assert(description < 1 << (DescriptionBits + 1), "Invalid Description");
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Description : uint {
|
static constexpr ResultModule GetModule(BaseType value) {
|
||||||
None = 0,
|
return static_cast<ResultModule>(value & ~(~BaseType() << ModuleBits));
|
||||||
|
|
||||||
InvalidCapabilityDescriptor = 14,
|
|
||||||
|
|
||||||
NotImplemented = 33,
|
|
||||||
|
|
||||||
ThreadTerminated = 59,
|
|
||||||
|
|
||||||
OutOfDebugEvents = 70,
|
|
||||||
|
|
||||||
InvalidSize = 101,
|
|
||||||
InvalidAddress = 102,
|
|
||||||
AllocatorDepleted = 103,
|
|
||||||
OutOfMemory = 104,
|
|
||||||
OutOfHandles = 105,
|
|
||||||
InvalidMemoryState = 106,
|
|
||||||
InvalidMemoryPermissions = 108,
|
|
||||||
InvalidMemoryRange = 110,
|
|
||||||
InvalidPriority = 112,
|
|
||||||
InvalidCoreId = 113,
|
|
||||||
InvalidHandle = 114,
|
|
||||||
InvalidUserBuffer = 115,
|
|
||||||
InvalidCombination = 116,
|
|
||||||
TimedOut = 117,
|
|
||||||
Cancelled = 118,
|
|
||||||
OutOfRange = 119,
|
|
||||||
InvalidEnumValue = 120,
|
|
||||||
NotFound = 121,
|
|
||||||
AlreadyExists = 122,
|
|
||||||
ConnectionClosed = 123,
|
|
||||||
UnhandledUserInterrupt = 124,
|
|
||||||
InvalidState = 125,
|
|
||||||
ReservedValue = 126,
|
|
||||||
InvalidHwBreakpoint = 127,
|
|
||||||
FatalUserException = 128,
|
|
||||||
OwnedByAnotherProcess = 129,
|
|
||||||
ConnectionRefused = 131,
|
|
||||||
OutOfResource = 132,
|
|
||||||
|
|
||||||
IpcMapFailed = 259,
|
|
||||||
IpcCmdbufTooSmall = 260,
|
|
||||||
|
|
||||||
NotDebugged = 520,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr Result() : module{(uint)Module::None}, description{(uint)Description::None}, padding{0} {}
|
|
||||||
constexpr Result(Description description, Module module = Module::Kernel) :
|
|
||||||
module{(uint)module}, description{(uint)description}, padding{0} {}
|
|
||||||
|
|
||||||
constexpr bool IsSuccess() const
|
|
||||||
{
|
|
||||||
return module == (uint)Module::None && description == (uint)Description::None && padding == 0;
|
|
||||||
}
|
}
|
||||||
constexpr bool operator==(const Result &other) const
|
|
||||||
{
|
static constexpr BaseType GetDescription(BaseType value) {
|
||||||
return module == other.module && description == other.description && padding == other.padding;
|
return ((value >> ModuleBits) & ~(~BaseType() << DescriptionBits));
|
||||||
}
|
}
|
||||||
constexpr bool operator!=(const Result &other) const { return !(*this == other); }
|
};
|
||||||
|
|
||||||
|
|
||||||
constexpr Module GetModule() const { return (Module)module; }
|
/* Use CRTP for Results. */
|
||||||
constexpr Description GetDescription() const { return (Description)module; }
|
template<typename Self>
|
||||||
|
class ResultBase {
|
||||||
void SetModule(Module module) { this->module = (uint)module; }
|
public:
|
||||||
void SetDescription(Description description) { this->description = (uint)description;}
|
using BaseType = typename ResultHelper::BaseType;
|
||||||
private:
|
static constexpr BaseType SuccessValue = ResultHelper::SuccessValue;
|
||||||
uint module : 9;
|
|
||||||
uint description : 13;
|
constexpr bool IsSuccess() const { return static_cast<const Self *>(this)->GetValue() == SuccessValue; }
|
||||||
uint padding : 10;
|
constexpr bool IsFailure() const { return !IsSuccess(); }
|
||||||
|
constexpr operator bool() const { return IsSuccess(); }
|
||||||
|
constexpr bool operator !() const { return IsFailure(); }
|
||||||
|
|
||||||
|
constexpr ResultModule GetModule() const { return static_cast<const Self *>(this)->GetValue(); }
|
||||||
|
constexpr BaseType GetDescription() const { return static_cast<const Self *>(this)->GetValue(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Actual result type. */
|
||||||
|
class Result final : public ResultBase<Result> {
|
||||||
|
public:
|
||||||
|
using BaseType = typename ResultBase<Result>::BaseType;
|
||||||
|
static constexpr BaseType SuccessValue = ResultBase<Result>::SuccessValue;
|
||||||
|
|
||||||
|
constexpr Result() : value(SuccessValue) {}
|
||||||
|
|
||||||
|
constexpr BaseType GetValue() const { return this->value; }
|
||||||
|
constexpr bool operator==(const Result &other) const { return value == other.value; }
|
||||||
|
constexpr bool operator!=(const Result &other) const { return value != other.value; }
|
||||||
|
|
||||||
|
static constexpr Result MakeResult(BaseType v) { return Result(v); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BaseType value;
|
||||||
|
constexpr explicit Result(BaseType v) : value(v) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(Result) == sizeof(Result::BaseType), "Bad Result definition!");
|
||||||
|
|
||||||
|
/* Successful result class. */
|
||||||
|
class ResultSuccess final : public ResultBase<ResultSuccess> {
|
||||||
|
public:
|
||||||
|
using BaseType = typename ResultBase<ResultSuccess>::BaseType;
|
||||||
|
static constexpr BaseType SuccessValue = ResultBase<ResultSuccess>::SuccessValue;
|
||||||
|
|
||||||
|
constexpr operator Result() { return Result::MakeResult(SuccessValue); }
|
||||||
|
constexpr BaseType GetValue() const { return SuccessValue; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Error result class. */
|
||||||
|
template<ResultModule module, ResultHelper::BaseType description>
|
||||||
|
class ResultError : public ResultBase<ResultError<module, description>> {
|
||||||
|
public:
|
||||||
|
using BaseType = typename ResultBase<ResultError<module, description>>::BaseType;
|
||||||
|
static constexpr BaseType SuccessValue = ResultBase<ResultError<module, description>>::SuccessValue;
|
||||||
|
|
||||||
|
static constexpr BaseType Value = ResultHelper::MakeResult<module, description>::value;
|
||||||
|
static_assert(Value != SuccessValue, "Invalid ResultError");
|
||||||
|
|
||||||
|
constexpr operator Result() { return Result::MakeResult(Value); }
|
||||||
|
constexpr BaseType GetValue() const { return Value; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFINE_RESULT(module, name, description) class Result##module##name final : public ResultError<ResultModule::module, description> {}
|
||||||
|
|
||||||
|
DEFINE_RESULT(Kernel, InvalidCapabilityDescriptor, 14);
|
||||||
|
|
||||||
|
DEFINE_RESULT(Kernel, NotImplemented, 33);
|
||||||
|
DEFINE_RESULT(Kernel, ThreadTerminated, 59);
|
||||||
|
|
||||||
|
DEFINE_RESULT(Kernel, OutOfDebugEvents, 70);
|
||||||
|
|
||||||
|
DEFINE_RESULT(Kernel, InvalidSize, 101);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidAddress, 102);
|
||||||
|
DEFINE_RESULT(Kernel, ResourceExhausted, 103);
|
||||||
|
DEFINE_RESULT(Kernel, OutOfMemory, 104);
|
||||||
|
DEFINE_RESULT(Kernel, OutOfHandles, 105);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidMemoryState, 106);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidMemoryPermissions, 108);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidMemoryRange, 110);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidPriority, 112);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidCoreId, 113);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidHandle, 114);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidUserBuffer, 115);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidCombination, 116);
|
||||||
|
DEFINE_RESULT(Kernel, TimedOut, 117);
|
||||||
|
DEFINE_RESULT(Kernel, Cancelled, 118);
|
||||||
|
DEFINE_RESULT(Kernel, OutOfRange, 119);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidEnumValue, 120);
|
||||||
|
DEFINE_RESULT(Kernel, NotFound, 121);
|
||||||
|
DEFINE_RESULT(Kernel, AlreadyExists, 122);
|
||||||
|
DEFINE_RESULT(Kernel, ConnectionClosed, 123);
|
||||||
|
DEFINE_RESULT(Kernel, UnhandledUserInterrupt, 124);
|
||||||
|
DEFINE_RESULT(Kernel, NotPermitted, 125);
|
||||||
|
DEFINE_RESULT(Kernel, ReservedValue, 126);
|
||||||
|
DEFINE_RESULT(Kernel, InvalidHwBreakpoint, 127);
|
||||||
|
DEFINE_RESULT(Kernel, FatalUserException, 128);
|
||||||
|
DEFINE_RESULT(Kernel, OwnedByAnotherProcess, 129);
|
||||||
|
DEFINE_RESULT(Kernel, ConnectionRefused, 131);
|
||||||
|
DEFINE_RESULT(Kernel, OutOfResource, 132);
|
||||||
|
|
||||||
|
DEFINE_RESULT(Kernel, IpcMapFailed, 259);
|
||||||
|
DEFINE_RESULT(Kernel, IpcCmdbufTooSmall, 260);
|
||||||
|
|
||||||
|
DEFINE_RESULT(Kernel, NotDebugged, 520);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,7 +245,7 @@ private:
|
||||||
size_t numKernelMutexWaiters = 0;
|
size_t numKernelMutexWaiters = 0;
|
||||||
|
|
||||||
Handle syncResultHandle{};
|
Handle syncResultHandle{};
|
||||||
Result syncResult{};
|
Result syncResult = ResultSuccess();
|
||||||
|
|
||||||
u64 lastScheduledTime = 0;
|
u64 lastScheduledTime = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue