92 lines
2.1 KiB
C++
92 lines
2.1 KiB
C++
#pragma once
|
|
#include <string>
|
|
#include <types.hpp>
|
|
#include <format>
|
|
#include <optional>
|
|
|
|
namespace Util {
|
|
struct Error {
|
|
enum Severity {
|
|
NONE,
|
|
WARN,
|
|
ERROR,
|
|
FATAL,
|
|
};
|
|
|
|
union MemoryAccess {
|
|
struct {
|
|
unsigned : 3;
|
|
unsigned is_write : 1;
|
|
unsigned is_fatal : 1;
|
|
unsigned size : 3;
|
|
};
|
|
|
|
u8 raw;
|
|
};
|
|
|
|
enum Type {
|
|
SCHEDULER_EOL,
|
|
SCHEDULER_UNKNOWN,
|
|
UNHANDLED_EXCEPTION,
|
|
UNHANDLED_INSTRUCTION,
|
|
INVALID_INSTRUCTION_FORMAT,
|
|
TLB_LIMIT_EXCEEDED,
|
|
TLB_INVALID_ERROR,
|
|
TLB_UNHANDLED_ERROR,
|
|
TLB_UNHANDLED_MAPPING,
|
|
JIT_BRANCH_INSIDE_DELAY_SLOT,
|
|
JIT_INVALID_X86_REG_ADDRESSING,
|
|
COULD_NOT_SYNC_SAVE_DATA,
|
|
SAVE_DATA_IS_CORRUPT_OR_INVALID_SIZE,
|
|
MMAP_MAKE_SINK_ERROR,
|
|
MEM_INVALID_ACCESS,
|
|
MEM_UNHANDLED_ACCESS,
|
|
RDP_LIMIT_EXCEEDED,
|
|
FLASH_EXECUTE_COMMAND_ERROR,
|
|
PIF_UNHANDLED_CHANNEL,
|
|
UNHANDLED_COP0_STATUS_BIT,
|
|
COP0_INVALID_ACCESS,
|
|
COP0_UNHANDLED_ACCESS,
|
|
SYSTEM_DIALOG_ERROR,
|
|
TAS_LOAD_ERROR,
|
|
ROM_LOAD_ERROR,
|
|
SAVE_OPTIONS_ERROR,
|
|
};
|
|
|
|
template <class... Args>
|
|
void Throw (Severity severity,
|
|
Type type,
|
|
std::optional<u64> lastPC,
|
|
std::optional<MemoryAccess> memoryAccess,
|
|
const std::format_string<Args...> fmt, Args... args) {
|
|
this->severity = severity;
|
|
this->lastPC = lastPC;
|
|
this->memoryAccess = memoryAccess;
|
|
this->type = type;
|
|
return std::format(fmt, std::forward<Args>(args)...);
|
|
}
|
|
|
|
void SetHandled() {
|
|
severity = NONE;
|
|
}
|
|
|
|
bool IsHandled() {
|
|
return severity == NONE;
|
|
}
|
|
|
|
static Error& GetInstance() {
|
|
static Error instance;
|
|
return instance;
|
|
}
|
|
|
|
static std::string Get() {
|
|
return GetInstance().err;
|
|
}
|
|
private:
|
|
std::string err;
|
|
Severity severity = NONE;
|
|
Type type = {};
|
|
std::optional<u64> lastPC = {};
|
|
std::optional<MemoryAccess> memoryAccess = {};
|
|
};
|
|
} |