mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Improve min-dep for Type Info
This commit is contained in:
+82
-19
@@ -1,7 +1,7 @@
|
|||||||
#shared_global_scope
|
#shared_global_scope
|
||||||
|
|
||||||
import "core:os.odin"
|
import "core:os.odin"
|
||||||
import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here
|
// import "core:fmt.odin" // TODO(bill): Remove the need for `fmt` here
|
||||||
import "core:utf8.odin"
|
import "core:utf8.odin"
|
||||||
import "core:raw.odin"
|
import "core:raw.odin"
|
||||||
|
|
||||||
@@ -599,22 +599,55 @@ nil_allocator :: proc() -> Allocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
assert :: proc "contextless" (condition: bool, message := "", args: ...any, using loc := #caller_location) -> bool {
|
__print_u64 :: proc(fd: os.Handle, u: u64) {
|
||||||
|
digits := "0123456789";
|
||||||
|
|
||||||
|
a: [129]byte;
|
||||||
|
i := len(a);
|
||||||
|
b := u64(10);
|
||||||
|
for u >= b {
|
||||||
|
i -= 1; a[i] = digits[u % b];
|
||||||
|
u /= b;
|
||||||
|
}
|
||||||
|
i -= 1; a[i] = digits[u % b];
|
||||||
|
|
||||||
|
os.write(fd, a[i..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
__print_caller_location :: proc(fd: os.Handle, using loc: Source_Code_Location) {
|
||||||
|
os.write_string(fd, file_path);
|
||||||
|
os.write_byte(fd, '(');
|
||||||
|
__print_u64(fd, u64(line));
|
||||||
|
os.write_byte(fd, ':');
|
||||||
|
__print_u64(fd, u64(column));
|
||||||
|
os.write_byte(fd, ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
assert :: proc "contextless" (condition: bool, message := "", using loc := #caller_location) -> bool {
|
||||||
if !condition {
|
if !condition {
|
||||||
fmt.fprintf(os.stderr, "%s(%d:%d) Runtime assertion", file_path, line, column);
|
fd := os.stderr;
|
||||||
if len(message) > 0 do fmt.fprint(os.stderr, ": ");
|
__print_caller_location(fd, loc);
|
||||||
fmt.fprintf(os.stderr, message, ...args);
|
os.write_string(fd, " Runtime assertion");
|
||||||
fmt.fprintf(os.stderr, "\n");
|
if len(message) > 0 {
|
||||||
|
os.write_string(fd, ": ");
|
||||||
|
os.write_string(fd, message);
|
||||||
|
os.write_byte(fd, '\n');
|
||||||
|
}
|
||||||
__debug_trap();
|
__debug_trap();
|
||||||
}
|
}
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
panic :: proc "contextless" (message := "", args: ...any, using loc := #caller_location) {
|
panic :: proc "contextless" (message := "", using loc := #caller_location) {
|
||||||
fmt.fprintf(os.stderr, "%s(%d:%d) Panic", file_path, line, column);
|
fd := os.stderr;
|
||||||
if len(message) > 0 do fmt.fprint(os.stderr, ": ");
|
__print_caller_location(fd, loc);
|
||||||
fmt.fprintf(os.stderr, message, ...args);
|
os.write_string(fd, " Panic");
|
||||||
fmt.fprintf(os.stderr, "\n");
|
if len(message) > 0 {
|
||||||
|
os.write_string(fd, ": ");
|
||||||
|
os.write_string(fd, message);
|
||||||
|
os.write_byte(fd, '\n');
|
||||||
|
}
|
||||||
__debug_trap();
|
__debug_trap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,29 +705,59 @@ __complex128_ne :: inline proc "contextless" (a, b: complex128) -> bool { return
|
|||||||
|
|
||||||
__bounds_check_error :: proc "contextless" (file: string, line, column: int, index, count: int) {
|
__bounds_check_error :: proc "contextless" (file: string, line, column: int, index, count: int) {
|
||||||
if 0 <= index && index < count do return;
|
if 0 <= index && index < count do return;
|
||||||
fmt.fprintf(os.stderr, "%s(%d:%d) Index %d is out of bounds range 0..%d\n",
|
|
||||||
file, line, column, index, count);
|
fd := os.stderr;
|
||||||
|
__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
|
||||||
|
os.write_string(fd, " Index ");
|
||||||
|
__print_u64(fd, u64(index));
|
||||||
|
os.write_string(fd, " is out of bounds range 0..");
|
||||||
|
__print_u64(fd, u64(count));
|
||||||
|
os.write_byte(fd, '\n');
|
||||||
__debug_trap();
|
__debug_trap();
|
||||||
}
|
}
|
||||||
|
|
||||||
__slice_expr_error :: proc "contextless" (file: string, line, column: int, low, high: int) {
|
__slice_expr_error :: proc "contextless" (file: string, line, column: int, low, high: int) {
|
||||||
if 0 <= low && low <= high do return;
|
if 0 <= low && low <= high do return;
|
||||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d\n",
|
|
||||||
file, line, column, low, high);
|
|
||||||
|
fd := os.stderr;
|
||||||
|
__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
|
||||||
|
os.write_string(fd, " Invalid slice indices: ");
|
||||||
|
__print_u64(fd, u64(low));
|
||||||
|
os.write_string(fd, "..");
|
||||||
|
__print_u64(fd, u64(high));
|
||||||
|
os.write_byte(fd, '\n');
|
||||||
|
__debug_trap();
|
||||||
|
|
||||||
|
// fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d\n",
|
||||||
|
// file, line, column, low, high);
|
||||||
__debug_trap();
|
__debug_trap();
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) {
|
__dynamic_array_expr_error :: proc "contextless" (file: string, line, column: int, low, high, max: int) {
|
||||||
if 0 <= low && low <= high && high <= max do return;
|
if 0 <= low && low <= high && high <= max do return;
|
||||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid slice indices: %d..%d..%d\n",
|
|
||||||
file, line, column, low, high, max);
|
fd := os.stderr;
|
||||||
|
__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
|
||||||
|
os.write_string(fd, " Invalid slice indices: ");
|
||||||
|
__print_u64(fd, u64(low));
|
||||||
|
os.write_string(fd, "..");
|
||||||
|
__print_u64(fd, u64(high));
|
||||||
|
os.write_string(fd, "..");
|
||||||
|
__print_u64(fd, u64(max));
|
||||||
|
os.write_byte(fd, '\n');
|
||||||
|
__debug_trap();
|
||||||
__debug_trap();
|
__debug_trap();
|
||||||
}
|
}
|
||||||
|
|
||||||
__type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: int, from, to: ^Type_Info) {
|
__type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: int, from, to: ^Type_Info) {
|
||||||
if ok do return;
|
if ok do return;
|
||||||
fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
|
|
||||||
file, line, column, from, to);
|
fd := os.stderr;
|
||||||
|
__print_caller_location(fd, Source_Code_Location{file, line, column, ""});
|
||||||
|
os.write_string(fd, " Invalid type assertion");
|
||||||
|
// fmt.fprintf(os.stderr, "%s(%d:%d) Invalid type_assertion from %T to %T\n",
|
||||||
|
// file, line, column, from, to);
|
||||||
__debug_trap();
|
__debug_trap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
|
|||||||
return write(fd, cast([]byte)str);
|
return write(fd, cast([]byte)str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_byte :: proc(fd: Handle, b: byte) -> (int, Errno) {
|
||||||
|
return write(fd, []byte{b});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
read_entire_file :: proc(name: string) -> (data: []byte, success: bool) {
|
read_entire_file :: proc(name: string) -> (data: []byte, success: bool) {
|
||||||
fd, err := open(name, O_RDONLY, 0);
|
fd, err := open(name, O_RDONLY, 0);
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
|
|||||||
+22
-17
@@ -576,18 +576,17 @@ void init_universal_scope(void) {
|
|||||||
|
|
||||||
void init_checker_info(CheckerInfo *i) {
|
void init_checker_info(CheckerInfo *i) {
|
||||||
gbAllocator a = heap_allocator();
|
gbAllocator a = heap_allocator();
|
||||||
map_init(&i->types, a);
|
map_init(&i->types, a);
|
||||||
array_init(&i->definitions, a);
|
array_init(&i->definitions, a);
|
||||||
array_init(&i->entities, a);
|
array_init(&i->entities, a);
|
||||||
map_init(&i->untyped, a);
|
map_init(&i->untyped, a);
|
||||||
map_init(&i->foreigns, a);
|
map_init(&i->foreigns, a);
|
||||||
map_init(&i->gen_procs, a);
|
map_init(&i->gen_procs, a);
|
||||||
map_init(&i->gen_types, a);
|
map_init(&i->gen_types, a);
|
||||||
map_init(&i->type_info_map, a);
|
array_init(&i->type_info_types, a);
|
||||||
map_init(&i->files, a);
|
map_init(&i->type_info_map, a);
|
||||||
|
map_init(&i->files, a);
|
||||||
array_init(&i->variable_init_order, a);
|
array_init(&i->variable_init_order, a);
|
||||||
|
|
||||||
i->type_info_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_checker_info(CheckerInfo *i) {
|
void destroy_checker_info(CheckerInfo *i) {
|
||||||
@@ -598,6 +597,7 @@ void destroy_checker_info(CheckerInfo *i) {
|
|||||||
map_destroy(&i->foreigns);
|
map_destroy(&i->foreigns);
|
||||||
map_destroy(&i->gen_procs);
|
map_destroy(&i->gen_procs);
|
||||||
map_destroy(&i->gen_types);
|
map_destroy(&i->gen_types);
|
||||||
|
array_free(&i->type_info_types);
|
||||||
map_destroy(&i->type_info_map);
|
map_destroy(&i->type_info_map);
|
||||||
map_destroy(&i->files);
|
map_destroy(&i->files);
|
||||||
array_free(&i->variable_init_order);
|
array_free(&i->variable_init_order);
|
||||||
@@ -922,6 +922,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool prev = false;
|
||||||
isize ti_index = -1;
|
isize ti_index = -1;
|
||||||
for_array(i, c->info.type_info_map.entries) {
|
for_array(i, c->info.type_info_map.entries) {
|
||||||
auto *e = &c->info.type_info_map.entries[i];
|
auto *e = &c->info.type_info_map.entries[i];
|
||||||
@@ -929,19 +930,22 @@ void add_type_info_type(Checker *c, Type *t) {
|
|||||||
if (are_types_identical(t, prev_type)) {
|
if (are_types_identical(t, prev_type)) {
|
||||||
// Duplicate entry
|
// Duplicate entry
|
||||||
ti_index = e->value;
|
ti_index = e->value;
|
||||||
|
prev = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ti_index < 0) {
|
if (ti_index < 0) {
|
||||||
// Unique entry
|
// Unique entry
|
||||||
// NOTE(bill): map entries grow linearly and in order
|
// NOTE(bill): map entries grow linearly and in order
|
||||||
ti_index = c->info.type_info_count;
|
ti_index = c->info.type_info_types.count;
|
||||||
c->info.type_info_count++;
|
array_add(&c->info.type_info_types, t);
|
||||||
}
|
}
|
||||||
map_set(&c->info.type_info_map, hash_type(t), ti_index);
|
map_set(&c->info.type_info_map, hash_type(t), ti_index);
|
||||||
|
|
||||||
|
if (prev) {
|
||||||
|
// NOTE(bill): If a previous one exists already, no need to continue
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Add nested types
|
// Add nested types
|
||||||
|
|
||||||
@@ -3053,7 +3057,8 @@ void check_parsed_files(Checker *c) {
|
|||||||
// Add "Basic" type information
|
// Add "Basic" type information
|
||||||
for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
|
for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
|
||||||
Type *t = &basic_types[i];
|
Type *t = &basic_types[i];
|
||||||
if (t->Basic.size > 0 && t->Basic.kind != Basic_llvm_bool) {
|
if (t->Basic.size > 0 &&
|
||||||
|
t->Basic.kind != Basic_llvm_bool) {
|
||||||
add_type_info_type(c, t);
|
add_type_info_type(c, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3064,7 +3069,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
if (e->kind == Entity_TypeName && e->type != nullptr) {
|
if (e->kind == Entity_TypeName && e->type != nullptr) {
|
||||||
// i64 size = type_size_of(c->allocator, e->type);
|
// i64 size = type_size_of(c->allocator, e->type);
|
||||||
i64 align = type_align_of(c->allocator, e->type);
|
i64 align = type_align_of(c->allocator, e->type);
|
||||||
if (align > 0) {
|
if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) {
|
||||||
add_type_info_type(c, e->type);
|
add_type_info_type(c, e->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -298,8 +298,8 @@ struct CheckerInfo {
|
|||||||
Map<Array<Entity *> > gen_procs; // Key: AstNode * | Identifier -> Entity
|
Map<Array<Entity *> > gen_procs; // Key: AstNode * | Identifier -> Entity
|
||||||
Map<Array<Entity *> > gen_types; // Key: Type *
|
Map<Array<Entity *> > gen_types; // Key: Type *
|
||||||
|
|
||||||
|
Array<Type *> type_info_types;
|
||||||
Map<isize> type_info_map; // Key: Type *
|
Map<isize> type_info_map; // Key: Type *
|
||||||
isize type_info_count;
|
|
||||||
|
|
||||||
Scope * init_scope;
|
Scope * init_scope;
|
||||||
Entity * entry_point;
|
Entity * entry_point;
|
||||||
|
|||||||
+2
-3
@@ -7838,9 +7838,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
|||||||
i32 type_info_member_names_index = 0;
|
i32 type_info_member_names_index = 0;
|
||||||
i32 type_info_member_offsets_index = 0;
|
i32 type_info_member_offsets_index = 0;
|
||||||
|
|
||||||
for_array(type_info_map_index, info->type_info_map.entries) {
|
for_array(type_info_type_index, info->type_info_types) {
|
||||||
auto *entry = &info->type_info_map.entries[type_info_map_index];
|
Type *t = info->type_info_types[type_info_type_index];
|
||||||
Type *t = cast(Type *)entry->key.ptr;
|
|
||||||
t = default_type(t);
|
t = default_type(t);
|
||||||
if (t == t_invalid) {
|
if (t == t_invalid) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user