package core.alloc.arena
-// TODO: Implement the arena allocator
\ No newline at end of file
+// This allocator is great for when you need to do bunch of
+// allocations is a small amount of time. Much like the Ring
+// allocator, it simply bumps up a pointer as you allocate
+// memory. Unlike the Ring allocator, it does not wrap around,
+// meaning you can run of out of memory, so make sure the buffer
+// provided has enough space for what you are going to do.
+
+ArenaState :: struct {
+ base_ptr : rawptr;
+ size : u32;
+ curr_ptr : rawptr;
+}
+
+#private_file
+arena_alloc_proc :: proc (data: rawptr, aa: AllocationAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {
+ ss := cast(^ArenaState) data;
+
+ if aa == AllocationAction.Alloc {
+ retval := null;
+ rem := ss.size - cast(u32) ss.curr_ptr + cast(u32) ss.base_ptr;
+
+ if size <= rem {
+ retval = ss.curr_ptr;
+ ss.curr_ptr = cast(rawptr) (cast(u32) ss.curr_ptr + size);
+ } else {
+ // Not enough space for the allocation
+ retval = null;
+ }
+
+ return retval;
+ }
+
+ return null;
+}
+
+make :: proc (buffer: rawptr, length: u32) -> ArenaState {
+ return ArenaState.{
+ base_ptr = buffer,
+ curr_ptr = buffer,
+ size = length,
+ };
+}
+
+make_allocator :: proc (rs: ^ArenaState) -> Allocator {
+ return Allocator.{
+ func = ring_alloc_proc,
+ data = rs,
+ };
+}
+
+reset :: proc (arena: ^ArenaState) {
+ arena.curr_ptr = arena.base_ptr;
+}
\ No newline at end of file
WASM code; i.e. foo().bar; This should at least produce an error until
the underlying issue is fixed.
- [ ] Every type should have a unique id assigned to it. This would make it
+ [X] Every type should have a unique id assigned to it. This would make it
easier to talk about types in a concrete way (for polymorphism and such),
and would prepare the compiler to output type information into data section.
+ This has been implemented for structs and enums, since those are the two
+ types that you can control the name and inadvertently give the same name
+ to two different structs / enums.
+
[ ] Switches should have range based statements, i.e.
switch expr {
case 10 .. 14 do ...
return bh__print_string(str, n, walker);
}
+// TODO: This implementation is VERY VERY BAD AND WRONG. Fix it.
isize bh__printf64(char* str, isize n, f64 value) {
fori (i, 0, 6) value *= 10.0;
i64 v = (i64) value;
-
-
u64 bh_time_curr() {
struct timespec spec;
clock_gettime(CLOCK_MONOTONIC, &spec);
u64 duration = bh_time_duration(start_time);
if (compiler_state->options->verbose_output) {
- bh_printf("\nStatistics:\n");
- bh_printf(" Time taken: %l.%l seconds\n",
- duration / 1000, duration % 1000);
- bh_printf(" Processed %l lines (%f lines/second).\n",
- lexer_lines_processed,
- ((f32) 1000 * lexer_lines_processed) / (duration));
- bh_printf(" Processed %l tokens (%f tokens/second).\n",
- lexer_tokens_processed,
- ((f32) 1000 * lexer_tokens_processed) / (duration));
- bh_printf("\n");
+ // TODO: Replace these with bh_printf when padded formatting is added.
+ printf("\nStatistics:\n");
+ printf(" Time taken: %lf seconds\n", (double) duration / 1000);
+ printf(" Processed %ld lines (%f lines/second).\n", lexer_lines_processed, ((f32) 1000 * lexer_lines_processed) / (duration));
+ printf(" Processed %ld tokens (%f tokens/second).\n", lexer_tokens_processed, ((f32) 1000 * lexer_tokens_processed) / (duration));
+ printf("\n");
}
return ONYX_COMPILER_PROGRESS_SUCCESS;