more fixes

This commit is contained in:
ed
2025-02-09 00:37:35 -05:00
parent d82af845bc
commit 83ce4d1bb2
17 changed files with 1348 additions and 1324 deletions
+5 -5
View File
@@ -12,22 +12,22 @@
//- rjf: arena creation/destruction //- rjf: arena creation/destruction
Arena* Arena*
arena_alloc_(ArenaParams* params) arena__alloc(ArenaParams params)
{ {
SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT); SPTR const header_size = align_pow2(size_of(Arena), MD_DEFAULT_MEMORY_ALIGNMENT);
// TODO(Ed): Do we need to be slapping the arena onto the memory now? // TODO(Ed): Do we need to be slapping the arena onto the memory now?
// (its technically not needed a its no longer always backed by vmem) // (its technically not needed a its no longer always backed by vmem)
void* base = alloc(params->backing, params->block_size); void* base = alloc(params.backing, params.block_size);
// rjf: extract arena header & fill // rjf: extract arena header & fill
Arena* arena = (Arena*) base; Arena* arena = (Arena*) base;
arena->prev = nullptr; arena->prev = nullptr;
arena->current = arena; arena->current = arena;
arena->backing = params->backing; arena->backing = params.backing;
arena->base_pos = 0; arena->base_pos = 0;
arena->pos = header_size; arena->pos = header_size;
arena->block_size = params->block_size; arena->block_size = params.block_size;
arena->flags = params->flags; arena->flags = params.flags;
asan_unpoison_memory_region(base, sizeof(Arena)); asan_unpoison_memory_region(base, sizeof(Arena));
return arena; return arena;
} }
+2 -2
View File
@@ -171,7 +171,7 @@ cmd_line_from_string_list(Arena* arena, String8List command_line)
} }
U8 splits[] = { ',' }; U8 splits[] = { ',' };
String8List args_in_this_string = str8_split(arena, string, splits, ArrayCount(splits), 0); String8List args_in_this_string = str8_split(arena, string, splits, array_count(splits), 0);
for (String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) { for (String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) {
str8_list_push(arena, &arguments, sub_arg->string); str8_list_push(arena, &arguments, sub_arg->string);
} }
@@ -273,7 +273,7 @@ cmd_line_from_string_list_alloc(AllocatorInfo ainfo, String8List command_line)
} }
U8 splits[] = { ',' }; U8 splits[] = { ',' };
String8List args_in_this_string = str8_split_alloc(ainfo, string, splits, ArrayCount(splits), 0); String8List args_in_this_string = str8_split_alloc(ainfo, string, splits, array_count(splits), 0);
for (String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) { for (String8Node* sub_arg = args_in_this_string.first; sub_arg; sub_arg = sub_arg->next) {
str8_list_alloc(ainfo, &arguments, sub_arg->string); str8_list_alloc(ainfo, &arguments, sub_arg->string);
} }
+3 -3
View File
@@ -14,9 +14,9 @@
#ifndef trap #ifndef trap
# if COMPILER_MSVC # if COMPILER_MSVC
# if _MSC_VER < 1300 # if _MSC_VER < 1300
# define MD_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */ # define trap() __asm int 3 /* Trap to debugger! */
# else # else
# define MD_DEBUG_TRAP() __debugbreak() # define trap() __debugbreak()
# endif # endif
# elif COMPILER_CLANG || COMPILER_GCC # elif COMPILER_CLANG || COMPILER_GCC
# define trap() __builtin_trap() # define trap() __builtin_trap()
@@ -31,7 +31,7 @@
if ( ! ( cond ) ) \ if ( ! ( cond ) ) \
{ \ { \
assert_handler( #cond, __FILE__, __func__, scast( S64, __LINE__ ), msg, ##__VA_ARGS__ ); \ assert_handler( #cond, __FILE__, __func__, scast( S64, __LINE__ ), msg, ##__VA_ARGS__ ); \
MD_DEBUG_TRAP(); \ trap(); \
} \ } \
} while ( 0 ) } while ( 0 )
+1 -1
View File
@@ -17,7 +17,7 @@ void main_thread_base_entry_point(MainThread_EntryPointProc* entry_point, char**
tmSetMaxThreadCount(256); tmSetMaxThreadCount(256);
tmInitialize(sizeof(tm_data), (char *)tm_data); tmInitialize(sizeof(tm_data), (char *)tm_data);
#endif #endif
ThreadNameF("[main thread]"); thread_namef("[main thread]");
// TODO(Ed): Review? // TODO(Ed): Review?
TempArena scratch = scratch_begin(0, 0); TempArena scratch = scratch_begin(0, 0);
+1
View File
@@ -2,6 +2,7 @@
# pragma once # pragma once
# include "linkage.h" # include "linkage.h"
# include "strings.h" # include "strings.h"
# include "thread_context.h"
#endif #endif
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
+2 -2
View File
@@ -370,10 +370,10 @@ struct Rng1S64Array
#endif #endif
#ifndef clamp_top #ifndef clamp_top
#define clamp_top(A, X) Min(A, X) #define clamp_top(A, X) md_min(A, X)
#endif #endif
#ifndef clamp_bot #ifndef clamp_bot
#define clamp_bot(X, B) Max(X, B) #define clamp_bot(X, B) md_max(X, B)
#endif #endif
#define clamp(A, X, B) (((X) < (A)) ? (A) : ((X) > (B)) ? (B) : (X)) #define clamp(A, X, B) (((X) < (A)) ? (A) : ((X) > (B)) ? (B) : (X))
+5 -5
View File
@@ -202,7 +202,7 @@ void* mem_move( void* destination, void const* source, SSIZE byte_count )
if ( dest_ptr < src_ptr ) if ( dest_ptr < src_ptr )
{ {
if ( to_uptr(src_ptr) % size_of( SSIZE ) == to_uptr(dest_ptr) % size_of( SSIZE ) ) if ( scast(UPTR, src_ptr) % size_of( SSIZE ) == scast(UPTR, dest_ptr) % size_of( SSIZE ) )
{ {
while ( pcast( UPTR, dest_ptr) % size_of( SSIZE ) ) while ( pcast( UPTR, dest_ptr) % size_of( SSIZE ) )
{ {
@@ -224,9 +224,9 @@ void* mem_move( void* destination, void const* source, SSIZE byte_count )
} }
else else
{ {
if ( ( to_uptr(src_ptr) % size_of( SSIZE ) ) == ( to_uptr(dest_ptr) % size_of( SSIZE ) ) ) if ( ( scast(UPTR, src_ptr) % size_of( SSIZE ) ) == ( scast(UPTR, dest_ptr) % size_of( SSIZE ) ) )
{ {
while ( to_uptr( dest_ptr + byte_count ) % size_of( SSIZE ) ) while ( scast(UPTR, dest_ptr + byte_count ) % size_of( SSIZE ) )
{ {
if ( ! byte_count-- ) if ( ! byte_count-- )
return destination; return destination;
@@ -274,7 +274,7 @@ void* mem_set( void* destination, U8 fill_byte, SSIZE byte_count )
if ( byte_count < 9 ) if ( byte_count < 9 )
return destination; return destination;
align_offset = -to_sptr( dest_ptr ) & 3; align_offset = -scast(SPTR, dest_ptr ) & 3;
dest_ptr += align_offset; dest_ptr += align_offset;
byte_count -= align_offset; byte_count -= align_offset;
byte_count &= -4; byte_count &= -4;
@@ -300,7 +300,7 @@ void* mem_set( void* destination, U8 fill_byte, SSIZE byte_count )
* rcast( U32*, dest_ptr + byte_count - 20 ) = fill_word; * rcast( U32*, dest_ptr + byte_count - 20 ) = fill_word;
* rcast( U32*, dest_ptr + byte_count - 16 ) = fill_word; * rcast( U32*, dest_ptr + byte_count - 16 ) = fill_word;
align_offset = 24 + to_uptr( dest_ptr ) & 4; align_offset = 24 + scast(UPTR, dest_ptr ) & 4;
dest_ptr += align_offset; dest_ptr += align_offset;
byte_count -= align_offset; byte_count -= align_offset;
+32 -1
View File
@@ -4,6 +4,37 @@
# include "../os/os.h" # include "../os/os.h"
#endif #endif
void*
default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE new_size, SSIZE alignment )
{
if ( ! old_memory )
return alloc_align( a, new_size, alignment );
if ( new_size == 0 )
{
alloc_free( a, old_memory );
return nullptr;
}
if ( new_size < old_size )
new_size = old_size;
if ( old_size == new_size )
{
return old_memory;
}
else
{
void* new_memory = alloc_align( a, new_size, alignment );
if ( ! new_memory )
return nullptr;
mem_move( new_memory, old_memory, md_min( new_size, old_size ) );
alloc_free( a, old_memory );
return new_memory;
}
}
#ifdef MD_HEAP_ANALYSIS #ifdef MD_HEAP_ANALYSIS
#define GEN_HEAP_STATS_MAGIC 0xDEADC0DE #define GEN_HEAP_STATS_MAGIC 0xDEADC0DE
@@ -96,7 +127,7 @@ heap_allocator_proc( void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE
{ {
ptr = _aligned_malloc( size, alignment ); ptr = _aligned_malloc( size, alignment );
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO ) if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
zero_size( ptr, size ); memory_zero( ptr, size );
} }
break; break;
-31
View File
@@ -287,34 +287,3 @@ resize_align( AllocatorInfo a, void* ptr, SSIZE old_size, SSIZE new_size, SSIZE
} }
return a.proc( a.data, AllocatorMode_Resize, new_size, alignment, ptr, old_size, MD_DEFAULT_ALLOCATOR_FLAGS ); return a.proc( a.data, AllocatorMode_Resize, new_size, alignment, ptr, old_size, MD_DEFAULT_ALLOCATOR_FLAGS );
} }
inline void*
default_resize_align( AllocatorInfo a, void* old_memory, SSIZE old_size, SSIZE new_size, SSIZE alignment )
{
if ( ! old_memory )
return alloc_align( a, new_size, alignment );
if ( new_size == 0 )
{
allocator_free( a, old_memory );
return nullptr;
}
if ( new_size < old_size )
new_size = old_size;
if ( old_size == new_size )
{
return old_memory;
}
else
{
void* new_memory = alloc_align( a, new_size, alignment );
if ( ! new_memory )
return nullptr;
mem_move( new_memory, old_memory, min( new_size, old_size ) );
allocator_free( a, old_memory );
return new_memory;
}
}
+2 -2
View File
@@ -2093,7 +2093,7 @@ fuzzy_match_range_list_copy_alloc(AllocatorInfo ainfo, FuzzyMatchRangeList* src)
U64 U64
str8_serial_push_align(Arena* arena, String8List* srl, U64 align) { str8_serial_push_align(Arena* arena, String8List* srl, U64 align) {
#if MD_DONT_MAP_ARENA_TO_ALLOCATOR_IMPL #if MD_DONT_MAP_ARENA_TO_ALLOCATOR_IMPL
Assert(is_pow2(align)); assert(is_pow2(align));
U64 pos = srl->total_size; U64 pos = srl->total_size;
U64 new_pos = align_pow2(pos, align); U64 new_pos = align_pow2(pos, align);
U64 size = (new_pos - pos); U64 size = (new_pos - pos);
@@ -2178,7 +2178,7 @@ str8_serial_push_u32(Arena* arena, String8List* srl, U32 x) {
U64 U64
str8_serial_alloc_align(AllocatorInfo ainfo, String8List* srl, U64 align) { str8_serial_alloc_align(AllocatorInfo ainfo, String8List* srl, U64 align) {
Assert(is_pow2(align)); assert(is_pow2(align));
U64 pos = srl->total_size; U64 pos = srl->total_size;
U64 new_pos = align_pow2(pos, align); U64 new_pos = align_pow2(pos, align);
U64 size = (new_pos - pos); U64 size = (new_pos - pos);
+2 -2
View File
@@ -38,7 +38,7 @@ msg_list_push(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, String8 str
sll_queue_push(msgs->first, msgs->last, msg); sll_queue_push(msgs->first, msgs->last, msg);
msgs->count += 1; msgs->count += 1;
msgs->worst_message_kind = Max(kind, msgs->worst_message_kind); msgs->worst_message_kind = md_max(kind, msgs->worst_message_kind);
} }
void void
@@ -912,7 +912,7 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray
Node* error = push_node(arena, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); Node* error = push_node(arena, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min);
String8 error_string = push_str8f(arena, "More than two newlines following \"%S\", which has implicitly-delimited children, resulting in an empty list of children.", node->string); String8 error_string = push_str8f(arena, "More than two newlines following \"%S\", which has implicitly-delimited children, resulting in an empty list of children.", node->string);
msg_list_push(arena, &msgs, error, MsgKind_Warning, error_string); msg_list_push(arena, &msgs, error, MsgKind_Warning, error_string);
MD_ParseWorkPop(); parse_work_pop();
} }
else else
{ {
+1
View File
@@ -19,6 +19,7 @@ MD_NS_BEGIN
#include "base/strings.c" #include "base/strings.c"
#include "base/text.c" #include "base/text.c"
#include "base/thread_context.c" #include "base/thread_context.c"
#include "base/markup.c"
#include "base/command_line.c" #include "base/command_line.c"
#include "base/logger.c" #include "base/logger.c"
#include "base/entry_point.c" #include "base/entry_point.c"
+1 -1
View File
@@ -536,7 +536,7 @@ mg_node_grid_make_from_node(Arena *arena, Node *root)
for each_node(row, root->first) for each_node(row, root->first)
{ {
U64 cell_count_this_row = child_count_from_node(row); U64 cell_count_this_row = child_count_from_node(row);
column_count = Max(column_count, cell_count_this_row); column_count = md_max(column_count, cell_count_this_row);
} }
// rjf: fill grid // rjf: fill grid
+3 -3
View File
@@ -950,10 +950,10 @@ os_safe_call(OS_ThreadFunctionType* func, OS_ThreadFunctionType* fail_handler, v
int signals_to_handle[] = { int signals_to_handle[] = {
SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP,
}; };
struct sigaction og_act[ArrayCount(signals_to_handle)] = {0}; struct sigaction og_act[array_count(signals_to_handle)] = {0};
// rjf: attach handler info for all signals // rjf: attach handler info for all signals
for(U32 i = 0; i < ArrayCount(signals_to_handle); i += 1) { for(U32 i = 0; i < array_count(signals_to_handle); i += 1) {
sigaction(signals_to_handle[i], &new_act, &og_act[i]); sigaction(signals_to_handle[i], &new_act, &og_act[i]);
} }
@@ -961,7 +961,7 @@ os_safe_call(OS_ThreadFunctionType* func, OS_ThreadFunctionType* fail_handler, v
func(ptr); func(ptr);
// rjf: reset handler info for all signals // rjf: reset handler info for all signals
for (U32 i = 0; i < ArrayCount(signals_to_handle); i += 1) { for (U32 i = 0; i < array_count(signals_to_handle); i += 1) {
sigaction(signals_to_handle[i], &og_act[i], 0); sigaction(signals_to_handle[i], &og_act[i], 0);
} }
} }
+15 -15
View File
@@ -859,7 +859,7 @@ os_thread_launch(OS_ThreadFunctionType* func, void* ptr, void* params) {
entity->thread.func = func; entity->thread.func = func;
entity->thread.ptr = ptr; entity->thread.ptr = ptr;
entity->thread.handle = CreateThread(0, 0, os_w32_thread_entry_point, entity, 0, &entity->thread.tid); entity->thread.handle = CreateThread(0, 0, os_w32_thread_entry_point, entity, 0, &entity->thread.tid);
OS_Handle result = {IntFromPtr(entity)}; OS_Handle result = {int_from_ptr(entity)};
return result; return result;
} }
@@ -891,7 +891,7 @@ OS_Handle
os_mutex_alloc(void) { os_mutex_alloc(void) {
OS_W32_Entity* entity = os_w32_entity_alloc(OS_W32_EntityKind_Mutex); OS_W32_Entity* entity = os_w32_entity_alloc(OS_W32_EntityKind_Mutex);
InitializeCriticalSection(&entity->mutex); InitializeCriticalSection(&entity->mutex);
OS_Handle result = {IntFromPtr(entity)}; OS_Handle result = {int_from_ptr(entity)};
return result; return result;
} }
@@ -920,7 +920,7 @@ OS_Handle
os_rw_mutex_alloc(void) { os_rw_mutex_alloc(void) {
OS_W32_Entity* entity = os_w32_entity_alloc(OS_W32_EntityKind_RWMutex); OS_W32_Entity* entity = os_w32_entity_alloc(OS_W32_EntityKind_RWMutex);
InitializeSRWLock(&entity->rw_mutex); InitializeSRWLock(&entity->rw_mutex);
OS_Handle result = {IntFromPtr(entity)}; OS_Handle result = {int_from_ptr(entity)};
return result; return result;
} }
@@ -960,7 +960,7 @@ OS_Handle
os_condition_variable_alloc(void) { os_condition_variable_alloc(void) {
OS_W32_Entity* entity = os_w32_entity_alloc(OS_W32_EntityKind_ConditionVariable); OS_W32_Entity* entity = os_w32_entity_alloc(OS_W32_EntityKind_ConditionVariable);
InitializeConditionVariable(&entity->cv); InitializeConditionVariable(&entity->cv);
OS_Handle result = {IntFromPtr(entity)}; OS_Handle result = {int_from_ptr(entity)};
return result; return result;
} }
@@ -1178,7 +1178,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
int buflen = 0; int buflen = 0;
DWORD exception_code = exception_ptrs->ExceptionRecord->ExceptionCode; DWORD exception_code = exception_ptrs->ExceptionRecord->ExceptionCode;
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"A fatal exception (code 0x%x) occurred. The process is terminating.\n", exception_code); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L"A fatal exception (code 0x%x) occurred. The process is terminating.\n", exception_code);
// load dbghelp dynamically just in case if it is missing // load dbghelp dynamically just in case if it is missing
HMODULE dbghelp = LoadLibraryA("dbghelp.dll"); HMODULE dbghelp = LoadLibraryA("dbghelp.dll");
@@ -1267,7 +1267,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
const U32 max_frames = 32; const U32 max_frames = 32;
if(idx == max_frames) if(idx == max_frames)
{ {
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"..."); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L"...");
break; break;
} }
@@ -1285,16 +1285,16 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
if(idx==0) if(idx==0)
{ {
#if BUILD_CONSOLE_INTERFACE #if BUILD_CONSOLE_INTERFACE
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"\nCreate a new issue with this report at %S.\n\n", BUILD_ISSUES_LINK_STRING_LITERAL); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L"\nCreate a new issue with this report at %S.\n\n", BUILD_ISSUES_LINK_STRING_LITERAL);
#else #else
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen,
L"\nPress Ctrl+C to copy this text to clipboard, then create a new issue at\n" L"\nPress Ctrl+C to copy this text to clipboard, then create a new issue at\n"
L"<a href=\"%S\">%S</a>\n\n", BUILD_ISSUES_LINK_STRING_LITERAL, BUILD_ISSUES_LINK_STRING_LITERAL); L"<a href=\"%S\">%S</a>\n\n", BUILD_ISSUES_LINK_STRING_LITERAL, BUILD_ISSUES_LINK_STRING_LITERAL);
#endif #endif
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"Call stack:\n"); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L"Call stack:\n");
} }
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"%u. [0x%I64x]", idx + 1, address); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L"%u. [0x%I64x]", idx + 1, address);
struct struct
{ {
@@ -1308,7 +1308,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
DWORD64 displacement = 0; DWORD64 displacement = 0;
if (dbg_SymFromAddrW(process, address, &displacement, &symbol.info)) if (dbg_SymFromAddrW(process, address, &displacement, &symbol.info))
{ {
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L" %s +%u", symbol.info.Name, (DWORD)displacement); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L" %s +%u", symbol.info.Name, (DWORD)displacement);
IMAGEHLP_LINEW64 IMAGEHLP_LINEW64
line = {0}; line = {0};
@@ -1316,7 +1316,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
DWORD line_displacement = 0; DWORD line_displacement = 0;
if(dbg_SymGetLineFromAddrW64(process, address, &line_displacement, &line)) { if(dbg_SymGetLineFromAddrW64(process, address, &line_displacement, &line)) {
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L", %s line %u", PathFindFileNameW(line.FileName), line.LineNumber); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L", %s line %u", PathFindFileNameW(line.FileName), line.LineNumber);
} }
} }
else else
@@ -1325,18 +1325,18 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
module = {0}; module = {0};
module.SizeOfStruct = sizeof(module); module.SizeOfStruct = sizeof(module);
if (dbg_SymGetModuleInfoW64(process, address, &module)) { if (dbg_SymGetModuleInfoW64(process, address, &module)) {
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L" %s", module.ModuleName); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L" %s", module.ModuleName);
} }
} }
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"\n"); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L"\n");
} }
} }
} }
} }
} }
buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"\nVersion: %S%S", BUILD_VERSION_STRING_LITERAL, BUILD_GIT_HASH_STRING_LITERAL_APPEND); buflen += wnsprintfW(buffer + buflen, array_count(buffer) - buflen, L"\nVersion: %S%S", BUILD_VERSION_STRING_LITERAL, BUILD_GIT_HASH_STRING_LITERAL_APPEND);
#if BUILD_CONSOLE_INTERFACE #if BUILD_CONSOLE_INTERFACE
fwprintf(stderr, L"\n--- Fatal Exception ---\n"); fwprintf(stderr, L"\n--- Fatal Exception ---\n");
+53 -31
View File
@@ -283,7 +283,8 @@ static struct
"75767778798081828384858687888990919293949596979899" "75767778798081828384858687888990919293949596979899"
}; };
STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char pcomma, char pperiod) STBSP__PUBLICDEF void
STB_SPRINTF_DECORATE(set_separators)(char pcomma, char pperiod)
{ {
stbsp__period = pperiod; stbsp__period = pperiod;
stbsp__comma = pcomma; stbsp__comma = pcomma;
@@ -303,8 +304,7 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char pcomma, char ppe
#define STBSP__METRIC_1024 2048 #define STBSP__METRIC_1024 2048
#define STBSP__METRIC_JEDEC 4096 #define STBSP__METRIC_JEDEC 4096
static void stbsp__lead_sign(stbsp__uint32 fl, char *sign) static void stbsp__lead_sign(stbsp__uint32 fl, char* sign) {
{
sign[0] = 0; sign[0] = 0;
if (fl & STBSP__NEGATIVE) { if (fl & STBSP__NEGATIVE) {
sign[0] = 1; sign[0] = 1;
@@ -321,9 +321,9 @@ static void stbsp__lead_sign(stbsp__uint32 fl, char *sign)
static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const* s, stbsp__uint32 limit) static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const* s, stbsp__uint32 limit)
{ {
char const * sn = s; char const * sn = s;
// get up to 4-byte alignment // get up to 4-byte alignment
for (;;) { for (;;)
{
if (((stbsp__uintptr)sn & 3) == 0) if (((stbsp__uintptr)sn & 3) == 0)
break; break;
@@ -333,13 +333,13 @@ static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uin
++ sn; ++ sn;
-- limit; -- limit;
} }
// scan over 4 bytes at a time to find terminating 0 // scan over 4 bytes at a time to find terminating 0
// this will intentionally scan up to 3 bytes past the end of buffers, // this will intentionally scan up to 3 bytes past the end of buffers,
// but becase it works 4B aligned, it will never cross page boundaries // but becase it works 4B aligned, it will never cross page boundaries
// (hence the STBSP__ASAN markup; the over-read here is intentional // (hence the STBSP__ASAN markup; the over-read here is intentional
// and harmless) // and harmless)
while (limit >= 4) { while (limit >= 4)
{
stbsp__uint32 v = *(stbsp__uint32 *)sn; stbsp__uint32 v = *(stbsp__uint32 *)sn;
// bit hack to find if there's a 0 byte in there // bit hack to find if there's a 0 byte in there
if ((v - 0x01010101) & (~v) & 0x80808080UL) if ((v - 0x01010101) & (~v) & 0x80808080UL)
@@ -348,13 +348,11 @@ static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uin
sn += 4; sn += 4;
limit -= 4; limit -= 4;
} }
// handle the last few characters to find actual size // handle the last few characters to find actual size
while (limit && *sn) { while (limit && *sn) {
++ sn; ++ sn;
-- limit; -- limit;
} }
return (stbsp__uint32)(sn - s); return (stbsp__uint32)(sn - s);
} }
@@ -368,7 +366,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
bf = buf; bf = buf;
f = fmt; f = fmt;
for (;;) { for (;;)
{
stbsp__int32 fw, pr, tz; stbsp__int32 fw, pr, tz;
stbsp__uint32 fl; stbsp__uint32 fl;
@@ -391,7 +390,8 @@ stbsp__chk_cb_bufL(bytes); \
#define stbsp__flush_cb() \ #define stbsp__flush_cb() \
{ \ { \
stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \ stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \
} // flush if there is even one byte in the buffer }
// flush if there is even one byte in the buffer
#define stbsp__cb_buf_clamp(cl, v) \ #define stbsp__cb_buf_clamp(cl, v) \
cl = v; \ cl = v; \
if (callback) { \ if (callback) { \
@@ -401,25 +401,32 @@ cl = lg; \
} }
// fast copy everything up to the next % (or end of string) // fast copy everything up to the next % (or end of string)
for (;;) { for (;;)
while (((stbsp__uintptr)f) & 3) { {
while (((stbsp__uintptr)f) & 3)
{
schk1: schk1:
if (f[0] == '%') if (f[0] == '%')
goto scandd; goto scandd;
schk2: schk2:
if (f[0] == 0) if (f[0] == 0)
goto endfmt; goto endfmt;
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
*bf ++ = f[0]; *bf ++ = f[0];
++ f; ++ f;
} }
for (;;) { for (;;)
{
// Check if the next 4 bytes contain %(0x25) or end of string. // Check if the next 4 bytes contain %(0x25) or end of string.
// Using the 'hasless' trick: // Using the 'hasless' trick:
// https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord // https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord
stbsp__uint32 v, c; stbsp__uint32 v, c;
v = *(stbsp__uint32 *)f; v = *(stbsp__uint32 *)f;
c = (~v) & 0x80808080; c = (~v) & 0x80808080;
if (((v ^ 0x25252525) - 0x01010101) & c) if (((v ^ 0x25252525) - 0x01010101) & c)
goto schk1; goto schk1;
if ((v - 0x01010101) & c) if ((v - 0x01010101) & c)
@@ -442,8 +449,8 @@ cl = lg; \
f += 4; f += 4;
} }
} }
scandd:
scandd:
++f; ++f;
// ok, we have a percent, read the modifiers first // ok, we have a percent, read the modifiers first
@@ -453,78 +460,92 @@ cl = lg; \
tz = 0; tz = 0;
// flags // flags
for (;;) { for (;;) switch (f[0])
switch (f[0]) { {
// if we have left justify // if we have left justify
case '-': case '-':
fl |= STBSP__LEFTJUST; fl |= STBSP__LEFTJUST;
++ f; ++ f;
continue; continue;
// if we have leading plus // if we have leading plus
case '+': case '+':
fl |= STBSP__LEADINGPLUS; fl |= STBSP__LEADINGPLUS;
++ f; ++ f;
continue; continue;
// if we have leading space // if we have leading space
case ' ': case ' ':
fl |= STBSP__LEADINGSPACE; fl |= STBSP__LEADINGSPACE;
++ f; ++ f;
continue; continue;
// if we have leading 0x // if we have leading 0x
case '#': case '#':
fl |= STBSP__LEADING_0X; fl |= STBSP__LEADING_0X;
++ f; ++ f;
continue; continue;
// if we have thousand commas // if we have thousand commas
case '\'': case '\'':
fl |= STBSP__TRIPLET_COMMA; fl |= STBSP__TRIPLET_COMMA;
++ f; ++ f;
continue; continue;
// if we have kilo marker (none->kilo->kibi->jedec) // if we have kilo marker (none->kilo->kibi->jedec)
case '$': case '$':
if (fl & STBSP__METRIC_SUFFIX) { if (fl & STBSP__METRIC_SUFFIX)
{
if (fl & STBSP__METRIC_1024) { if (fl & STBSP__METRIC_1024) {
fl |= STBSP__METRIC_JEDEC; fl |= STBSP__METRIC_JEDEC;
} else { }
else {
fl |= STBSP__METRIC_1024; fl |= STBSP__METRIC_1024;
} }
} else { }
else {
fl |= STBSP__METRIC_SUFFIX; fl |= STBSP__METRIC_SUFFIX;
} }
++ f; ++ f;
continue; continue;
// if we don't want space between metric suffix and number // if we don't want space between metric suffix and number
case '_': case '_':
fl |= STBSP__METRIC_NOSPACE; fl |= STBSP__METRIC_NOSPACE;
++ f; ++ f;
continue; continue;
// if we have leading zero // if we have leading zero
case '0': case '0':
fl |= STBSP__LEADINGZERO; fl |= STBSP__LEADINGZERO;
++ f; ++ f;
goto flags_done; goto flags_done;
default: goto flags_done; default: goto flags_done;
} }
}
flags_done:
flags_done:
// get the field width // get the field width
if (f[0] == '*') { if (f[0] == '*') {
fw = va_arg(va, stbsp__uint32); fw = va_arg(va, stbsp__uint32);
++ f; ++ f;
} else { }
else
{
while ((f[0] >= '0') && (f[0] <= '9')) { while ((f[0] >= '0') && (f[0] <= '9')) {
fw = fw * 10 + f[0] - '0'; fw = fw * 10 + f[0] - '0';
f ++; f ++;
} }
} }
// get the precision // get the precision
if (f[0] == '.') { if (f[0] == '.')
{
++ f; ++ f;
if (f[0] == '*') { if (f[0] == '*') {
pr = va_arg(va, stbsp__uint32); pr = va_arg(va, stbsp__uint32);
++ f; ++ f;
} else { }
else {
pr = 0; pr = 0;
while ((f[0] >= '0') && (f[0] <= '9')) { while ((f[0] >= '0') && (f[0] <= '9')) {
pr = pr * 10 + f[0] - '0'; pr = pr * 10 + f[0] - '0';
@@ -534,7 +555,8 @@ cl = lg; \
} }
// handle integer size overrides // handle integer size overrides
switch (f[0]) { switch (f[0])
{
// are we halfwidth? // are we halfwidth?
case 'h': case 'h':
fl |= STBSP__HALFWIDTH; fl |= STBSP__HALFWIDTH;
@@ -679,7 +701,7 @@ cl = lg; \
} }
else else
{ {
Assert(size <= max_U64/100ull); assert(size <= MAX_U64 / 100ull);
hi = size / one_tib; hi = size / one_tib;
lo = ((size * 100) / one_tib) % 100; lo = ((size * 100) / one_tib) % 100;
units = "TiB"; units = "TiB";
@@ -1522,8 +1544,7 @@ cl = lg; \
// ============================================================================ // ============================================================================
// wrapper functions // wrapper functions
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(sprintf)(char *buf, char const *fmt, ...) STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(sprintf)(char* buf, char const* fmt, ...) {
{
int result; int result;
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
@@ -1532,12 +1553,13 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(sprintf)(char *buf, char const *fmt, .
return result; return result;
} }
typedef struct stbsp__context { typedef struct stbsp__context stbsp__context;
struct stbsp__context {
char* buf; char* buf;
int count; int count;
int length; int length;
char tmp[STB_SPRINTF_MIN]; char tmp[STB_SPRINTF_MIN];
} stbsp__context; };
static char *stbsp__clamp_callback(const char *buf, void *user, int len) static char *stbsp__clamp_callback(const char *buf, void *user, int len)
{ {