|
| 1 | +// |
| 2 | +// HACK |
| 3 | +// |
| 4 | +// Currently, in stb_ds.h there is no way to choose the allocator |
| 5 | +// for arrays, and in turn hashmaps. You can provide your own |
| 6 | +// REALLOC and FREE macros, but the context pointer they are given |
| 7 | +// is always NULL. In order to allocate and free from the global |
| 8 | +// heap allocator, there needs to be a *global* pointer to it. |
| 9 | +// This is a problem for the compiler as it is meant to be a DLL, |
| 10 | +// so there should not be any global state in it. |
| 11 | +// |
| 12 | +// The tradeoff here is either: |
| 13 | +// |
| 14 | +// 1. The compiler is no longer thread-safe and only one compilation should |
| 15 | +// be done per process at any given time. |
| 16 | +// |
| 17 | +// 2. The compiler leaks memory after every compilation. (around 400K for |
| 18 | +// a hello world program). |
| 19 | +// |
| 20 | +// With those two options, I'm choosing the former. Most uses of the compiler |
| 21 | +// should not be multi-threaded in that way (at least I don't think so... time |
| 22 | +// may prove me wrong) |
| 23 | +// |
| 24 | +static void * HACK_global_heap_allocator = (void *) 0; |
| 25 | + |
| 26 | +#define STBDS_REALLOC(c, p, s) \ |
| 27 | + (HACK_global_heap_allocator) ? \ |
| 28 | + (bh_resize(*(bh_allocator *) HACK_global_heap_allocator, p, s)) : \ |
| 29 | + (realloc(p, s)) |
| 30 | + |
| 31 | +#define STBDS_FREE(c, p) \ |
| 32 | + (HACK_global_heap_allocator) ? \ |
| 33 | + (bh_free(*(bh_allocator *) HACK_global_heap_allocator, p)) : \ |
| 34 | + (free(p)) |
| 35 | + |
1 | 36 | #define BH_DEFINE
|
2 | 37 | #define BH_NO_TABLE
|
3 | 38 | #define STB_DS_IMPLEMENTATION
|
4 | 39 | #include "bh.h"
|
5 | 40 |
|
| 41 | + |
6 | 42 | #include "lex.h"
|
7 | 43 | #include "errors.h"
|
8 | 44 | #include "parser.h"
|
@@ -83,6 +119,13 @@ onyx_context_t *onyx_context_create() {
|
83 | 119 | bh_managed_heap_init(&context->heap);
|
84 | 120 | context->gp_alloc = bh_managed_heap_allocator(&context->heap);
|
85 | 121 |
|
| 122 | + if (HACK_global_heap_allocator) { |
| 123 | + printf("[WARNING] The Onyx compiler is being used by multiple threads at once. This is currently not supported and may result in catastrophic errors.\n"); |
| 124 | + |
| 125 | + } else { |
| 126 | + HACK_global_heap_allocator = (void *) &context->gp_alloc; |
| 127 | + } |
| 128 | + |
86 | 129 | context->token_alloc = context->gp_alloc;
|
87 | 130 |
|
88 | 131 | // NOTE: Create the arena where tokens and AST nodes will exist
|
@@ -134,8 +177,11 @@ void onyx_context_free(onyx_context_t *ctx) {
|
134 | 177 | bh_scratch_free(&context->scratch);
|
135 | 178 | bh_managed_heap_free(&context->heap);
|
136 | 179 |
|
| 180 | + bh_arr_free(context->options->mapped_folders); |
137 | 181 | free(context->options);
|
138 | 182 | free(ctx);
|
| 183 | + |
| 184 | + HACK_global_heap_allocator = NULL; |
139 | 185 | }
|
140 | 186 |
|
141 | 187 | void onyx_options_ready(onyx_context_t *ctx) {
|
|
0 commit comments