authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-14 21:01:48-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-14 21:01:48-05:00
logaf4d4c882a588f82667ddfaf41a59ff3cbcc5832
treed321a3b15bde07d4150875ef78611ad44c8daa5a
parent2edc6c1a3fbce80132a023820897b929732f837e

IR: implement compile time array access


1 files changed, 58 insertions(+), 6 deletions(-)

src/ir.cpp+58-6
...@@ -2180,7 +2180,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in...@@ -2180,7 +2180,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in
2180 } else if (old_instruction->id == IrInstructionIdFieldPtr) {2180 } else if (old_instruction->id == IrInstructionIdFieldPtr) {
2181 zig_panic("TODO");2181 zig_panic("TODO");
2182 } else if (old_instruction->id == IrInstructionIdElemPtr) {2182 } else if (old_instruction->id == IrInstructionIdElemPtr) {
2183 zig_panic("TODO");2183 IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec,
2184 old_instruction->source_node);
2185 new_instruction = &elem_ptr_instruction->base;
2184 } else {2186 } else {
2185 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec,2187 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec,
2186 old_instruction->source_node);2188 old_instruction->source_node);
...@@ -2577,7 +2579,7 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira,...@@ -2577,7 +2579,7 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira,
2577 IrInstructionReturn *return_instruction)2579 IrInstructionReturn *return_instruction)
2578{2580{
2579 IrInstruction *value = return_instruction->value->other;2581 IrInstruction *value = return_instruction->value->other;
2580 if (value == ira->codegen->invalid_instruction)2582 if (value->type_entry->id == TypeTableEntryIdInvalid)
2581 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);2583 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
2582 ira->implicit_return_type_list.append(value);2584 ira->implicit_return_type_list.append(value);
25832585
...@@ -3512,7 +3514,12 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct...@@ -3512,7 +3514,12 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct
35123514
3513static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {3515static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {
3514 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other;3516 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other;
3517 if (array_ptr->type_entry->id == TypeTableEntryIdInvalid)
3518 return ira->codegen->builtin_types.entry_invalid;
3519
3515 IrInstruction *elem_index = elem_ptr_instruction->elem_index->other;3520 IrInstruction *elem_index = elem_ptr_instruction->elem_index->other;
3521 if (elem_index->type_entry->id == TypeTableEntryIdInvalid)
3522 return ira->codegen->builtin_types.entry_invalid;
35163523
3517 TypeTableEntry *array_type = array_ptr->type_entry;3524 TypeTableEntry *array_type = array_ptr->type_entry;
3518 TypeTableEntry *return_type;3525 TypeTableEntry *return_type;
...@@ -3522,7 +3529,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -3522,7 +3529,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
3522 } else if (array_type->id == TypeTableEntryIdArray) {3529 } else if (array_type->id == TypeTableEntryIdArray) {
3523 if (array_type->data.array.len == 0) {3530 if (array_type->data.array.len == 0) {
3524 add_node_error(ira->codegen, elem_ptr_instruction->base.source_node,3531 add_node_error(ira->codegen, elem_ptr_instruction->base.source_node,
3525 buf_sprintf("out of bounds array access"));3532 buf_sprintf("index 0 outside array of size 0"));
3526 }3533 }
3527 TypeTableEntry *child_type = array_type->data.array.child_type;3534 TypeTableEntry *child_type = array_type->data.array.child_type;
3528 return_type = get_pointer_to_type(ira->codegen, child_type, false);3535 return_type = get_pointer_to_type(ira->codegen, child_type, false);
...@@ -3541,12 +3548,57 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -3541,12 +3548,57 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
3541 if (casted_elem_index == ira->codegen->invalid_instruction)3548 if (casted_elem_index == ira->codegen->invalid_instruction)
3542 return ira->codegen->builtin_types.entry_invalid;3549 return ira->codegen->builtin_types.entry_invalid;
35433550
3544 if (array_ptr->static_value.ok && casted_elem_index->static_value.ok) {3551 if (casted_elem_index->static_value.ok) {
3545 zig_panic("TODO compile time array access");3552 uint64_t index = casted_elem_index->static_value.data.x_bignum.data.x_uint;
3553 if (array_type->id == TypeTableEntryIdArray) {
3554 uint64_t array_len = array_type->data.array.len;
3555 if (index >= array_len) {
3556 add_node_error(ira->codegen, elem_ptr_instruction->base.source_node,
3557 buf_sprintf("index %" PRIu64 " outside array of size %" PRIu64,
3558 index, array_len));
3559 return ira->codegen->builtin_types.entry_invalid;
3560 }
3561 }
3562
3563 if (array_ptr->static_value.ok) {
3564 bool depends_on_compile_var = array_ptr->static_value.depends_on_compile_var ||
3565 casted_elem_index->static_value.depends_on_compile_var;
3566 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var);
3567 out_val->data.x_ptr.len = 1;
3568 out_val->data.x_ptr.is_c_str = false;
3569 out_val->data.x_ptr.ptr = allocate<ConstExprValue *>(1);
3570 if (array_type->id == TypeTableEntryIdPointer) {
3571 uint64_t pointer_len = array_ptr->static_value.data.x_ptr.len;
3572 if (index >= pointer_len) {
3573 add_node_error(ira->codegen, elem_ptr_instruction->base.source_node,
3574 buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64,
3575 index, pointer_len));
3576 return ira->codegen->builtin_types.entry_invalid;
3577 }
3578 out_val->data.x_ptr.ptr[0] = array_ptr->static_value.data.x_ptr.ptr[index];
3579 } else if (is_slice(array_type)) {
3580 ConstExprValue *ptr_field = array_ptr->static_value.data.x_struct.fields[0];
3581 ConstExprValue *len_field = array_ptr->static_value.data.x_struct.fields[1];
3582 uint64_t slice_len = len_field->data.x_bignum.data.x_uint;
3583 if (index >= slice_len) {
3584 add_node_error(ira->codegen, elem_ptr_instruction->base.source_node,
3585 buf_sprintf("index %" PRIu64 " outside slice of size %" PRIu64,
3586 index, slice_len));
3587 return ira->codegen->builtin_types.entry_invalid;
3588 }
3589 assert(index < ptr_field->data.x_ptr.len);
3590 out_val->data.x_ptr.ptr[0] = ptr_field->data.x_ptr.ptr[index];
3591 } else if (array_type->id == TypeTableEntryIdArray) {
3592 out_val->data.x_ptr.ptr[0] = array_ptr->static_value.data.x_array.fields[index];
3593 } else {
3594 zig_unreachable();
3595 }
3596 return return_type;
3597 }
3598
3546 }3599 }
35473600
3548 ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr, casted_elem_index);3601 ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr, casted_elem_index);
3549
3550 return return_type;3602 return return_type;
3551}3603}
35523604