From 2e087824a37432e114d375cffefeae26214501bc Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 22 Nov 2025 15:37:59 +0100 Subject: [PATCH] Save --- build.bat | 1 - src/core/core_platform.c | 940 ++++++++++++++++++------------------- src/scratch/scratch.html | 327 ++++++------- src/scratch/scratch_main.c | 176 ++++--- 4 files changed, 728 insertions(+), 716 deletions(-) diff --git a/build.bat b/build.bat index f51706c..0b97864 100644 --- a/build.bat +++ b/build.bat @@ -2,7 +2,6 @@ for %%a in (%*) do set "%%~a=1" - set common=-I ../src/ -g -fdiagnostics-absolute-paths -Wno-unsequenced -Wno-single-bit-bitfield-constant-conversion -Wall -Wno-missing-braces -Wextra -Wno-missing-field-initializers set wasm_flags=--target=wasm32 -nostdlib -mbulk-memory -msimd128 -Wl,-export-dynamic,--allow-undefined,--import-memory,--no-entry,--initial-memory=131072000,--max-memory=4294967296 diff --git a/src/core/core_platform.c b/src/core/core_platform.c index 7f72e3b..9ef7672 100644 --- a/src/core/core_platform.c +++ b/src/core/core_platform.c @@ -1,470 +1,470 @@ -#include "core_platform.h" -#include "core_ctx.h" - -#if PLATFORM_WASM && PLATFORM_EMSCRIPTEN == 0 -#define gb_wasm_export __attribute__((visibility("default"))) -#define fn_wasm_export __attribute__((visibility("default"))) -#define fn_wasm_import - -fn_wasm_import void wasm_alert(isize ptr, i32 len); -fn_wasm_import f64 wasm_parse_float(isize str, i32 len); -fn_wasm_import void wasm_write_to_console(isize str, i32 len); - -extern char __heap_base; - -fn void *os_vmem_reserve(usize size) { - unused(size); - return NULL; -} - -fn b32 os_vmem_commit(void *p, usize size) { - unused(p); - unused(size); - return false; -} - -fn b32 os_vmem_release(void *p) { - unused(p); - return true; -} - -fn b32 os_vmem_decommit(void *p, usize size) { - unused(p); - unused(size); - return true; -} - -fn void os_error_box(char *str) { - wasm_alert((isize)str, str_len(str)); -} - -fn void os_console_log(char *str) { - s8_t string = s8_from_char(str); - if (s8_ends_with(string, s8("\n"))) { - string = s8_chop(string, 1); - } - wasm_write_to_console((isize)string.str, (i32)string.len); -} - -fn f64 os_parse_float(char *str) { - return wasm_parse_float((isize)str, str_len((char *)str)); -} - -fn void os_core_small_init(ma_arena_t *arena) { - tcx = ma_push_type(arena, thread_ctx_t); - tcx->log.break_on_error = true; - tcx->log.break_on_fatal = true; - tcx->log.break_on_warning = true; - tcx->log.print_file_and_line = true; - tcx->log.log_proc = default_log_proc; -} - -fn void os_core_init(void) { - ma_arena_t perm = {0}; - isize page_size = kib(64); - isize page_count = __builtin_wasm_memory_size(0); - u8 *memory = (u8 *)&__heap_base; - usize memory_size = page_count * (page_size) - (isize)memory; - perm.data = memory; - perm.commit = perm.reserve = memory_size; - os_core_small_init(&perm); - tcx->perm = perm; - ma_push_arena_ex(&tcx->perm, &tcx->temp, mib(16)); - ma_push_arena_ex(&tcx->perm, &tcx->scratch[0], mib(2)); - ma_push_arena_ex(&tcx->perm, &tcx->scratch[1], kib(256)); - ma_push_arena_ex(&tcx->perm, &tcx->scratch[2], kib(64)); - debugf("memory size = %lld", memory_size); -} -#elif PLATFORM_WINDOWS - #pragma comment(lib, "user32.lib") - #pragma comment(lib, "DbgHelp.lib") - #pragma comment(lib, "Shell32.lib") - #pragma comment(lib, "Ole32.lib") - #define NOMINMAX - #define WIN32_LEAN_AND_MEAN - #include - #include - #include - #include - #include - #include - #include - #include - #include - -typedef struct b_stacktrace_tag* b_stacktrace_handle; - -/* - Returns a stack-trace handle from the point of view of the caller which - can be expanded to a string via b_stacktrace_to_string. - The handle is allocated with `malloc` and needs to be freed with `free` -*/ -fn b_stacktrace_handle b_stacktrace_get(); - -/* - Converts a stack-trace handle to a human-readable string. - The string is allocated with `malloc` and needs to be freed with `free` -*/ -fn char* b_stacktrace_to_string(b_stacktrace_handle stacktrace); - -/* - Returns a human-readable stack-trace string from the point of view of the - caller. - The string is allocated with `malloc` and needs to be freed with `free` -*/ -fn char* b_stacktrace_get_string(void); - -/* version */ - -typedef struct print_buf { - char* buf; - int pos; - int size; -} print_buf; - -static print_buf buf_init(void) { - print_buf ret = { - (char*) malloc(1024), - 0, - 1024 - }; - return ret; -} - -static void buf_printf(print_buf* b, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - const int len = vsnprintf(NULL, 0, fmt, args) + 1; - va_end(args); - - const int new_end = b->pos + len; - - if (new_end > b->size) { - while (new_end > b->size) b->size *= 2; - b->buf = (char*)realloc(b->buf, b->size); - } - - va_start(args, fmt); - b->pos += vsnprintf(b->buf + b->pos, len, fmt, args); - va_end(args); -} - -char* b_stacktrace_get_string(void) { - b_stacktrace_handle h = b_stacktrace_get(); - char* ret = b_stacktrace_to_string(h); - free(h); - return ret; -} - -#define B_STACKTRACE_MAX_DEPTH 1024 - -#define B_STACKTRACE_ERROR_FLAG ((DWORD64)1 << 63) - -typedef struct b_stacktrace_entry { - DWORD64 AddrPC_Offset; - DWORD64 AddrReturn_Offset; -} b_stacktrace_entry; - -static int SymInitialize_called = 0; - -b_stacktrace_handle b_stacktrace_get(void) { - HANDLE process = GetCurrentProcess(); - HANDLE thread = GetCurrentThread(); - CONTEXT context; - STACKFRAME64 frame; /* in/out stackframe */ - DWORD imageType; - b_stacktrace_entry* ret = (b_stacktrace_entry*)malloc(B_STACKTRACE_MAX_DEPTH * sizeof(b_stacktrace_entry)); - int i = 0; - - if (!SymInitialize_called) { - SymInitialize(process, NULL, TRUE); - SymInitialize_called = 1; - } - - RtlCaptureContext(&context); - - memset(&frame, 0, sizeof(frame)); -#ifdef _M_IX86 - imageType = IMAGE_FILE_MACHINE_I386; - frame.AddrPC.Offset = context.Eip; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context.Ebp; - frame.AddrFrame.Mode = AddrModeFlat; - frame.AddrStack.Offset = context.Esp; - frame.AddrStack.Mode = AddrModeFlat; -#elif _M_X64 - imageType = IMAGE_FILE_MACHINE_AMD64; - frame.AddrPC.Offset = context.Rip; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context.Rsp; - frame.AddrFrame.Mode = AddrModeFlat; - frame.AddrStack.Offset = context.Rsp; - frame.AddrStack.Mode = AddrModeFlat; -#elif _M_IA64 - imageType = IMAGE_FILE_MACHINE_IA64; - frame.AddrPC.Offset = context.StIIP; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context.IntSp; - frame.AddrFrame.Mode = AddrModeFlat; - frame.AddrBStore.Offset = context.RsBSP; - frame.AddrBStore.Mode = AddrModeFlat; - frame.AddrStack.Offset = context.IntSp; - frame.AddrStack.Mode = AddrModeFlat; -#else - #error "Platform not supported!" -#endif - - while (1) { - b_stacktrace_entry* cur = ret + i++; - if (i == B_STACKTRACE_MAX_DEPTH) { - cur->AddrPC_Offset = 0; - cur->AddrReturn_Offset = 0; - break; - } - - if (!StackWalk64(imageType, process, thread, &frame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) { - cur->AddrPC_Offset = frame.AddrPC.Offset; - cur->AddrReturn_Offset = B_STACKTRACE_ERROR_FLAG; /* mark error */ - cur->AddrReturn_Offset |= GetLastError(); - break; - } - - cur->AddrPC_Offset = frame.AddrPC.Offset; - cur->AddrReturn_Offset = frame.AddrReturn.Offset; - - if (frame.AddrReturn.Offset == 0) { - break; - } - } - - return (b_stacktrace_handle)(ret); -} - -char* b_stacktrace_to_string(b_stacktrace_handle h) { - const b_stacktrace_entry* entries = (b_stacktrace_entry*)h; - int i = 0; - HANDLE process = GetCurrentProcess(); - print_buf out = buf_init(); - IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + 1024); - symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); - symbol->MaxNameLength = 1024; - - while (1) { - IMAGEHLP_LINE64 lineData; - DWORD lineOffset = 0; - DWORD64 symOffset = 0; - const b_stacktrace_entry* cur = entries + i++; - - if (cur->AddrReturn_Offset & B_STACKTRACE_ERROR_FLAG) { - DWORD error = cur->AddrReturn_Offset & 0xFFFFFFFF; - buf_printf(&out, "StackWalk64 error: %d @ %p\n", error, cur->AddrPC_Offset); - break; - } - - if (cur->AddrPC_Offset == cur->AddrReturn_Offset) { - buf_printf(&out, "Stack overflow @ %p\n", cur->AddrPC_Offset); - break; - } - - SymGetLineFromAddr64(process, cur->AddrPC_Offset, &lineOffset, &lineData); - buf_printf(&out, "%s(%d): ", lineData.FileName, lineData.LineNumber); - - if (SymGetSymFromAddr64(process, cur->AddrPC_Offset, &symOffset, symbol)) { - buf_printf(&out, "%s\n", symbol->Name); - } - else { - buf_printf(&out, " Unkown symbol @ %p\n", cur->AddrPC_Offset); - } - - if (cur->AddrReturn_Offset == 0) { - break; - } - } - - free(symbol); - return out.buf; -} - -fn void *os_vmem_reserve(usize size) { - void *result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE); - return result; -} - -fn b32 os_vmem_commit(void *p, usize size) { - void *result = VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE); - return result ? true : false; -} -fn b32 os_vmem_release(void *p) { - BOOL result = VirtualFree(p, 0, MEM_RELEASE); - return result ? true : false; -} - -fn b32 os_vmem_decommit(void *p, usize size) { - BOOL result = VirtualFree(p, size, MEM_DECOMMIT); - return result ? true : false; -} - -fn void os_error_box(char *str) { - OutputDebugStringA(str); - fprintf(stderr, "%s", str); - fflush(stderr); - MessageBoxA(NULL, str, "fatal error", MB_OK); -} - -fn void os_console_log(char *str) { - OutputDebugStringA(str); - fputs(str, stdout); - fflush(stdout); -} - -fn f64 os_parse_float(char *str) { - return strtod(str, NULL); -} - -fn void os_win32_crash_handler(int signal) { - printf("signal: %d\n", signal); - puts(b_stacktrace_get_string()); - exit(1); -} - -fn void os_win32_register_crash_handler() { - signal(SIGSEGV, os_win32_crash_handler); - signal(SIGABRT, os_win32_crash_handler); -} - -fn void os_core_small_init(ma_arena_t *arena) { - tcx = ma_push_type(arena, thread_ctx_t); - tcx->log.break_on_error = true; - tcx->log.break_on_fatal = true; - tcx->log.break_on_warning = true; - tcx->log.print_file_and_line = true; - tcx->log.log_proc = default_log_proc; - os_win32_register_crash_handler(); -} - -fn void os_core_init(void) { - ma_arena_t perm = {0}; - os_core_small_init(&perm); - tcx->perm = perm; -} -#elif PLATFORM_POSIX - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - -#if !PLATFORM_EMSCRIPTEN - #include - #include -#endif -fn void *os_vmem_reserve(usize size) { - void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - return result == MAP_FAILED ? NULL : result; -} - -fn b32 os_vmem_commit(void *ptr, usize size) { - mprotect(ptr, size, PROT_READ|PROT_WRITE); - return true; -} - -fn b32 os_vmem_release(void *ptr) { - int result = munmap(ptr, 0); - return result == 0 ? true : false; -} - -fn b32 os_vmem_decommit(void *ptr, usize size) { - madvise(ptr, size, MADV_DONTNEED); - mprotect(ptr, size, PROT_NONE); - return true; -} - -fn void os_error_box(char *str) { - fprintf(stderr, "%s", str); - fflush(stderr); -} - -fn void os_console_log(char *str) { - fputs(str, stdout); - fflush(stdout); -} - -fn f64 os_parse_float(char *str) { - return strtod(str, NULL); -} - -gb struct backtrace_state *backtrace_state = NULL; - -fn void os_core_backtrace_error_callback(void *data, const char *msg, int errnum) { - unused(data); - errorf("libbacktrace error: %s (errnum: %d)\n", msg, errnum); -} - -fn int os_core_backtrace_print_callback(void *data, uintptr_t pc, const char *filename, int lineno, const char *function) { - unused(data); - unused(pc); - b32 printed = false; - if (filename != NULL) { - char buffer[512]; - char *f = realpath(filename, buffer); - printf("%s:%d:1: ", f, lineno); - printed = true; - } - if (function != NULL) { - printf("%s", function); - printed = true; - } - if (printed) { - printf("\n"); - } - return 0; -} - -#if !PLATFORM_EMSCRIPTEN -fn void os_unix_crash_handler(int signal, siginfo_t* info, void* context) { - unused(context); - unused(signal); - unused(info); - backtrace_full(backtrace_state, 2, os_core_backtrace_print_callback, os_core_backtrace_error_callback, NULL); - exit(1); -} - -fn void os_unix_register_crash_handler() { - backtrace_state = backtrace_create_state(NULL, 1, os_core_backtrace_error_callback, NULL); - - struct sigaction sa; - sa.sa_sigaction = os_unix_crash_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART | SA_SIGINFO; - - sigaction(SIGSEGV, &sa, NULL); - sigaction(SIGABRT, &sa, NULL); - sigaction(SIGBUS, &sa, NULL); - sigaction(SIGILL, &sa, NULL); - sigaction(SIGFPE, &sa, NULL); -} -#endif - -fn void os_core_small_init(ma_arena_t *arena) { - tcx = ma_push_type(arena, thread_ctx_t); - tcx->log.break_on_error = true; - tcx->log.break_on_fatal = true; - tcx->log.break_on_warning = true; - tcx->log.print_file_and_line = true; - tcx->log.log_proc = default_log_proc; -#if !PLATFORM_EMSCRIPTEN - os_unix_register_crash_handler(); -#endif -} - -fn void os_core_init(void) { - ma_arena_t perm = {0}; - os_core_small_init(&perm); - tcx->perm = perm; -} -#endif +#include "core_platform.h" +#include "core_ctx.h" +#include "stb_sprintf.h" + +#if PLATFORM_WASM && PLATFORM_EMSCRIPTEN == 0 +#define gb_wasm_export __attribute__((visibility("default"))) +#define fn_wasm_export __attribute__((visibility("default"))) +#define fn_wasm_import + +fn_wasm_import void wasm_alert(isize ptr, i32 len); +fn_wasm_import f64 wasm_parse_float(isize str, i32 len); +fn_wasm_import void wasm_write_to_console(isize str, i32 len); + +extern char __heap_base; + +fn void *os_vmem_reserve(usize size) { + unused(size); + return NULL; +} + +fn b32 os_vmem_commit(void *p, usize size) { + unused(p); + unused(size); + return false; +} + +fn b32 os_vmem_release(void *p) { + unused(p); + return true; +} + +fn b32 os_vmem_decommit(void *p, usize size) { + unused(p); + unused(size); + return true; +} + +fn void os_error_box(char *str) { + wasm_alert((isize)str, str_len(str)); +} + +fn void os_console_log(char *str) { + s8_t string = s8_from_char(str); + if (s8_ends_with(string, s8("\n"))) { + string = s8_chop(string, 1); + } + wasm_write_to_console((isize)string.str, (i32)string.len); +} + +fn f64 os_parse_float(char *str) { + return wasm_parse_float((isize)str, str_len((char *)str)); +} + +fn void os_core_small_init(ma_arena_t *arena) { + tcx = ma_push_type(arena, thread_ctx_t); + tcx->log.break_on_error = true; + tcx->log.break_on_fatal = true; + tcx->log.break_on_warning = true; + tcx->log.print_file_and_line = true; + tcx->log.log_proc = default_log_proc; +} + +fn void os_core_init(void) { + ma_arena_t perm = {0}; + isize page_size = kib(64); + isize page_count = __builtin_wasm_memory_size(0); + u8 *memory = (u8 *)&__heap_base; + usize memory_size = page_count * (page_size) - (isize)memory; + perm.data = memory; + perm.commit = perm.reserve = memory_size; + os_core_small_init(&perm); + tcx->perm = perm; + ma_push_arena_ex(&tcx->perm, &tcx->temp, mib(64)); + ma_push_arena_ex(&tcx->perm, &tcx->scratch[0], mib(2)); + ma_push_arena_ex(&tcx->perm, &tcx->scratch[1], kib(256)); + ma_push_arena_ex(&tcx->perm, &tcx->scratch[2], kib(64)); + debugf("memory size = %lld", memory_size); +} +#elif PLATFORM_WINDOWS + #pragma comment(lib, "user32.lib") + #pragma comment(lib, "DbgHelp.lib") + #pragma comment(lib, "Shell32.lib") + #pragma comment(lib, "Ole32.lib") + #define NOMINMAX + #define WIN32_LEAN_AND_MEAN + #include + #include + #include + #include + #include + #include + #include + #include + #include + +typedef struct b_stacktrace_tag* b_stacktrace_handle; + +/* + Returns a stack-trace handle from the point of view of the caller which + can be expanded to a string via b_stacktrace_to_string. + The handle is allocated with `malloc` and needs to be freed with `free` +*/ +fn b_stacktrace_handle b_stacktrace_get(); + +/* + Converts a stack-trace handle to a human-readable string. + The string is allocated with `malloc` and needs to be freed with `free` +*/ +fn char* b_stacktrace_to_string(b_stacktrace_handle stacktrace); + +/* + Returns a human-readable stack-trace string from the point of view of the + caller. + The string is allocated with `malloc` and needs to be freed with `free` +*/ +fn char* b_stacktrace_get_string(void); + +/* version */ + +typedef struct print_buf { + char* buf; + int pos; + int size; +} print_buf; + +static print_buf buf_init(void) { + print_buf ret = { + (char*) malloc(1024), + 0, + 1024 + }; + return ret; +} + +static void buf_printf(print_buf* b, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + const int len = stbsp_vsnprintf(NULL, 0, fmt, args) + 1; + va_end(args); + + const int new_end = b->pos + len; + + if (new_end > b->size) { + while (new_end > b->size) b->size *= 2; + b->buf = (char*)realloc(b->buf, b->size); + } + + va_start(args, fmt); + b->pos += stbsp_vsnprintf(b->buf + b->pos, len, fmt, args); + va_end(args); +} + +char* b_stacktrace_get_string(void) { + b_stacktrace_handle h = b_stacktrace_get(); + char* ret = b_stacktrace_to_string(h); + free(h); + return ret; +} + +#define B_STACKTRACE_MAX_DEPTH 1024 +#define B_STACKTRACE_ERROR_FLAG ((DWORD64)1 << 63) + +typedef struct b_stacktrace_entry { + DWORD64 AddrPC_Offset; + DWORD64 AddrReturn_Offset; +} b_stacktrace_entry; + +static int SymInitialize_called = 0; + +b_stacktrace_handle b_stacktrace_get(void) { + HANDLE process = GetCurrentProcess(); + HANDLE thread = GetCurrentThread(); + CONTEXT context; + STACKFRAME64 frame; /* in/out stackframe */ + DWORD imageType; + b_stacktrace_entry* ret = (b_stacktrace_entry*)malloc(B_STACKTRACE_MAX_DEPTH * sizeof(b_stacktrace_entry)); + int i = 0; + + if (!SymInitialize_called) { + SymInitialize(process, NULL, TRUE); + SymInitialize_called = 1; + } + + RtlCaptureContext(&context); + + memset(&frame, 0, sizeof(frame)); +#ifdef _M_IX86 + imageType = IMAGE_FILE_MACHINE_I386; + frame.AddrPC.Offset = context.Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Esp; + frame.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + imageType = IMAGE_FILE_MACHINE_AMD64; + frame.AddrPC.Offset = context.Rip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Rsp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Rsp; + frame.AddrStack.Mode = AddrModeFlat; +#elif _M_IA64 + imageType = IMAGE_FILE_MACHINE_IA64; + frame.AddrPC.Offset = context.StIIP; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.IntSp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrBStore.Offset = context.RsBSP; + frame.AddrBStore.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.IntSp; + frame.AddrStack.Mode = AddrModeFlat; +#else + #error "Platform not supported!" +#endif + + while (1) { + b_stacktrace_entry* cur = ret + i++; + if (i == B_STACKTRACE_MAX_DEPTH) { + cur->AddrPC_Offset = 0; + cur->AddrReturn_Offset = 0; + break; + } + + if (!StackWalk64(imageType, process, thread, &frame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) { + cur->AddrPC_Offset = frame.AddrPC.Offset; + cur->AddrReturn_Offset = B_STACKTRACE_ERROR_FLAG; /* mark error */ + cur->AddrReturn_Offset |= GetLastError(); + break; + } + + cur->AddrPC_Offset = frame.AddrPC.Offset; + cur->AddrReturn_Offset = frame.AddrReturn.Offset; + + if (frame.AddrReturn.Offset == 0) { + break; + } + } + + return (b_stacktrace_handle)(ret); +} + +char* b_stacktrace_to_string(b_stacktrace_handle h) { + const b_stacktrace_entry* entries = (b_stacktrace_entry*)h; + int i = 0; + HANDLE process = GetCurrentProcess(); + print_buf out = buf_init(); + IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + 1024); + symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + symbol->MaxNameLength = 1024; + + while (1) { + IMAGEHLP_LINE64 lineData; + DWORD lineOffset = 0; + DWORD64 symOffset = 0; + const b_stacktrace_entry* cur = entries + i++; + + if (cur->AddrReturn_Offset & B_STACKTRACE_ERROR_FLAG) { + DWORD error = cur->AddrReturn_Offset & 0xFFFFFFFF; + buf_printf(&out, "StackWalk64 error: %d @ %p\n", error, cur->AddrPC_Offset); + break; + } + + if (cur->AddrPC_Offset == cur->AddrReturn_Offset) { + buf_printf(&out, "Stack overflow @ %p\n", cur->AddrPC_Offset); + break; + } + + SymGetLineFromAddr64(process, cur->AddrPC_Offset, &lineOffset, &lineData); + buf_printf(&out, "%s(%d): ", lineData.FileName, lineData.LineNumber); + + if (SymGetSymFromAddr64(process, cur->AddrPC_Offset, &symOffset, symbol)) { + buf_printf(&out, "%s\n", symbol->Name); + } + else { + buf_printf(&out, " Unkown symbol @ %p\n", cur->AddrPC_Offset); + } + + if (cur->AddrReturn_Offset == 0) { + break; + } + } + + free(symbol); + return out.buf; +} + +fn void *os_vmem_reserve(usize size) { + void *result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE); + return result; +} + +fn b32 os_vmem_commit(void *p, usize size) { + void *result = VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE); + return result ? true : false; +} +fn b32 os_vmem_release(void *p) { + BOOL result = VirtualFree(p, 0, MEM_RELEASE); + return result ? true : false; +} + +fn b32 os_vmem_decommit(void *p, usize size) { + BOOL result = VirtualFree(p, size, MEM_DECOMMIT); + return result ? true : false; +} + +fn void os_error_box(char *str) { + OutputDebugStringA(str); + fprintf(stderr, "%s", str); + fflush(stderr); + MessageBoxA(NULL, str, "fatal error", MB_OK); +} + +fn void os_console_log(char *str) { + OutputDebugStringA(str); + fputs(str, stdout); + fflush(stdout); +} + +fn f64 os_parse_float(char *str) { + return strtod(str, NULL); +} + +fn void os_win32_crash_handler(int signal) { + printf("signal: %d\n", signal); + puts(b_stacktrace_get_string()); + exit(1); +} + +fn void os_win32_register_crash_handler() { + signal(SIGSEGV, os_win32_crash_handler); + signal(SIGABRT, os_win32_crash_handler); +} + +fn void os_core_small_init(ma_arena_t *arena) { + tcx = ma_push_type(arena, thread_ctx_t); + tcx->log.break_on_error = true; + tcx->log.break_on_fatal = true; + tcx->log.break_on_warning = true; + tcx->log.print_file_and_line = true; + tcx->log.log_proc = default_log_proc; + os_win32_register_crash_handler(); +} + +fn void os_core_init(void) { + ma_arena_t perm = {0}; + os_core_small_init(&perm); + tcx->perm = perm; +} +#elif PLATFORM_POSIX + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + +#if !PLATFORM_EMSCRIPTEN + #include + #include +#endif +fn void *os_vmem_reserve(usize size) { + void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + return result == MAP_FAILED ? NULL : result; +} + +fn b32 os_vmem_commit(void *ptr, usize size) { + mprotect(ptr, size, PROT_READ|PROT_WRITE); + return true; +} + +fn b32 os_vmem_release(void *ptr) { + int result = munmap(ptr, 0); + return result == 0 ? true : false; +} + +fn b32 os_vmem_decommit(void *ptr, usize size) { + madvise(ptr, size, MADV_DONTNEED); + mprotect(ptr, size, PROT_NONE); + return true; +} + +fn void os_error_box(char *str) { + fprintf(stderr, "%s", str); + fflush(stderr); +} + +fn void os_console_log(char *str) { + fputs(str, stdout); + fflush(stdout); +} + +fn f64 os_parse_float(char *str) { + return strtod(str, NULL); +} + +gb struct backtrace_state *backtrace_state = NULL; + +fn void os_core_backtrace_error_callback(void *data, const char *msg, int errnum) { + unused(data); + errorf("libbacktrace error: %s (errnum: %d)\n", msg, errnum); +} + +fn int os_core_backtrace_print_callback(void *data, uintptr_t pc, const char *filename, int lineno, const char *function) { + unused(data); + unused(pc); + b32 printed = false; + if (filename != NULL) { + char buffer[512]; + char *f = realpath(filename, buffer); + printf("%s:%d:1: ", f, lineno); + printed = true; + } + if (function != NULL) { + printf("%s", function); + printed = true; + } + if (printed) { + printf("\n"); + } + return 0; +} + +#if !PLATFORM_EMSCRIPTEN +fn void os_unix_crash_handler(int signal, siginfo_t* info, void* context) { + unused(context); + unused(signal); + unused(info); + backtrace_full(backtrace_state, 2, os_core_backtrace_print_callback, os_core_backtrace_error_callback, NULL); + exit(1); +} + +fn void os_unix_register_crash_handler() { + backtrace_state = backtrace_create_state(NULL, 1, os_core_backtrace_error_callback, NULL); + + struct sigaction sa; + sa.sa_sigaction = os_unix_crash_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART | SA_SIGINFO; + + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGABRT, &sa, NULL); + sigaction(SIGBUS, &sa, NULL); + sigaction(SIGILL, &sa, NULL); + sigaction(SIGFPE, &sa, NULL); +} +#endif + +fn void os_core_small_init(ma_arena_t *arena) { + tcx = ma_push_type(arena, thread_ctx_t); + tcx->log.break_on_error = true; + tcx->log.break_on_fatal = true; + tcx->log.break_on_warning = true; + tcx->log.print_file_and_line = true; + tcx->log.log_proc = default_log_proc; +#if !PLATFORM_EMSCRIPTEN + os_unix_register_crash_handler(); +#endif +} + +fn void os_core_init(void) { + ma_arena_t perm = {0}; + os_core_small_init(&perm); + tcx->perm = perm; +} +#endif diff --git a/src/scratch/scratch.html b/src/scratch/scratch.html index 514a418..51984c9 100644 --- a/src/scratch/scratch.html +++ b/src/scratch/scratch.html @@ -4,57 +4,138 @@ Canvas -
-

Hello world (html)

-
-