add stacktrace, improve assert, improve debugbreak

This commit is contained in:
krzosa
2025-02-23 11:36:44 +01:00
parent 47e6dbaf79
commit e8841153c6
20 changed files with 493 additions and 31 deletions

2
.gitignore vendored
View File

@@ -5,6 +5,8 @@ multimedia.h
playground.py
ui_notes.txt
l.log
build/
*.wasm

View File

@@ -39,9 +39,9 @@ int main(int argc, char **argv) {
b32 run_server = false;
b32 core_test_target = false;
b32 win32_target = true;
b32 win32_target = false;
b32 standalone_w32_target = false;
b32 wasm_target = false;
b32 wasm_target = true;
if (run_server) {
os_systemf("start /D ..\\package ..\\package\\run_server.bat");

View File

@@ -1,4 +1,4 @@
// automatically generated using: C:\dev\wasm\src/app/app.meta.c
// automatically generated using: D:\dev\wasm\src/app/app.meta.c
type_t type__app_key_t = { type_kind_enum, s8_const_lit("app_key_t"), sizeof(app_key_t),
.members = (type_member_t[]){
@@ -228,7 +228,7 @@ app_key_t w32_map_wparam_to_app_key(WPARAM wparam) {
default: {return app_key_null;} break;
}
}
#endif/*C:\dev\wasm\src/app/app.meta.c(135)*/
#endif/*D:\dev\wasm\src/app/app.meta.c(135)*/
type_t type__app_mouse_button_t = { type_kind_enum, s8_const_lit("app_mouse_button_t"), sizeof(app_mouse_button_t),
.members = (type_member_t[]){
{.name = s8_const_lit("app_mouse_button_null"), .value = app_mouse_button_null},

View File

@@ -1,4 +1,4 @@
// automatically generated using: C:\dev\wasm\src/app/app.meta.c
// automatically generated using: D:\dev\wasm\src/app/app.meta.c
typedef enum {
app_key_null,
app_key_1,
@@ -71,7 +71,7 @@ app_key_page_up,
app_key_page_down,
app_key_count,
} app_key_t;
/*C:\dev\wasm\src/app/app.meta.c(135)*/
/*D:\dev\wasm\src/app/app.meta.c(135)*/
typedef enum {
app_mouse_button_null,
app_mouse_button_left,

View File

@@ -9,6 +9,9 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#define B_STACKTRACE_IMPL
#include "stacktrace.h"
#include "core_platform_win32.c"
#else
#include <math.h>
@@ -17,6 +20,12 @@
#include <stdlib.h>
#include <time.h>
#include <sys/mman.h>
#include <signal.h>
#define B_STACKTRACE_IMPL
#include "stacktrace.h"
//:unix_debug_break
//static void os_unix_sigtrap(int signum) { signal(SIGTRAP, SIG_DFL); }
#include "core_platform_unix.c"
#endif

View File

@@ -106,9 +106,9 @@ union convert_f32_i32_t { f32 f; i32 i; };
#define STACK_CAP(stack) (lengthof((stack).data))
#define STACK_EMPTY(stack) ((stack).len == 0)
#define STACK_FULL(stack) ((stack).len == STACK_CAP(stack))
#define STACK_PUSH(stack, ...) (assert(!STACK_FULL(stack)), (stack).data[(stack).len++] = __VA_ARGS__)
#define STACK_POP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[--(stack).len])
#define STACK_TOP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[((stack).len-1)])
#define STACK_PUSH(stack, ...) (assert_expr(!STACK_FULL(stack)), (stack).data[(stack).len++] = __VA_ARGS__)
#define STACK_POP(stack) (assert_expr(!STACK_EMPTY(stack)), (stack).data[--(stack).len])
#define STACK_TOP(stack) (assert_expr(!STACK_EMPTY(stack)), (stack).data[((stack).len-1)])
#define STRINGIFY_(S) #S
#define STRINGIFY(S) STRINGIFY_(S)
@@ -141,11 +141,14 @@ union convert_f32_i32_t { f32 f; i32 i; };
#endif
#if PLATFORM_CL
#define debug__break() __debugbreak()
#define debug__break() (IsDebuggerPresent() && (__debugbreak(), 1))
#else
#define debug__break() __builtin_trap()
//:unix_debug_break
// https://github.com/r-lyeh/tinybits/blob/master/tinyassert.c
// #define debug__break() (signal(SIGTRAP, break_handler_), raise(SIGTRAP))
#endif
#define debug_break() (debug__break(), 0)
#define debug_break() (debug__break(), 1)
#if PLATFORM_WASM
#define gb_thread
@@ -164,7 +167,7 @@ union convert_f32_i32_t { f32 f; i32 i; };
// Single linked list Queue
#define SLLQ_APPEND_EX(f, l, n, next) \
do { \
assert((n)->next == NULL); \
assert_expr((n)->next == NULL); \
if ((f) == 0) { \
(f) = (l) = (n); \
} else { \
@@ -175,7 +178,7 @@ union convert_f32_i32_t { f32 f; i32 i; };
#define SLLQ_PREPEND_EX(f, l, n, next) \
do { \
assert((n)->next == NULL); \
assert_expr((n)->next == NULL); \
if ((f) == 0) { \
(f) = (l) = (n); \
} else { \
@@ -217,8 +220,8 @@ union convert_f32_i32_t { f32 f; i32 i; };
// Doubly linked list Queue
#define DLLQ_APPEND_EX(f, l, node, next, prev) \
do { \
assert((node)->next == NULL); \
assert((node)->prev == NULL); \
assert_expr((node)->next == NULL); \
assert_expr((node)->prev == NULL); \
if ((f) == 0) { \
(f) = (l) = (node); \
} else { \
@@ -231,8 +234,8 @@ union convert_f32_i32_t { f32 f; i32 i; };
#define DLLQ_PREPEND_EX(f, l, node, next, prev) \
do { \
assert((node)->next == NULL); \
assert((node)->prev == NULL); \
assert_expr((node)->next == NULL); \
assert_expr((node)->prev == NULL); \
if ((f) == 0) { \
(f) = (l) = (node); \
} else { \
@@ -248,7 +251,7 @@ union convert_f32_i32_t { f32 f; i32 i; };
#define DLLQ_REMOVE_EX(first, last, node, next, prev) \
do { \
if ((first) == (last)) { \
assert((node) == (first)); \
assert_expr((node) == (first)); \
(first) = (last) = 0; \
} else if ((last) == (node)) { \
(last) = (last)->prev; \
@@ -270,8 +273,8 @@ union convert_f32_i32_t { f32 f; i32 i; };
// Doubly linked list Stack
#define DLLS_PUSH_EX(first, node, next, prev) \
do { \
assert((node)->next == NULL); \
assert((node)->prev == NULL); \
assert_expr((node)->next == NULL); \
assert_expr((node)->prev == NULL); \
(node)->next = (first); \
if ((first)) \
(first)->prev = (node); \

View File

@@ -26,9 +26,11 @@ fn void default_log_proc(log_level_t level, s8_t file_and_line, s8_t string);
fn void log_basef(log_level_t level, s8_t file_and_line, const char *str, ...);
#if PLATFORM_DEBUG_ASSERT
#define assert(x) (!(x) && (os_error_box(FILE_AND_LINE ": assertion failed: " #x "\n"), debug_break()))
#define assert_expr(x) (!(x) && (os_error_box(FILE_AND_LINE ": assertion failed: " #x "\n"), debug_break()))
#define assert(x) do { static int once = 1; for (;once;once=0) assert_expr(x); } while(0)
#else
#define assert(x) (void)(x)
#define assert_expr(x) (void)(x)
#define assert(x) do { (void)(x); } while(0)
#endif
#define not_implemented assert(!"not implemented!")
#define invalid_codepath assert(!"invalid code path!")

View File

@@ -33,7 +33,29 @@ fn f64 os_parse_float(char *str) {
return strtod(str, NULL);
}
fn void os_unix_crash_handler(int signal, siginfo_t* info, void* context) {
context; // unused
printf("signal: %d", signal);
if (signal == SIGSEGV) {
printf(" at addr: %p", info->si_addr);
}
puts("");
puts(b_stacktrace_get_string());
exit(1);
}
fn void os_unix_register_crash_handler() {
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);
}
fn void os_core_init(void) {
tcx->temp = ma_create(ma_default_reserve_size);
ma_init(&tcx->perm, ma_default_reserve_size);
os_unix_register_crash_handler();
}

View File

@@ -34,7 +34,19 @@ 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_init(void) {
tcx->temp = ma_create(ma_default_reserve_size);
ma_init(&tcx->perm, ma_default_reserve_size);
os_win32_register_crash_handler();
}

412
src/core/stacktrace.h Normal file
View File

@@ -0,0 +1,412 @@
#if !defined(B_STACKTRACE_INCLUDED)
#define B_STACKTRACE_INCLUDED (1)
/*
b_stacktrace v0.21 -- a cross-platform stack-trace generator
SPDX-License-Identifier: MIT
URL: https://github.com/iboB/b_stacktrace
Usage
=====
#define B_STACKTRACE_IMPL before including b_stacktrace.h in *one* C or C++
file to create the implementation
#include "b_stacktrace.h" to get access to the following functions:
char* b_stacktrace_get_string();
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`
b_stacktrace_handle b_stacktrace_get();
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`
b_stacktrace_to_string(b_stacktrace_handle stacktrace);
Converts a stack-trace handle to a human-readable string.
The string is allocated with `malloc` and needs to be freed with `free`
Config
======
#define B_STACKTRACE_API to custom export symbols to export the library
functions from a shared lib
Revision History
================
* 0.21 (2022-12-20) Fixed typo
* 0.20 (2022-12-18) Beta.
Expanded interface
Minor fixes
* 0.10 (2020-12-07) Initial public release. Alpha version
MIT License
===========
Copyright (c) 2020-2023 Borislav Stanimirov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#if !defined(B_STACKTRACE_API)
#define B_STACKTRACE_API extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
A stacktrace handle
*/
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`
*/
B_STACKTRACE_API 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`
*/
B_STACKTRACE_API 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`
*/
B_STACKTRACE_API char* b_stacktrace_get_string(void);
/* version */
#define B_STACKTRACE_VER_MAJOR 0
#define B_STACKTRACE_VER_MINOR 20
#ifdef __cplusplus
}
#endif
#if defined(B_STACKTRACE_IMPL)
#if defined(__linux__) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
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
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <TlHelp32.h>
#include <DbgHelp.h>
#pragma comment(lib, "DbgHelp.lib")
#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;
}
#elif defined(__APPLE__)
#include <execinfo.h>
#include <unistd.h>
#include <dlfcn.h>
typedef struct b_stacktrace {
void* trace[B_STACKTRACE_MAX_DEPTH];
int trace_size;
} b_stacktrace;
b_stacktrace_handle b_stacktrace_get(void) {
b_stacktrace* ret = (b_stacktrace*)malloc(sizeof(b_stacktrace));
ret->trace_size = backtrace(ret->trace, B_STACKTRACE_MAX_DEPTH);
return (b_stacktrace_handle)(ret);
}
char* b_stacktrace_to_string(b_stacktrace_handle h) {
const b_stacktrace* stacktrace = (b_stacktrace*)h;
char** messages = backtrace_symbols(stacktrace->trace, stacktrace->trace_size);
print_buf out = buf_init();
*out.buf = 0;
for (int i = 0; i < stacktrace->trace_size; ++i) {
buf_printf(&out, "%s\n", messages[i]);
}
free(messages);
return out.buf;
}
#elif defined(__linux__)
#include <execinfo.h>
#include <ucontext.h>
#include <unistd.h>
#include <dlfcn.h>
#include <string.h>
typedef struct b_stacktrace {
void* trace[B_STACKTRACE_MAX_DEPTH];
int trace_size;
} b_stacktrace;
b_stacktrace_handle b_stacktrace_get(void) {
b_stacktrace* ret = (b_stacktrace*)malloc(sizeof(b_stacktrace));
ret->trace_size = backtrace(ret->trace, B_STACKTRACE_MAX_DEPTH);
return (b_stacktrace_handle)(ret);
}
char* b_stacktrace_to_string(b_stacktrace_handle h) {
const b_stacktrace* stacktrace = (b_stacktrace*)h;
char** messages = backtrace_symbols(stacktrace->trace, stacktrace->trace_size);
print_buf out = buf_init();
for (int i = 0; i < stacktrace->trace_size; ++i) {
void* tracei = stacktrace->trace[i];
char* msg = messages[i];
/* calculate load offset */
Dl_info info;
dladdr(tracei, &info);
if (info.dli_fbase == (void*)0x400000) {
/* address from executable, so don't offset */
info.dli_fbase = NULL;
}
while (*msg && *msg != '(') ++msg;
*msg = 0;
{
char cmd[1024];
char line[2048];
FILE* fp;
snprintf(cmd, 1024, "addr2line -e %s -f -C -p %p 2>/dev/null", messages[i], (void*)((char*)tracei - (char*)info.dli_fbase));
fp = popen(cmd, "r");
if (!fp) {
buf_printf(&out, "Failed to generate trace further...\n");
break;
}
while (fgets(line, sizeof(line), fp)) {
buf_printf(&out, "%s: ", messages[i]);
if (strstr(line, "?? ")) {
/* just output address if nothing can be found */
buf_printf(&out, "%p\n", tracei);
}
else {
buf_printf(&out, "%s", line);
}
}
pclose(fp);
}
}
free(messages);
return out.buf;
}
#else
/* noop implementation */
char* b_stacktrace_get_string(void) {
print_buf out = buf_init();
buf_printf("b_stacktrace: unsupported platform\n");
return out.buf;
}
#endif /* platform */
#endif /* B_STACKTRACE_IMPL */
#endif /* B_STACKTRACE_INCLUDED */

View File

@@ -9,7 +9,7 @@
#define STBTT_cos(x) (f64_cos(x))
#define STBTT_acos(x) (f64_acos(x))
#define STBTT_fabs(x) (f64_abs(x))
#define STBTT_assert(x) (assert(x))
#define STBTT_assert(x) assert(x)
#define STBTT_malloc(x,u) (ma_push_size(tcx->temp, x))
#define STBTT_free(x,u)
#define STBTT_strlen(x) (str_len(x))

View File

@@ -1,4 +1,4 @@
// automatically generated using: C:\dev\wasm\src/render/render.meta.c
// automatically generated using: D:\dev\wasm\src/render/render.meta.c
gb_read_only u8 main_font_data[] = {
0,1,0,0,0,16,1,0,0,4,0,0,71,68,69,70,9,171,18,85,0,0,2,40,0,0,1,242,71,80,79,83,196,118,81,155,0,0,24,140,0,0,22,52,71,83,85,66,112,248,190,150,0,0,222,16,0,0,83,202,79,83,47,50,
138,149,152,224,0,0,1,200,0,0,0,96,83,84,65,84,121,145,108,221,0,0,1,96,0,0,0,46,99,109,97,112,147,243,132,151,0,0,75,136,0,0,65,218,103,97,115,112,0,0,0,16,0,0,1,20,0,0,0,8,103,108,121,102,

View File

@@ -92,7 +92,7 @@ fn b32 rn_reload_font_atlas(rn_font_t *font, s8_t font_data, rn_atlas_t *atlas,
i32 xadvance, left_side_bearing;
stbtt_GetCodepointHMetrics(&stb_font, ascii_symbol, &xadvance, &left_side_bearing);
rn_glyph_t glyph = {};
rn_glyph_t glyph = {0};
glyph.atlas_bounding_box = rn_pack_bitmap(atlas, bitmap, width, height);
glyph.size = (v2f32_t){(f32)width, (f32)height};
glyph.offset = (v2f32_t){(f32)xoff, (f32)yoff};

View File

@@ -1,5 +1,5 @@
fn rn_shader_t rn_create_shader(char *glsl_vshader, char *glsl_fshader) {
rn_shader_t result = {};
rn_shader_t result = {0};
result.vshader = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vshader);
result.fshader = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fshader);

View File

@@ -120,6 +120,7 @@ fn void test_s8(void) {
assert(s8_are_equal(s0, s8_lit("23456789")));
assert(s8_are_equal(s1, s8_lit("01")));
}
ma_destroy(arena);
}

View File

@@ -1,4 +1,4 @@
// automatically generated using: C:\dev\wasm\src/ui/ui.meta.c
// automatically generated using: D:\dev\wasm\src/ui/ui.meta.c
type_t type__ui_color_t = { type_kind_enum, s8_const_lit("ui_color_t"), sizeof(ui_color_t),
.members = (type_member_t[]){

View File

@@ -1,4 +1,4 @@
// automatically generated using: C:\dev\wasm\src/ui/ui.meta.c
// automatically generated using: D:\dev\wasm\src/ui/ui.meta.c
typedef enum {
ui_color_rect,
ui_color_rect_hot,

View File

@@ -3,7 +3,6 @@
#include "app/app.h"
#include "ui/ui.h"
#include "core/core.c"
#include "os/os.c"
#include "app/app.c"

View File

@@ -1,4 +1,4 @@
// automatically generated using: C:\dev\wasm\src/wasm_app/wasm_app.meta.c
// automatically generated using: D:\dev\wasm\src/wasm_app/wasm_app.meta.c
gb f32 font_size = 30;
gb f32 _font_size = 30;
gb_read_only mt_tweak_t tweak_table[] = {