mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 22:09:49 +00:00
parent
99f077baf9
commit
01f066de37
@ -3638,6 +3638,23 @@ ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bo
|
||||
return const_val;
|
||||
}
|
||||
|
||||
void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *pointee_type,
|
||||
size_t addr, bool is_const)
|
||||
{
|
||||
const_val->special = ConstValSpecialStatic;
|
||||
const_val->type = get_pointer_to_type(g, pointee_type, is_const);
|
||||
const_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
|
||||
const_val->data.x_ptr.data.hard_coded_addr.addr = addr;
|
||||
}
|
||||
|
||||
ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type,
|
||||
size_t addr, bool is_const)
|
||||
{
|
||||
ConstExprValue *const_val = allocate<ConstExprValue>(1);
|
||||
init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const);
|
||||
return const_val;
|
||||
}
|
||||
|
||||
void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end) {
|
||||
const_val->special = ConstValSpecialStatic;
|
||||
const_val->type = g->builtin_types.entry_arg_tuple;
|
||||
|
||||
@ -135,6 +135,11 @@ ConstExprValue *create_const_runtime(TypeTableEntry *type);
|
||||
void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *pointee_val, bool is_const);
|
||||
ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const);
|
||||
|
||||
void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *pointee_type,
|
||||
size_t addr, bool is_const);
|
||||
ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type,
|
||||
size_t addr, bool is_const);
|
||||
|
||||
void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,
|
||||
size_t elem_index, bool is_const);
|
||||
ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const);
|
||||
|
||||
117
src/ir.cpp
117
src/ir.cpp
@ -12515,6 +12515,8 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
|
||||
zig_panic("TODO slice const inner struct");
|
||||
case ConstPtrSpecialHardCodedAddr:
|
||||
array_val = nullptr;
|
||||
abs_offset = 0;
|
||||
rel_end = SIZE_MAX;
|
||||
break;
|
||||
}
|
||||
} else if (is_slice(array_type)) {
|
||||
@ -12540,69 +12542,72 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
|
||||
zig_panic("TODO slice const inner struct");
|
||||
case ConstPtrSpecialHardCodedAddr:
|
||||
array_val = nullptr;
|
||||
abs_offset = 0;
|
||||
rel_end = len_val->data.x_bignum.data.x_uint;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
if (array_val || parent_ptr->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
|
||||
uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint;
|
||||
if (start_scalar > rel_end) {
|
||||
ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
uint64_t end_scalar;
|
||||
if (end) {
|
||||
end_scalar = end->value.data.x_bignum.data.x_uint;
|
||||
} else {
|
||||
end_scalar = rel_end;
|
||||
}
|
||||
if (end_scalar > rel_end) {
|
||||
ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
if (start_scalar > end_scalar) {
|
||||
ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end"));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
||||
out_val->data.x_struct.fields = allocate<ConstExprValue>(2);
|
||||
|
||||
ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];
|
||||
|
||||
if (array_val) {
|
||||
size_t index = abs_offset + start_scalar;
|
||||
bool is_const = slice_is_const(return_type);
|
||||
init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const);
|
||||
if (array_type->id == TypeTableEntryIdArray) {
|
||||
ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut;
|
||||
}
|
||||
} else {
|
||||
switch (parent_ptr->data.x_ptr.special) {
|
||||
case ConstPtrSpecialInvalid:
|
||||
case ConstPtrSpecialDiscard:
|
||||
zig_unreachable();
|
||||
case ConstPtrSpecialRef:
|
||||
init_const_ptr_ref(ira->codegen, ptr_val,
|
||||
parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type));
|
||||
break;
|
||||
case ConstPtrSpecialBaseArray:
|
||||
zig_unreachable();
|
||||
case ConstPtrSpecialBaseStruct:
|
||||
zig_panic("TODO");
|
||||
case ConstPtrSpecialHardCodedAddr:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];
|
||||
init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);
|
||||
|
||||
return return_type;
|
||||
uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint;
|
||||
if (start_scalar > rel_end) {
|
||||
ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
uint64_t end_scalar;
|
||||
if (end) {
|
||||
end_scalar = end->value.data.x_bignum.data.x_uint;
|
||||
} else {
|
||||
end_scalar = rel_end;
|
||||
}
|
||||
if (end_scalar > rel_end) {
|
||||
ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice"));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
if (start_scalar > end_scalar) {
|
||||
ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end"));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
||||
out_val->data.x_struct.fields = allocate<ConstExprValue>(2);
|
||||
|
||||
ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];
|
||||
|
||||
if (array_val) {
|
||||
size_t index = abs_offset + start_scalar;
|
||||
bool is_const = slice_is_const(return_type);
|
||||
init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const);
|
||||
if (array_type->id == TypeTableEntryIdArray) {
|
||||
ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut;
|
||||
}
|
||||
} else {
|
||||
switch (parent_ptr->data.x_ptr.special) {
|
||||
case ConstPtrSpecialInvalid:
|
||||
case ConstPtrSpecialDiscard:
|
||||
zig_unreachable();
|
||||
case ConstPtrSpecialRef:
|
||||
init_const_ptr_ref(ira->codegen, ptr_val,
|
||||
parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type));
|
||||
break;
|
||||
case ConstPtrSpecialBaseArray:
|
||||
zig_unreachable();
|
||||
case ConstPtrSpecialBaseStruct:
|
||||
zig_panic("TODO");
|
||||
case ConstPtrSpecialHardCodedAddr:
|
||||
init_const_ptr_hard_coded_addr(ira->codegen, ptr_val,
|
||||
parent_ptr->type->data.pointer.child_type,
|
||||
parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar,
|
||||
slice_is_const(return_type));
|
||||
}
|
||||
}
|
||||
|
||||
ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];
|
||||
init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);
|
||||
|
||||
return return_type;
|
||||
}
|
||||
|
||||
IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr_ptr,
|
||||
|
||||
@ -26,6 +26,7 @@ comptime {
|
||||
_ = @import("cases/pub_enum/index.zig");
|
||||
_ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
_ = @import("cases/sizeof_and_typeof.zig");
|
||||
_ = @import("cases/slice.zig");
|
||||
_ = @import("cases/struct.zig");
|
||||
_ = @import("cases/struct_contains_slice_of_itself.zig");
|
||||
_ = @import("cases/switch.zig");
|
||||
|
||||
11
test/cases/slice.zig
Normal file
11
test/cases/slice.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
const x = @intToPtr(&i32, 0x1000)[0...0x500];
|
||||
const y = x[0x100...];
|
||||
test "compile time slice of pointer to hard coded address" {
|
||||
assert(usize(x.ptr) == 0x1000);
|
||||
assert(x.len == 0x500);
|
||||
|
||||
assert(usize(y.ptr) == 0x1100);
|
||||
assert(y.len == 0x400);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user