Disable exception handling.

Use -fno-exceptions in cmake.
On MSVC, enable _HAS_EXCEPTION=0.
Cleanup throw/catch from the source.
Create yaml.cpp enclave because it needs exception to work.
Disable thread_local optimizations in logs.cpp (TODO).
Implement cpu_counter for cpu_threads (moved globals).
This commit is contained in:
Nekotekina 2020-03-09 19:18:39 +03:00
parent 47bbfdd2aa
commit 04dedb17eb
39 changed files with 421 additions and 437 deletions

4
.gitmodules vendored
View File

@ -16,7 +16,7 @@
ignore = dirty
[submodule "3rdparty/cereal"]
path = 3rdparty/cereal
url = https://github.com/USCiLab/cereal.git
url = https://github.com/RPCS3/cereal.git
ignore = dirty
[submodule "3rdparty/zlib"]
path = 3rdparty/zlib
@ -37,7 +37,7 @@
ignore = dirty
[submodule "3rdparty/yaml-cpp"]
path = 3rdparty/yaml-cpp
url = https://github.com/jbeder/yaml-cpp.git
url = https://github.com/RPCS3/yaml-cpp.git
ignore = dirty
[submodule "3rdparty/libpng"]
path = 3rdparty/libpng

2
3rdparty/cereal vendored

@ -1 +1 @@
Subproject commit 42a45b6e15fcbd1a3d65b033f5d4d0b2ef6c023d
Subproject commit 60c69df968d1c72c998cd5f23ba34e2e3718a84b

2
3rdparty/yaml-cpp vendored

@ -1 +1 @@
Subproject commit eca9cfd64899525d0a61abb0553849676a0fe511
Subproject commit 6a211f0bc71920beef749e6c35d7d1bcc2447715

View File

@ -37,6 +37,11 @@
<Import Project="..\rpcs3_release.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="yaml-cpp\src\binary.cpp">
</ClCompile>

View File

@ -1,11 +1,14 @@
#include "stdafx.h"
#include "Config.h"
#include "Utilities/types.h"
#include "yaml-cpp/yaml.h"
#include "util/yaml.hpp"
#include <typeinfo>
#include <charconv>
[[noreturn]] void report_fatal_error(const std::string&);
LOG_CHANNEL(cfg_log, "CFG");
namespace cfg
@ -15,7 +18,7 @@ namespace cfg
{
if (_type != type::node)
{
fmt::throw_exception("Invalid root node" HERE);
cfg_log.fatal("Invalid root node" HERE);
}
}
@ -26,7 +29,7 @@ namespace cfg
{
if (pair.first == name)
{
fmt::throw_exception("Node already exists: %s" HERE, name);
cfg_log.fatal("Node already exists: %s" HERE, name);
}
}
@ -35,12 +38,12 @@ namespace cfg
bool _base::from_string(const std::string&, bool)
{
fmt::throw_exception("from_string() purecall" HERE);
report_fatal_error("from_string() purecall" HERE);
}
bool _base::from_list(std::vector<std::string>&&)
{
fmt::throw_exception("from_list() purecall" HERE);
report_fatal_error("from_list() purecall" HERE);
}
// Emit YAML
@ -302,14 +305,17 @@ std::string cfg::node::to_string() const
return {out.c_str(), out.size()};
}
bool cfg::node::from_string(const std::string& value, bool dynamic) try
bool cfg::node::from_string(const std::string& value, bool dynamic)
{
cfg::decode(YAML::Load(value), *this, dynamic);
return true;
}
catch (const std::exception& e)
{
cfg_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
auto [result, error] = yaml_load(value);
if (error.empty())
{
cfg::decode(result, *this, dynamic);
return true;
}
cfg_log.fatal("Failed to load node: %s", error);
return false;
}

View File

