Begin work on setting up type information table

This commit is contained in:
gingerBill
2023-07-24 17:12:23 +01:00
parent 28fca190ee
commit 28c97a9467
5 changed files with 366 additions and 19 deletions
+27 -1
View File
@@ -199,6 +199,13 @@ gb_internal void cg_set_debug_pos_from_node(cgProcedure *p, Ast *node) {
}
}
gb_internal void cg_add_symbol(cgModule *m, Entity *e, TB_Symbol *symbol) {
if (e) {
rw_mutex_lock(&m->values_mutex);
map_set(&m->symbols, e, symbol);
rw_mutex_unlock(&m->values_mutex);
}
}
gb_internal void cg_add_entity(cgModule *m, Entity *e, cgValue const &val) {
if (e) {
@@ -221,12 +228,27 @@ gb_internal void cg_add_procedure_value(cgModule *m, cgProcedure *p) {
rw_mutex_lock(&m->values_mutex);
if (p->entity != nullptr) {
map_set(&m->procedure_values, p->func, p->entity);
if (p->symbol != nullptr) {
map_set(&m->symbols, p->entity, p->symbol);
}
}
string_map_set(&m->procedures, p->name, p);
rw_mutex_unlock(&m->values_mutex);
}
gb_internal TB_Symbol *cg_find_symbol_from_entity(cgModule *m, Entity *e) {
if (e) {
rw_mutex_lock(&m->values_mutex);
defer (rw_mutex_unlock(&m->values_mutex));
TB_Symbol **found = map_get(&m->symbols, e);
if (found) {
return *found;
}
}
return nullptr;
}
gb_internal isize cg_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) {
auto *set = &info->minimum_dependency_type_info_set;
isize index = type_info_index(info, type, err_on_not_found);
@@ -449,11 +471,13 @@ gb_internal bool cg_global_variables_create(cgModule *m) {
var.is_initialized = true;
}
} else {
tb_global_set_storage(m->mod, section, global, type_size_of(e->type), type_align_of(e->type), 0);
i64 max_regions = cg_global_const_calculate_region_count_from_basic_type(e->type);
tb_global_set_storage(m->mod, section, global, type_size_of(e->type), type_align_of(e->type), max_regions);
}
array_add(&global_variables, var);
cg_add_symbol(m, e, cast(TB_Symbol *)global);
cg_add_entity(m, e, g);
cg_add_member(m, name, g);
}
@@ -478,6 +502,7 @@ gb_internal cgModule *cg_module_create(Checker *c) {
tb_module_set_tls_index(m->mod, 10, "_tls_index");
map_init(&m->values);
map_init(&m->symbols);
map_init(&m->file_id_map);
@@ -500,6 +525,7 @@ gb_internal cgModule *cg_module_create(Checker *c) {
gb_internal void cg_module_destroy(cgModule *m) {
map_destroy(&m->values);
map_destroy(&m->symbols);
map_destroy(&m->file_id_map);
map_destroy(&m->debug_type_map);
map_destroy(&m->proc_debug_type_map);
+2
View File
@@ -214,6 +214,7 @@ struct cgModule {
RwMutex values_mutex;
PtrMap<Entity *, cgValue> values;
PtrMap<Entity *, TB_Symbol *> symbols;
StringMap<cgValue> members;
StringMap<cgProcedure *> procedures;
PtrMap<TB_Function *, Entity *> procedure_values;
@@ -257,6 +258,7 @@ gb_internal void cg_add_procedure_to_queue(cgProcedure *p);
gb_internal void cg_setup_type_info_data(cgModule *m);
gb_internal isize cg_global_const_calculate_region_count(ExactValue const &value, Type *type);
gb_internal i64 cg_global_const_calculate_region_count_from_basic_type(Type *type);
gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value, Type *type, TB_Global *global, i64 offset);
gb_internal cgValue cg_value(TB_Global * g, Type *type);
+70 -2
View File
@@ -143,6 +143,33 @@ gb_internal TB_Global *cg_global_const_string(cgModule *m, String const &str, Ty
return global;
}
gb_internal void cg_global_source_code_location_const(cgModule *m, String const &proc_name, TokenPos pos, TB_Global *global, i64 offset) {
// Source_Code_Location :: struct {
// file_path: string,
// line, column: i32,
// procedure: string,
// }
i64 file_path_offset = type_offset_of(t_source_code_location, 0);
i64 line_offset = type_offset_of(t_source_code_location, 1);
i64 column_offset = type_offset_of(t_source_code_location, 2);
i64 procedure_offset = type_offset_of(t_source_code_location, 3);
String file_path = get_file_path_string(pos.file_id);
if (file_path.len != 0) {
cg_global_const_string(m, file_path, t_string, global, offset+file_path_offset);
}
void *line_ptr = tb_global_add_region(m->mod, global, offset+line_offset, 4);
void *column_ptr = tb_global_add_region(m->mod, global, offset+column_offset, 4);
cg_write_int_at_ptr(line_ptr, pos.line, t_i32);
cg_write_int_at_ptr(column_ptr, pos.column, t_i32);
if (proc_name.len != 0) {
cg_global_const_string(m, proc_name, t_string, global, offset+procedure_offset);
}
}
gb_internal bool cg_elem_type_can_be_constant(Type *t) {
t = base_type(t);
if (t == t_invalid) {
@@ -201,10 +228,11 @@ gb_internal i64 cg_global_const_calculate_region_count_from_basic_type(Type *typ
return 1;
case Type_Pointer:
case Type_MultiPointer:
return 2; // allows for offsets
case Type_Proc:
return true;
return 1;
case Type_Slice:
return 2;
return 3; // alows for offsets
case Type_DynamicArray:
return 5;
case Type_Map:
@@ -221,6 +249,46 @@ gb_internal i64 cg_global_const_calculate_region_count_from_basic_type(Type *typ
case Type_Matrix:
return 1;
case Type_Array:
{
Type *elem = type->Array.elem;
i64 count = cg_global_const_calculate_region_count_from_basic_type(elem);
return count*type->Array.count;
}
case Type_EnumeratedArray:
{
Type *elem = type->EnumeratedArray.elem;
i64 count = cg_global_const_calculate_region_count_from_basic_type(elem);
return count*type->EnumeratedArray.count;
}
case Type_Struct:
if (type->Struct.is_raw_union) {
i64 max_count = 0;
for (Entity *f : type->Struct.fields) {
i64 count = cg_global_const_calculate_region_count_from_basic_type(f->type);
max_count = gb_max(count, max_count);
}
return max_count;
} else {
i64 max_count = 0;
for (Entity *f : type->Struct.fields) {
max_count += cg_global_const_calculate_region_count_from_basic_type(f->type);
}
return max_count;
}
break;
case Type_Union:
{
i64 max_count = 0;
for (Type *t : type->Union.variants) {
i64 count = cg_global_const_calculate_region_count_from_basic_type(t);
max_count = gb_max(count, max_count);
}
return max_count+1;
}
break;
default:
GB_PANIC("TODO(bill): %s", type_to_string(type));
break;
+2
View File
@@ -103,6 +103,8 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i
}
p->value = cg_value(p->symbol, p->type);
cg_add_symbol(m, entity, p->symbol);
cg_add_entity(m, entity, p->value);
cg_add_member(m, p->name, p->value);
cg_add_procedure_value(m, p);
+265 -16
View File
@@ -1,3 +1,16 @@
gb_internal void cg_global_const_type_info_ptr(cgModule *m, TB_Global *type_info_array, Type *type, TB_Global *global, i64 offset) {
i64 index_in_bytes = cast(i64)cg_type_info_index(m->info, type);
index_in_bytes *= type_size_of(t_type_info);
void *ti_ptr_ptr = tb_global_add_region(m->mod, global, offset, build_context.ptr_size);
// NOTE(bill): define the byte offset for the pointer
cg_write_int_at_ptr(ti_ptr_ptr, index_in_bytes, t_uintptr);
// NOTE(bill): this will add to the byte offset set previously
tb_global_add_symbol_reloc(m->mod, global, offset, cast(TB_Symbol *)type_info_array);
}
gb_internal void cg_setup_type_info_data(cgModule *m) {
if (build_context.no_rtti) {
return;
@@ -9,11 +22,14 @@ gb_internal void cg_setup_type_info_data(cgModule *m) {
// gb_printf_err("max_type_info_count: %td\n", max_type_info_count);
Type *t = alloc_type_array(t_type_info, max_type_info_count);
i64 max_objects = cast(i64)max_type_info_count * cg_global_const_calculate_region_count_from_basic_type(t_type_info);
TB_Global *g = tb_global_create(m->mod, -1, CG_TYPE_INFO_DATA_NAME, nullptr, TB_LINKAGE_PRIVATE);
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, max_type_info_count);
tb_global_set_storage(m->mod, tb_module_get_rdata(m->mod), g, type_size_of(t), 16, max_objects);
cgValue value = cg_value(g, alloc_type_pointer(t));
cg_global_type_info_data_entity = alloc_entity_variable(nullptr, make_token_ident(CG_TYPE_INFO_DATA_NAME), t, EntityState_Resolved);
cg_add_symbol(m, cg_global_type_info_data_entity, cast(TB_Symbol *)g);
cg_add_entity(m, cg_global_type_info_data_entity, value);
}
@@ -83,22 +99,255 @@ gb_internal void cg_setup_type_info_data(cgModule *m) {
gb_unused(info);
// i64 global_type_info_data_entity_count = 0;
// {
// // NOTE(bill): Set the type_table slice with the global backing array
// cgValue global_type_table = cg_find_runtime_value(m, str_lit("type_table"));
// Type *type = base_type(cg_global_type_info_data_entity->type);
// GB_ASSERT(is_type_array(type));
// global_type_info_data_entity_count = type->Array.count;
i64 global_type_info_data_entity_count = 0;
// LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
// LLVMValueRef data = LLVMConstInBoundsGEP2(cg_type(m, cg_global_type_info_data_entity->type), cg_global_type_info_data_ptr(m).value, indices, gb_count_of(indices));
// LLVMValueRef len = LLVMConstInt(cg_type(m, t_int), type->Array.count, true);
// Type *t = type_deref(global_type_table.type);
// GB_ASSERT(is_type_slice(t));
// LLVMValueRef slice = llvm_const_slice_internal(m, data, len);
// NOTE(bill): Set the type_table slice with the global backing array
TB_Global *type_table_slice = cast(TB_Global *)cg_find_symbol_from_entity(m, scope_lookup_current(m->info->runtime_package->scope, str_lit("type_table")));
GB_ASSERT(type_table_slice != nullptr);
// LLVMSetInitializer(global_type_table.value, slice);
// }
TB_Global *type_table_array = cast(TB_Global *)cg_find_symbol_from_entity(m, cg_global_type_info_data_entity);
GB_ASSERT(type_table_array != nullptr);
Type *type = base_type(cg_global_type_info_data_entity->type);
GB_ASSERT(is_type_array(type));
global_type_info_data_entity_count = type->Array.count;
tb_global_add_symbol_reloc(m->mod, type_table_slice, 0, cast(TB_Symbol *)type_table_array);
void *len_ptr = tb_global_add_region(m->mod, type_table_slice, build_context.int_size, build_context.int_size);
cg_write_int_at_ptr(len_ptr, type->Array.count, t_int);
// Useful types
Entity *type_info_flags_entity = find_core_entity(info->checker, str_lit("Type_Info_Flags"));
Type *t_type_info_flags = type_info_flags_entity->type;
GB_ASSERT(type_size_of(t_type_info_flags) == 4);
auto entries_handled = slice_make<bool>(heap_allocator(), cast(isize)global_type_info_data_entity_count);
defer (gb_free(heap_allocator(), entries_handled.data));
entries_handled[0] = true;
i64 type_info_size = type_size_of(t_type_info);
i64 size_offset = type_offset_of(t_type_info, 0);
i64 align_offset = type_offset_of(t_type_info, 1);
i64 flags_offset = type_offset_of(t_type_info, 2);
i64 id_offset = type_offset_of(t_type_info, 3);
i64 variant_offset = type_offset_of(t_type_info, 4);
Type *type_info_union = base_type(t_type_info)->Struct.fields[4]->type;
GB_ASSERT(type_info_union->kind == Type_Union);
i64 union_tag_offset = type_info_union->Union.variant_block_size;
Type *ti_union_tag_type = union_tag_type(type_info_union);
u64 union_tag_type_size = type_size_of(ti_union_tag_type);
for_array(type_info_type_index, info->type_info_types) {
Type *t = info->type_info_types[type_info_type_index];
if (t == nullptr || t == t_invalid) {
continue;
}
isize entry_index = cg_type_info_index(info, t, false);
if (entry_index <= 0) {
continue;
}
if (entries_handled[entry_index]) {
continue;
}
entries_handled[entry_index] = true;
TB_Global *global = type_table_array;
i64 offset = entry_index * type_info_size;
i64 size = type_size_of(t);
i64 align = type_align_of(t);
u32 flags = type_info_flags_of_type(t);
u64 id = cg_typeid_as_u64(m, t);
void *size_ptr = tb_global_add_region(m->mod, global, offset+size_offset, build_context.int_size);
void *align_ptr = tb_global_add_region(m->mod, global, offset+align_offset, build_context.int_size);
void *flags_ptr = tb_global_add_region(m->mod, global, offset+flags_offset, 4);
void *id_ptr = tb_global_add_region(m->mod, global, offset+id_offset, build_context.ptr_size);
cg_write_int_at_ptr (size_ptr, size, t_int);
cg_write_int_at_ptr (align_ptr, align, t_int);
cg_write_int_at_ptr (flags_ptr, flags, t_u32);
cg_write_uint_at_ptr(id_ptr, id, t_typeid);
// add data to the offset to make it easier to deal with later on
offset += variant_offset;
Type *tag_type = nullptr;
switch (t->kind) {
case Type_Named: {
// Type_Info_Named :: struct {
// name: string,
// base: ^Type_Info,
// pkg: string,
// loc: Source_Code_Location,
// }
tag_type = t_type_info_named;
if (t->Named.type_name->pkg) {
i64 pkg_offset = type_offset_of(tag_type, 2);
String pkg_name = t->Named.type_name->pkg->name;
cg_global_const_string(m, pkg_name, t_string, global, offset+pkg_offset);
}
String proc_name = {};
if (t->Named.type_name->parent_proc_decl) {
DeclInfo *decl = t->Named.type_name->parent_proc_decl;
if (decl->entity && decl->entity->kind == Entity_Procedure) {
i64 name_offset = type_offset_of(tag_type, 0);
proc_name = decl->entity->token.string;
cg_global_const_string(m, proc_name, t_string, global, offset+name_offset);
}
}
i64 loc_offset = type_offset_of(tag_type, 3);
TokenPos pos = t->Named.type_name->token.pos;
cg_global_source_code_location_const(m, proc_name, pos, global, offset+loc_offset);
i64 base_offset = type_offset_of(tag_type, 1);
cg_global_const_type_info_ptr(m, type_table_array, t->Named.base, global, offset+base_offset);
break;
}
case Type_Basic:
switch (t->Basic.kind) {
case Basic_bool:
case Basic_b8:
case Basic_b16:
case Basic_b32:
case Basic_b64:
tag_type = t_type_info_boolean;
break;
case Basic_i8:
case Basic_u8:
case Basic_i16:
case Basic_u16:
case Basic_i32:
case Basic_u32:
case Basic_i64:
case Basic_u64:
case Basic_i128:
case Basic_u128:
case Basic_i16le:
case Basic_u16le:
case Basic_i32le:
case Basic_u32le:
case Basic_i64le:
case Basic_u64le:
case Basic_i128le:
case Basic_u128le:
case Basic_i16be:
case Basic_u16be:
case Basic_i32be:
case Basic_u32be:
case Basic_i64be:
case Basic_u64be:
case Basic_i128be:
case Basic_u128be:
case Basic_int:
case Basic_uint:
case Basic_uintptr: {
tag_type = t_type_info_integer;
bool is_signed = (t->Basic.flags & BasicFlag_Unsigned) == 0;
// NOTE(bill): This is matches the runtime layout
u8 endianness_value = 0;
if (t->Basic.flags & BasicFlag_EndianLittle) {
endianness_value = 1;
} else if (t->Basic.flags & BasicFlag_EndianBig) {
endianness_value = 2;
}
u8 *signed_ptr = cast(u8 *)tb_global_add_region(m->mod, global, offset+0, 1);
u8 *endianness_ptr = cast(u8 *)tb_global_add_region(m->mod, global, offset+1, 1);
*signed_ptr = is_signed;
*endianness_ptr = endianness_value;
break;
}
case Basic_rune:
tag_type = t_type_info_rune;
break;
case Basic_f16:
case Basic_f32:
case Basic_f64:
case Basic_f16le:
case Basic_f32le:
case Basic_f64le:
case Basic_f16be:
case Basic_f32be:
case Basic_f64be:
{
tag_type = t_type_info_float;
// // NOTE(bill): This is matches the runtime layout
u8 endianness_value = 0;
if (t->Basic.flags & BasicFlag_EndianLittle) {
endianness_value = 1;
} else if (t->Basic.flags & BasicFlag_EndianBig) {
endianness_value = 2;
}
u8 *ptr = cast(u8 *)tb_global_add_region(m->mod, global, offset+0, 1);
*ptr = endianness_value;
}
break;
case Basic_complex32:
case Basic_complex64:
case Basic_complex128:
tag_type = t_type_info_complex;
break;
case Basic_quaternion64:
case Basic_quaternion128:
case Basic_quaternion256:
tag_type = t_type_info_quaternion;
break;
case Basic_rawptr:
tag_type = t_type_info_pointer;
break;
case Basic_string:
tag_type = t_type_info_string;
break;
case Basic_cstring:
{
tag_type = t_type_info_string;
bool *b = cast(bool *)tb_global_add_region(m->mod, global, offset+0, 1);
*b = true;
}
break;
case Basic_any:
tag_type = t_type_info_any;
break;
case Basic_typeid:
tag_type = t_type_info_typeid;
break;
}
break;
}
if (tag_type != nullptr) {
i64 union_index = union_variant_index(type_info_union, tag_type);
GB_ASSERT(union_index != 0);
void *tag_ptr = tb_global_add_region(m->mod, global, offset+union_tag_offset, union_tag_type_size);
cg_write_int_at_ptr(tag_ptr, union_index, ti_union_tag_type);
}
}
}