made bh.h able to be static
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 25 Jun 2022 04:32:28 +0000 (23:32 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 25 Jun 2022 04:32:28 +0000 (23:32 -0500)
include/bh.h

index 30bb0952a7776db53697b715fb4900ef33dc8d37..08238f5053dbcc0fb410ec0920487344cb022964 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef BH_H
 #define BH_H
 
+#ifdef BH_STATIC
+    #define BH_DEF static
+#else
+    #define BH_DEF
+#endif
+
 // NOTE: For lseek64
 #define _LARGEFILE64_SOURCE
 
@@ -73,13 +79,13 @@ typedef double f64;
 //-------------------------------------------------------------------------------------
 // Better character functions
 //-------------------------------------------------------------------------------------
-b32 char_is_alpha(const char a);
-b32 char_is_num(const char a);
-b32 char_is_alphanum(const char a);
-char charset_contains(const char* charset, char ch);
-b32 char_is_whitespace(const char a);
-b32 char_in_range(const char lo, const char hi, const char a);
-i64 chars_match(char* ptr1, char* ptr2);
+BH_DEF b32 char_is_alpha(const char a);
+BH_DEF b32 char_is_num(const char a);
+BH_DEF b32 char_is_alphanum(const char a);
+BH_DEF char charset_contains(const char* charset, char ch);
+BH_DEF b32 char_is_whitespace(const char a);
+BH_DEF b32 char_in_range(const char lo, const char hi, const char a);
+BH_DEF i64 chars_match(char* ptr1, char* ptr2);
 
 
 
@@ -162,12 +168,12 @@ static inline const char* bh_num_suffix(u64 i) {
 //-------------------------------------------------------------------------------------
 
 // Converts an unsigned integer to the unsigned LEB128 format
-u8* uint_to_uleb128(u64 n, i32* output_length);
-u8* int_to_leb128(i64 n, i32* output_length);
-u8* float_to_ieee754(f32 f, b32 reverse);
-u8* double_to_ieee754(f64 f, b32 reverse);
+BH_DEF u8* uint_to_uleb128(u64 n, i32* output_length);
+BH_DEF u8* int_to_leb128(i64 n, i32* output_length);
+BH_DEF u8* float_to_ieee754(f32 f, b32 reverse);
+BH_DEF u8* double_to_ieee754(f64 f, b32 reverse);
 
-u64 uleb128_to_uint(u8* bytes, i32 *byte_walker);
+BH_DEF u64 uleb128_to_uint(u8* bytes, i32 *byte_walker);
 
 
 
@@ -225,11 +231,11 @@ typedef enum bh_allocator_flags {
     bh_allocator_flag_clear = 1    // Sets all memory to be 0
 } bh_allocator_flags;
 
-ptr bh_alloc(bh_allocator a, isize size);
-ptr bh_alloc_aligned(bh_allocator a, isize size, isize alignment);
-ptr bh_resize(bh_allocator a, ptr data, isize new_size);
-ptr bh_resize_aligned(bh_allocator a, ptr data, isize new_size, isize alignment);
-void bh_free(bh_allocator a, ptr data);
+BH_DEF ptr bh_alloc(bh_allocator a, isize size);
+BH_DEF ptr bh_alloc_aligned(bh_allocator a, isize size, isize alignment);
+BH_DEF ptr bh_resize(bh_allocator a, ptr data, isize new_size);
+BH_DEF ptr bh_resize_aligned(bh_allocator a, ptr data, isize new_size, isize alignment);
+BH_DEF void bh_free(bh_allocator a, ptr data);
 
 #define bh_alloc_item(allocator_, T)                (T *) bh_alloc(allocator_, sizeof(T))
 #define bh_alloc_array(allocator_, T, n)            (T *) bh_alloc(allocator_, sizeof(T) * (n))
@@ -242,8 +248,8 @@ void bh_free(bh_allocator a, ptr data);
 
 // HEAP ALLOCATOR
 // Essentially a wrapper for malloc, free and realloc
-bh_allocator bh_heap_allocator(void);
-BH_ALLOCATOR_PROC(bh_heap_allocator_proc);
+BH_DEF bh_allocator bh_heap_allocator(void);
+BH_DEF BH_ALLOCATOR_PROC(bh_heap_allocator_proc);
 
 
 
@@ -261,10 +267,10 @@ typedef struct bh__arena_internal {
     void* data; // Not actually a pointer, just used for the offset
 } bh__arena_internal;
 
-void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size);
-void bh_arena_free(bh_arena* alloc);
-bh_allocator bh_arena_allocator(bh_arena* alloc);
-BH_ALLOCATOR_PROC(bh_arena_allocator_proc);
+BH_DEF void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size);
+BH_DEF void bh_arena_free(bh_arena* alloc);
+BH_DEF bh_allocator bh_arena_allocator(bh_arena* alloc);
+BH_DEF BH_ALLOCATOR_PROC(bh_arena_allocator_proc);
 
 
 
@@ -277,10 +283,10 @@ typedef struct bh_scratch {
     ptr memory, end, curr;
 } bh_scratch;
 
-void bh_scratch_init(bh_scratch* scratch, bh_allocator backing, isize scratch_size);
-void bh_scratch_free(bh_scratch* scratch);
-bh_allocator bh_scratch_allocator(bh_scratch* scratch);
-BH_ALLOCATOR_PROC(bh_scratch_allocator_proc);
+BH_DEF void bh_scratch_init(bh_scratch* scratch, bh_allocator backing, isize scratch_size);
+BH_DEF void bh_scratch_free(bh_scratch* scratch);
+BH_DEF bh_allocator bh_scratch_allocator(bh_scratch* scratch);
+BH_DEF BH_ALLOCATOR_PROC(bh_scratch_allocator_proc);
 
 
 
@@ -292,9 +298,9 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc);
 // Allocator based string functions
 //-------------------------------------------------------------------------------------
 
-b32 bh_str_starts_with(char* str, char* start);
-b32 bh_str_ends_with(char* str, char* end);
-char* bh_strdup(bh_allocator a, char* str);
+BH_DEF b32 bh_str_starts_with(char* str, char* start);
+BH_DEF b32 bh_str_ends_with(char* str, char* end);
+BH_DEF char* bh_strdup(bh_allocator a, char* str);
 
 
 
@@ -358,41 +364,41 @@ typedef struct bh_file_contents {
     void* data;
 } bh_file_contents;
 
-bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand);
-
-bh_file_error bh_file_create(bh_file* file, char const* filename);
-bh_file_error bh_file_open(bh_file* file, char const* filename);
-bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* filename);
-bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename);
-b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read);
-b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote);
-i64 bh_file_seek(bh_file* file, i64 offset, bh_file_whence whence);
-i64 bh_file_seek_to(bh_file* file, i64 offset);
-i64 bh_file_seek_to_end(bh_file* file);
-i64 bh_file_skip(bh_file* file, i64 bytes);
-i64 bh_file_tell(bh_file* file);
-bh_file_error bh_file_close(bh_file* file);
-i32 bh_file_read(bh_file* file, void* buffer, isize buff_size);
-i32 bh_file_write(bh_file* file, void* buffer, isize buff_size);
-void bh_file_flush(bh_file* file);
-i64 bh_file_size(bh_file* file);
-b32 bh_file_exists(char const* filename);
-char* bh_path_get_full_name(char const* filename, bh_allocator a);
-char* bh_path_get_parent(char const* filename, bh_allocator a);
-char* bh_path_convert_separators(char* path);
+BH_DEF bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand);
+
+BH_DEF bh_file_error bh_file_create(bh_file* file, char const* filename);
+BH_DEF bh_file_error bh_file_open(bh_file* file, char const* filename);
+BH_DEF bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* filename);
+BH_DEF bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename);
+BH_DEF b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read);
+BH_DEF b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote);
+BH_DEF i64 bh_file_seek(bh_file* file, i64 offset, bh_file_whence whence);
+BH_DEF i64 bh_file_seek_to(bh_file* file, i64 offset);
+BH_DEF i64 bh_file_seek_to_end(bh_file* file);
+BH_DEF i64 bh_file_skip(bh_file* file, i64 bytes);
+BH_DEF i64 bh_file_tell(bh_file* file);
+BH_DEF bh_file_error bh_file_close(bh_file* file);
+BH_DEF i32 bh_file_read(bh_file* file, void* buffer, isize buff_size);
+BH_DEF i32 bh_file_write(bh_file* file, void* buffer, isize buff_size);
+BH_DEF void bh_file_flush(bh_file* file);
+BH_DEF i64 bh_file_size(bh_file* file);
+BH_DEF b32 bh_file_exists(char const* filename);
+BH_DEF char* bh_path_get_full_name(char const* filename, bh_allocator a);
+BH_DEF char* bh_path_get_parent(char const* filename, bh_allocator a);
+BH_DEF char* bh_path_convert_separators(char* path);
 
 // This function returns a volatile pointer. Do not store it without copying!
 // `included_folders` is bh_arr(const char *).
-char* bh_lookup_file(char* filename, char* relative_to, char *suffix, b32 add_suffix, const char ** included_folders, b32 search_included_folders);
+BH_DEF char* bh_lookup_file(char* filename, char* relative_to, char *suffix, b32 add_suffix, const char ** included_folders, b32 search_included_folders);
 
 #define bh_file_read_contents(allocator_, x) _Generic((x), \
     bh_file*: bh_file_read_contents_bh_file, \
     const char*: bh_file_read_contents_direct, \
     char*: bh_file_read_contents_direct)((allocator_), x)
 
-bh_file_contents bh_file_read_contents_bh_file(bh_allocator alloc, bh_file* file);
-bh_file_contents bh_file_read_contents_direct(bh_allocator alloc, const char* filename);
-i32 bh_file_contents_free(bh_file_contents* contents);
+BH_DEF bh_file_contents bh_file_read_contents_bh_file(bh_allocator alloc, bh_file* file);
+BH_DEF bh_file_contents bh_file_read_contents_direct(bh_allocator alloc, const char* filename);
+BH_DEF i32 bh_file_contents_free(bh_file_contents* contents);
 
 
 #ifdef _BH_WINDOWS
@@ -423,9 +429,9 @@ typedef struct bh_dirent {
     char name[256];
 } bh_dirent;
 
-bh_dir bh_dir_open(char* path);
-b32    bh_dir_read(bh_dir dir, bh_dirent* out);
-void   bh_dir_close(bh_dir dir);
+BH_DEF bh_dir bh_dir_open(char* path);
+BH_DEF b32    bh_dir_read(bh_dir dir, bh_dirent* out);
+BH_DEF void   bh_dir_close(bh_dir dir);
 
 #endif
 
@@ -461,18 +467,18 @@ typedef struct bh__print_format {
     u32 base;
 } bh__print_format;
 
-isize bh_printf(char const *fmt, ...);
-isize bh_printf_va(char const *fmt, va_list va);
-isize bh_printf_err(char const *fmt, ...);
-isize bh_printf_err_va(char const *fmt, va_list va);
-isize bh_fprintf(bh_file* f, char const *fmt, ...);
-isize bh_fprintf_va(bh_file* f, char const *fmt, va_list va);
-char* bh_bprintf(char const *fmt, ...);
-char* bh_bprintf_va(char const *fmt, va_list va);
-char* bh_aprintf(bh_allocator alloc, const char* fmt, ...);
-char* bh_aprintf_va(bh_allocator alloc, const char* fmt, va_list va);
-isize bh_snprintf(char *str, isize n, char const *fmt, ...);
-isize bh_snprintf_va(char *str, isize n, char const *fmt, va_list va);
+BH_DEF isize bh_printf(char const *fmt, ...);
+BH_DEF isize bh_printf_va(char const *fmt, va_list va);
+BH_DEF isize bh_printf_err(char const *fmt, ...);
+BH_DEF isize bh_printf_err_va(char const *fmt, va_list va);
+BH_DEF isize bh_fprintf(bh_file* f, char const *fmt, ...);
+BH_DEF isize bh_fprintf_va(bh_file* f, char const *fmt, va_list va);
+BH_DEF char* bh_bprintf(char const *fmt, ...);
+BH_DEF char* bh_bprintf_va(char const *fmt, va_list va);
+BH_DEF char* bh_aprintf(bh_allocator alloc, const char* fmt, ...);
+BH_DEF char* bh_aprintf_va(bh_allocator alloc, const char* fmt, va_list va);
+BH_DEF isize bh_snprintf(char *str, isize n, char const *fmt, ...);
+BH_DEF isize bh_snprintf_va(char *str, isize n, char const *fmt, va_list va);
 
 
 
@@ -506,15 +512,15 @@ typedef struct bh_buffer {
 #define BH_BUFFER_GROW_FORMULA(x)            ((x) > 0 ? ((x) << 1) : 16)
 #endif
 
-void bh_buffer_init(bh_buffer* buffer, bh_allocator alloc, i32 length);
-void bh_buffer_free(bh_buffer* buffer);
-void bh_buffer_grow(bh_buffer* buffer, i32 length);
-void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length);
-void bh_buffer_concat(bh_buffer* buffer, bh_buffer other);
-void bh_buffer_write_byte(bh_buffer* buffer, u8 byte);
-void bh_buffer_write_u32(bh_buffer* buffer, u32 i);
-void bh_buffer_write_u64(bh_buffer* buffer, u64 i);
-void bh_buffer_align(bh_buffer* buffer, u32 alignment);
+BH_DEF void bh_buffer_init(bh_buffer* buffer, bh_allocator alloc, i32 length);
+BH_DEF void bh_buffer_free(bh_buffer* buffer);
+BH_DEF void bh_buffer_grow(bh_buffer* buffer, i32 length);
+BH_DEF void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length);
+BH_DEF void bh_buffer_concat(bh_buffer* buffer, bh_buffer other);
+BH_DEF void bh_buffer_write_byte(bh_buffer* buffer, u8 byte);
+BH_DEF void bh_buffer_write_u32(bh_buffer* buffer, u32 i);
+BH_DEF void bh_buffer_write_u64(bh_buffer* buffer, u64 i);
+BH_DEF void bh_buffer_align(bh_buffer* buffer, u32 alignment);
 
 
 
