diff --git a/code/demo.odin b/code/demo.odin index 9f9658e08..57052d66d 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -2,16 +2,8 @@ #import "utf8.odin" #import "hash.odin" #import "mem.odin" - - +#import "game.odin" main :: proc() { - Vec3 :: struct { - x, y: i16 - z: int - } - z := 123 - v := Vec3{x = 4, y = 5, z = z} - fmt.println(v) } diff --git a/core/os.odin b/core/os.odin index 6f0d0d516..279722790 100644 --- a/core/os.odin +++ b/core/os.odin @@ -43,19 +43,16 @@ File_Standard :: type enum { COUNT, } -__std_files := __set_file_standards(); +__std_files := [..]File{ + File{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE)}, + File{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)}, + File{handle = win32.GetStdHandle(win32.STD_ERROR_HANDLE)}, +} stdin := ^__std_files[File_Standard.INPUT] stdout := ^__std_files[File_Standard.OUTPUT] stderr := ^__std_files[File_Standard.ERROR] -__set_file_standards :: proc() -> [File_Standard.COUNT as int]File { - return [File_Standard.COUNT as int]File{ - File{handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE)}, - File{handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)}, - File{handle = win32.GetStdHandle(win32.STD_ERROR_HANDLE)}, - } -} read_entire_file :: proc(name: string) -> (string, bool) { diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 9e2db6544..6f9957408 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -3372,7 +3372,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint } break; - // case Type_Slice: + case Type_Slice: case Type_Array: case Type_Vector: { @@ -3392,7 +3392,11 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint i64 max = 0; isize index = 0; - for (; index < gb_array_count(cl->elems); index++) { + isize elem_count = 0; + if (cl->elems != NULL) { + elem_count = gb_array_count(cl->elems); + } + for (; index < elem_count; index++) { AstNode *e = cl->elems[index]; if (e->kind == AstNode_FieldValue) { error(ast_node_token(e), diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 87aaab101..9999c7cdb 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -278,6 +278,7 @@ void ssa_gen_tree(ssaGen *s) { } { // NOTE(bill): Setup type_info data + // TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR ssaValue *type_info_data = NULL; ssaValue *type_info_member_data = NULL; diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 3957b0e36..3ae53e596 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -263,7 +263,32 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) { } } -void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type_hint); +void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type); + +void ssa_print_compound_element(ssaFileBuffer *f, ssaModule *m, ExactValue v, Type *elem_type) { + if (v.kind == ExactValue_Invalid) { + ssa_fprintf(f, "zeroinitializer"); + } else if (v.kind == ExactValue_String) { + // HACK NOTE(bill): This is a hack but it works because strings are created at the very end + // of the .ll file + ssaValue *str_array = ssa_add_global_string_array(m, v.value_string); + + ssa_fprintf(f, "{i8* getelementptr inbounds ("); + ssa_print_type(f, m, str_array->Global.entity->type); + ssa_fprintf(f, ", "); + ssa_print_type(f, m, str_array->Global.entity->type); + ssa_fprintf(f, "* "); + ssa_print_encoded_global(f, str_array->Global.entity->token.string, false); + ssa_fprintf(f, ", "); + ssa_print_type(f, m, t_int); + ssa_fprintf(f, " 0, i32 0), "); + ssa_print_type(f, m, t_int); + ssa_fprintf(f, " %lld}", cast(i64)v.value_string.len); + + } else { + ssa_print_exact_value(f, m, v, elem_type); + } +} void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type) { type = base_type(type); @@ -324,14 +349,19 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ break; case ExactValue_Compound: { - // ssa_fprintf(f, "%s", (value.value_bool ? "true" : "false")); type = base_type(type); if (is_type_array(type)) { + ast_node(cl, CompoundLit, value.value_compound); + isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0; + if (elem_count == 0) { + ssa_fprintf(f, "zeroinitializer"); + break; + } + ssa_fprintf(f, "["); Type *elem_type = type->Array.elem; - ast_node(cl, CompoundLit, value.value_compound); - for (isize i = 0; i < type->Array.count; i++) { + for (isize i = 0; i < elem_count; i++) { if (i > 0) { ssa_fprintf(f, ", "); } @@ -340,10 +370,55 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); GB_ASSERT(tav != NULL); - ssa_print_exact_value(f, m, tav->value, elem_type); + ssa_print_compound_element(f, m, tav->value, elem_type); + } + for (isize i = elem_count; i < type->Array.count; i++) { + if (i >= elem_count) { + ssa_fprintf(f, ", "); + } + ssa_print_type(f, m, elem_type); + ssa_fprintf(f, " zeroinitializer"); } ssa_fprintf(f, "]"); + } else if (is_type_vector(type)) { + ast_node(cl, CompoundLit, value.value_compound); + isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0; + if (elem_count == 0) { + ssa_fprintf(f, "zeroinitializer"); + break; + } + + ssa_fprintf(f, "<"); + Type *elem_type = type->Vector.elem; + + if (elem_count == 1 && type->Vector.count > 1) { + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[0]); + GB_ASSERT(tav != NULL); + + for (isize i = 0; i < type->Vector.count; i++) { + if (i > 0) { + ssa_fprintf(f, ", "); + } + ssa_print_type(f, m, elem_type); + ssa_fprintf(f, " "); + ssa_print_compound_element(f, m, tav->value, elem_type); + } + } else { + for (isize i = 0; i < elem_count; i++) { + if (i > 0) { + ssa_fprintf(f, ", "); + } + ssa_print_type(f, m, elem_type); + ssa_fprintf(f, " "); + + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); + GB_ASSERT(tav != NULL); + ssa_print_compound_element(f, m, tav->value, elem_type); + } + } + + ssa_fprintf(f, ">"); } else if (is_type_struct(type)) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena); defer (gb_temp_arena_memory_end(tmp)); @@ -361,7 +436,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ if (cl->elems[0]->kind == AstNode_FieldValue) { - isize elem_count = gb_array_count(cl->elems); + isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0; for (isize i = 0; i < elem_count; i++) { ast_node(fv, FieldValue, cl->elems[i]); String name = fv->field->Ident.string; @@ -401,30 +476,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ ssa_print_type(f, m, elem_type); ssa_fprintf(f, " "); - - ExactValue v = values[i]; - if (v.kind == ExactValue_Invalid) { - ssa_fprintf(f, "zeroinitializer"); - } else if (v.kind == ExactValue_String) { - // HACK NOTE(bill): This is a hack but it works because strings are created at the very end - // of the .ll file - ssaValue *str_array = ssa_add_global_string_array(m, v.value_string); - - ssa_fprintf(f, "{i8* getelementptr inbounds ("); - ssa_print_type(f, m, str_array->Global.entity->type); - ssa_fprintf(f, ", "); - ssa_print_type(f, m, str_array->Global.entity->type); - ssa_fprintf(f, "* "); - ssa_print_encoded_global(f, str_array->Global.entity->token.string, false); - ssa_fprintf(f, ", "); - ssa_print_type(f, m, t_int); - ssa_fprintf(f, " 0, i32 0), "); - ssa_print_type(f, m, t_int); - ssa_fprintf(f, " %lld}", cast(i64)v.value_string.len); - - } else { - ssa_print_exact_value(f, m, v, elem_type); - } + ssa_print_compound_element(f, m, values[i], elem_type); } @@ -455,9 +507,37 @@ void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type return; } switch (value->kind) { + default: GB_PANIC("Unknown ssaValue kind"); break; + case ssaValue_Constant: ssa_print_exact_value(f, m, value->Constant.value, type_hint); break; + + case ssaValue_ConstantSlice: { + auto *cs = &value->ConstantSlice; + if (cs->backing_array == NULL || cs->count == 0) { + ssa_fprintf(f, "zeroinitializer"); + } else { + Type *at = base_type(type_deref(ssa_type(cs->backing_array))); + Type *et = at->Array.elem; + ssa_fprintf(f, "{"); + ssa_print_type(f, m, et); + ssa_fprintf(f, "* getelementptr inbounds ("); + ssa_print_type(f, m, at); + ssa_fprintf(f, ", "); + ssa_print_type(f, m, at); + ssa_fprintf(f, "* "); + ssa_print_value(f, m, cs->backing_array, at); + ssa_fprintf(f, ", "); + ssa_print_type(f, m, t_int); + ssa_fprintf(f, " 0, i32 0), "); + ssa_print_type(f, m, t_int); + ssa_fprintf(f, " %lld, ", cs->count); + ssa_print_type(f, m, t_int); + ssa_fprintf(f, " %lld}", cs->count); + } + } break; + case ssaValue_TypeName: ssa_print_encoded_local(f, value->TypeName.name); break; @@ -467,21 +547,7 @@ void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type if (scope != NULL) { in_global_scope = scope->is_global || scope->is_init; } - // if (type_hint != NULL && is_type_string(type_hint)) { - // ssa_fprintf(f, "{i8* getelementptr inbounds ("); - // ssa_print_type(f, m, value->Global.entity->type); - // ssa_fprintf(f, ", "); - // ssa_print_type(f, m, value->Global.entity->type); - // ssa_fprintf(f, "* "); - // ssa_print_encoded_global(f, value->Global.entity->token.string, in_global_scope); - // ssa_fprintf(f, ", "); - // ssa_print_type(f, m, t_int); - // ssa_fprintf(f, " 0, i32 0), "); - // ssa_print_type(f, m, t_int); - // ssa_fprintf(f, " %lld}", 0); - // } else { - ssa_print_encoded_global(f, value->Global.entity->token.string, in_global_scope); - // } + ssa_print_encoded_global(f, value->Global.entity->token.string, in_global_scope); } break; case ssaValue_Param: ssa_print_encoded_local(f, value->Param.entity->token.string); diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 7cc23e2ce..e8aa3bebf 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -62,9 +62,9 @@ struct ssaModule { Map type_names; // Key: Type * Map debug_info; // Key: Unique pointer i32 global_string_index; + i32 global_array_index; // For ConstantSlice gbArray(ssaValue *) procs; // NOTE(bill): Procedures to generate - gbArray(ssaValue *) const_compound_lits; }; @@ -144,6 +144,7 @@ struct ssaProcedure { SSA_INSTR_KIND(Load), \ SSA_INSTR_KIND(GetElementPtr), \ SSA_INSTR_KIND(ExtractValue), \ + SSA_INSTR_KIND(InsertValue), \ SSA_INSTR_KIND(Conv), \ SSA_INSTR_KIND(Br), \ SSA_INSTR_KIND(Ret), \ @@ -238,6 +239,11 @@ struct ssaInstr { Type * elem_type; i32 index; } ExtractValue; + struct { + ssaValue *value; + ssaValue *elem; + ssaValue *index; + } InsertValue; struct { ssaConvKind kind; ssaValue *value; @@ -291,7 +297,7 @@ enum ssaValueKind { ssaValue_Invalid, ssaValue_Constant, - ssaValue_ConstantArray, + ssaValue_ConstantSlice, ssaValue_TypeName, ssaValue_Global, ssaValue_Param, @@ -314,8 +320,9 @@ struct ssaValue { } Constant; struct { Type *type; - gbArray(ssaValue *) values; - } ConstantArray; + ssaValue *backing_array; + i64 count; + } ConstantSlice; struct { String name; Type * type; @@ -415,7 +422,6 @@ void ssa_init_module(ssaModule *m, Checker *c) { map_init(&m->debug_info, gb_heap_allocator()); map_init(&m->type_names, gb_heap_allocator()); gb_array_init(m->procs, gb_heap_allocator()); - gb_array_init(m->const_compound_lits, gb_heap_allocator()); // Default states m->stmt_state_flags = 0; @@ -480,7 +486,6 @@ void ssa_destroy_module(ssaModule *m) { map_destroy(&m->type_names); map_destroy(&m->debug_info); gb_array_free(m->procs); - gb_array_free(m->const_compound_lits); gb_arena_free(&m->arena); } @@ -498,6 +503,8 @@ Type *ssa_type(ssaInstr *instr) { return instr->GetElementPtr.result_type; case ssaInstr_ExtractValue: return instr->ExtractValue.result_type; + case ssaInstr_InsertValue: + return ssa_type(instr->InsertValue.value); case ssaInstr_BinaryOp: return instr->BinaryOp.type; case ssaInstr_Conv: @@ -531,6 +538,8 @@ Type *ssa_type(ssaValue *value) { switch (value->kind) { case ssaValue_Constant: return value->Constant.type; + case ssaValue_ConstantSlice: + return value->ConstantSlice.type; case ssaValue_TypeName: return value->TypeName.type; case ssaValue_Global: @@ -697,6 +706,15 @@ ssaValue *ssa_make_instr_extract_value(ssaProcedure *p, ssaValue *address, i32 i // GB_ASSERT(et->kind == Type_Struct || et->kind == Type_Array || et->kind == Type_Tuple); return v; } +ssaValue *ssa_make_instr_insert_value(ssaProcedure *p, ssaValue *value, ssaValue *elem, ssaValue *index) { + Type *t = ssa_type(value); + GB_ASSERT(is_type_array(t) || is_type_struct(t)); + ssaValue *v = ssa_alloc_instr(p, ssaInstr_InsertValue); + v->Instr.InsertValue.value = value; + v->Instr.InsertValue.elem = elem; + v->Instr.InsertValue.index = index; + return v; +} ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, Token op, ssaValue *left, ssaValue *right, Type *type) { @@ -803,6 +821,15 @@ ssaValue *ssa_make_value_constant(gbAllocator a, Type *type, ExactValue value) { return v; } + +ssaValue *ssa_make_value_constant_slice(gbAllocator a, Type *type, ssaValue *backing_array, i64 count) { + ssaValue *v = ssa_alloc_value(a, ssaValue_ConstantSlice); + v->ConstantSlice.type = type; + v->ConstantSlice.backing_array = backing_array; + v->ConstantSlice.count = count; + return v; +} + ssaValue *ssa_make_const_int(gbAllocator a, i64 i) { return ssa_make_value_constant(a, t_int, make_exact_value_integer(i)); } @@ -817,13 +844,39 @@ ssaValue *ssa_make_const_bool(gbAllocator a, b32 b) { } ssaValue *ssa_add_module_constant(ssaModule *m, Type *type, ExactValue value) { - ssaValue *v = ssa_make_value_constant(m->allocator, type, value); + if (is_type_slice(type)) { + ast_node(cl, CompoundLit, value.value_compound); + gbAllocator a = m->allocator; - if (!is_type_constant_type(type)) { - gb_array_append(m->const_compound_lits, v); + isize count = 0; + if (cl->elems) { + count = gb_array_count(cl->elems); + } + if (count > 0) { + Type *elem = base_type(type)->Slice.elem; + Type *t = make_type_array(a, elem, count); + ssaValue *backing_array = ssa_add_module_constant(m, t, value); + + + isize max_len = 7+8+1; + u8 *str = cast(u8 *)gb_alloc_array(a, u8, max_len); + isize len = gb_snprintf(cast(char *)str, max_len, "__csba$%x", m->global_array_index); + m->global_array_index++; + + String name = make_string(str, len-1); + + Entity *e = make_entity_constant(a, NULL, make_token_ident(name), t, value); + ssaValue *g = ssa_make_value_global(a, e, backing_array); + ssa_module_add_value(m, e, g); + map_set(&m->members, hash_string(name), g); + + return ssa_make_value_constant_slice(a, type, g, count); + } else { + return ssa_make_value_constant_slice(a, type, NULL, 0); + } } - return v; + return ssa_make_value_constant(m->allocator, type, value); } @@ -1547,7 +1600,7 @@ ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *ba ssaValue *ssa_add_global_string_array(ssaModule *m, String string) { gbAllocator a = m->allocator; - isize max_len = 4+8+1; + isize max_len = 6+8+1; u8 *str = cast(u8 *)gb_alloc_array(a, u8, max_len); isize len = gb_snprintf(cast(char *)str, max_len, "__str$%x", m->global_string_index); m->global_string_index++; @@ -2119,33 +2172,45 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case Type_Slice: et = bt->Slice.elem; break; } + auto is_elem_const = [](ssaModule *m, AstNode *elem) -> b32 { + if (elem->kind == AstNode_FieldValue) { + elem = elem->FieldValue.value; + } + TypeAndValue *tav = type_and_value_of_expression(m->info, elem); + GB_ASSERT(tav != NULL); + return tav->value.kind != ExactValue_Invalid; + }; + switch (bt->kind) { default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break; case Type_Vector: { - - ssaValue *result = ssa_emit_load(proc, v); - for (isize index = 0; index < gb_array_count(cl->elems); index++) { - AstNode *elem = cl->elems[index]; - ssaValue *field_elem = ssa_build_expr(proc, elem); - Type *t = ssa_type(field_elem); - GB_ASSERT(t->kind != Type_Tuple); - ssaValue *ev = ssa_emit_conv(proc, field_elem, et); - ssaValue *i = ssa_make_const_int(proc->module->allocator, index); - result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i)); - } - - if (gb_array_count(cl->elems) == 1 && bt->Vector.count > 1) { - isize index_count = bt->Vector.count; - i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); - for (isize i = 0; i < index_count; i++) { - indices[i] = 0; + ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)); + if (cl->elems != NULL) { + for (isize index = 0; index < gb_array_count(cl->elems); index++) { + AstNode *elem = cl->elems[index]; + if (is_elem_const(proc->module, elem)) { + continue; + } + ssaValue *field_elem = ssa_build_expr(proc, elem); + Type *t = ssa_type(field_elem); + GB_ASSERT(t->kind != Type_Tuple); + ssaValue *ev = ssa_emit_conv(proc, field_elem, et); + ssaValue *i = ssa_make_const_int(proc->module->allocator, index); + result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i)); } - ssaValue *sv = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, result, indices, index_count)); - ssa_emit_store(proc, v, sv); - return ssa_emit_load(proc, v); - } + if (gb_array_count(cl->elems) == 1 && bt->Vector.count > 1) { + isize index_count = bt->Vector.count; + i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); + for (isize i = 0; i < index_count; i++) { + indices[i] = 0; + } + ssaValue *sv = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, result, indices, index_count)); + ssa_emit_store(proc, v, sv); + return ssa_emit_load(proc, v); + } + } return result; } break; @@ -2153,18 +2218,24 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue GB_ASSERT(is_type_struct(bt)); auto *st = &bt->Record; if (cl->elems != NULL && gb_array_count(cl->elems) > 0) { + ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr))); gb_for_array(field_index, cl->elems) { - isize index = field_index; - AstNode *elem = cl->elems[index]; + AstNode *elem = cl->elems[field_index]; + if (is_elem_const(proc->module, elem)) { + continue; + } + ssaValue *field_expr = NULL; Entity *field = NULL; + isize index = field_index; if (elem->kind == AstNode_FieldValue) { - ast_node(kv, FieldValue, elem); - Selection sel = lookup_field(proc->module->allocator, bt, kv->field->Ident.string, false); + ast_node(fv, FieldValue, elem); + Selection sel = lookup_field(proc->module->allocator, bt, fv->field->Ident.string, false); index = sel.index[0]; - field_expr = ssa_build_expr(proc, kv->value); + field_expr = ssa_build_expr(proc, fv->value); } else { + TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem); Selection sel = lookup_field(proc->module->allocator, bt, st->fields_in_src_order[field_index]->token.string, false); index = sel.index[0]; field_expr = ssa_build_expr(proc, elem); @@ -2182,47 +2253,62 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue } } break; case Type_Array: { - gb_for_array(i, cl->elems) { - AstNode *elem = cl->elems[i]; - ssaValue *field_expr = ssa_build_expr(proc, elem); - Type *t = ssa_type(field_expr); - GB_ASSERT(t->kind != Type_Tuple); - ssaValue *ev = ssa_emit_conv(proc, field_expr, et); - ssaValue *gep = ssa_emit_struct_gep(proc, v, i, et); - ssa_emit_store(proc, gep, ev); + if (cl->elems != NULL && gb_array_count(cl->elems) > 0) { + ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr))); + gb_for_array(i, cl->elems) { + AstNode *elem = cl->elems[i]; + if (is_elem_const(proc->module, elem)) { + continue; + } + ssaValue *field_expr = ssa_build_expr(proc, elem); + Type *t = ssa_type(field_expr); + GB_ASSERT(t->kind != Type_Tuple); + ssaValue *ev = ssa_emit_conv(proc, field_expr, et); + ssaValue *gep = ssa_emit_struct_gep(proc, v, i, et); + ssa_emit_store(proc, gep, ev); + } } } break; case Type_Slice: { - i64 count = gb_array_count(cl->elems); - Type *elem_type = bt->Slice.elem; - Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type); - ssaValue *array = ssa_add_local_generated(proc, make_type_array(proc->module->allocator, elem_type, count)); + if (cl->elems != NULL && gb_array_count(cl->elems) > 0) { + Type *elem_type = bt->Slice.elem; + Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type); + Type *elem_ptr_ptr_type = make_type_pointer(proc->module->allocator, elem_ptr_type); + Type *t_int_ptr = make_type_pointer(proc->module->allocator, t_int); + ssaValue *slice = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)); + GB_ASSERT(slice->kind == ssaValue_ConstantSlice); - gb_for_array(i, cl->elems) { - AstNode *elem = cl->elems[i]; - ssaValue *field_expr = ssa_build_expr(proc, elem); - Type *t = ssa_type(field_expr); - GB_ASSERT(t->kind != Type_Tuple); - ssaValue *ev = ssa_emit_conv(proc, field_expr, elem_type); - ssaValue *gep = ssa_emit_struct_gep(proc, array, i, elem_ptr_type); - ssa_emit_store(proc, gep, ev); + ssaValue *data = ssa_emit_struct_gep(proc, slice->ConstantSlice.backing_array, v_zero32, elem_ptr_type); + + gb_for_array(i, cl->elems) { + AstNode *elem = cl->elems[i]; + if (is_elem_const(proc->module,elem)) { + continue; + } + + ssaValue *field_expr = ssa_build_expr(proc, elem); + Type *t = ssa_type(field_expr); + GB_ASSERT(t->kind != Type_Tuple); + ssaValue *ev = ssa_emit_conv(proc, field_expr, elem_type); + ssaValue *offset = ssa_emit_ptr_offset(proc, data, ssa_make_const_int(proc->module->allocator, i)); + ssa_emit_store(proc, offset, ev); + } + + ssaValue *gep0 = ssa_emit_struct_gep(proc, v, v_zero32, elem_ptr_ptr_type); + ssaValue *gep1 = ssa_emit_struct_gep(proc, v, v_one32, t_int_ptr); + ssaValue *gep2 = ssa_emit_struct_gep(proc, v, v_two32, t_int_ptr); + + ssa_emit_store(proc, gep0, data); + ssa_emit_store(proc, gep1, ssa_make_const_int(proc->module->allocator, slice->ConstantSlice.count)); + ssa_emit_store(proc, gep2, ssa_make_const_int(proc->module->allocator, slice->ConstantSlice.count)); } - - ssaValue *elem = ssa_array_elem(proc, array); - ssaValue *len = ssa_array_len(proc, ssa_emit_load(proc, array)); - ssaValue *gep0 = ssa_emit_struct_gep(proc, v, v_zero32, ssa_type(elem)); - ssaValue *gep1 = ssa_emit_struct_gep(proc, v, v_one32, t_int); - ssaValue *gep2 = ssa_emit_struct_gep(proc, v, v_two32, t_int); - - ssa_emit_store(proc, gep0, elem); - ssa_emit_store(proc, gep1, len); - ssa_emit_store(proc, gep2, len); } break; } return ssa_emit_load(proc, v); case_end; + case_ast_node(ce, CallExpr, expr); AstNode *p = unparen_expr(ce->proc); if (p->kind == AstNode_Ident) { diff --git a/src/common.cpp b/src/common.cpp index f5fe5b50c..73f11b172 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -4,20 +4,39 @@ #include "string.cpp" -String get_module_dir(gbAllocator a) { - isize len = GetModuleFileNameW(NULL, NULL, 0); - if (len == 0) { - return make_string(NULL, 0); +gb_global String global_module_path = {}; +gb_global b32 global_module_path_set = false; + +String get_module_dir() { + if (global_module_path_set) { + return global_module_path; } + + gbArray(wchar_t) path_buf; + gb_array_init_reserve(path_buf, gb_heap_allocator(), 300); + defer (gb_array_free(path_buf)); + gb_array_resize(path_buf, 300); + + isize len = 0; + for (;;) { + len = GetModuleFileNameW(NULL, path_buf, gb_array_count(path_buf)); + if (len == 0) { + return make_string(NULL, 0); + } + if (len < gb_array_count(path_buf)) { + break; + } + gb_array_resize(path_buf, 2*gb_array_count(path_buf) + 300); + } + gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena); defer (gb_temp_arena_memory_end(tmp)); - wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1); String16 str = {text, len}; GetModuleFileNameW(NULL, text, len); - String path = string16_to_string(a, str); + String path = string16_to_string(gb_heap_allocator(), str); for (isize i = path.len-1; i >= 0; i--) { u8 c = path.text[i]; if (c == '/' || c == '\\') { @@ -26,6 +45,8 @@ String get_module_dir(gbAllocator a) { path.len--; } + global_module_path = path; + global_module_path_set = true; return path; } diff --git a/src/main.cpp b/src/main.cpp index 3e1398fb1..9982f6b68 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -118,8 +118,7 @@ int main(int argc, char **argv) { init_string_buffer_memory(); init_global_error_collector(); - String module_dir = get_module_dir(gb_heap_allocator()); - // defer (gb_free(gb_heap_allocator(), module_dir.text)); + String module_dir = get_module_dir(); INIT_TIMER(); diff --git a/src/parser.cpp b/src/parser.cpp index 6824d9561..136e88f33 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2919,10 +2919,7 @@ String get_fullpath_relative(gbAllocator a, String base_dir, String path) { } String get_fullpath_core(gbAllocator a, String path) { - String module_dir = get_module_dir(gb_heap_allocator()); - defer (if (module_dir.len > 0) { - gb_free(gb_heap_allocator(), module_dir.text); - }); + String module_dir = get_module_dir(); char core[] = "core/"; isize core_len = gb_size_of(core)-1;