@ -60,22 +60,6 @@ void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
out += ss.str();
}
[[noreturn]] void catch_all_exceptions()
{
try
{
throw;
}
catch (const std::exception& e)
{
report_fatal_error("{" + g_tls_log_prefix() + "} Unhandled exception of type '"s + typeid(e).name() + "': "s + e.what());
}
catch (...)
{
report_fatal_error("{" + g_tls_log_prefix() + "} Unhandled exception (unknown)");
}
}
#ifndef _WIN32
bool IsDebuggerPresent()
{
@ -1151,33 +1135,12 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
if (rsx::g_access_violation_handler)
{
bool handled = false;
try
if (cpu)
{
if (cpu)
{
vm::temporary_unlock(*cpu);
}
handled = rsx::g_access_violation_handler(addr, is_writing);
vm::temporary_unlock(*cpu);
}
catch (const std::exception& e)
{
rsx_log.fatal("g_access_violation_handler(0x%x, %d): %s", addr, is_writing, e.what());
if (cpu)
{
cpu->state += cpu_flag::dbg_pause;
if (cpu->test_stopped())
{
std::terminate();
}
}
return false;
}
bool handled = rsx::g_access_violation_handler(addr, is_writing);
if (handled)
{
@ -1769,7 +1732,7 @@ const bool s_exception_handler_set = []() -> bool
if (::sigaction(SIGSEGV, &sa, NULL) == -1)
{
std::fprintf(stderr, "sigaction(SIGSEGV) failed (0x%x).", errno);
std::fprintf(stderr, "sigaction(SIGSEGV) failed (%d).\n", errno);
std::abort();
}
@ -1779,6 +1742,23 @@ const bool s_exception_handler_set = []() -> bool
#endif
const bool s_terminate_handler_set = []() -> bool
{
std::set_terminate([]()
{
if (IsDebuggerPresent())
#ifdef _MSC_VER
__debugbreak();
#else
__asm("int3;");
#endif
report_fatal_error("RPCS3 has abnormally terminated.");
});
return true;
}();
thread_local DECLARE(thread_ctrl::g_tls_this_thread) = nullptr;
DECLARE(thread_ctrl::g_native_core_layout) { native_core_arrangement::undefined };

View File

@ -15,9 +15,6 @@
// Report error and call std::abort(), defined in main.cpp
[[noreturn]] void report_fatal_error(const std::string&);
// Will report exception and call std::abort() if put in catch(...)
[[noreturn]] void catch_all_exceptions();
// Hardware core layout
enum class native_core_arrangement : u32
{
@ -256,9 +253,9 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
// Type-erased thread entry point
#ifdef _WIN32
static inline uint __stdcall entry_point(void* arg) try
static inline uint __stdcall entry_point(void* arg)
#else
static inline void* entry_point(void* arg) try
static inline void* entry_point(void* arg)
#endif
{
const auto _this = static_cast<named_thread*>(static_cast<thread*>(arg));
@ -272,10 +269,6 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
thread::finalize();
return 0;
}
catch (...)
{
catch_all_exceptions();
}
bool entry_point()
{

View File

@ -1,5 +1,5 @@
#include "bin_patch.h"
#include <yaml-cpp/yaml.h>
#include "util/yaml.hpp"
#include "File.h"
#include "Config.h"
@ -34,15 +34,11 @@ void patch_engine::append(const std::string& patch)
{
if (fs::file f{patch})
{
YAML::Node root;
auto [root, error] = yaml_load(f.to_string());
try
if (!error.empty())
{
root = YAML::Load(f.to_string());
}
catch (const std::exception& e)
{
patch_log.fatal("Failed to load patch file %s\n%s thrown: %s", patch, typeid(e).name(), e.what());
patch_log.fatal("Failed to load patch file %s:\n%s", patch, error);
return;
}

View File

@ -32,6 +32,8 @@ target_sources(rpcs3_emu PRIVATE
../util/shared_cptr.cpp
../util/fixed_typemap.cpp
../util/logs.cpp
../util/yaml.cpp
../util/cereal.cpp
../../Utilities/bin_patch.cpp
../../Utilities/cond.cpp
../../Utilities/Config.cpp
@ -62,6 +64,12 @@ else()
set_source_files_properties("../../Utilities/JIT.cpp" PROPERTIES COMPILE_FLAGS -fno-rtti)
endif()
if (MSVC)
set_source_files_properties("../util/yaml.cpp" PROPERTIES COMPILE_FLAGS /EHsc)
else()
set_source_files_properties("../util/yaml.cpp" PROPERTIES COMPILE_FLAGS -fexceptions)
endif()
# Crypto
target_sources(rpcs3_emu PRIVATE

View File

@ -243,28 +243,83 @@ using cpu_profiler = named_thread<cpu_prof>;
thread_local cpu_thread* g_tls_current_cpu_thread = nullptr;
// For synchronizing suspend_all operation
alignas(64) shared_mutex g_cpu_suspend_lock;
struct cpu_counter
{
// For synchronizing suspend_all operation
alignas(64) shared_mutex cpu_suspend_lock;
// Semaphore for global thread array (global counter)
alignas(64) atomic_t<u32> g_cpu_array_sema{0};
// Semaphore for global thread array (global counter)
alignas(64) atomic_t<u32> cpu_array_sema{0};
// Semaphore subdivision for each array slot (64 x N in total)
atomic_t<u64> g_cpu_array_bits[6]{};
// Semaphore subdivision for each array slot (64 x N in total)
atomic_t<u64> cpu_array_bits[6]{};
// All registered threads
atomic_t<cpu_thread*> g_cpu_array[sizeof(g_cpu_array_bits) * 8]{};
// All registered threads
atomic_t<cpu_thread*> cpu_array[sizeof(cpu_array_bits) * 8]{};
u64 add(cpu_thread* _this)
{
if (!cpu_array_sema.try_inc(sizeof(cpu_counter::cpu_array_bits) * 8))
{
return -1;
}
u64 array_slot = -1;
for (u32 i = 0;; i = (i + 1) % ::size32(cpu_array_bits))
{
const auto [bits, ok] = cpu_array_bits[i].fetch_op([](u64& bits) -> u64
{
if (~bits) [[likely]]
{
// Set lowest clear bit
bits |= bits + 1;
return true;
}
return false;
});
if (ok) [[likely]]
{
// Get actual slot number
array_slot = i * 64 + utils::cnttz64(~bits, false);
break;
}
}
// Register and wait if necessary
verify("cpu_counter::add()" HERE), cpu_array[array_slot].exchange(_this) == nullptr;
_this->state += cpu_flag::wait;
cpu_suspend_lock.lock_unlock();
return array_slot;
}
void remove(cpu_thread* _this, u64 slot)
{
// Unregister and wait if necessary
_this->state += cpu_flag::wait;
if (cpu_array[slot].exchange(nullptr) != _this)
sys_log.fatal("Inconsistency for array slot %u", slot);
cpu_array_bits[slot / 64] &= ~(1ull << (slot % 64));
cpu_array_sema--;
cpu_suspend_lock.lock_unlock();
}
};
template <typename F>
void for_all_cpu(F&& func) noexcept
{
for (u32 i = 0; i < ::size32(g_cpu_array_bits); i++)
auto ctr = g_fxo->get<cpu_counter>();
for (u32 i = 0; i < ::size32(ctr->cpu_array_bits); i++)
{
for (u64 bits = g_cpu_array_bits[i]; bits; bits &= bits - 1)
for (u64 bits = ctr->cpu_array_bits[i]; bits; bits &= bits - 1)
{
const u64 index = i * 64 + utils::cnttz64(bits, true);
if (cpu_thread* cpu = g_cpu_array[index].load())
if (cpu_thread* cpu = ctr->cpu_array[index].load())
{
func(cpu);
}
@ -301,6 +356,12 @@ void cpu_thread::operator()()
}
}
while (!g_fxo->get<cpu_counter>() && !g_fxo->get<cpu_profiler>())
{
// Can we have a little race, right? First thread is started concurrently with g_fxo->init()
std::this_thread::sleep_for(1ms);
}
if (id_type() == 1 && false)
{
g_fxo->get<cpu_profiler>()->registered.push(id);
@ -312,67 +373,51 @@ void cpu_thread::operator()()
}
// Register thread in g_cpu_array
if (!g_cpu_array_sema.try_inc(sizeof(g_cpu_array_bits) * 8))
const u64 array_slot = g_fxo->get<cpu_counter>()->add(this);
if (array_slot == umax)
{
sys_log.fatal("Too many threads.");
return;
}
u64 array_slot = -1;
for (u32 i = 0;; i = (i + 1) % ::size32(g_cpu_array_bits))
{
const auto [bits, ok] = g_cpu_array_bits[i].fetch_op([](u64& bits) -> u64
{
if (~bits) [[likely]]
{
// Set lowest clear bit
bits |= bits + 1;
return true;
}
return false;
});
if (ok) [[likely]]
{
// Get actual slot number
array_slot = i * 64 + utils::cnttz64(~bits, false);
break;
}
}
// Register and wait if necessary
verify("g_cpu_array[...] -> this" HERE), g_cpu_array[array_slot].exchange(this) == nullptr;
state += cpu_flag::wait;
g_cpu_suspend_lock.lock_unlock();
static thread_local struct thread_cleanup_t
{
cpu_thread* _this;
u64 slot;
std::string name;
thread_cleanup_t(cpu_thread* _this, u64 slot)
: _this(_this)
, slot(slot)
, name(thread_ctrl::get_name())
{
}
~thread_cleanup_t()
void cleanup()
{
if (_this == nullptr)
{
return;
}
if (auto ptr = vm::g_tls_locked)
{
ptr->compare_and_swap(_this, nullptr);
}
// Unregister and wait if necessary
_this->state += cpu_flag::wait;
if (g_cpu_array[slot].exchange(nullptr) != _this)
sys_log.fatal("Inconsistency for array slot %u", slot);
g_cpu_array_bits[slot / 64] &= ~(1ull << (slot % 64));
g_cpu_array_sema--;
g_cpu_suspend_lock.lock_unlock();
g_fxo->get<cpu_counter>()->remove(_this, slot);
_this = nullptr;
}
~thread_cleanup_t()
{
if (_this)
{
sys_log.warning("CPU Thread '%s' terminated abnormally:\n%s", name, _this->dump());
cleanup();
}
}
} cleanup{this, array_slot};
@ -382,23 +427,16 @@ void cpu_thread::operator()()
// Check stop status
if (!(state & cpu_flag::stop))
{
try
{
cpu_task();
}
catch (const std::exception& e)
{
sys_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
sys_log.notice("\n%s", dump());
break;
}
cpu_task();
state -= cpu_flag::ret;
continue;
}
thread_ctrl::wait();
}
// Complete cleanup gracefully
cleanup.cleanup();
}
cpu_thread::~cpu_thread()
@ -493,7 +531,7 @@ bool cpu_thread::check_state() noexcept
else
{
// If only cpu_flag::pause was set, notification won't arrive
g_cpu_suspend_lock.lock_unlock();
g_fxo->get<cpu_counter>()->cpu_suspend_lock.lock_unlock();
}
}
@ -577,7 +615,7 @@ cpu_thread::suspend_all::suspend_all(cpu_thread* _this) noexcept
m_this->state += cpu_flag::wait;
}
g_cpu_suspend_lock.lock_vip();
g_fxo->get<cpu_counter>()->cpu_suspend_lock.lock_vip();
for_all_cpu([](cpu_thread* cpu)
{
@ -610,18 +648,18 @@ cpu_thread::suspend_all::suspend_all(cpu_thread* _this) noexcept
cpu_thread::suspend_all::~suspend_all()
{
// Make sure the latest thread does the cleanup and notifies others
if (g_cpu_suspend_lock.downgrade_unique_vip_lock_to_low_or_unlock())
if (g_fxo->get<cpu_counter>()->cpu_suspend_lock.downgrade_unique_vip_lock_to_low_or_unlock())
{
for_all_cpu([&](cpu_thread* cpu)
{
cpu->state -= cpu_flag::pause;
});
g_cpu_suspend_lock.unlock_low();
g_fxo->get<cpu_counter>()->cpu_suspend_lock.unlock_low();
}
else
{
g_cpu_suspend_lock.lock_unlock();
g_fxo->get<cpu_counter>()->cpu_suspend_lock.lock_unlock();
}
if (m_this)
@ -640,7 +678,7 @@ void cpu_thread::stop_all() noexcept
}
else
{
::vip_lock lock(g_cpu_suspend_lock);
::vip_lock lock(g_fxo->get<cpu_counter>()->cpu_suspend_lock);
for_all_cpu([](cpu_thread* cpu)
{
@ -651,7 +689,7 @@ void cpu_thread::stop_all() noexcept
sys_log.notice("All CPU threads have been signaled.");
while (g_cpu_array_sema)
while (g_fxo->get<cpu_counter>()->cpu_array_sema)
{
std::this_thread::sleep_for(10ms);
}

View File

@ -138,15 +138,9 @@ struct content_permission final
bool success = false;
fs::g_tls_error = fs::error::ok;
try
{
if (temp.size() <= 1 || fs::remove_all(temp))
{
success = true;
}
}
catch (...)
if (temp.size() <= 1 || fs::remove_all(temp))
{
success = true;
}
if (!success)

View File

@ -151,7 +151,7 @@ void pngDecError(png_structp png_ptr, png_const_charp error_message)
{
cellPngDec.error("%s", error_message);
// we can't return here or libpng blows up
throw LibPngCustomException("Fatal Error in libpng");
report_fatal_error("Fatal Error in libpng");
}
// Custom warning handler for libpng
@ -486,14 +486,7 @@ s32 pngDecOpen(ppu_thread& ppu, PHandle handle, PPStream png_stream, PSrc source
png_set_progressive_read_fn(stream->png_ptr, stream.get_ptr(), pngDecInfoCallback, pngDecRowCallback, pngDecEndCallback);
// push header tag to libpng to keep us in sync
try
{
png_process_data(stream->png_ptr, stream->info_ptr, header, 8);
}
catch (LibPngCustomException&)
{
return CELL_PNGDEC_ERROR_HEADER;
}
png_process_data(stream->png_ptr, stream->info_ptr, header, 8);
}
else
{
@ -729,15 +722,7 @@ s32 pngDecodeData(ppu_thread& ppu, PHandle handle, PStream stream, vm::ptr<u8> d
if (stream->buffer->length > stream->buffer->cursor)
{
u8* data = static_cast<u8*>(stream->buffer->data.get_ptr()) + stream->buffer->cursor;
try
{
png_process_data(stream->png_ptr, stream->info_ptr, data, stream->buffer->length - stream->buffer->cursor);
}
catch (LibPngCustomException&)
{
freeMem();
return CELL_PNGDEC_ERROR_FATAL;
}
png_process_data(stream->png_ptr, stream->info_ptr, data, stream->buffer->length - stream->buffer->cursor);
streamInfo->decodedStrmSize = ::narrow<u32>(stream->buffer->length);
}
@ -747,15 +732,7 @@ s32 pngDecodeData(ppu_thread& ppu, PHandle handle, PStream stream, vm::ptr<u8> d
{
stream->cbCtrlStream.cbCtrlStrmFunc(ppu, streamInfo, streamParam, stream->cbCtrlStream.cbCtrlStrmArg);
streamInfo->decodedStrmSize += streamParam->strmSize;
try
{
png_process_data(stream->png_ptr, stream->info_ptr, static_cast<u8*>(streamParam->strmPtr.get_ptr()), streamParam->strmSize);
}
catch (LibPngCustomException&)
{
freeMem();
return CELL_PNGDEC_ERROR_FATAL;
}
png_process_data(stream->png_ptr, stream->info_ptr, static_cast<u8*>(streamParam->strmPtr.get_ptr()), streamParam->strmSize);
}
freeMem();
@ -767,7 +744,6 @@ s32 pngDecodeData(ppu_thread& ppu, PHandle handle, PStream stream, vm::ptr<u8> d
// Decode the image
// todo: commandptr
try
{
for (u32 j = 0; j < stream->passes; j++)
{
@ -779,10 +755,6 @@ s32 pngDecodeData(ppu_thread& ppu, PHandle handle, PStream stream, vm::ptr<u8> d
}
png_read_end(stream->png_ptr, stream->info_ptr);
}
catch (LibPngCustomException&)
{
return CELL_PNGDEC_ERROR_FATAL;
}
}
// Get the number of iTXt, tEXt and zTXt chunks
@ -862,14 +834,7 @@ s32 cellPngDecExtReadHeader(PHandle handle, PStream stream, PInfo info, PExtInfo
// lets push what we have so far
u8* data = static_cast<u8*>(stream->buffer->data.get_ptr()) + stream->buffer->cursor;
try
{
png_process_data(stream->png_ptr, stream->info_ptr, data, stream->buffer->length);
}
catch (LibPngCustomException&)
{
return CELL_PNGDEC_ERROR_HEADER;
}
png_process_data(stream->png_ptr, stream->info_ptr, data, stream->buffer->length);
// lets hope we pushed enough for callback
pngSetHeader(stream.get_ptr());

View File

@ -114,7 +114,9 @@ void cellSpursModuleExit(spu_thread& spu)
{
auto ctxt = vm::_ptr<SpursKernelContext>(spu.offset + 0x100);
spu.pc = ctxt->exitToKernelAddr;
throw SpursModuleExit();
// TODO: use g_escape for actual long jump
//throw SpursModuleExit();
}
// Execute a DMA operation
@ -728,7 +730,6 @@ bool spursSysServiceEntry(spu_thread& spu)
auto arg = spu.gpr[4]._u64[1];
auto pollStatus = spu.gpr[5]._u32[3];
try
{
if (ctxt->wklCurrentId == CELL_SPURS_SYS_SERVICE_WORKLOAD_ID)
{
@ -743,10 +744,6 @@ bool spursSysServiceEntry(spu_thread& spu)
cellSpursModuleExit(spu);
}
catch (SpursModuleExit)
{
}
return false;
}
@ -1326,7 +1323,6 @@ bool spursTasksetEntry(spu_thread& spu)
//spu.RegisterHleFunction(CELL_SPURS_TASKSET_PM_ENTRY_ADDR, spursTasksetEntry);
//spu.RegisterHleFunction(ctxt->syscallAddr, spursTasksetSyscallEntry);
try
{
// Initialise the taskset policy module
spursTasksetInit(spu, pollStatus);
@ -1334,9 +1330,6 @@ bool spursTasksetEntry(spu_thread& spu)
// Dispatch
spursTasksetDispatch(spu);
}
catch (SpursModuleExit)
{
}
return false;
}
@ -1346,7 +1339,6 @@ bool spursTasksetSyscallEntry(spu_thread& spu)
{
auto ctxt = vm::_ptr<SpursTasksetContext>(spu.offset + 0x2700);
try
{
// Save task context
ctxt->savedContextLr = spu.gpr[0];
@ -1365,9 +1357,6 @@ bool spursTasksetSyscallEntry(spu_thread& spu)
// spursTasksetResumeTask(spu);
//}
}
catch (SpursModuleExit)
{
}
return false;
}

View File

@ -5,7 +5,7 @@
#include "PPUModule.h"
#include <unordered_set>
#include "yaml-cpp/yaml.h"
#include "util/yaml.hpp"
#include "Utilities/asm.h"
LOG_CHANNEL(ppu_validator);
@ -54,7 +54,13 @@ void ppu_module::validate(u32 reloc)
// Load custom PRX configuration if available
if (fs::file yml{path + ".yml"})
{
const auto cfg = YAML::Load(yml.to_string());
const auto [cfg, error] = yaml_load(yml.to_string());
if (!error.empty())
{
ppu_validator.error("Failed to load %s.yml: %s", path, error);
return;
}
u32 index = 0;

View File

@ -859,16 +859,7 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
}
};
try
{
exec_task();
}
catch (...)
{
at_ret();
throw;
}
exec_task();
at_ret();
}

View File

@ -4357,7 +4357,7 @@ Value* PPUTranslator::GetVr(u32 vr, VrType type)
case VrType::i128: return m_ir->CreateBitCast(value, GetType<u128>());
}
throw std::logic_error("GetVr(): invalid type");
report_fatal_error("GetVr(): invalid type");
}
void PPUTranslator::SetVr(u32 vr, Value* value)
@ -4435,7 +4435,7 @@ void PPUTranslator::SetFPRF(Value* value, bool set_cr)
const bool is32 =
value->getType()->isFloatTy() ? true :
value->getType()->isDoubleTy() ? false :
throw std::logic_error("SetFPRF(): invalid value type");
(report_fatal_error("SetFPRF(): invalid value type"), false);
//const auto zero = ConstantFP::get(value->getType(), 0.0);
//const auto is_nan = m_ir->CreateFCmpUNO(value, zero);

View File

@ -1154,7 +1154,7 @@ void spu_recompiler_base::branch(spu_thread& spu, void*, u8* rip)
spu_runtime::g_tail_escape(&spu, func, rip);
}
void spu_recompiler_base::old_interpreter(spu_thread& spu, void* ls, u8* rip) try
void spu_recompiler_base::old_interpreter(spu_thread& spu, void* ls, u8* rip)
{
// Select opcode table
const auto& table = *(
@ -1178,11 +1178,6 @@ void spu_recompiler_base::old_interpreter(spu_thread& spu, void* ls, u8* rip) tr
spu.pc += 4;
}
}
catch (const std::exception& e)
{
spu_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
spu_log.notice("\n%s", spu.dump());
}
spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point)
{
@ -4608,19 +4603,7 @@ public:
}
// Execute recompiler function (TODO)
try
{
(this->*g_decoder.decode(op))({op});
}
catch (const std::exception&)
{
std::string dump;
raw_string_ostream out(dump);
out << *module; // print IR
out.flush();
spu_log.error("[0x%x] LLVM dump:\n%s", m_pos, dump);
throw;
}
(this->*g_decoder.decode(op))({op});
}
// Finalize block with fallthrough if necessary
@ -4994,7 +4977,6 @@ public:
}
}
try
{
m_interp_bblock = nullptr;
@ -5142,15 +5124,6 @@ public:
}
}
}
catch (const std::exception&)
{
std::string dump;
raw_string_ostream out(dump);
out << *module; // print IR
out.flush();
spu_log.error("[0x%x] LLVM dump:\n%s", m_pos, dump);
throw;
}
}
if (last_itype != itype && g_cfg.core.spu_decoder != spu_decoder_type::llvm)

View File

@ -303,21 +303,13 @@ bool gdb_thread::read_cmd(gdb_cmd& out_cmd)
{
while (true)
{
try
if (try_read_cmd(out_cmd))
{
if (try_read_cmd(out_cmd))
{
ack(true);
return true;
}
ack(true);
return true;
}
ack(false);
}
catch (const std::runtime_error& e)
{
GDB.error("Error: %s", e.what());
return false;
}
ack(false);
}
}
@ -866,7 +858,7 @@ void gdb_thread::operator()()
Emu.Pause();
}
try {
{
char hostbuf[32];
inet_ntop(client.sin_family, reinterpret_cast<void*>(&client.sin_addr), hostbuf, 32);
GDB.success("Got connection to GDB debug server from %s:%d.", hostbuf, client.sin_port);
@ -905,16 +897,6 @@ void gdb_thread::operator()()
}
}
}
catch (const std::runtime_error& e)
{
if (client_socket != -1)
{
closesocket(client_socket);
client_socket = -1;
}
GDB.error("Error: %s", e.what());
}
}
}