@@ -592,12 +598,12 @@ typedef struct bh__arr {
 
 #define bh_arr_zero(arr) memset(arr, 0, bh_arr_length(arr) * sizeof(*(arr)));
 
-b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap);
-b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap);
-b32 bh__arr_free(void **arr);
-void* bh__arr_copy(bh_allocator alloc, void *arr, i32 elemsize);
-void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems);
-void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems);
+BH_DEF b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap);
+BH_DEF b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap);
+BH_DEF b32 bh__arr_free(void **arr);
+BH_DEF void* bh__arr_copy(bh_allocator alloc, void *arr, i32 elemsize);
+BH_DEF void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems);
+BH_DEF void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems);
 
 #endif
 
@@ -678,15 +684,15 @@ typedef struct bh__table {
         T value = bh_table_iter_value(T, it);
 #define bh_table_each_end            } }
 
-b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size);
-b32 bh__table_free(bh__table **table);
-ptr bh__table_put(bh__table *table, i32 elemsize, char *key);
-b32 bh__table_has(bh__table *table, i32 elemsize, char *key);
-ptr bh__table_get(bh__table *table, i32 elemsize, char *key);
-void bh__table_delete(bh__table *table, i32 elemsize, char *key);
-void bh__table_clear(bh__table *table);
-bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize);
-b32 bh_table_iter_next(bh_table_iterator* it);
+BH_DEF b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size);
+BH_DEF b32 bh__table_free(bh__table **table);
+BH_DEF ptr bh__table_put(bh__table *table, i32 elemsize, char *key);
+BH_DEF b32 bh__table_has(bh__table *table, i32 elemsize, char *key);
+BH_DEF ptr bh__table_get(bh__table *table, i32 elemsize, char *key);
+BH_DEF void bh__table_delete(bh__table *table, i32 elemsize, char *key);
+BH_DEF void bh__table_clear(bh__table *table);
+BH_DEF bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize);
+BH_DEF b32 bh_table_iter_next(bh_table_iterator* it);
 
 #endif
 // Using stb_ds for tables now because they are better in every single way.
@@ -725,13 +731,13 @@ typedef struct bh_imap {
 } bh_imap;
 
 
-void bh_imap_init(bh_imap* imap, bh_allocator alloc, i32 hash_count);
-void bh_imap_free(bh_imap* imap);
-void bh_imap_put(bh_imap* imap, bh_imap_entry_t key, bh_imap_entry_t value);
-b32 bh_imap_has(bh_imap* imap, bh_imap_entry_t key);
-bh_imap_entry_t bh_imap_get(bh_imap* imap, bh_imap_entry_t key);
-void bh_imap_delete(bh_imap* imap, bh_imap_entry_t key);
-void bh_imap_clear(bh_imap* imap);
+BH_DEF void bh_imap_init(bh_imap* imap, bh_allocator alloc, i32 hash_count);
+BH_DEF void bh_imap_free(bh_imap* imap);
+BH_DEF void bh_imap_put(bh_imap* imap, bh_imap_entry_t key, bh_imap_entry_t value);
+BH_DEF b32 bh_imap_has(bh_imap* imap, bh_imap_entry_t key);
+BH_DEF bh_imap_entry_t bh_imap_get(bh_imap* imap, bh_imap_entry_t key);
+BH_DEF void bh_imap_delete(bh_imap* imap, bh_imap_entry_t key);
+BH_DEF void bh_imap_clear(bh_imap* imap);
 
 #ifdef BH_DEFINE
 #endif // BH_DEFINE
@@ -754,10 +760,10 @@ typedef struct bh_managed_heap {
     bh_imap ptrs;
 } bh_managed_heap;
 
-void bh_managed_heap_init(bh_managed_heap* mh);
-void bh_managed_heap_free(bh_managed_heap* mh);
-bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh);
-BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc);
+BH_DEF void bh_managed_heap_init(bh_managed_heap* mh);
+BH_DEF void bh_managed_heap_free(bh_managed_heap* mh);
+BH_DEF bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh);
+BH_DEF BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc);
 
 
 
@@ -798,8 +804,8 @@ BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc);
 //------------------------------------------------------------------------------
 // TIME / DURATION
 //------------------------------------------------------------------------------
-u64 bh_time_curr();
-u64 bh_time_duration(u64 old);
+BH_DEF u64 bh_time_curr();
+BH_DEF u64 bh_time_duration(u64 old);
 
 
 
@@ -822,11 +828,11 @@ u64 bh_time_duration(u64 old);
 // CHAR FUNCTIONS
 //-------------------------------------------------------------------------------------
 
