authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-09 22:23:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-09 22:23:38-04:00
log01f066de379caf545ec65c572f75cc1ed1312799
tree0e96968a4ce4acf3eaa25a8edf43218ed25dd637
parent99f077baf96c0f19026ea3d7f9475aa41b720cb9

ability to slice ptr to hard coded integer at comptime

closes #369

5 files changed, 89 insertions(+), 50 deletions(-)

src/analyze.cpp+17
...@@ -3638,6 +3638,23 @@ ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bo...@@ -3638,6 +3638,23 @@ ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bo
3638 return const_val;3638 return const_val;
3639}3639}
36403640
3641void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *pointee_type,
3642 size_t addr, bool is_const)
3643{
3644 const_val->special = ConstValSpecialStatic;
3645 const_val->type = get_pointer_to_type(g, pointee_type, is_const);
3646 const_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
3647 const_val->data.x_ptr.data.hard_coded_addr.addr = addr;
3648}
3649
3650ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type,
3651 size_t addr, bool is_const)
3652{
3653 ConstExprValue *const_val = allocate<ConstExprValue>(1);
3654 init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const);
3655 return const_val;
3656}
3657
3641void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end) {3658void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end) {
3642 const_val->special = ConstValSpecialStatic;3659 const_val->special = ConstValSpecialStatic;
3643 const_val->type = g->builtin_types.entry_arg_tuple;3660 const_val->type = g->builtin_types.entry_arg_tuple;
src/analyze.hpp+5
...@@ -135,6 +135,11 @@ ConstExprValue *create_const_runtime(TypeTableEntry *type);...@@ -135,6 +135,11 @@ ConstExprValue *create_const_runtime(TypeTableEntry *type);
135void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *pointee_val, bool is_const);135void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *pointee_val, bool is_const);
136ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const);136ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const);
137137
138void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *pointee_type,
139 size_t addr, bool is_const);
140ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type,
141 size_t addr, bool is_const);
142
138void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,143void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,
139 size_t elem_index, bool is_const);144 size_t elem_index, bool is_const);
140ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const);145ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const);
src/ir.cpp+55-50
...@@ -12515,6 +12515,8 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -12515,6 +12515,8 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
12515 zig_panic("TODO slice const inner struct");12515 zig_panic("TODO slice const inner struct");
12516 case ConstPtrSpecialHardCodedAddr:12516 case ConstPtrSpecialHardCodedAddr:
12517 array_val = nullptr;12517 array_val = nullptr;
12518 abs_offset = 0;
12519 rel_end = SIZE_MAX;
12518 break;12520 break;
12519 }12521 }
12520 } else if (is_slice(array_type)) {12522 } else if (is_slice(array_type)) {
...@@ -12540,69 +12542,72 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -12540,69 +12542,72 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
12540 zig_panic("TODO slice const inner struct");12542 zig_panic("TODO slice const inner struct");
12541 case ConstPtrSpecialHardCodedAddr:12543 case ConstPtrSpecialHardCodedAddr:
12542 array_val = nullptr;12544 array_val = nullptr;
12545 abs_offset = 0;
12546 rel_end = len_val->data.x_bignum.data.x_uint;
12543 break;12547 break;
12544 }12548 }
12545 } else {12549 } else {
12546 zig_unreachable();12550 zig_unreachable();
12547 }12551 }
1254812552
12549 if (array_val || parent_ptr->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {12553 uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint;
12550 uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint;12554 if (start_scalar > rel_end) {
12551 if (start_scalar > rel_end) {12555 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));
12552 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));12556 return ira->codegen->builtin_types.entry_invalid;
12553 return ira->codegen->builtin_types.entry_invalid;12557 }
12554 }
1255512558
12556 uint64_t end_scalar;12559 uint64_t end_scalar;
12557 if (end) {12560 if (end) {
12558 end_scalar = end->value.data.x_bignum.data.x_uint;12561 end_scalar = end->value.data.x_bignum.data.x_uint;
12559 } else {12562 } else {
12560 end_scalar = rel_end;12563 end_scalar = rel_end;
12561 }12564 }
12562 if (end_scalar > rel_end) {12565 if (end_scalar > rel_end) {
12563 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));12566 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));
12564 return ira->codegen->builtin_types.entry_invalid;12567 return ira->codegen->builtin_types.entry_invalid;
12565 }12568 }
12566 if (start_scalar > end_scalar) {12569 if (start_scalar > end_scalar) {
12567 ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end"));12570 ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end"));
12568 return ira->codegen->builtin_types.entry_invalid;12571 return ira->codegen->builtin_types.entry_invalid;
12569 }12572 }
1257012573
12571 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);12574 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
12572 out_val->data.x_struct.fields = allocate<ConstExprValue>(2);12575 out_val->data.x_struct.fields = allocate<ConstExprValue>(2);
1257312576
12574 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];12577 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];
1257512578
12576 if (array_val) {12579 if (array_val) {
12577 size_t index = abs_offset + start_scalar;12580 size_t index = abs_offset + start_scalar;
12578 bool is_const = slice_is_const(return_type);12581 bool is_const = slice_is_const(return_type);
12579 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const);12582 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const);
12580 if (array_type->id == TypeTableEntryIdArray) {12583 if (array_type->id == TypeTableEntryIdArray) {
12581 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut;12584 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut;
12582 }
12583 } else {
12584 switch (parent_ptr->data.x_ptr.special) {
12585 case ConstPtrSpecialInvalid:
12586 case ConstPtrSpecialDiscard:
12587 zig_unreachable();
12588 case ConstPtrSpecialRef:
12589 init_const_ptr_ref(ira->codegen, ptr_val,
12590 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type));
12591 break;
12592 case ConstPtrSpecialBaseArray:
12593 zig_unreachable();
12594 case ConstPtrSpecialBaseStruct:
12595 zig_panic("TODO");
12596 case ConstPtrSpecialHardCodedAddr:
12597 zig_unreachable();
12598 }
12599 }12585 }
12586 } else {
12587 switch (parent_ptr->data.x_ptr.special) {
12588 case ConstPtrSpecialInvalid:
12589 case ConstPtrSpecialDiscard:
12590 zig_unreachable();
12591 case ConstPtrSpecialRef:
12592 init_const_ptr_ref(ira->codegen, ptr_val,
12593 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type));
12594 break;
12595 case ConstPtrSpecialBaseArray:
12596 zig_unreachable();
12597 case ConstPtrSpecialBaseStruct:
12598 zig_panic("TODO");
12599 case ConstPtrSpecialHardCodedAddr:
12600 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val,
12601 parent_ptr->type->data.pointer.child_type,
12602 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar,
12603 slice_is_const(return_type));
12604 }
12605 }
1260012606
12601 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];12607 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];
12602 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);12608 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);
1260312609
12604 return return_type;12610 return return_type;
12605 }
12606 }12611 }
1260712612
12608 IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr_ptr,12613 IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr_ptr,
test/behavior.zig+1
...@@ -26,6 +26,7 @@ comptime {...@@ -26,6 +26,7 @@ comptime {
26 _ = @import("cases/pub_enum/index.zig");26 _ = @import("cases/pub_enum/index.zig");
27 _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");27 _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
28 _ = @import("cases/sizeof_and_typeof.zig");28 _ = @import("cases/sizeof_and_typeof.zig");
29 _ = @import("cases/slice.zig");
29 _ = @import("cases/struct.zig");30 _ = @import("cases/struct.zig");
30 _ = @import("cases/struct_contains_slice_of_itself.zig");31 _ = @import("cases/struct_contains_slice_of_itself.zig");
31 _ = @import("cases/switch.zig");32 _ = @import("cases/switch.zig");
test/cases/slice.zig created+11
...@@ -0,0 +1,11 @@
1const assert = @import("std").debug.assert;
2
3const x = @intToPtr(&i32, 0x1000)[0...0x500];
4const y = x[0x100...];
5test "compile time slice of pointer to hard coded address" {
6 assert(usize(x.ptr) == 0x1000);
7 assert(x.len == 0x500);
8
9 assert(usize(y.ptr) == 0x1100);
10 assert(y.len == 0x400);
11}