return (cast(^T) __stack_top)[0 .. size];
}
-TEMPORARY_ALLOCATOR_SIZE :: 1 << 12; // 4Kb
+TEMPORARY_ALLOCATOR_SIZE :: 1 << 16; // 16Kb
// The global heap allocator, set up upon program intialization.
heap_allocator : Allocator;
// The global temp allocator, set up upon program intialization.
#local
-temp_state : ring.RingState;
+temp_state : arena.ArenaState;
temp_allocator : Allocator;
init :: () {
heap.init();
- temp_buffer := cast(^u8) raw_alloc(heap_allocator, TEMPORARY_ALLOCATOR_SIZE);
- temp_state = ring.make(temp_buffer[0 .. TEMPORARY_ALLOCATOR_SIZE]);
- temp_allocator = ring.make_allocator(^temp_state);
+ temp_state = arena.make(heap_allocator, TEMPORARY_ALLOCATOR_SIZE);
+ temp_allocator = as_allocator(^temp_state);
}
+
+clear_temp_allocator :: () {
+ arena.clear(^temp_state);
+}
+
arena.size = 0;
}
+// Clears and frees every page, except for first page.
+clear :: (arena: ^ArenaState) {
+ walker := arena.first_arena.next;
+ while walker != null {
+ raw_free(arena.backing_allocator, walker);
+ walker = walker.next;
+ }
+
+ arena.size = sizeof rawptr;
+}
+
auto :: #match {
- macro (size := 32 * 1024) {
+ macro (size := 32 * 1024, $dest: Code = #(context.allocator)) {
alloc :: package core.alloc
arena := alloc.arena.make(alloc.heap_allocator, size);
- context.allocator = alloc.arena.make_allocator(^arena);
+ (#unquote dest) = alloc.arena.make_allocator(^arena);
defer alloc.arena.free(^arena);
},
done : bool; // If an .EOF was reached.
+ is_empty :: reader_empty;
read_all :: read_all;
read_byte :: read_byte;
unread_byte :: unread_byte;
return out;
}
-read_until :: (use reader: ^Reader, until: u8, skip: u32 = 0, allocator := context.allocator, consume_end := false, inplace := false, shift_buffer := true) -> str {
+read_until :: (use reader: ^Reader, until: u8, skip: u32 = 0, allocator := context.allocator, consume_end := false, inplace := false) -> str {
//
// Reading in place is special. It does not make a special allocation for the data,
// instead just return a pointer to the internal data.
}
write_format :: (use writer: ^Writer, format: str, va: ..any) {
+ write_format_va(writer, format, ~~ va);
+}
+
+write_format_va :: (use writer: ^Writer, format: str, va: [] any) {
flush :: (writer, to_output) => {
write_str(writer, to_output);
return true;
dir_read :: (dir: Directory, out_entry: ^DirectoryEntry) -> bool {
return fs.__dir_read(dir, out_entry);
}
+
+dir_exists :: fs.__file_exists
}
}
-file_exists :: (path: str) -> bool {
- return fs.__file_exists(path);
-}
+file_exists :: fs.__file_exists
get_contents_from_file :: (file: ^File) -> str {
size := cast(u32) io.stream_size(file);
return 0;
}
-offset_of :: (T: type_expr, member: str) -> u32 {
+offset_of :: (T: type_expr, member_name: str) -> u32 {
info := get_type_info(T);
if info == null do return 0;
if info.kind != .Struct do return 0;
struct_info := cast(^Type_Info_Struct) info;
for ^m: struct_info.members {
- if m.name == member do return m.offset;
+ if m.name == member_name do return m.offset;
}
// Should this return something else if the member was not found?
return 0;
}
+get_struct_member :: (S: type_expr, member_name: str) -> ^Type_Info_Struct.Member {
+ info := cast(^Type_Info_Struct) get_type_info(S);
+ if info == null do return null;
+ if info.kind != .Struct do return null;
+
+ for^ info.members {
+ if it.name == member_name do return it;
+ }
+
+ return null;
+}
+
get_tags_for_member :: (S: type_expr, member_name: str) -> [] any {
ti := get_type_info(S);
if ti.kind != .Struct do return .[];
}
buffer: [1024] u8;
- print(conv.format_va(buffer, format, va, .{null, flush}));
+ (package runtime).__output_error(conv.format_va(buffer, format, va, .{null, flush}));
}
}
return string.alloc_copy(out);
}
+// Print to a TEMPORARY dynamically allocated string.
+tprintf :: (format: str, va: ..any) -> str {
+ buffer: [8196] u8;
+ out := conv.format_va(buffer, format, va);
+ return string.alloc_copy(out, allocator=context.temp_allocator);
+}
+
byte_dump :: (ptr: rawptr, byte_count: u32, bytes_per_line := 8) {
temp: [3] u8;
#local stdin_vtable := io.Stream_Vtable.{
read = (_: ^io.Stream, buffer: [] u8) -> (io.Error, u32) {
+ __flush_stdio();
bytes_read := runtime.__read_from_input(buffer);
if bytes_read == 0 do return .ReadPending, 0;
if bytes_read < 0 do return .EOF, 0;
},
read_byte = (_: ^io.Stream) -> (io.Error, u8) {
+ __flush_stdio();
buf: [1] u8;
bytes_read := runtime.__read_from_input(buf);
if bytes_read <= 0 do return .EOF, 0;
}
}
-stdin: io.Stream;
\ No newline at end of file
+stdin: io.Stream;
Hello, I am Billy!
-Go away!! func[51]
+Go away!! func[52]