-b32 char_is_alpha(const char a) {
+BH_DEF b32 char_is_alpha(const char a) {
     return ('a' <= a && a <= 'z') || ('A' <= a && a <= 'Z');
 }
 
-char charset_contains(const char* charset, char ch) {
+BH_DEF char charset_contains(const char* charset, char ch) {
     while (*charset) {
         if (*charset == ch) return ch;
         charset++;
@@ -835,23 +841,23 @@ char charset_contains(const char* charset, char ch) {
     return 0;
 }
 
-b32 char_is_num(const char a) {
+BH_DEF b32 char_is_num(const char a) {
     return ('0' <= a && a <= '9');
 }
 
-b32 char_is_alphanum(const char a) {
+BH_DEF b32 char_is_alphanum(const char a) {
     return char_is_alpha(a) || char_is_num(a);
 }
 
-b32 char_is_whitespace(const char a) {
+BH_DEF b32 char_is_whitespace(const char a) {
     return charset_contains(" \t\r\n", a);
 }
 
-b32 char_in_range(const char lo, const char hi, const char a) {
+BH_DEF b32 char_in_range(const char lo, const char hi, const char a) {
     return lo <= a && a <= hi;
 }
 
-i64 chars_match(char* ptr1, char* ptr2) {
+BH_DEF i64 chars_match(char* ptr1, char* ptr2) {
     i64 len = 0;
     while (*ptr2 != '\0' && *ptr1 == *ptr2) ptr1++, ptr2++, len++;
     return *ptr2 == '\0' ? len : 0;
@@ -867,37 +873,37 @@ i64 chars_match(char* ptr1, char* ptr2) {
 //-------------------------------------------------------------------------------------
 // CUSTOM ALLOCATORS IMPLEMENTATION
 //-------------------------------------------------------------------------------------
-ptr bh_alloc(bh_allocator a, isize size) {
+BH_DEF ptr bh_alloc(bh_allocator a, isize size) {
     return bh_alloc_aligned(a, size, 16);
 }
 
-ptr bh_alloc_aligned(bh_allocator a, isize size, isize alignment) {
+BH_DEF ptr bh_alloc_aligned(bh_allocator a, isize size, isize alignment) {
     return a.proc(a.data, bh_allocator_action_alloc, size, alignment, NULL,  0);
 }
 
-ptr bh_resize(bh_allocator a, ptr data, isize new_size) {
+BH_DEF ptr bh_resize(bh_allocator a, ptr data, isize new_size) {
     return bh_resize_aligned(a, data, new_size, 16);
 }
 
-ptr bh_resize_aligned(bh_allocator a, ptr data, isize new_size, isize alignment) {
+BH_DEF ptr bh_resize_aligned(bh_allocator a, ptr data, isize new_size, isize alignment) {
     return a.proc(a.data, bh_allocator_action_resize, new_size, alignment, data, 0);
 }
 
-void bh_free(bh_allocator a, ptr data) {
+BH_DEF void bh_free(bh_allocator a, ptr data) {
     if (data != NULL) a.proc(a.data, bh_allocator_action_free, 0, 0, data, 0);
 }
 
 
 
 // HEAP ALLOCATOR IMPLEMENTATION
-bh_allocator bh_heap_allocator(void) {
+BH_DEF bh_allocator bh_heap_allocator(void) {
     return (bh_allocator) {
         .proc = bh_heap_allocator_proc,
         .data = NULL
     };
 }
 
-BH_ALLOCATOR_PROC(bh_heap_allocator_proc) {
+BH_DEF BH_ALLOCATOR_PROC(bh_heap_allocator_proc) {
     ptr retval = NULL;
 
     switch (action) {
@@ -939,11 +945,11 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc) {
 
 
 // MANAGED HEAP ALLOCATOR IMPLEMENTATION
-void bh_managed_heap_init(bh_managed_heap* mh) {
+BH_DEF void bh_managed_heap_init(bh_managed_heap* mh) {
     bh_imap_init(&mh->ptrs, bh_heap_allocator(), 512);
 }
 
-void bh_managed_heap_free(bh_managed_heap* mh) {
+BH_DEF void bh_managed_heap_free(bh_managed_heap* mh) {
     bh_arr_each(bh__imap_entry, p, mh->ptrs.entries) {
 #if defined(_BH_WINDOWS)
         _aligned_free((void *) p->key);
@@ -955,14 +961,14 @@ void bh_managed_heap_free(bh_managed_heap* mh) {
     bh_imap_free(&mh->ptrs);
 }
 
-bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh) {
+BH_DEF bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh) {
     return (bh_allocator) {
         .proc = bh_managed_heap_allocator_proc,
         .data = mh
     };
 }
 
-BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc) {
+BH_DEF BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc) {
     bh_managed_heap* mh = (bh_managed_heap *) data;
     ptr retval = NULL;
 
@@ -1013,7 +1019,7 @@ BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc) {
 
 
 // ARENA ALLOCATOR IMPLEMENTATION
-void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size) {
+BH_DEF void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size) {
     arena_size = bh_max(arena_size, size_of(ptr));
     ptr data = bh_alloc(backing, arena_size);
 
@@ -1026,7 +1032,7 @@ void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size) {
     ((bh__arena_internal *)(alloc->first_arena))->next_arena = NULL;
 }
 
-void bh_arena_free(bh_arena* alloc) {
+BH_DEF void bh_arena_free(bh_arena* alloc) {
     bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena;
     bh__arena_internal *trailer = walker;
     while (walker != NULL) {
@@ -1041,14 +1047,14 @@ void bh_arena_free(bh_arena* alloc) {
     alloc->size = 0;
 }
 
-bh_allocator bh_arena_allocator(bh_arena* alloc) {
+BH_DEF bh_allocator bh_arena_allocator(bh_arena* alloc) {
     return (bh_allocator) {
         .proc = bh_arena_allocator_proc,
         .data = alloc,
     };
 }
 
-BH_ALLOCATOR_PROC(bh_arena_allocator_proc) {
+BH_DEF BH_ALLOCATOR_PROC(bh_arena_allocator_proc) {
     bh_arena* alloc_arena = (bh_arena*) data;
 
     ptr retval = NULL;
@@ -1097,7 +1103,7 @@ BH_ALLOCATOR_PROC(bh_arena_allocator_proc) {
 
 
 // SCRATCH ALLOCATOR IMPLEMENTATION
-void bh_scratch_init(bh_scratch* scratch, bh_allocator backing, isize scratch_size) {
+BH_DEF void bh_scratch_init(bh_scratch* scratch, bh_allocator backing, isize scratch_size) {
     ptr memory = bh_alloc(backing, scratch_size);
 
     scratch->backing = backing;
@@ -1106,7 +1112,7 @@ void bh_scratch_init(bh_scratch* scratch, bh_allocator backing, isize scratch_si
     scratch->end = bh_pointer_add(memory, scratch_size);
 }
 
-void bh_scratch_free(bh_scratch* scratch) {
+BH_DEF void bh_scratch_free(bh_scratch* scratch) {
     bh_free(scratch->backing, scratch->memory);
 
     scratch->memory = NULL;
@@ -1114,14 +1120,14 @@ void bh_scratch_free(bh_scratch* scratch) {
     scratch->end = NULL;
 }
 
-bh_allocator bh_scratch_allocator(bh_scratch* scratch) {
+BH_DEF bh_allocator bh_scratch_allocator(bh_scratch* scratch) {
     return (bh_allocator) {
         .proc = bh_scratch_allocator_proc,
         .data = scratch,
     };
 }
 
-BH_ALLOCATOR_PROC(bh_scratch_allocator_proc) {
+BH_DEF BH_ALLOCATOR_PROC(bh_scratch_allocator_proc) {
     bh_scratch* scratch = (bh_scratch*) data;
     ptr retval = NULL;
 
@@ -1169,7 +1175,7 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc) {
 //-------------------------------------------------------------------------------------
 // CONVERSION FUNCTIONS IMPLEMENTATION
 //-------------------------------------------------------------------------------------
-u8* uint_to_uleb128(u64 n, i32* output_length) {
+BH_DEF u8* uint_to_uleb128(u64 n, i32* output_length) {
     static u8 buffer[16];
 
     *output_length = 0;
@@ -1188,7 +1194,7 @@ u8* uint_to_uleb128(u64 n, i32* output_length) {
 
 
 // Converts a signed integer to the signed LEB128 format
-u8* int_to_leb128(i64 n, i32* output_length) {
+BH_DEF u8* int_to_leb128(i64 n, i32* output_length) {
     static u8 buffer[16];
 
     *output_length = 0;
@@ -1214,7 +1220,7 @@ u8* int_to_leb128(i64 n, i32* output_length) {
 
 // NOTE: This assumes the underlying implementation of float on the host
 // system is already IEEE-754. This is safe to assume in most cases.
-u8* float_to_ieee754(f32 f, b32 reverse) {
+BH_DEF u8* float_to_ieee754(f32 f, b32 reverse) {
     static u8 buffer[4];
 
     u8* fmem = (u8*) &f;
@@ -1233,7 +1239,7 @@ u8* float_to_ieee754(f32 f, b32 reverse) {
     return buffer;
 }
 
-u8* double_to_ieee754(f64 f, b32 reverse) {
+BH_DEF u8* double_to_ieee754(f64 f, b32 reverse) {
     static u8 buffer[8];
 
     u8* fmem = (u8*) &f;
@@ -1260,7 +1266,7 @@ u8* double_to_ieee754(f64 f, b32 reverse) {
     return buffer;
 }
 
-u64 uleb128_to_uint(u8* bytes, i32 *byte_count) {
+BH_DEF u64 uleb128_to_uint(u8* bytes, i32 *byte_count) {
     u64 res = 0;
     u64 shift = 0;
 
@@ -1278,7 +1284,7 @@ u64 uleb128_to_uint(u8* bytes, i32 *byte_count) {
 //-------------------------------------------------------------------------------------
 // STRING IMPLEMENTATION
 //-------------------------------------------------------------------------------------
-b32 bh_str_starts_with(char* str, char* start) {
+BH_DEF b32 bh_str_starts_with(char* str, char* start) {
     char* s = str;
     char* p = start;
 
@@ -1287,7 +1293,7 @@ b32 bh_str_starts_with(char* str, char* start) {
     return *p == '\0';
 }
 
-b32 bh_str_ends_with(char* str, char* end) {
+BH_DEF b32 bh_str_ends_with(char* str, char* end) {
     i32 slen = strlen(str);
     i32 elen = strlen(end);
 
@@ -1299,7 +1305,7 @@ b32 bh_str_ends_with(char* str, char* end) {
     return *e == *s;
 }
 
-char* bh_strdup(bh_allocator a, char* str) {
+BH_DEF char* bh_strdup(bh_allocator a, char* str) {
     u32 len = strlen(str);
     char* buf = bh_alloc(a, len + 1);
 
@@ -1319,7 +1325,7 @@ char* bh_strdup(bh_allocator a, char* str) {
 
 static b32 bh__file_seek_wrapper(bh_file_descriptor fd, i64 offset, bh_file_whence whence, i64* new_offset);
 
-bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand) {
+BH_DEF bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand) {
     const char* filename = NULL;
 
 #if defined(_BH_WINDOWS)
@@ -1371,17 +1377,17 @@ bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand) {
     return BH_FILE_ERROR_NONE;
 }
 
-bh_file_error bh_file_create(bh_file* file, const char* filename) {
+BH_DEF bh_file_error bh_file_create(bh_file* file, const char* filename) {
     // Need to do this to avoid compiler complaining about types
     bh_file_mode write_rw = (bh_file_mode) (BH_FILE_MODE_WRITE | BH_FILE_MODE_RW);
     return bh_file_open_mode(file, write_rw, filename);
 }
 
-bh_file_error bh_file_open(bh_file* file, const char* filename) {
+BH_DEF bh_file_error bh_file_open(bh_file* file, const char* filename) {
     return bh_file_open_mode(file, BH_FILE_MODE_READ, filename);
 }
 
-bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* filename) {
+BH_DEF bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* filename) {
 #if defined(_BH_WINDOWS)
     DWORD desired_access;
     DWORD creation_disposition;
@@ -1458,13 +1464,13 @@ bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* fi
 #endif
 }
 
-bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename) {
+BH_DEF bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename) {
     file->filename = filename; // This may be unsafe
     file->fd = fd;
     return BH_FILE_ERROR_NONE;
 }
 
-b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read) {
+BH_DEF b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read) {
 #if defined(_BH_WINDOWS)
     bh_file_seek_to(file, offset);
     BOOL res = ReadFile(file->fd, buffer, buff_size, (i32 *) bytes_read, NULL);
@@ -1491,7 +1497,7 @@ b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, is
 #endif
 }
 
-b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote) {
+BH_DEF b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote) {
     isize res;
     i64 current_offset = 0;
     bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_CURRENT, &current_offset);
@@ -1535,37 +1541,37 @@ static b32 bh__file_seek_wrapper(bh_file_descriptor fd, i64 offset, bh_file_when
 }
 
 // Returns new offset
-i64 bh_file_seek(bh_file* file, i64 offset, bh_file_whence whence) {
+BH_DEF i64 bh_file_seek(bh_file* file, i64 offset, bh_file_whence whence) {
     i64 new_offset = -1;
     bh__file_seek_wrapper(file->fd, offset, whence, &new_offset);
     return new_offset;
 }
 
-i64 bh_file_seek_to(bh_file* file, i64 offset) {
+BH_DEF i64 bh_file_seek_to(bh_file* file, i64 offset) {
     i64 new_offset = -1;
     bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_BEGIN, &new_offset);
     return new_offset;
 }
 
-i64 bh_file_seek_to_end(bh_file* file) {
+BH_DEF i64 bh_file_seek_to_end(bh_file* file) {
     i64 new_offset = -1;
     bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_END, &new_offset);
     return new_offset;
 }
 
-i64 bh_file_skip(bh_file* file, i64 bytes) {
+BH_DEF i64 bh_file_skip(bh_file* file, i64 bytes) {
     i64 new_offset = 0;
     bh__file_seek_wrapper(file->fd, bytes, BH_FILE_WHENCE_CURRENT, &new_offset);
     return new_offset;
 }
 
-i64 bh_file_tell(bh_file* file) {
+BH_DEF i64 bh_file_tell(bh_file* file) {
     i64 new_offset = 0;
     bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_CURRENT, &new_offset);
     return new_offset;
 }
 
-bh_file_error bh_file_close(bh_file* file) {
+BH_DEF bh_file_error bh_file_close(bh_file* file) {
     bh_file_error err = BH_FILE_ERROR_NONE;
 
 #if defined(_BH_WINDOWS)
@@ -1583,21 +1589,21 @@ bh_file_error bh_file_close(bh_file* file) {
 #endif
 }
 
-b32 bh_file_read(bh_file* file, void* buffer, isize buff_size) {
+BH_DEF b32 bh_file_read(bh_file* file, void* buffer, isize buff_size) {
     return bh_file_read_at(file, bh_file_tell(file), buffer, buff_size, NULL);
 }
 
-b32 bh_file_write(bh_file* file, void* buffer, isize buff_size) {
+BH_DEF b32 bh_file_write(bh_file* file, void* buffer, isize buff_size) {
     return bh_file_write_at(file, bh_file_tell(file), buffer, buff_size, NULL);
 }
 
-void bh_file_flush(bh_file* file) {
+BH_DEF void bh_file_flush(bh_file* file) {
     #ifdef _BH_LINUX
     fdatasync(file->fd);
     #endif
 }
 
-i64 bh_file_size(bh_file* file) {
+BH_DEF i64 bh_file_size(bh_file* file) {
     i64 size = 0;
     i64 prev = bh_file_tell(file);
     bh_file_seek_to_end(file);
@@ -1606,7 +1612,7 @@ i64 bh_file_size(bh_file* file) {
     return size;
 }
 
-bh_file_contents bh_file_read_contents_bh_file(bh_allocator alloc, bh_file* file) {
+BH_DEF bh_file_contents bh_file_read_contents_bh_file(bh_allocator alloc, bh_file* file) {
     bh_file_contents fc = {
         .allocator = alloc,
         .filename  = bh_strdup(alloc, (char *) file->filename),
@@ -1624,7 +1630,7 @@ bh_file_contents bh_file_read_contents_bh_file(bh_allocator alloc, bh_file* file
     return fc;
 }
 
-bh_file_contents bh_file_read_contents_direct(bh_allocator alloc, const char* filename) {
+BH_DEF bh_file_contents bh_file_read_contents_direct(bh_allocator alloc, const char* filename) {
     bh_file file;
     bh_file_open(&file, filename);
     bh_file_contents fc = bh_file_read_contents(alloc, &file);
@@ -1632,18 +1638,18 @@ bh_file_contents bh_file_read_contents_direct(bh_allocator alloc, const char* fi
     return fc;
 }
 
-b32 bh_file_contents_free(bh_file_contents* contents) {
+BH_DEF b32 bh_file_contents_free(bh_file_contents* contents) {
     bh_free(contents->allocator, contents->data);
     contents->length = 0;
     return 1;
 }
 
-b32 bh_file_exists(char const* filename) {
+BH_DEF b32 bh_file_exists(char const* filename) {
     struct stat s;
     return stat(filename, &s) != -1;
 }
 
-char* bh_path_get_full_name(char const* filename, bh_allocator a) {
+BH_DEF char* bh_path_get_full_name(char const* filename, bh_allocator a) {
 #if defined(_BH_WINDOWS)
     char buffer[4096];
     GetFullPathNameA(filename, 4096, buffer, NULL);
@@ -1679,7 +1685,7 @@ char* bh_path_get_full_name(char const* filename, bh_allocator a) {
 #elif defined(_BH_WINDOWS)
     #define DIR_SEPARATOR '\\'
 #endif
-char* bh_path_get_parent(char const* filename, bh_allocator a) {
+BH_DEF char* bh_path_get_parent(char const* filename, bh_allocator a) {
 
     char* result = bh_strdup(a, (char *) filename);
     char* end = result + strlen(result);
@@ -1689,7 +1695,7 @@ char* bh_path_get_parent(char const* filename, bh_allocator a) {
 }
 
 // This function returns a volatile pointer. Do not store it without copying!
-char* bh_lookup_file(char* filename, char* relative_to, char *suffix, b32 add_suffix, bh_arr(const char *) included_folders, b32 search_included_folders) {
+BH_DEF char* bh_lookup_file(char* filename, char* relative_to, char *suffix, b32 add_suffix, bh_arr(const char *) included_folders, b32 search_included_folders) {
     assert(relative_to != NULL);
 
     static char path[512];
@@ -1733,7 +1739,7 @@ char* bh_lookup_file(char* filename, char* relative_to, char *suffix, b32 add_su
 
 //
 // Modifies the path in-place.
-char* bh_path_convert_separators(char* path) {
+BH_DEF char* bh_path_convert_separators(char* path) {
 #if defined(_BH_LINUX)
     #define DIR_SEPARATOR '/'
     #define OTHER_SEPARATOR '\\'
@@ -1752,7 +1758,7 @@ char* bh_path_convert_separators(char* path) {
 }
 
 
-bh_dir bh_dir_open(char* path) {
+BH_DEF bh_dir bh_dir_open(char* path) {
 #ifdef _BH_WINDOWS
     char new_path[512] = { 0 };
     strncpy(new_path, path, 511);
@@ -1774,7 +1780,7 @@ bh_dir bh_dir_open(char* path) {
 #endif
 }
 
-b32 bh_dir_read(bh_dir dir, bh_dirent* out) {
+BH_DEF b32 bh_dir_read(bh_dir dir, bh_dirent* out) {
 
 #ifdef _BH_WINDOWS
     do {
@@ -1825,7 +1831,7 @@ b32 bh_dir_read(bh_dir dir, bh_dirent* out) {
 #endif
 }
 
-void bh_dir_close(bh_dir dir) {
+BH_DEF void bh_dir_close(bh_dir dir) {
 #ifdef _BH_WINDOWS
     if (dir == NULL) return;
 
@@ -1863,7 +1869,7 @@ void bh_dir_close(bh_dir dir) {
 //-------------------------------------------------------------------------------------
 // ALTERNATE PRINTF IMPLEMENTATION
 //-------------------------------------------------------------------------------------
-isize bh_printf(char const *fmt, ...) {
+BH_DEF isize bh_printf(char const *fmt, ...) {
     isize res;
     va_list va;
     va_start(va, fmt);
@@ -1872,13 +1878,13 @@ isize bh_printf(char const *fmt, ...) {
     return res;
 }
 
-isize bh_printf_va(char const *fmt, va_list va) {
+BH_DEF isize bh_printf_va(char const *fmt, va_list va) {
     bh_file file;
     bh_file_get_standard(&file, BH_FILE_STANDARD_OUTPUT);
     return bh_fprintf_va(&file, fmt, va);
 }
 
-isize bh_printf_err(char const *fmt, ...) {
+BH_DEF isize bh_printf_err(char const *fmt, ...) {
     isize res;
     va_list va;
     va_start(va, fmt);
@@ -1887,13 +1893,13 @@ isize bh_printf_err(char const *fmt, ...) {
     return res;
 }
 
-isize bh_printf_err_va(char const *fmt, va_list va) {
+BH_DEF isize bh_printf_err_va(char const *fmt, va_list va) {
     bh_file file;
     bh_file_get_standard(&file, BH_FILE_STANDARD_ERROR);
     return bh_fprintf_va(&file, fmt, va);
 }
 
-isize bh_fprintf(bh_file* f, char const *fmt, ...) {
+BH_DEF isize bh_fprintf(bh_file* f, char const *fmt, ...) {
     isize res;
     va_list va;
     va_start(va, fmt);
@@ -1902,14 +1908,14 @@ isize bh_fprintf(bh_file* f, char const *fmt, ...) {
     return res;
 }
 
-isize bh_fprintf_va(bh_file* f, char const *fmt, va_list va) {
+BH_DEF isize bh_fprintf_va(bh_file* f, char const *fmt, va_list va) {
     static char buffer[4096];
     isize len = bh_snprintf_va(buffer, sizeof(buffer), fmt, va);
     bh_file_write(f, buffer, len - 1);
     return len;
 }
 
-char* bh_bprintf(char const *fmt, ...) {
+BH_DEF char* bh_bprintf(char const *fmt, ...) {
     char* res;
     va_list va;
     va_start(va, fmt);
@@ -1918,14 +1924,14 @@ char* bh_bprintf(char const *fmt, ...) {
     return res;
 }
 
-char* bh_bprintf_va(char const *fmt, va_list va) {
+BH_DEF char* bh_bprintf_va(char const *fmt, va_list va) {
     static char buffer[4096];
     isize len = bh_snprintf_va(buffer, sizeof(buffer), fmt, va);
     buffer[len - 1] = 0;
     return buffer;
 }
 
-char* bh_aprintf(bh_allocator alloc, const char* fmt, ...) {
+BH_DEF char* bh_aprintf(bh_allocator alloc, const char* fmt, ...) {
     char* res;
     va_list va;
     va_start(va, fmt);
@@ -1934,7 +1940,7 @@ char* bh_aprintf(bh_allocator alloc, const char* fmt, ...) {
     return res;
 }
 
-char* bh_aprintf_va(bh_allocator alloc, const char* fmt, va_list va) {
+BH_DEF char* bh_aprintf_va(bh_allocator alloc, const char* fmt, va_list va) {
     static char buffer[4096];
     isize len = bh_snprintf_va(buffer, sizeof(buffer), fmt, va);
     char* res = bh_alloc(alloc, len);
@@ -1943,7 +1949,7 @@ char* bh_aprintf_va(bh_allocator alloc, const char* fmt, va_list va) {
     return res;
 }
 
-isize bh_snprintf(char *str, isize n, char const *fmt, ...) {
+BH_DEF isize bh_snprintf(char *str, isize n, char const *fmt, ...) {
     isize res;
     va_list va;
     va_start(va, fmt);
@@ -1952,13 +1958,13 @@ isize bh_snprintf(char *str, isize n, char const *fmt, ...) {
     return res;
 }
 
-isize bh__print_string(char* dest, isize n, char* src) {
+BH_DEF isize bh__print_string(char* dest, isize n, char* src) {
     isize len = 0;
     while (n-- && (*dest++ = *src++)) len++;
     return len;
 }
 
-isize bh__printu64(char* str, isize n, bh__print_format format, u64 value) {
+BH_DEF isize bh__printu64(char* str, isize n, bh__print_format format, u64 value) {
     char buf[128];
     buf[127] = 0;
     char* walker = buf + 127;
@@ -1991,7 +1997,7 @@ isize bh__printu64(char* str, isize n, bh__print_format format, u64 value) {
     return bh__print_string(str, n, walker);
 }
 
-isize bh__printi64(char* str, isize n, bh__print_format format, i64 value) {
+BH_DEF isize bh__printi64(char* str, isize n, bh__print_format format, i64 value) {
     char buf[128];
     buf[127] = 0;
     char* walker = buf + 127;
@@ -2036,7 +2042,7 @@ isize bh__printi64(char* str, isize n, bh__print_format format, i64 value) {
 }
 
 // TODO: This implementation is VERY VERY BAD AND WRONG. Fix it.
-isize bh__printf64(char* str, isize n, f64 value) {
+BH_DEF isize bh__printf64(char* str, isize n, f64 value) {
     fori (i, 0, 6) value *= 10.0;
     i64 v = (i64) value;
 
@@ -2054,7 +2060,7 @@ isize bh__printf64(char* str, isize n, f64 value) {
 }
 
 // TODO: This is very hacked together but for now it will work.
-isize bh_snprintf_va(char *str, isize n, char const *fmt, va_list va) {
+BH_DEF isize bh_snprintf_va(char *str, isize n, char const *fmt, va_list va) {
     char const *text_start = str;
     isize res;
 
@@ -2136,20 +2142,20 @@ end_of_format:
 //-------------------------------------------------------------------------------------
 #ifndef BH_NO_BUFFER
 
-void bh_buffer_init(bh_buffer* buffer, bh_allocator alloc, i32 init_size) {
+BH_DEF void bh_buffer_init(bh_buffer* buffer, bh_allocator alloc, i32 init_size) {
     buffer->allocator = alloc;
     buffer->length = 0;
     buffer->capacity = init_size;
     buffer->data = bh_alloc(alloc, init_size);
 }
 
-void bh_buffer_free(bh_buffer* buffer) {
+BH_DEF void bh_buffer_free(bh_buffer* buffer) {
     bh_free(buffer->allocator, buffer->data);
     buffer->length = 0;
     buffer->capacity = 0;
 }
 
-void bh_buffer_grow(bh_buffer* buffer, i32 length) {
+BH_DEF void bh_buffer_grow(bh_buffer* buffer, i32 length) {
     if (buffer == NULL) return;
 
     if (buffer->capacity >= length) {
@@ -2167,7 +2173,7 @@ void bh_buffer_grow(bh_buffer* buffer, i32 length) {
     buffer->data = new_data;
 }
 
-void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length) {
+BH_DEF void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length) {
     if (buffer == NULL) return;
 
     if (buffer->length + length > buffer->capacity) {
@@ -2178,11 +2184,11 @@ void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length) {
     buffer->length += length;
 }
 
-void bh_buffer_concat(bh_buffer* buffer, bh_buffer other) {
+BH_DEF void bh_buffer_concat(bh_buffer* buffer, bh_buffer other) {
     bh_buffer_append(buffer, other.data, other.length);
 }
 
-void bh_buffer_write_byte(bh_buffer* buffer, u8 byte) {
+BH_DEF void bh_buffer_write_byte(bh_buffer* buffer, u8 byte) {
     bh_buffer_grow(buffer, buffer->length + 1);
     buffer->data[buffer->length++] = byte;
 }
@@ -2236,7 +2242,7 @@ void bh_buffer_align(bh_buffer* buffer, u32 alignment) {
 //-------------------------------------------------------------------------------------
 #ifndef BH_NO_ARRAY
 
-b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap) {
+BH_DEF b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap) {
     bh__arr* arrptr;
 
     if (*arr == NULL) {
@@ -2272,7 +2278,7 @@ b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap) {
     return 1;
 }
 
-b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap) {
+BH_DEF b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap) {
     if (*arr == NULL) return 0;
 
     bh__arr* arrptr = bh__arrhead(*arr);
@@ -2293,7 +2299,7 @@ b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap) {
     return 1;
 }
 
-b32 bh__arr_free(void **arr) {
+BH_DEF b32 bh__arr_free(void **arr) {
     if (*arr == NULL) return 0;
 
     bh__arr* arrptr = bh__arrhead(*arr);
@@ -2302,7 +2308,7 @@ b32 bh__arr_free(void **arr) {
     return 1;
 }
 
-void* bh__arr_copy(bh_allocator alloc, void *arr, i32 elemsize) {
+BH_DEF void* bh__arr_copy(bh_allocator alloc, void *arr, i32 elemsize) {
     bh__arr* arrptr = bh__arrhead(arr);
 
     const i32 cap = arrptr->length;
@@ -2316,7 +2322,7 @@ void* bh__arr_copy(bh_allocator alloc, void *arr, i32 elemsize) {
     return newarr;
 }
 
-void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems) {
+BH_DEF void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems) {
     bh__arr* arrptr = bh__arrhead(*arr);
 
     if (index >= arrptr->length) return; // Can't delete past the end of the array
@@ -2329,7 +2335,7 @@ void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems) {
     arrptr->length -= numelems;
 }
 
-void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) {
+BH_DEF void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) {
     if (numelems) {
         if (*arr == NULL) {
             bh__arr_grow(bh_arr_allocator(arr), arr, elemsize, numelems); // Making a new array
@@ -2368,7 +2374,7 @@ void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) {
 //-------------------------------------------------------------------------------------
 #ifndef BH_NO_TABLE
 
-b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size) {
+BH_DEF b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size) {
     *table = bh_alloc(allocator, sizeof(bh__table) + sizeof(ptr) * table_size);
     if (*table == NULL) return 0;
 
@@ -2382,7 +2388,7 @@ b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size) {
     return 1;
 }
 
-b32 bh__table_free(bh__table **table) {
+BH_DEF b32 bh__table_free(bh__table **table) {
     if (*table == NULL) return 0;
 
     for (u64 i = 0; i < (*table)->table_size; i++) {
@@ -2397,7 +2403,7 @@ b32 bh__table_free(bh__table **table) {
 }
 
 // Assumes NULL terminated string for key
-ptr bh__table_put(bh__table *table, i32 elemsize, char *key) {
+BH_DEF ptr bh__table_put(bh__table *table, i32 elemsize, char *key) {
     elemsize += (elemsize & 1);
 
     u64 index = bh__table_hash_function(key, 0, table->table_size);
@@ -2450,7 +2456,7 @@ found_matching:
     return bh_pointer_add(arrptr, -(sizeof(u16) + elemsize));
 }
 
-b32 bh__table_has(bh__table *table, i32 elemsize, char *key) {
+BH_DEF b32 bh__table_has(bh__table *table, i32 elemsize, char *key) {
     elemsize += (elemsize & 1);
 
     u64 index = bh__table_hash_function(key, 0, table->table_size);
@@ -2473,7 +2479,7 @@ b32 bh__table_has(bh__table *table, i32 elemsize, char *key) {
     return 0;
 }
 
-ptr bh__table_get(bh__table *table, i32 elemsize, char *key) {
+BH_DEF ptr bh__table_get(bh__table *table, i32 elemsize, char *key) {
     elemsize += (elemsize & 1);
 
     u64 index = bh__table_hash_function(key, 0, table->table_size);
@@ -2498,7 +2504,7 @@ ptr bh__table_get(bh__table *table, i32 elemsize, char *key) {
     return NULL;
 }
 
-void bh__table_delete(bh__table *table, i32 elemsize, char *key) {
+BH_DEF void bh__table_delete(bh__table *table, i32 elemsize, char *key) {
     elemsize += (elemsize & 1);
 
     u64 index = bh__table_hash_function(key, 0, table->table_size);
@@ -2535,7 +2541,7 @@ found_matching:
     (*(u64 *) arrptr)--;
 }
 
-void bh__table_clear(bh__table *table) {
+BH_DEF void bh__table_clear(bh__table *table) {
     for (u64 i = 0; i < table->table_size; i++) {
         if (table->arrs[i] != NULL) {
             // NOTE: Set length property to 0
@@ -2545,7 +2551,7 @@ void bh__table_clear(bh__table *table) {
     }
 }
 
-bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize) {
+BH_DEF bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize) {
     elemsize += (elemsize & 1);
 
     bh_table_iterator it = {
@@ -2557,7 +2563,7 @@ bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize) {
     return it;
 }
 
-b32 bh_table_iter_next(bh_table_iterator* it) {
+BH_DEF b32 bh_table_iter_next(bh_table_iterator* it) {
     if (it->tab == NULL) return 0;
 
     if (it->entry != NULL) {
@@ -2598,7 +2604,7 @@ step_to_next:
 // IMAP IMPLEMENTATION
 //-------------------------------------------------------------------------------------
 #ifndef BH_NO_IMAP
-void bh_imap_init(bh_imap* imap, bh_allocator alloc, i32 hash_count) {
+BH_DEF void bh_imap_init(bh_imap* imap, bh_allocator alloc, i32 hash_count) {
     imap->allocator = alloc;
 
     imap->hashes  = NULL;
@@ -2610,7 +2616,7 @@ void bh_imap_init(bh_imap* imap, bh_allocator alloc, i32 hash_count) {
     fori(count, 0, hash_count) bh_arr_push(imap->hashes, -1);
 }
 
-void bh_imap_free(bh_imap* imap) {
+BH_DEF void bh_imap_free(bh_imap* imap) {
     bh_arr_free(imap->hashes);
     bh_arr_free(imap->entries);
 
@@ -2618,7 +2624,7 @@ void bh_imap_free(bh_imap* imap) {
     imap->entries = NULL;
 }
 
-bh__imap_lookup_result bh__imap_lookup(bh_imap* imap, bh_imap_entry_t key) {
+BH_DEF bh__imap_lookup_result bh__imap_lookup(bh_imap* imap, bh_imap_entry_t key) {
     bh__imap_lookup_result lr = { -1, -1, -1 };
 
     u64 hash = 0xcbf29ce484222325ull ^ key;
@@ -2638,7 +2644,7 @@ bh__imap_lookup_result bh__imap_lookup(bh_imap* imap, bh_imap_entry_t key) {
     return lr;
 }
 
-void bh_imap_put(bh_imap* imap, bh_imap_entry_t key, bh_imap_entry_t value) {
+BH_DEF void bh_imap_put(bh_imap* imap, bh_imap_entry_t key, bh_imap_entry_t value) {
     bh__imap_lookup_result lr = bh__imap_lookup(imap, key);
 
     if (lr.entry_index >= 0) {
@@ -2655,12 +2661,12 @@ void bh_imap_put(bh_imap* imap, bh_imap_entry_t key, bh_imap_entry_t value) {
     imap->hashes[lr.hash_index] = bh_arr_length(imap->entries) - 1;
 }
 
-b32 bh_imap_has(bh_imap* imap, bh_imap_entry_t key) {
+BH_DEF b32 bh_imap_has(bh_imap* imap, bh_imap_entry_t key) {
     bh__imap_lookup_result lr = bh__imap_lookup(imap, key);
     return lr.entry_index >= 0;
 }
 
-bh_imap_entry_t bh_imap_get(bh_imap* imap, bh_imap_entry_t key) {
+BH_DEF bh_imap_entry_t bh_imap_get(bh_imap* imap, bh_imap_entry_t key) {
     bh__imap_lookup_result lr = bh__imap_lookup(imap, key);
     if (lr.entry_index >= 0) {
         return imap->entries[lr.entry_index].value;
@@ -2669,7 +2675,7 @@ bh_imap_entry_t bh_imap_get(bh_imap* imap, bh_imap_entry_t key) {
     }
 }
 
-void bh_imap_delete(bh_imap* imap, bh_imap_entry_t key) {
+BH_DEF void bh_imap_delete(bh_imap* imap, bh_imap_entry_t key) {
     bh__imap_lookup_result lr = bh__imap_lookup(imap, key);
     if (lr.entry_index < 0) return;
 
@@ -2694,7 +2700,7 @@ void bh_imap_delete(bh_imap* imap, bh_imap_entry_t key) {
     }
 }
 
-void bh_imap_clear(bh_imap* imap) {
+BH_DEF void bh_imap_clear(bh_imap* imap) {
     // NOTE: Does not clear out an of the data that was in the map
     bh_arr_each(i64, hash, imap->hashes) *hash = -1;
     bh_arr_set_length(imap->entries, 0);
@@ -2706,7 +2712,7 @@ void bh_imap_clear(bh_imap* imap) {
 
 
 
-u64 bh_time_curr() {
+BH_DEF u64 bh_time_curr() {
 #if defined(_BH_WINDOWS)
     LARGE_INTEGER result;
     QueryPerformanceCounter(&result);
@@ -2727,7 +2733,7 @@ u64 bh_time_curr() {
 #endif
 }
 
-u64 bh_time_duration(u64 old) {
+BH_DEF u64 bh_time_duration(u64 old) {
 #if defined(_BH_WINDOWS)
     u64 curr = bh_time_curr();
     u64 duration = curr - old;