View File

@ -242,13 +242,6 @@ namespace rsx
void rsx_replay_thread::operator()()
{
try
{
on_task();
}
catch (const std::exception& e)
{
rsx_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
}
on_task();
}
}

View File

@ -2396,42 +2396,6 @@ public:
namespace glsl
{
class compilation_exception : public exception
{
public:
explicit compilation_exception(const std::string& what_arg)
{
m_what = "compilation failed: '" + what_arg + "'";
}
};
class link_exception : public exception
{
public:
explicit link_exception(const std::string& what_arg)
{
m_what = "linkage failed: '" + what_arg + "'";
}
};
class validation_exception : public exception
{
public:
explicit validation_exception(const std::string& what_arg)
{
m_what = "compilation failed: '" + what_arg + "'";
}
};
class not_found_exception : public exception
{
public:
explicit not_found_exception(const std::string& what_arg)
{
m_what = what_arg + " not found.";
}
};
class shader
{
public:
@ -2533,7 +2497,7 @@ public:
error_msg = buf.get();
}
throw compilation_exception(error_msg);
rsx_log.fatal("Compilation failed: %s", error_msg);
}
return *this;
@ -2655,7 +2619,8 @@ public:
}
else
{
throw not_found_exception(name);
rsx_log.fatal("%s not found.", name);
return -1;
}
}
@ -2663,7 +2628,8 @@ public:
if (result < 0)
{
throw not_found_exception(name);
rsx_log.fatal("%s not found.", name);
return result;
}
locations[name] = result;
@ -2749,7 +2715,7 @@ public:
error_msg = buf.get();
}
throw link_exception(error_msg);
rsx_log.fatal("Linkage failed: %s", error_msg);
}
}

