From ba23cb0c709c8a5d7ca4eb97e87dbf2bbf4c98a4 Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Sun, 2 Mar 2025 14:35:37 +0100 Subject: [PATCH] Made the lib work with -fno-exceptions (at least for now). --- source/mijin/async/coroutine.hpp | 20 +++++++++++++++++++ source/mijin/debug/stacktrace.hpp | 4 ++-- source/mijin/internal/exception.hpp | 18 +++++++++++++---- source/mijin/io/stream.hpp | 2 ++ .../mijin/virtual_filesystem/filesystem.cpp | 18 +++++++++++------ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/source/mijin/async/coroutine.hpp b/source/mijin/async/coroutine.hpp index a2cda8f..2433af9 100644 --- a/source/mijin/async/coroutine.hpp +++ b/source/mijin/async/coroutine.hpp @@ -27,6 +27,18 @@ #include "../debug/stacktrace.hpp" #endif +#if !defined(MIJIN_COROUTINE_ENABLE_EXCEPTION_HANDLING) +# define MIJIN_COROUTINE_ENABLE_EXCEPTION_HANDLING MIJIN_ENABLE_EXCEPTIONS +#elif !__cpp_exceptions +# error "Coroutine exception handling enabled, but exceptions are disabled." +#endif + +#if !defined(MIJIN_COROUTINE_ENABLE_CANCEL) +# define MIJIN_COROUTINE_ENABLE_CANCEL MIJIN_ENABLE_EXCEPTIONS +#elif !__cpp_exceptions +# error "Cancelling tasks requires exceptions to be anbled." +#endif + namespace mijin { @@ -56,7 +68,9 @@ class TaskLoop; template class TaskBase; +#if MIJIN_COROUTINE_ENABLE_CANCEL struct TaskCancelled : std::exception {}; +#endif namespace impl { @@ -585,10 +599,12 @@ extern thread_local TaskLoop::StoredTask* gCurrentTask; inline void throwIfCancelled() { +#if MIJIN_COROUTINE_ENABLE_CANCEL if (gCurrentTask->task->sharedState()->cancelled_) { throw TaskCancelled(); } +#endif } } @@ -657,13 +673,16 @@ inline TaskStatus TaskLoop::tickTask(StoredTask& task) while (status == TaskStatus::RUNNING); impl::gCurrentTask = nullptr; +#if MIJIN_COROUTINE_ENABLE_EXCEPTION_HANDLING if (task.task && task.task->exception()) { try { std::rethrow_exception(task.task->exception()); } +#if MIJIN_COROUTINE_ENABLE_CANCEL catch(TaskCancelled&) {} // ignore those +#endif catch(...) { if (uncaughtExceptionHandler_) @@ -679,6 +698,7 @@ inline TaskStatus TaskLoop::tickTask(StoredTask& task) // TODO: handle the exception somehow, others may be waiting return TaskStatus::FINISHED; } +#endif // MIJIN_COROUTINE_ENABLE_EXCEPTION_HANDLING if (status == TaskStatus::YIELDED || status == TaskStatus::FINISHED) { task.setFuture(task); diff --git a/source/mijin/debug/stacktrace.hpp b/source/mijin/debug/stacktrace.hpp index d49843e..ac7e485 100644 --- a/source/mijin/debug/stacktrace.hpp +++ b/source/mijin/debug/stacktrace.hpp @@ -96,7 +96,7 @@ struct fmt::formatter auto it = ctx.begin(); auto end = ctx.end(); - if (it != end && *it != '}') throw format_error("invalid format"); + if (it != end && *it != '}') FMT_THROW(format_error("invalid format")); return it; } @@ -119,7 +119,7 @@ struct fmt::formatter auto it = ctx.begin(); auto end = ctx.end(); - if (it != end && *it != '}') throw format_error("invalid format"); + if (it != end && *it != '}') FMT_THROW(format_error("invalid format")); return it; } diff --git a/source/mijin/internal/exception.hpp b/source/mijin/internal/exception.hpp index cd7fad6..cbccf00 100644 --- a/source/mijin/internal/exception.hpp +++ b/source/mijin/internal/exception.hpp @@ -4,19 +4,21 @@ #if !defined(MIJIN_INTERNAL_EXCEPTION_HPP_INCLUDED) #define MIJIN_INTERNAL_EXCEPTION_HPP_INCLUDED 1 -#if !defined(MIJIN_WITH_EXCEPTIONS) -#define MIJIN_WITH_EXCEPTIONS 0 +#if !defined(MIJIN_ENABLE_EXCEPTIONS) +# define MIJIN_ENABLE_EXCEPTIONS (__cpp_exceptions) #endif +#define MIJIN_CATCH_EXCEPTIONS (__cpp_exceptions) + #if !defined(MIJIN_THROWING_ASSERTS) -#define MIJIN_THROWING_ASSERTS 0 +# define MIJIN_THROWING_ASSERTS 0 #endif #if MIJIN_THROWING_ASSERTS && !defined(MIJIN_TEST_NO_NOEXCEPT) #define MIJIN_TEST_NO_NOEXCEPT #endif -#if MIJIN_WITH_EXCEPTIONS +#if 0 // TODO: what? MIJIN_WITH_EXCEPTIONS #error "Maybe someday" #else #if defined(MIJIN_TEST_NO_NOEXCEPT) // only use for testing @@ -30,4 +32,12 @@ #endif #endif +#if MIJIN_CATCH_EXCEPTIONS +# define MIJIN_TRY try +# define MIJIN_CATCH catch +#else +# define MIJIN_TRY +# define MIJIN_CATCH(...) if constexpr(false) +#endif + #endif // !defined(MIJIN_INTERNAL_EXCEPTION_HPP_INCLUDED) diff --git a/source/mijin/io/stream.hpp b/source/mijin/io/stream.hpp index e8915c9..9eed8f9 100644 --- a/source/mijin/io/stream.hpp +++ b/source/mijin/io/stream.hpp @@ -457,6 +457,7 @@ inline const char* errorName(StreamError error) MIJIN_NOEXCEPT return ""; } +#if MIJIN_ENABLE_EXCEPTIONS // these functions don't make sense with exceptions disabled inline void throwOnError(mijin::StreamError error) { if (error == mijin::StreamError::SUCCESS) { @@ -500,6 +501,7 @@ inline decltype(auto) throwOnError(StreamResult&& result, const std::s } return *result; } +#endif // MIJIN_ENABLE_EXCEPTIONS } // namespace mijin #endif // !defined(MIJIN_IO_STREAM_HPP_INCLUDED) diff --git a/source/mijin/virtual_filesystem/filesystem.cpp b/source/mijin/virtual_filesystem/filesystem.cpp index 758f739..3bd0aa4 100644 --- a/source/mijin/virtual_filesystem/filesystem.cpp +++ b/source/mijin/virtual_filesystem/filesystem.cpp @@ -57,18 +57,22 @@ std::vector OSFileSystemAdapter::listFiles(const fs::path& folder) info.isSymlink = entry.is_symlink(err); info.isSpecial = !info.isFolder && !entry.is_regular_file(err); info.isHidden = info.path.filename().string().starts_with('.'); // at least for Linux - if (info.isFolder) { - try { + if (info.isFolder) + { + MIJIN_TRY + { info.size = std::distance(fs::directory_iterator(info.path), fs::directory_iterator()); } - catch(std::runtime_error&) { + MIJIN_CATCH(std::runtime_error&) + { info.size = 0; } } else if (!info.isSpecial) { info.size = entry.file_size(err); - if (err) { + if (err) + { info.size = 0; } } @@ -89,10 +93,12 @@ FileInfo OSFileSystemAdapter::getFileInfo(const fs::path& file) info.isSpecial = !info.isFolder && !fs::is_regular_file(file, err); info.isHidden = info.path.filename().string().starts_with('.'); // at least for Linux if (info.isFolder) { - try { + MIJIN_TRY + { info.size = std::distance(fs::directory_iterator(info.path), fs::directory_iterator()); } - catch(std::runtime_error&) { + MIJIN_CATCH(std::runtime_error&) + { info.size = 0; } }