diff --git a/Source/Base/dn_base_assert.h b/Source/Base/dn_base_assert.h index 6005df0..fc28428 100644 --- a/Source/Base/dn_base_assert.h +++ b/Source/Base/dn_base_assert.h @@ -13,34 +13,44 @@ } while (0) #define DN_HardAssert(expr) DN_HardAssertF(expr, "") +// NOTE: Our default assert requires stack traces which has a bit of a chicken-and-egg problem if +// we're trying to detect some code related to the DN startup sequence. If we try to assert before +// the OS layer is initialised stack-traces will try to use temporary memory which requires TLS to +// be setup which belongs to the OS. +// +// This causes recursion errors as they call into each other. We use RawAsserts for these kind of +// checks. #if defined(DN_NO_ASSERT) + #define DN_RawAssert(...) #define DN_Assert(...) #define DN_AssertOnce(...) #define DN_AssertF(...) #define DN_AssertFOnce(...) #else - #define DN_AssertF(expr, fmt, ...) \ - do { \ - if (!(expr)) { \ + #define DN_RawAssert(expr) do { if (!(expr)) DN_DebugBreak; } while (0) + + #define DN_AssertF(expr, fmt, ...) \ + do { \ + if (!(expr)) { \ DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ - DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ } while (0) - #define DN_AssertFOnce(expr, fmt, ...) \ - do { \ - static bool once = true; \ - if (!(expr) && once) { \ - once = false; \ + #define DN_AssertFOnce(expr, fmt, ...) \ + do { \ + static bool once = true; \ + if (!(expr) && once) { \ + once = false; \ DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ - DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ } while (0) #define DN_Assert(expr) DN_AssertF((expr), "") diff --git a/Source/Base/dn_base_compiler.h b/Source/Base/dn_base_compiler.h index 6f06d72..efd33da 100644 --- a/Source/Base/dn_base_compiler.h +++ b/Source/Base/dn_base_compiler.h @@ -1,7 +1,7 @@ #if !defined(DN_BASE_COMPILER_H) #define DN_BASE_COMPILER_H -// NOTE: Compiler identification /////////////////////////////////////////////////////////////////// +// NOTE: Compiler identification // Warning! Order is important here, clang-cl on Windows defines _MSC_VER #if defined(_MSC_VER) #if defined(__clang__) @@ -16,7 +16,7 @@ #define DN_COMPILER_GCC #endif -// NOTE: __has_feature ///////////////////////////////////////////////////////////////////////////// +// NOTE: __has_feature // MSVC for example does not support the feature detection macro for instance so we compile it out #if defined(__has_feature) #define DN_HAS_FEATURE(expr) __has_feature(expr) @@ -24,7 +24,7 @@ #define DN_HAS_FEATURE(expr) 0 #endif -// NOTE: __has_builtin ///////////////////////////////////////////////////////////////////////////// +// NOTE: __has_builtin // MSVC for example does not support the feature detection macro for instance so we compile it out #if defined(__has_builtin) #define DN_HAS_BUILTIN(expr) __has_builtin(expr) @@ -32,7 +32,7 @@ #define DN_HAS_BUILTIN(expr) 0 #endif -// NOTE: Warning suppression macros //////////////////////////////////////////////////////////////// +// NOTE: Warning suppression macros #if defined(DN_COMPILER_MSVC) #define DN_MSVC_WARNING_PUSH __pragma(warning(push)) #define DN_MSVC_WARNING_DISABLE(...) __pragma(warning(disable :##__VA_ARGS__)) @@ -55,14 +55,14 @@ #define DN_GCC_WARNING_POP #endif -// NOTE: Host OS identification //////////////////////////////////////////////////////////////////// +// NOTE: Host OS identification #if defined(_WIN32) #define DN_OS_WIN32 #elif defined(__gnu_linux__) || defined(__linux__) #define DN_OS_UNIX #endif -// NOTE: Platform identification /////////////////////////////////////////////////////////////////// +// NOTE: Platform identification #if !defined(DN_PLATFORM_EMSCRIPTEN) && \ !defined(DN_PLATFORM_POSIX) && \ !defined(DN_PLATFORM_WIN32) @@ -77,7 +77,7 @@ #endif #endif -// NOTE: Windows crap ////////////////////////////////////////////////////////////////////////////// +// NOTE: Windows crap #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) #if defined(_CRT_SECURE_NO_WARNINGS) #define DN_CRT_SECURE_NO_WARNINGS_PREVIOUSLY_DEFINED @@ -86,21 +86,21 @@ #endif #endif -// NOTE: Force Inline ////////////////////////////////////////////////////////////////////////////// +// NOTE: Force Inline #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) #define DN_FORCE_INLINE __forceinline #else #define DN_FORCE_INLINE inline __attribute__((always_inline)) #endif -// NOTE: Function/Variable Annotations ///////////////////////////////////////////////////////////// +// NOTE: Function/Variable Annotations #if defined(DN_STATIC_API) #define DN_API static #else #define DN_API #endif -// NOTE: C/CPP Literals //////////////////////////////////////////////////////////////////////////// +// NOTE: C/CPP Literals // Declare struct literals that work in both C and C++ because the syntax is different between // languages. #if 0 @@ -114,14 +114,14 @@ #define DN_Literal(T) (T) #endif -// NOTE: Thread Locals ///////////////////////////////////////////////////////////////////////////// +// NOTE: Thread Locals #if defined(__cplusplus) #define DN_THREAD_LOCAL thread_local #else #define DN_THREAD_LOCAL _Thread_local #endif -// NOTE: C variadic argument annotations /////////////////////////////////////////////////////////// +// NOTE: C variadic argument annotations // TODO: Other compilers #if defined(DN_COMPILER_MSVC) #define DN_FMT_ATTRIB _Printf_format_string_ @@ -129,17 +129,17 @@ #define DN_FMT_ATTRIB #endif -// NOTE: Type Cast ///////////////////////////////////////////////////////////////////////////////// +// NOTE: Type Cast #define DN_Cast(val) (val) -// NOTE: Zero initialisation macro ///////////////////////////////////////////////////////////////// +// NOTE: Zero initialisation macro #if defined(__cplusplus) #define DN_ZeroInit {} #else #define DN_ZeroInit {0} #endif -// NOTE: Address sanitizer ///////////////////////////////////////////////////////////////////////// +// NOTE: Address sanitizer #if !defined(DN_ASAN_POISON) #define DN_ASAN_POISON 0 #endif diff --git a/Source/Extra/dn_net.cpp b/Source/Extra/dn_net.cpp index 24e89dd..76ee8a0 100644 --- a/Source/Extra/dn_net.cpp +++ b/Source/Extra/dn_net.cpp @@ -3,6 +3,23 @@ #include "../dn_base_inc.h" #include "../dn_os_inc.h" +DN_Str8 DN_NET_Str8FromResponseState(DN_NETResponseState state) +{ + DN_Str8 result = {}; + switch (state) { + case DN_NETResponseState_Nil: result = DN_Str8Lit("Nil"); break; + case DN_NETResponseState_Error: result = DN_Str8Lit("Error"); break; + case DN_NETResponseState_HTTP: result = DN_Str8Lit("HTTP"); break; + case DN_NETResponseState_WSOpen: result = DN_Str8Lit("WS Open"); break; + case DN_NETResponseState_WSText: result = DN_Str8Lit("WS Text"); break; + case DN_NETResponseState_WSBinary: result = DN_Str8Lit("WS Binary"); break; + case DN_NETResponseState_WSClose: result = DN_Str8Lit("WS Close"); break; + case DN_NETResponseState_WSPing: result = DN_Str8Lit("WS Ping"); break; + case DN_NETResponseState_WSPong: result = DN_Str8Lit("WS Pong"); break; + } + return result; +} + DN_NETRequest *DN_NET_RequestFromHandle(DN_NETRequestHandle handle) { DN_NETRequest *ptr = DN_Cast(DN_NETRequest *) handle.handle; diff --git a/Source/Extra/dn_net.h b/Source/Extra/dn_net.h index 05e9b47..0552342 100644 --- a/Source/Extra/dn_net.h +++ b/Source/Extra/dn_net.h @@ -114,12 +114,13 @@ struct DN_NETInterface DN_NETWaitForAnyResponseFunc* wait_for_any_response; }; -DN_NETRequest * DN_NET_RequestFromHandle (DN_NETRequestHandle handle); -DN_NETRequestHandle DN_NET_HandleFromRequest (DN_NETRequest *request); +DN_Str8 DN_NET_Str8FromResponseState(DN_NETResponseState state); +DN_NETRequest * DN_NET_RequestFromHandle (DN_NETRequestHandle handle); +DN_NETRequestHandle DN_NET_HandleFromRequest (DN_NETRequest *request); // NOTE: Internal functions for different networking implementations to use -void DN_NET_BaseInit_ (DN_NETCore *net, char *base, DN_U64 base_size); -DN_NETRequestHandle DN_NET_SetupRequest_ (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type); -void DN_NET_EndFinishedRequest_ (DN_NETRequest *request); +void DN_NET_BaseInit_ (DN_NETCore *net, char *base, DN_U64 base_size); +DN_NETRequestHandle DN_NET_SetupRequest_ (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type); +void DN_NET_EndFinishedRequest_ (DN_NETRequest *request); #endif // DN_NET_H diff --git a/Source/OS/dn_os_w32.cpp b/Source/OS/dn_os_w32.cpp index e56f707..6185f52 100644 --- a/Source/OS/dn_os_w32.cpp +++ b/Source/OS/dn_os_w32.cpp @@ -110,6 +110,7 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem) { + DN_RawAssert(g_dn_->init_flags & DN_InitFlags_OS && "DN must be initialised with the OS flag"); DN_U32 flags = z_mem == DN_ZMem_Yes ? HEAP_ZERO_MEMORY : 0; DN_Assert(size <= DN_Cast(DWORD)(-1)); void *result = HeapAlloc(GetProcessHeap(), flags, DN_Cast(DWORD) size); diff --git a/Source/dn_inc.cpp b/Source/dn_inc.cpp index a8dfd65..a5a8bee 100644 --- a/Source/dn_inc.cpp +++ b/Source/dn_inc.cpp @@ -93,7 +93,8 @@ static void DN_InitOS_(DN_OSCore *os, DN_InitArgs *args) DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args) { - g_dn_ = dn; + g_dn_ = dn; + dn->init_flags = flags; if (flags & DN_InitFlags_OS) { #if defined(DN_OS_H) && defined(DN_OS_CPP) diff --git a/Source/dn_inc.h b/Source/dn_inc.h index 06b8562..16c7148 100644 --- a/Source/dn_inc.h +++ b/Source/dn_inc.h @@ -1,15 +1,6 @@ #if !defined(DN_INC_H) #define DN_INC_H -struct DN_Core -{ - DN_USize mem_allocs_frame; - DN_LeakTracker leak; - #if defined(DN_OS_H) - DN_OSCore os; - #endif -}; - struct DN_InitArgs { DN_U64 os_tls_reserve; @@ -29,6 +20,16 @@ enum DN_InitFlags_ DN_InitFlags_LogAllFeatures = DN_InitFlags_LogLibFeatures | DN_InitFlags_LogCPUFeatures, }; +struct DN_Core +{ + DN_InitFlags init_flags; + DN_USize mem_allocs_frame; + DN_LeakTracker leak; + #if defined(DN_OS_H) + DN_OSCore os; + #endif +}; + extern DN_Core *g_dn_; DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args);