Browse Source

Add `Assertion_Failure_Proc` to `context`

gingerBill 7 years ago
parent
commit
ae57284912
2 changed files with 41 additions and 21 deletions
  1. 19 1
      core/mem/alloc.odin
  2. 22 20
      core/runtime/core.odin

+ 19 - 1
core/mem/alloc.odin

@@ -164,6 +164,7 @@ Scratch_Allocator :: struct {
 	curr_offset: int,
 	prev_offset: int,
 	backup_allocator: Allocator,
+	leaked_allocations: [dynamic]rawptr,
 }
 
 scratch_allocator_init :: proc(scratch: ^Scratch_Allocator, data: []byte, backup_allocator := context.allocator) {
@@ -179,6 +180,11 @@ scratch_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 
 	scratch := (^Scratch_Allocator)(allocator_data);
 
+	if scratch.data == nil {
+		DEFAULT_SCRATCH_BACKING_SIZE :: 1<<22;
+		scratch_allocator_init(scratch, make([]byte, 1<<22));
+	}
+
 	switch mode {
 	case Allocator_Mode.Alloc:
 		switch {
@@ -201,8 +207,16 @@ scratch_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 		a := scratch.backup_allocator;
 		if a.procedure == nil {
 			a = context.allocator;
+			scratch.backup_allocator = a;
+		}
+
+		ptr := alloc(size, alignment, a, loc);
+		if scratch.leaked_allocations == nil {
+			scratch.leaked_allocations = make([dynamic]rawptr, a);
 		}
-		return alloc(size, alignment, a, loc);
+		append(&scratch.leaked_allocations, ptr);
+
+		return ptr;
 
 	case Allocator_Mode.Free:
 		last_ptr := rawptr(&scratch.data[scratch.prev_offset]);
@@ -217,6 +231,10 @@ scratch_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 	case Allocator_Mode.Free_All:
 		scratch.curr_offset = 0;
 		scratch.prev_offset = 0;
+		for ptr in scratch.leaked_allocations {
+			free(ptr, scratch.backup_allocator);
+		}
+		clear(&scratch.leaked_allocations);
 
 	case Allocator_Mode.Resize:
 		last_ptr := rawptr(&scratch.data[scratch.prev_offset]);

+ 22 - 20
core/runtime/core.odin

@@ -183,11 +183,15 @@ Source_Code_Location :: struct {
 	procedure:    string,
 }
 
+Assertion_Failure_Proc :: #type proc(prefix, message: string, loc: Source_Code_Location);
+
 Context :: struct {
 	allocator:      mem.Allocator,
 	temp_allocator: mem.Allocator,
 	thread_id:  int,
 
+	assertion_failure_proc:  Assertion_Failure_Proc,
+
 	user_data:  any,
 	user_index: int,
 
@@ -320,6 +324,7 @@ __init_context :: proc "contextless" (c: ^Context) {
 	c.allocator = os.heap_allocator();
 	c.temp_allocator = mem.scratch_allocator(&global_scratch_allocator_data);
 	c.thread_id = os.current_thread_id();
+	c.assertion_failure_proc = default_assertion_failure_proc;
 }
 
 @(builtin)
@@ -327,6 +332,19 @@ init_global_temporary_allocator :: proc(data: []byte, backup_allocator := contex
 	mem.scratch_allocator_init(&global_scratch_allocator_data, data, backup_allocator);
 }
 
+default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code_Location) {
+	fd := os.stderr;
+	__print_caller_location(fd, loc);
+	os.write_string(fd, " ");
+	os.write_string(fd, prefix);
+	if len(message) > 0 {
+		os.write_string(fd, ": ");
+		os.write_string(fd, message);
+	}
+	os.write_byte(fd, '\n');
+	debug_trap();
+}
+
 
 
 @(builtin)
@@ -535,32 +553,16 @@ excl_bit_set :: inline proc(s: ^$S/bit_set[$E; $U], other: S) -> S {
 
 
 @(builtin)
-assert :: proc "contextless" (condition: bool, message := "", using loc := #caller_location) -> bool {
+assert :: proc "contextless" (condition: bool, message := "", loc := #caller_location) -> bool {
 	if !condition {
-		fd := os.stderr;
-		__print_caller_location(fd, loc);
-		os.write_string(fd, " Runtime assertion");
-		if len(message) > 0 {
-			os.write_string(fd, ": ");
-			os.write_string(fd, message);
-		}
-		os.write_byte(fd, '\n');
-		debug_trap();
+		context.assertion_failure_proc("Runtime assertion", message, loc);
 	}
 	return condition;
 }
 
 @(builtin)
-panic :: proc "contextless" (message := "", using loc := #caller_location) {
-	fd := os.stderr;
-	__print_caller_location(fd, loc);
-	os.write_string(fd, " Panic");
-	if len(message) > 0 {
-		os.write_string(fd, ": ");
-		os.write_string(fd, message);
-	}
-	os.write_byte(fd, '\n');
-	debug_trap();
+panic :: proc "contextless" (message := "", loc := #caller_location) {
+	context.assertion_failure_proc("Panic", message, loc);
 }