View File

@ -42,7 +42,7 @@ namespace
case rsx::index_array_type::u16: return GL_UNSIGNED_SHORT;
case rsx::index_array_type::u32: return GL_UNSIGNED_INT;
}
throw;
fmt::throw_exception("Invalid index array type (%u)", static_cast<u8>(type));
}
struct vertex_input_state

View File

@ -9,6 +9,7 @@
#include <algorithm>
#include <utility>
#include <charconv>
namespace rsx
{
@ -21,22 +22,65 @@ namespace rsx
hex_color.erase(0, 1);
}
unsigned long hexval;
const size_t len = hex_color.length();
unsigned hexval = 0;
const auto len = hex_color.length();
try
if (len != 6 && len != 8)
{
if (len != 6 && len != 8)
{
fmt::throw_exception("wrong length: %d", len);
}
hexval = std::stoul(hex_color, nullptr, 16);
}
catch (const std::exception& e)
{
rsx_log.error("Overlays: tried to convert incompatible color code: '%s' exception: '%s'", hex_color, e.what());
rsx_log.error("Incompatible color code: '%s' has wrong length: %d", hex_color, len);
return color4f(0.0f, 0.0f, 0.0f, 0.0f);
}
else
{
// auto&& [ptr, ec] = std::from_chars(hex_color.c_str(), hex_color.c_str() + len, &hexval, 16);
// if (ptr != hex_color.c_str() + len || ec)
// {
// rsx_log.error("Overlays: tried to convert incompatible color code: '%s'", hex_color);
// return color4f(0.0f, 0.0f, 0.0f, 0.0f);
// }
for (u32 i = 0; i < len; i++)
{
hexval <<= 4;
switch (char c = hex_color[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
hexval |= (c - '0');
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
hexval |= (c - 'a' + 10);
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
hexval |= (c - 'A' + 10);
break;
default:
{
rsx_log.error("Overlays: invalid characters in color code: '%s'", hex_color);
return color4f(0.0f, 0.0f, 0.0f, 0.0f);
}
}
}
}
const int r = (len == 8 ? (hexval >> 24) : (hexval >> 16)) & 0xff;
const int g = (len == 8 ? (hexval >> 16) : (hexval >> 8)) & 0xff;

View File

@ -442,7 +442,6 @@ namespace rsx
void thread::operator()()
{
try
{
// Wait for startup (TODO)
while (m_rsx_thread_exiting)
@ -457,10 +456,6 @@ namespace rsx
on_task();
}
catch (const std::exception& e)
{
rsx_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
}
on_exit();
}

View File

@ -52,7 +52,7 @@ namespace vk
case rsx::index_array_type::u16:
return VK_INDEX_TYPE_UINT16;
}
throw;
fmt::throw_exception("Invalid index array type (%u)", static_cast<u8>(type));
}
}

