src/bytecode/procs.c
// Emit code for initializing an array with a string literal (is a copy of string literal).
//    var a: [6] char = "Hello";
//
//    Equivalent to:
//
//    var a: [6] char = {'H', 'e', 'l', 'l', 'o', '\0'};
Emit code for initializing an array with a string literal (is a copy of string literal).

Equivalent to.


Emit code for initializing an array with a string literal ( is a copy of string literal ) . Equivalent to .
static void IR_emit_array_str_init(IR_ProcBuilder* builder, IR_Operand* array_op, IR_Operand* init_op)
{
    assert(array_op->kind == IR_OPERAND_VAR || array_op->kind == IR_OPERAND_DEREF_ADDR);
    assert(init_op->kind == IR_OPERAND_STR_LIT);
    assert(array_op->type->kind == TYPE_ARRAY);
    Type* arr_type = array_op->type;
    Type* ptr_type = try_array_decay(builder->arena, &builder->type_cache->ptrs, arr_type);
    Type* elem_type = ptr_type->as_ptr.base;
    u64 num_elems = arr_type->as_array.len;
    StrLit* str_lit = init_op->str_lit;
    const char* str = str_lit->str;
    assert((str_lit->len + 1) == num_elems);
    IR_Operand base_ptr_op = {.kind = IR_OPERAND_MEM_ADDR, .type = ptr_type};
    IR_get_object_addr(builder, &base_ptr_op.addr, array_op);
    for (u64 elem_index = 0; elem_index < num_elems; elem_index += 1) {
        IR_Operand char_op = {.kind = IR_OPERAND_IMM, .type = elem_type, .imm.as_int._u64 = str[elem_index]};
        IR_Operand elem_ptr_op = {.kind = IR_OPERAND_DEREF_ADDR, .type = elem_type, .addr = base_ptr_op.addr};
        elem_ptr_op.addr.disp += elem_type->size * elem_index;
        IR_emit_assign(builder, &elem_ptr_op, &char_op);
    }
    IR_try_free_op_reg(builder, &base_ptr_op);
}
static void IR_emit_array_str_init ( IR_ProcBuilder * builder , IR_Operand * array_op , IR_Operand * init_op ) { assert ( array_op -> kind == IR_OPERAND_VAR || array_op -> kind == IR_OPERAND_DEREF_ADDR ) ; assert ( init_op -> kind == IR_OPERAND_STR_LIT ) ; assert ( array_op -> type -> kind == TYPE_ARRAY ) ; Type * arr_type = array_op -> type ; Type * ptr_type = try_array_decay ( builder -> arena , & builder -> type_cache -> ptrs , arr_type ) ; Type * elem_type = ptr_type -> as_ptr . base ; u64 num_elems = arr_type -> as_array . len ; StrLit * str_lit = init_op -> str_lit ; const char * str = str_lit -> str ; assert ( ( str_lit -> len + 1 ) == num_elems ) ; IR_Operand base_ptr_op = { . kind = IR_OPERAND_MEM_ADDR , . type = ptr_type } ; IR_get_object_addr ( builder , & base_ptr_op . addr , array_op ) ; for ( u64 elem_index = 0 ; elem_index < num_elems ; elem_index += 1 ) { IR_Operand char_op = { . kind = IR_OPERAND_IMM , . type = elem_type , . imm . as_int . _u64 = str [ elem_index ] } ; IR_Operand elem_ptr_op = { . kind = IR_OPERAND_DEREF_ADDR , . type = elem_type , . addr = base_ptr_op . addr } ; elem_ptr_op . addr . disp += elem_type -> size * elem_index ; IR_emit_assign ( builder , & elem_ptr_op , & char_op ) ; } IR_try_free_op_reg ( builder , & base_ptr_op ) ; }
Emit code for initializing an array with a string literal (is a copy of string literal).
Emit code for initializing an array with a string literal ( is a copy of string literal ) .
// Decay array into pointer to the first elem. // TODO: Reduce the number of assignment (mov) instructions by initializing // multiple elements at a time (one machine word's worth).