mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 09:22:22 -07:00
map immutable fields: count, capacity, allocator
This commit is contained in:
+7
-4
@@ -142,10 +142,13 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
||||
if info.params == nil {
|
||||
buffer_write_string(buf, "()");
|
||||
} else {
|
||||
count := (cast(^Tuple)info.params).fields.count;
|
||||
if count == 1 { buffer_write_string(buf, "("); }
|
||||
buffer_write_type(buf, info.params);
|
||||
if count == 1 { buffer_write_string(buf, ")"); }
|
||||
fields := (cast(^Tuple)info.params).fields;
|
||||
buffer_write_string(buf, "(");
|
||||
for f, i in fields {
|
||||
if i > 0 { buffer_write_string(buf, ", "); }
|
||||
buffer_write_type(buf, f.type_info);
|
||||
}
|
||||
buffer_write_string(buf, ")");
|
||||
}
|
||||
if info.results != nil {
|
||||
buffer_write_string(buf, " -> ");
|
||||
|
||||
+84
-2
@@ -58,6 +58,7 @@ TODOS
|
||||
- More date & time functions
|
||||
|
||||
VERSION HISTORY
|
||||
0.27 - OSX fixes and Linux gbAffinity
|
||||
0.26d - Minor changes to how gbFile works
|
||||
0.26c - gb_str_to_f* fix
|
||||
0.26b - Minor fixes
|
||||
@@ -1008,7 +1009,12 @@ typedef struct gbAffinity {
|
||||
} gbAffinity;
|
||||
|
||||
#elif defined(GB_SYSTEM_LINUX)
|
||||
#error TODO(bill): Implement gbAffinity for linux
|
||||
typedef struct gbAffinity {
|
||||
b32 is_accurate;
|
||||
isize core_count;
|
||||
isize thread_count;
|
||||
isize threads_per_core;
|
||||
} gbAffinity;
|
||||
#else
|
||||
#error TODO(bill): Unknown system
|
||||
#endif
|
||||
@@ -4979,7 +4985,83 @@ isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
|
||||
}
|
||||
|
||||
#elif defined(GB_SYSTEM_LINUX)
|
||||
#error TODO(bill): Implement gbAffinity for linux
|
||||
// IMPORTANT TODO(bill): This gbAffinity stuff for linux needs be improved a lot!
|
||||
// NOTE(zangent): I have to read /proc/cpuinfo to get the number of threads per core.
|
||||
#include <stdio.h>
|
||||
|
||||
void gb_affinity_init(gbAffinity *a) {
|
||||
b32 accurate = true;
|
||||
isize threads = 0;
|
||||
|
||||
a->thread_count = 1;
|
||||
a->core_count = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
a->threads_per_core = 1;
|
||||
|
||||
|
||||
if(a->core_count <= 0) {
|
||||
a->core_count = 1;
|
||||
accurate = false;
|
||||
}
|
||||
|
||||
// Parsing /proc/cpuinfo to get the number of threads per core.
|
||||
// NOTE(zangent): This calls the CPU's threads "cores", although the wording
|
||||
// is kind of weird. This should be right, though.
|
||||
if (fopen("/proc/cpuinfo", "r") != NULL) {
|
||||
for (;;) {
|
||||
// The 'temporary char'. Everything goes into this char,
|
||||
// so that we can check against EOF at the end of this loop.
|
||||
char c;
|
||||
|
||||
#define AF__CHECK(letter) ((c = getc(cpu_info)) == letter)
|
||||
if (AF__CHECK('c') && AF__CHECK('p') && AF__CHECK('u') && AF__CHECK(' ') &&
|
||||
AF__CHECK('c') && AF__CHECK('o') && AF__CHECK('r') && AF__CHECK('e') && AF__CHECK('s')) {
|
||||
// We're on a CPU info line.
|
||||
while (!AF__CHECK(EOF)) {
|
||||
if (c == '\n') {
|
||||
break;
|
||||
} else if (c < '0' || '9' > c) {
|
||||
continue;
|
||||
}
|
||||
threads = threads * 10 + (c - '0');
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
while (!AF__CHECK('\n')) {
|
||||
if (c==EOF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c == EOF) {
|
||||
break;
|
||||
}
|
||||
#undef AF__CHECK
|
||||
}
|
||||
}
|
||||
|
||||
if (threads == 0) {
|
||||
threads = 1;
|
||||
accurate = false;
|
||||
}
|
||||
|
||||
a->threads_per_core = threads;
|
||||
a->thread_count = a->threads_per_core * a->core_count;
|
||||
a->is_accurate = accurate;
|
||||
|
||||
}
|
||||
|
||||
void gb_affinity_destroy(gbAffinity *a) {
|
||||
gb_unused(a);
|
||||
}
|
||||
|
||||
b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) {
|
||||
GB_ASSERT(0 <= core && core < a->core_count);
|
||||
return a->threads_per_core;
|
||||
}
|
||||
#else
|
||||
#error TODO(bill): Unknown system
|
||||
#endif
|
||||
|
||||
@@ -1495,7 +1495,7 @@ Type *ir_addr_type(irAddr addr) {
|
||||
return type_deref(t);
|
||||
}
|
||||
|
||||
irValue *ir_insert_map_key_and_value(irProcedure *proc, irValue *addr, Type *map_type,
|
||||
irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, Type *map_type,
|
||||
irValue *map_key, irValue *map_value) {
|
||||
map_type = base_type(map_type);
|
||||
|
||||
@@ -1519,7 +1519,7 @@ irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
||||
return NULL;
|
||||
}
|
||||
if (addr.kind == irAddr_Map) {
|
||||
return ir_insert_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
|
||||
return ir_insert_dynamic_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
|
||||
}
|
||||
|
||||
irValue *v = ir_emit_conv(proc, value, ir_addr_type(addr));
|
||||
@@ -1925,6 +1925,13 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, Type *type, irValue *e, Selec
|
||||
e = ir_emit_array_epi(proc, e, index);
|
||||
} else if (type->kind == Type_Array) {
|
||||
e = ir_emit_array_epi(proc, e, index);
|
||||
} else if (type->kind == Type_Map) {
|
||||
e = ir_emit_struct_ep(proc, e, 1);
|
||||
switch (index) {
|
||||
case 0: e = ir_emit_struct_ep(proc, e, 1); break; // count
|
||||
case 1: e = ir_emit_struct_ep(proc, e, 2); break; // capacity
|
||||
case 2: e = ir_emit_struct_ep(proc, e, 3); break; // allocator
|
||||
}
|
||||
} else {
|
||||
GB_PANIC("un-gep-able type");
|
||||
}
|
||||
@@ -1951,6 +1958,13 @@ irValue *ir_emit_deep_field_ev(irProcedure *proc, Type *type, irValue *e, Select
|
||||
GB_PANIC("TODO(bill): IS THIS EVEN CORRECT?");
|
||||
type = type->Record.fields[index]->type;
|
||||
e = ir_emit_conv(proc, e, type);
|
||||
} else if (type->kind == Type_Map) {
|
||||
e = ir_emit_struct_ev(proc, e, 1);
|
||||
switch (index) {
|
||||
case 0: e = ir_emit_struct_ev(proc, e, 1); break; // count
|
||||
case 1: e = ir_emit_struct_ev(proc, e, 2); break; // capacity
|
||||
case 2: e = ir_emit_struct_ev(proc, e, 3); break; // allocator
|
||||
}
|
||||
} else {
|
||||
e = ir_emit_struct_ev(proc, e, index);
|
||||
}
|
||||
@@ -4192,7 +4206,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
|
||||
irValue *key = ir_build_expr(proc, fv->field);
|
||||
irValue *value = ir_build_expr(proc, fv->value);
|
||||
ir_insert_map_key_and_value(proc, v, type, key, value);
|
||||
ir_insert_dynamic_map_key_and_value(proc, v, type, key, value);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
+35
-1
@@ -1073,6 +1073,10 @@ gb_global Entity *entity__dynamic_array_count = NULL;
|
||||
gb_global Entity *entity__dynamic_array_capacity = NULL;
|
||||
gb_global Entity *entity__dynamic_array_allocator = NULL;
|
||||
|
||||
gb_global Entity *entity__dynamic_map_count = NULL;
|
||||
gb_global Entity *entity__dynamic_map_capacity = NULL;
|
||||
gb_global Entity *entity__dynamic_map_allocator = NULL;
|
||||
|
||||
Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel);
|
||||
|
||||
Selection lookup_field(gbAllocator a, Type *type_, String field_name, bool is_type) {
|
||||
@@ -1240,7 +1244,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
|
||||
sel.entity = entity__slice_count;
|
||||
return sel;
|
||||
}
|
||||
} else if (type->kind == Type_DynamicArray) {
|
||||
} else if (type->kind == Type_DynamicArray) {
|
||||
String data_str = str_lit("data");
|
||||
String count_str = str_lit("count");
|
||||
String capacity_str = str_lit("capacity");
|
||||
@@ -1273,6 +1277,36 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
|
||||
sel.entity = entity__dynamic_array_allocator;
|
||||
return sel;
|
||||
}
|
||||
} else if (type->kind == Type_Map) {
|
||||
String count_str = str_lit("count");
|
||||
String capacity_str = str_lit("capacity");
|
||||
String allocator_str = str_lit("allocator");
|
||||
|
||||
if (str_eq(field_name, count_str)) {
|
||||
selection_add_index(&sel, 0);
|
||||
if (entity__dynamic_map_count == NULL) {
|
||||
entity__dynamic_map_count = make_entity_field(a, NULL, make_token_ident(count_str), t_int, false, 0);
|
||||
entity__dynamic_map_count->Variable.is_immutable = true;
|
||||
}
|
||||
sel.entity = entity__dynamic_map_count;
|
||||
return sel;
|
||||
} else if (str_eq(field_name, capacity_str)) {
|
||||
selection_add_index(&sel, 1);
|
||||
if (entity__dynamic_map_capacity == NULL) {
|
||||
entity__dynamic_map_capacity = make_entity_field(a, NULL, make_token_ident(capacity_str), t_int, false, 1);
|
||||
entity__dynamic_map_capacity->Variable.is_immutable = true;
|
||||
}
|
||||
sel.entity = entity__dynamic_map_capacity;
|
||||
return sel;
|
||||
} else if (str_eq(field_name, allocator_str)) {
|
||||
selection_add_index(&sel, 2);
|
||||
if (entity__dynamic_map_allocator == NULL) {
|
||||
entity__dynamic_map_allocator = make_entity_field(a, NULL, make_token_ident(allocator_str), t_allocator, false, 2);
|
||||
entity__dynamic_map_allocator->Variable.is_immutable = true;
|
||||
}
|
||||
sel.entity = entity__dynamic_map_allocator;
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->kind != Type_Record) {
|
||||
|
||||
Reference in New Issue
Block a user