mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 16:18:52 +00:00
Support non-constant global slices
This commit is contained in:
+15
-10
@@ -694,22 +694,14 @@ gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) {
|
|||||||
Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
|
Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
|
||||||
cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_STARTUP_RUNTIME_PROC_NAME), proc_type);
|
cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_STARTUP_RUNTIME_PROC_NAME), proc_type);
|
||||||
p->is_startup = true;
|
p->is_startup = true;
|
||||||
|
cg_startup_runtime_proc = p;
|
||||||
cg_procedure_begin(p);
|
|
||||||
cg_global_variables_initialize(p, &global_variables);
|
|
||||||
|
|
||||||
tb_inst_ret(p->func, 0, nullptr);
|
|
||||||
cg_procedure_end(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
|
Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
|
||||||
cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_CLEANUP_RUNTIME_PROC_NAME), proc_type);
|
cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_CLEANUP_RUNTIME_PROC_NAME), proc_type);
|
||||||
p->is_startup = true;
|
p->is_startup = true;
|
||||||
|
cg_cleanup_runtime_proc = p;
|
||||||
cg_procedure_begin(p);
|
|
||||||
tb_inst_ret(p->func, 0, nullptr);
|
|
||||||
cg_procedure_end(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *min_dep_set = &info->minimum_dependency_set;
|
auto *min_dep_set = &info->minimum_dependency_set;
|
||||||
@@ -741,6 +733,19 @@ gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) {
|
|||||||
array_add(&procedures_to_generate, p);
|
array_add(&procedures_to_generate, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
cgProcedure *p = cg_startup_runtime_proc;
|
||||||
|
cg_procedure_begin(p);
|
||||||
|
cg_global_variables_initialize(p, &global_variables);
|
||||||
|
tb_inst_ret(p->func, 0, nullptr);
|
||||||
|
cg_procedure_end(p);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
cgProcedure *p = cg_cleanup_runtime_proc;
|
||||||
|
cg_procedure_begin(p);
|
||||||
|
tb_inst_ret(p->func, 0, nullptr);
|
||||||
|
cg_procedure_end(p);
|
||||||
|
}
|
||||||
|
|
||||||
for (cgProcedure *p : procedures_to_generate) {
|
for (cgProcedure *p : procedures_to_generate) {
|
||||||
cg_add_procedure_to_queue(p);
|
cg_add_procedure_to_queue(p);
|
||||||
|
|||||||
@@ -257,6 +257,9 @@ gb_global GlobalTypeInfoData cg_global_type_info_member_usings = {};
|
|||||||
gb_global GlobalTypeInfoData cg_global_type_info_member_tags = {};
|
gb_global GlobalTypeInfoData cg_global_type_info_member_tags = {};
|
||||||
gb_global GlobalTypeInfoData cg_global_type_info_member_enum_values = {};
|
gb_global GlobalTypeInfoData cg_global_type_info_member_enum_values = {};
|
||||||
|
|
||||||
|
gb_global cgProcedure *cg_startup_runtime_proc = nullptr;
|
||||||
|
gb_global cgProcedure *cg_cleanup_runtime_proc = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gb_internal TB_Arena *cg_arena(void);
|
gb_internal TB_Arena *cg_arena(void);
|
||||||
|
|||||||
+7
-1
@@ -555,11 +555,11 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GB_ASSERT(!is_type_array_like(bt));
|
|
||||||
|
|
||||||
switch (value.kind) {
|
switch (value.kind) {
|
||||||
case ExactValue_Bool:
|
case ExactValue_Bool:
|
||||||
{
|
{
|
||||||
|
GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type));
|
||||||
bool *res = cast(bool *)tb_global_add_region(m->mod, global, offset, size);
|
bool *res = cast(bool *)tb_global_add_region(m->mod, global, offset, size);
|
||||||
*res = !!value.value_bool;
|
*res = !!value.value_bool;
|
||||||
}
|
}
|
||||||
@@ -567,6 +567,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value
|
|||||||
|
|
||||||
case ExactValue_Integer:
|
case ExactValue_Integer:
|
||||||
{
|
{
|
||||||
|
GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type));
|
||||||
void *res = tb_global_add_region(m->mod, global, offset, size);
|
void *res = tb_global_add_region(m->mod, global, offset, size);
|
||||||
cg_write_big_int_at_ptr(res, &value.value_integer, type);
|
cg_write_big_int_at_ptr(res, &value.value_integer, type);
|
||||||
}
|
}
|
||||||
@@ -574,6 +575,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value
|
|||||||
|
|
||||||
case ExactValue_Float:
|
case ExactValue_Float:
|
||||||
{
|
{
|
||||||
|
GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type));
|
||||||
f64 f = exact_value_to_f64(value);
|
f64 f = exact_value_to_f64(value);
|
||||||
void *res = tb_global_add_region(m->mod, global, offset, size);
|
void *res = tb_global_add_region(m->mod, global, offset, size);
|
||||||
switch (size) {
|
switch (size) {
|
||||||
@@ -586,6 +588,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value
|
|||||||
|
|
||||||
case ExactValue_Pointer:
|
case ExactValue_Pointer:
|
||||||
{
|
{
|
||||||
|
GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type));
|
||||||
void *res = tb_global_add_region(m->mod, global, offset, size);
|
void *res = tb_global_add_region(m->mod, global, offset, size);
|
||||||
*(u64 *)res = exact_value_to_u64(value);
|
*(u64 *)res = exact_value_to_u64(value);
|
||||||
}
|
}
|
||||||
@@ -603,6 +606,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value
|
|||||||
|
|
||||||
case ExactValue_Typeid:
|
case ExactValue_Typeid:
|
||||||
{
|
{
|
||||||
|
GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type));
|
||||||
void *dst = tb_global_add_region(m->mod, global, offset, size);
|
void *dst = tb_global_add_region(m->mod, global, offset, size);
|
||||||
u64 id = cg_typeid_as_u64(m, value.value_typeid);
|
u64 id = cg_typeid_as_u64(m, value.value_typeid);
|
||||||
cg_write_uint_at_ptr(dst, id, t_typeid);
|
cg_write_uint_at_ptr(dst, id, t_typeid);
|
||||||
@@ -621,6 +625,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value
|
|||||||
break;
|
break;
|
||||||
case ExactValue_Complex:
|
case ExactValue_Complex:
|
||||||
{
|
{
|
||||||
|
GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type));
|
||||||
Complex128 c = {};
|
Complex128 c = {};
|
||||||
if (value.value_complex) {
|
if (value.value_complex) {
|
||||||
c = *value.value_complex;
|
c = *value.value_complex;
|
||||||
@@ -644,6 +649,7 @@ gb_internal bool cg_global_const_add_region(cgModule *m, ExactValue const &value
|
|||||||
break;
|
break;
|
||||||
case ExactValue_Quaternion:
|
case ExactValue_Quaternion:
|
||||||
{
|
{
|
||||||
|
GB_ASSERT_MSG(!is_type_array_like(bt), "%s", type_to_string(type));
|
||||||
// @QuaternionLayout
|
// @QuaternionLayout
|
||||||
Quaternion256 q = {};
|
Quaternion256 q = {};
|
||||||
if (value.value_quaternion) {
|
if (value.value_quaternion) {
|
||||||
|
|||||||
+47
-8
@@ -86,6 +86,39 @@ gb_internal cgValue cg_find_value_from_entity(cgModule *m, Entity *e) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal cgValue cg_get_using_variable(cgProcedure *p, Entity *e) {
|
||||||
|
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
|
||||||
|
String name = e->token.string;
|
||||||
|
Entity *parent = e->using_parent;
|
||||||
|
Selection sel = lookup_field(parent->type, name, false);
|
||||||
|
GB_ASSERT(sel.entity != nullptr);
|
||||||
|
cgValue *pv = map_get(&p->module->values, parent);
|
||||||
|
|
||||||
|
cgValue v = {};
|
||||||
|
|
||||||
|
if (pv == nullptr && parent->flags & EntityFlag_SoaPtrField) {
|
||||||
|
// NOTE(bill): using SOA value (probably from for-in statement)
|
||||||
|
GB_PANIC("TODO(bill): cg_get_soa_variable_addr");
|
||||||
|
// cgAddr parent_addr = cg_get_soa_variable_addr(p, parent);
|
||||||
|
// v = cg_addr_get_ptr(p, parent_addr);
|
||||||
|
} else if (pv != nullptr) {
|
||||||
|
v = *pv;
|
||||||
|
} else {
|
||||||
|
GB_ASSERT_MSG(e->using_expr != nullptr, "%.*s %.*s", LIT(e->token.string), LIT(name));
|
||||||
|
v = cg_build_addr_ptr(p, e->using_expr);
|
||||||
|
}
|
||||||
|
GB_ASSERT(v.node != nullptr);
|
||||||
|
GB_ASSERT_MSG(parent->type == type_deref(v.type), "%s %s", type_to_string(parent->type), type_to_string(v.type));
|
||||||
|
cgValue ptr = cg_emit_deep_field_gep(p, v, sel);
|
||||||
|
// if (parent->scope) {
|
||||||
|
// if ((parent->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) {
|
||||||
|
// cg_add_debug_local_variable(p, ptr.value, e->type, e->token);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// cg_add_debug_local_variable(p, ptr.value, e->type, e->token);
|
||||||
|
// }
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *expr) {
|
gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *expr) {
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
if (e->kind == Entity_Constant) {
|
if (e->kind == Entity_Constant) {
|
||||||
@@ -111,9 +144,8 @@ gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *exp
|
|||||||
if (found) {
|
if (found) {
|
||||||
v = *found;
|
v = *found;
|
||||||
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
||||||
GB_PANIC("TODO(bill): cg_get_using_variable");
|
|
||||||
// NOTE(bill): Calculate the using variable every time
|
// NOTE(bill): Calculate the using variable every time
|
||||||
// v = cg_get_using_variable(p, e);
|
v = cg_get_using_variable(p, e);
|
||||||
} else if (e->flags & EntityFlag_SoaPtrField) {
|
} else if (e->flags & EntityFlag_SoaPtrField) {
|
||||||
GB_PANIC("TODO(bill): cg_get_soa_variable_addr");
|
GB_PANIC("TODO(bill): cg_get_soa_variable_addr");
|
||||||
// return cg_get_soa_variable_addr(p, e);
|
// return cg_get_soa_variable_addr(p, e);
|
||||||
@@ -434,11 +466,10 @@ gb_internal cgValue cg_emit_comp(cgProcedure *p, TokenKind op_kind, cgValue left
|
|||||||
}
|
}
|
||||||
GB_ASSERT(runtime_procedure != nullptr);
|
GB_ASSERT(runtime_procedure != nullptr);
|
||||||
|
|
||||||
GB_PANIC("TODO(bill): cg_emit_runtime_call");
|
auto args = slice_make<cgValue>(permanent_allocator(), 2);
|
||||||
// auto args = array_make<lbValue>(permanent_allocator(), 2);
|
args[0] = left;
|
||||||
// args[0] = left;
|
args[1] = right;
|
||||||
// args[1] = right;
|
return cg_emit_runtime_call(p, runtime_procedure, args);
|
||||||
// return cg_emit_runtime_call(p, runtime_procedure, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_type_complex(a)) {
|
if (is_type_complex(a)) {
|
||||||
@@ -2514,7 +2545,15 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) {
|
|||||||
|
|
||||||
TB_CharUnits backing_size = cast(TB_CharUnits)(type_size_of(bt->Slice.elem) * count);
|
TB_CharUnits backing_size = cast(TB_CharUnits)(type_size_of(bt->Slice.elem) * count);
|
||||||
TB_CharUnits align = cast(TB_CharUnits)type_align_of(bt->Slice.elem);
|
TB_CharUnits align = cast(TB_CharUnits)type_align_of(bt->Slice.elem);
|
||||||
TB_Node *backing = tb_inst_local(p->func, backing_size, align);
|
|
||||||
|
TB_Node *backing = nullptr;
|
||||||
|
if (p->is_startup) {
|
||||||
|
TB_Global *global = tb_global_create(p->module->mod, 0, "", nullptr, TB_LINKAGE_PRIVATE);
|
||||||
|
tb_global_set_storage(p->module->mod, tb_module_get_data(p->module->mod), global, backing_size, align, 0);
|
||||||
|
backing = tb_inst_get_symbol_address(p->func, cast(TB_Symbol *)global);
|
||||||
|
} else {
|
||||||
|
backing = tb_inst_local(p->func, backing_size, align);
|
||||||
|
}
|
||||||
|
|
||||||
cgValue data = cg_value(backing, alloc_type_multi_pointer(bt->Slice.elem));
|
cgValue data = cg_value(backing, alloc_type_multi_pointer(bt->Slice.elem));
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -408,8 +408,11 @@ gb_internal void cg_procedure_end(cgProcedure *p) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (tb_inst_get_control(p->func)) {
|
if (tb_inst_get_control(p->func)) {
|
||||||
GB_ASSERT(p->type->Proc.result_count == 0);
|
if (p->type->Proc.result_count == 0) {
|
||||||
tb_inst_ret(p->func, 0, nullptr);
|
tb_inst_ret(p->func, 0, nullptr);
|
||||||
|
} else {
|
||||||
|
tb_inst_unreachable(p->func);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->module->do_threading) {
|
if (p->module->do_threading) {
|
||||||
|
|||||||
Reference in New Issue
Block a user