View File

@ -30,7 +30,7 @@
#include "../Crypto/unself.h"
#include "../Crypto/unpkg.h"
#include <yaml-cpp/yaml.h>
#include "util/yaml.hpp"
#include "cereal/archives/binary.hpp"
@ -760,12 +760,23 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
m_title_id = title_id;
}
try
{
Init();
// Load game list (maps ABCD12345 IDs to /dev_bdvd/ locations)
YAML::Node games = YAML::Load(fs::file{fs::get_config_dir() + "/games.yml", fs::read + fs::create}.to_string());
YAML::Node games;
if (fs::file f{fs::get_config_dir() + "/games.yml", fs::read + fs::create})
{
auto [result, error] = yaml_load(f.to_string());
if (!error.empty())
{
sys_log.error("Failed to load games.yml: %s", error);
}
games = result;
}
if (!games.IsMap())
{
@ -1462,12 +1473,6 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
}
return game_boot_result::no_errors;
}
catch (const std::exception& e)
{
sys_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
Stop();
return game_boot_result::generic_error;
}
}
void Emulator::Run(bool start_playtime)

View File

@ -2,7 +2,7 @@
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:throwingNew /D _CRT_SECURE_NO_DEPRECATE=1 /D _CRT_NON_CONFORMING_SWPRINTFS=1 /D _SCL_SECURE_NO_WARNINGS=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D _ENABLE_EXTENDED_ALIGNED_STORAGE=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D _ENABLE_EXTENDED_ALIGNED_STORAGE=1 /D _HAS_EXCEPTIONS=0")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /DYNAMICBASE:NO /BASE:0x10000 /FIXED")
@ -23,7 +23,7 @@ else()
CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
add_compile_options(-Wall)
add_compile_options(-fexceptions)
add_compile_options(-fno-exceptions)
add_compile_options(-ftemplate-depth=1024)
add_compile_options(-msse -msse2 -mcx16)
add_compile_options(-fno-strict-aliasing)

