shader: Handle host exceptions
This commit is contained in:
		| @@ -5,38 +5,62 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <stdexcept> | ||||
| #include <string> | ||||
| #include <string_view> | ||||
| #include <utility> | ||||
|  | ||||
| #include <fmt/format.h> | ||||
|  | ||||
| namespace Shader { | ||||
|  | ||||
| class LogicError : public std::logic_error { | ||||
| class Exception : public std::exception { | ||||
| public: | ||||
|     explicit Exception(std::string message_) noexcept : message{std::move(message_)} {} | ||||
|  | ||||
|     const char* what() const override { | ||||
|         return message.c_str(); | ||||
|     } | ||||
|  | ||||
|     void Prepend(std::string_view prepend) { | ||||
|         message.insert(0, prepend); | ||||
|     } | ||||
|  | ||||
|     void Append(std::string_view append) { | ||||
|         message += append; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     std::string message; | ||||
| }; | ||||
|  | ||||
| class LogicError : public Exception { | ||||
| public: | ||||
|     template <typename... Args> | ||||
|     LogicError(const char* message, Args&&... args) | ||||
|         : std::logic_error{fmt::format(message, std::forward<Args>(args)...)} {} | ||||
|         : Exception{fmt::format(message, std::forward<Args>(args)...)} {} | ||||
| }; | ||||
|  | ||||
| class RuntimeError : public std::runtime_error { | ||||
| class RuntimeError : public Exception { | ||||
| public: | ||||
|     template <typename... Args> | ||||
|     RuntimeError(const char* message, Args&&... args) | ||||
|         : std::runtime_error{fmt::format(message, std::forward<Args>(args)...)} {} | ||||
|         : Exception{fmt::format(message, std::forward<Args>(args)...)} {} | ||||
| }; | ||||
|  | ||||
| class NotImplementedException : public std::logic_error { | ||||
| class NotImplementedException : public Exception { | ||||
| public: | ||||
|     template <typename... Args> | ||||
|     NotImplementedException(const char* message, Args&&... args) | ||||
|         : std::logic_error{fmt::format(message, std::forward<Args>(args)...)} {} | ||||
|         : Exception{fmt::format(message, std::forward<Args>(args)...)} { | ||||
|         Append(" is not implemented"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class InvalidArgument : public std::invalid_argument { | ||||
| class InvalidArgument : public Exception { | ||||
| public: | ||||
|     template <typename... Args> | ||||
|     InvalidArgument(const char* message, Args&&... args) | ||||
|         : std::invalid_argument{fmt::format(message, std::forward<Args>(args)...)} {} | ||||
|         : Exception{fmt::format(message, std::forward<Args>(args)...)} {} | ||||
| }; | ||||
|  | ||||
| } // namespace Shader | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| namespace Shader::Maxwell { | ||||
| namespace { | ||||
| constexpr std::array NAME_TABLE{ | ||||
| #define INST(name, cute, encode) #cute, | ||||
| #define INST(name, cute, encode) cute, | ||||
| #include "maxwell.inc" | ||||
| #undef INST | ||||
| }; | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include <ranges> | ||||
| #include <vector> | ||||
|  | ||||
| #include "shader_recompiler/exception.h" | ||||
| #include "shader_recompiler/frontend/ir/basic_block.h" | ||||
| #include "shader_recompiler/frontend/ir/post_order.h" | ||||
| #include "shader_recompiler/frontend/maxwell/program.h" | ||||
|   | ||||
| @@ -30,16 +30,21 @@ void Translate(Environment& env, IR::Block* block, u32 location_begin, u32 locat | ||||
|     TranslatorVisitor visitor{env, *block}; | ||||
|     for (Location pc = location_begin; pc != location_end; ++pc) { | ||||
|         const u64 insn{env.ReadInstruction(pc.Offset())}; | ||||
|         const Opcode opcode{Decode(insn)}; | ||||
|         switch (opcode) { | ||||
|         try { | ||||
|             const Opcode opcode{Decode(insn)}; | ||||
|             switch (opcode) { | ||||
| #define INST(name, cute, mask)                                                                     \ | ||||
|     case Opcode::name:                                                                             \ | ||||
|         Invoke<&TranslatorVisitor::name>(visitor, pc, insn);                                       \ | ||||
|         break; | ||||
| #include "shader_recompiler/frontend/maxwell/maxwell.inc" | ||||
| #undef OPCODE | ||||
|         default: | ||||
|             throw LogicError("Invalid opcode {}", opcode); | ||||
|             default: | ||||
|                 throw LogicError("Invalid opcode {}", opcode); | ||||
|             } | ||||
|         } catch (Exception& exception) { | ||||
|             exception.Prepend(fmt::format("Translate {}: ", Decode(insn))); | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user