View File

@ -87,6 +87,13 @@
<ClCompile Include="util\atomic2.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="util\yaml.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
<ClCompile Include="util\cereal.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="util\shared_cptr.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>

View File

@ -869,6 +869,15 @@
<ClCompile Include="util\atomic2.cpp">
<Filter>Utilities</Filter>
</ClCompile>
<ClCompile Include="util\yaml.cpp">
<Filter>Utilities</Filter>
</ClCompile>
<ClCompile Include="util\cereal.cpp">
<Filter>Utilities</Filter>
</ClCompile>
<ClCompile Include="util\yaml.hpp">
<Filter>Utilities</Filter>
</ClCompile>
<ClCompile Include="util\shared_cptr.cpp">
<Filter>Utilities</Filter>
</ClCompile>

View File

@ -38,9 +38,11 @@ DYNAMIC_IMPORT("ntdll.dll", NtSetTimerResolution, NTSTATUS(ULONG DesiredResoluti
#endif
#include "Utilities/sysinfo.h"
#include "Utilities/Config.h"
#include "rpcs3_version.h"
#include "Emu/System.h"
#include <thread>
#include <charconv>
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
@ -213,49 +215,44 @@ QCoreApplication* createApplication(int& argc, char* argv[])
auto rounding_val = Qt::HighDpiScaleFactorRoundingPolicy::PassThrough;
auto rounding_str = std::to_string(static_cast<int>(rounding_val));
const auto i_rounding = find_arg(arg_rounding, argc, argv);
if (i_rounding)
{
const auto i_rounding_2 = (argc > (i_rounding + 1)) ? (i_rounding + 1) : 0;
if (i_rounding_2)
{
const auto arg_val = argv[i_rounding_2];
try
{
const auto rounding_val_cli = std::stoi(arg_val);
if (rounding_val_cli >= static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::Unset) && rounding_val_cli <= static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough))
{
rounding_val = static_cast<Qt::HighDpiScaleFactorRoundingPolicy>(rounding_val_cli);
rounding_str = std::to_string(static_cast<int>(rounding_val));
}
else
{
throw std::exception();
}
}
catch (const std::exception&)
const auto arg_len = std::strlen(arg_val);
s64 rounding_val_cli = 0;
if (!cfg::try_to_int64(&rounding_val_cli, arg_val, static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::Unset), static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough)))
{
std::cout << "The value " << arg_val << " for " << arg_rounding << " is not allowed. Please use a valid value for Qt::HighDpiScaleFactorRoundingPolicy.\n";
}
else
{
rounding_val = static_cast<Qt::HighDpiScaleFactorRoundingPolicy>(static_cast<int>(rounding_val_cli));
rounding_str = std::to_string(static_cast<int>(rounding_val));
}
}
}
try
{
rounding_str = qEnvironmentVariable("QT_SCALE_FACTOR_ROUNDING_POLICY", rounding_str.c_str()).toStdString();
const auto rounding_val_final = std::stoi(rounding_str);
if (rounding_val_final >= static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::Unset) && rounding_val_final <= static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough))
s64 rounding_val_final = 0;
if (cfg::try_to_int64(&rounding_val_final, rounding_str, static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::Unset), static_cast<int>(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough)))
{
rounding_val = static_cast<Qt::HighDpiScaleFactorRoundingPolicy>(rounding_val_final);
rounding_val = static_cast<Qt::HighDpiScaleFactorRoundingPolicy>(static_cast<int>(rounding_val_final));
rounding_str = std::to_string(static_cast<int>(rounding_val));
}
else
{
throw std::exception();
std::cout << "The value " << rounding_str << " for " << arg_rounding << " is not allowed. Please use a valid value for Qt::HighDpiScaleFactorRoundingPolicy.\n";
}
}
catch (const std::exception&)
{
std::cout << "The value " << rounding_str << " for " << arg_rounding << " is not allowed. Please use a valid value for Qt::HighDpiScaleFactorRoundingPolicy.\n";
}
QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_val);
}

View File

@ -127,7 +127,6 @@
<BrowseInformation>false</BrowseInformation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ExceptionHandling>Sync</ExceptionHandling>
<ObjectFileName>$(IntDir)</ObjectFileName>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;WITH_DISCORD_RPC;QT_NO_DEBUG;QT_OPENGL_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_QML_LIB;QT_NETWORK_LIB;QT_CORE_LIB;NDEBUG;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -180,7 +179,6 @@
<BrowseInformation>false</BrowseInformation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ExceptionHandling>Sync</ExceptionHandling>
<ObjectFileName>$(IntDir)</ObjectFileName>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;WITH_DISCORD_RPC;QT_NO_DEBUG;QT_OPENGL_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_QML_LIB;QT_NETWORK_LIB;QT_CORE_LIB;NDEBUG;QT_WINEXTRAS_LIB;BRANCH=$(BRANCH);QT_CONCURRENT_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -233,7 +231,6 @@
<BrowseInformation>false</BrowseInformation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ExceptionHandling>Sync</ExceptionHandling>
<ObjectFileName>$(IntDir)</ObjectFileName>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;QT_OPENGL_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_QML_LIB;QT_NETWORK_LIB;QT_CORE_LIB;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -287,7 +284,6 @@
<BrowseInformation>false</BrowseInformation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ExceptionHandling>Sync</ExceptionHandling>
<ObjectFileName>$(IntDir)</ObjectFileName>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WINDOWS;UNICODE;WIN32;WIN64;QT_OPENGL_LIB;QT_WIDGETS_LIB;QT_GUI_LIB;QT_QML_LIB;QT_NETWORK_LIB;QT_CORE_LIB;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@ -6,8 +6,6 @@
#include <QClipboard>
#include <QGuiApplication>
#include <yaml-cpp/yaml.h>
#include "cheat_manager.h"
#include "Emu/System.h"
@ -19,6 +17,7 @@
#include "Emu/Cell/PPUAnalyser.h"
#include "Emu/Cell/PPUFunction.h"
#include "util/yaml.hpp"
#include "Utilities/StrUtil.h"
LOG_CHANNEL(log_cheat, "Cheat");
@ -110,9 +109,14 @@ std::string cheat_info::to_str() const
cheat_engine::cheat_engine()
{
try
if (fs::file cheat_file{fs::get_config_dir() + cheats_filename, fs::read + fs::create})
{
YAML::Node yml_cheats = YAML::Load(fs::file{fs::get_config_dir() + cheats_filename, fs::read + fs::create}.to_string());
auto [yml_cheats, error] = yaml_load(cheat_file.to_string());
if (!error.empty())
{
log_cheat.error("Error parsing %s: %s", cheats_filename, error);
}
for (const auto& yml_cheat : yml_cheats)
{
@ -127,9 +131,9 @@ cheat_engine::cheat_engine()
}
}
}
catch (YAML::Exception& e)
else
{
log_cheat.error("Error parsing %s\n%s", cheats_filename, e.what());
log_cheat.error("Error loading %s", cheats_filename);
}
}

View File

@ -18,6 +18,7 @@
#include "Loader/PSF.h"
#include "Utilities/types.h"
#include "Utilities/lockless.h"
#include "util/yaml.hpp"
#include <algorithm>
#include <iterator>
@ -543,24 +544,23 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
auto get_games = []() -> YAML::Node
{
try
{
fs::file games(fs::get_config_dir() + "/games.yml", fs::read + fs::create);
fs::file games(fs::get_config_dir() + "/games.yml", fs::read + fs::create);
if (games)
if (games)
{
auto [result, error] = yaml_load(games.to_string());
if (!error.empty())
{
return YAML::Load(games.to_string());
}
else
{
game_list_log.error("Failed to load games.yml, check permissions.");
game_list_log.error("Failed to load games.yml: %s", error);
return {};
}
return result;
}
catch (...)
else
{
// YAML exception aren't very useful so just ignore them
game_list_log.fatal("Failed to parse games.yml");
game_list_log.error("Failed to load games.yml, check permissions.");
return {};
}
@ -616,7 +616,6 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
{
const Localized thread_localized;
try
{
const std::string sfo_dir = Emulator::GetSfoDirFromGamePath(dir, Emu.GetUsr());
const fs::file sfo_file(sfo_dir + "/PARAM.SFO");
@ -724,11 +723,6 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
games.push(std::make_shared<gui_game_info>(gui_game_info{game, qt_cat, compat, icon, pxmap, hasCustomConfig, hasCustomPadConfig}));
}
catch (const std::exception& e)
{
game_list_log.fatal("Failed to update game list at %s\n%s thrown: %s", dir, typeid(e).name(), e.what());
return;
}
});
for (auto&& g : games.pop_all())
@ -744,29 +738,37 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
for (const auto& other : m_game_data)
{
// The patch is game data and must have the same serial and an app version
static constexpr auto version_is_bigger = [](const std::string& v0, const std::string& v1, const std::string& serial, bool is_fw)
{
std::add_pointer_t<char> ev0, ev1;
const double ver0 = std::strtod(v0.c_str(), &ev0);
const double ver1 = std::strtod(v1.c_str(), &ev1);
if (v0.c_str() + v0.size() == ev0 && v1.c_str() + v1.size() == ev1)
{
return ver0 > ver1;
}
game_list_log.error("Failed to update the displayed %s numbers for title ID %s\n'%s'-'%s'", is_fw ? "firmware version" : "version", serial, v0, v1);
return false;
};
if (entry->info.serial == other->info.serial && other->info.category == "GD" && other->info.app_ver != cat_unknown_localized)
{
try
// Update the app version if it's higher than the disc's version (old games may not have an app version)
if (entry->info.app_ver == cat_unknown_localized || version_is_bigger(other->info.app_ver, entry->info.app_ver, entry->info.serial, true))
{
// Update the app version if it's higher than the disc's version (old games may not have an app version)
if (entry->info.app_ver == cat_unknown_localized || std::stod(other->info.app_ver) > std::stod(entry->info.app_ver))
{
entry->info.app_ver = other->info.app_ver;
}
// Update the firmware version if possible and if it's higher than the disc's version
if (other->info.fw != cat_unknown_localized && std::stod(other->info.fw) > std::stod(entry->info.fw))
{
entry->info.fw = other->info.fw;
}
// Update the parental level if possible and if it's higher than the disc's level
if (other->info.parental_lvl != 0 && other->info.parental_lvl > entry->info.parental_lvl)
{
entry->info.parental_lvl = other->info.parental_lvl;
}
entry->info.app_ver = other->info.app_ver;
}
catch (const std::exception& e)
// Update the firmware version if possible and if it's higher than the disc's version
if (other->info.fw != cat_unknown_localized && version_is_bigger(other->info.fw, entry->info.fw, entry->info.serial, false))
{
game_list_log.error("Failed to update the displayed version numbers for title ID %s\n%s thrown: %s", entry->info.serial, typeid(e).name(), e.what());
entry->info.fw = other->info.fw;
}
// Update the parental level if possible and if it's higher than the disc's level
if (other->info.parental_lvl != 0 && other->info.parental_lvl > entry->info.parental_lvl)
{
entry->info.parental_lvl = other->info.parental_lvl;
}
}
}

View File

@ -147,7 +147,7 @@ void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
while (value.length() < 32) value = "0" + value;
const auto first_brk = reg.find('[');
try
// TODO: handle invalid conversions
{
if (first_brk != umax)
{
@ -182,9 +182,6 @@ void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
return;
}
}
catch (std::invalid_argument&) //if any of the stoull conversion fail
{
}
}
else
{
@ -192,7 +189,7 @@ void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
while (value.length() < 32) value = "0" + value;
const auto first_brk = reg.find('[');
try
// TODO: handle invalid conversions
{
if (first_brk != umax)
{
@ -207,9 +204,6 @@ void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
}
}
}
catch (std::invalid_argument&)
{
}
}
QMessageBox::critical(this, tr("Error"), tr("This value could not be converted.\nNo changes were made."));
}

View File

@ -710,15 +710,12 @@ void trophy_manager_dialog::StartTrophyLoadThreads()
{
const std::string dir_name = sstr(folder_list.value(i));
gui_log.trace("Loading trophy dir: %s", dir_name);
try
{
LoadTrophyFolderToDB(dir_name);
}
catch (const std::exception& e)
if (!LoadTrophyFolderToDB(dir_name))
{
// TODO: Add error checks & throws to LoadTrophyFolderToDB so that they can be caught here.
// Also add a way of showing the number of corrupted/invalid folders in UI somewhere.
gui_log.error("Exception occurred while parsing folder %s for trophies: %s", dir_name, e.what());
gui_log.error("Error occurred while parsing folder %s for trophies.", dir_name);
}
}));

10
rpcs3/util/cereal.cpp Normal file
View File

@ -0,0 +1,10 @@
#include <string>
#include "Utilities/Thread.h"
namespace cereal
{
[[noreturn]] void throw_exception(const std::string& err)
{
report_fatal_error(err);
}
}

View File

@ -307,8 +307,8 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) co
const u64 stamp = get_stamp();
// Get text, extract va_args
thread_local std::string text;
thread_local std::vector<u64> args;
/*constinit thread_local*/ std::string text;
/*constinit thread_local*/ std::basic_string<u64> args;
static constexpr fmt_type_info empty_sup{};
@ -316,7 +316,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) co
for (auto v = sup; v && v->fmt_string; v++)
args_count++;
text.clear();
text.reserve(50000);
args.resize(args_count);
va_list c_args;
@ -589,7 +589,8 @@ logs::file_listener::file_listener(const std::string& path, u64 max_size)
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
{
thread_local std::string text;
/*constinit thread_local*/ std::string text;
text.reserve(50000);
// Used character: U+00B7 (Middle Dot)
switch (msg.sev)

17
rpcs3/util/yaml.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "util/yaml.hpp"
std::pair<YAML::Node, std::string> yaml_load(const std::string& from)
{
YAML::Node result;
try
{
result = YAML::Load(from);
}
catch(const std::exception& e)
{
return{YAML::Node(), std::string("YAML exception:\n") + e.what()};
}
return{result, ""};
}

20
rpcs3/util/yaml.hpp Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <utility>
#include <string>
#ifdef _MSC_VER
#pragma warning(push, 0)
#include "yaml-cpp/yaml.h"
#pragma warning(pop)
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wall"
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#include "yaml-cpp/yaml.h"
#pragma GCC diagnostic pop
#endif
// Load from string and consume exception
std::pair<YAML::Node, std::string> yaml_load(const std::string& from);

View File

@ -13,10 +13,11 @@
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ClCompile>
<PreprocessorDefinitions>PUGIXML_HEADER_ONLY;_ENABLE_EXTENDED_ALIGNED_STORAGE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>PUGIXML_HEADER_ONLY;_ENABLE_EXTENDED_ALIGNED_STORAGE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>false</SDLCheck>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<AdditionalOptions>/Zc:throwingNew %(AdditionalOptions)</AdditionalOptions>