mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Making slicing a little more robust
This commit is contained in:
+1
-3
@@ -28,9 +28,7 @@ Calling_Convention :: enum {
|
|||||||
Type_Info_Record :: struct #ordered {
|
Type_Info_Record :: struct #ordered {
|
||||||
types: []^Type_Info,
|
types: []^Type_Info,
|
||||||
names: []string,
|
names: []string,
|
||||||
offsets: []int, // offsets may not be used in tuples
|
offsets: []int, // offsets may not be used in tuples
|
||||||
// size: int,
|
|
||||||
// align: int,
|
|
||||||
packed: bool,
|
packed: bool,
|
||||||
ordered: bool,
|
ordered: bool,
|
||||||
custom_align: bool,
|
custom_align: bool,
|
||||||
|
|||||||
@@ -2522,6 +2522,21 @@ void ir_fill_slice(irProcedure *proc, irValue *slice_ptr, irValue *data, irValue
|
|||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 1), len);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 1), len);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 2), cap);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, slice_ptr, 2), cap);
|
||||||
}
|
}
|
||||||
|
void ir_fill_string(irProcedure *proc, irValue *string_ptr, irValue *data, irValue *len) {
|
||||||
|
Type *t = ir_type(string_ptr);
|
||||||
|
GB_ASSERT(is_type_pointer(t));
|
||||||
|
t = type_deref(t);
|
||||||
|
GB_ASSERT(is_type_string(t));
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, string_ptr, 0), data);
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, string_ptr, 1), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
irValue *ir_emit_string(irProcedure *proc, irValue *elem, irValue *len) {
|
||||||
|
irValue *str = ir_add_local_generated(proc, t_string);
|
||||||
|
ir_fill_string(proc, str, elem, len);
|
||||||
|
return ir_emit_load(proc, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2566,16 +2581,6 @@ irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base,
|
|||||||
return slice;
|
return slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *ir_emit_string(irProcedure *proc, irValue *elem, irValue *len) {
|
|
||||||
irValue *str = ir_add_local_generated(proc, t_string);
|
|
||||||
irValue *str_elem = ir_emit_struct_ep(proc, str, 0);
|
|
||||||
irValue *str_len = ir_emit_struct_ep(proc, str, 1);
|
|
||||||
ir_emit_store(proc, str_elem, elem);
|
|
||||||
ir_emit_store(proc, str_len, len);
|
|
||||||
return ir_emit_load(proc, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
|
String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
|
||||||
@@ -4906,14 +4911,16 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
if (se->high != NULL) high = ir_build_expr(proc, se->high);
|
if (se->high != NULL) high = ir_build_expr(proc, se->high);
|
||||||
if (se->max != NULL) max = ir_build_expr(proc, se->max);
|
if (se->max != NULL) max = ir_build_expr(proc, se->max);
|
||||||
|
|
||||||
|
bool add_one_to_len = false;
|
||||||
|
bool add_one_to_cap = false;
|
||||||
|
|
||||||
if (high != NULL && se->interval0.kind == Token_Ellipsis) {
|
if (high != NULL && se->interval0.kind == Token_Ellipsis) {
|
||||||
high = ir_emit_arith(proc, Token_Add, high, v_one, t_int);
|
add_one_to_len = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max != NULL && se->interval1.kind == Token_Ellipsis) {
|
if (max != NULL && se->interval1.kind == Token_Ellipsis) {
|
||||||
GB_ASSERT(se->interval0.kind == se->interval1.kind);
|
GB_ASSERT(se->interval0.kind == se->interval1.kind);
|
||||||
max = ir_emit_arith(proc, Token_Add, max, v_one, t_int);
|
add_one_to_cap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *addr = ir_build_addr(proc, se->expr).addr;
|
irValue *addr = ir_build_addr(proc, se->expr).addr;
|
||||||
@@ -4925,7 +4932,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
addr = base;
|
addr = base;
|
||||||
base = ir_emit_load(proc, base);
|
base = ir_emit_load(proc, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bill): Cleanup like mad!
|
// TODO(bill): Cleanup like mad!
|
||||||
|
|
||||||
switch (type->kind) {
|
switch (type->kind) {
|
||||||
@@ -4940,6 +4946,9 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
irValue *elem = ir_emit_ptr_offset(proc, ir_slice_elem(proc, base), low);
|
irValue *elem = ir_emit_ptr_offset(proc, ir_slice_elem(proc, base), low);
|
||||||
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
||||||
irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int);
|
irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int);
|
||||||
|
if (add_one_to_len) len = ir_emit_arith(proc, Token_Add, len, v_one, t_int);
|
||||||
|
if (add_one_to_cap) cap = ir_emit_arith(proc, Token_Add, cap, v_one, t_int);
|
||||||
|
|
||||||
irValue *slice = ir_add_local_generated(proc, slice_type);
|
irValue *slice = ir_add_local_generated(proc, slice_type);
|
||||||
ir_fill_slice(proc, slice, elem, len, cap);
|
ir_fill_slice(proc, slice, elem, len, cap);
|
||||||
return ir_addr(slice);
|
return ir_addr(slice);
|
||||||
@@ -4957,6 +4966,9 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
irValue *elem = ir_emit_ptr_offset(proc, ir_dynamic_array_elem(proc, base), low);
|
irValue *elem = ir_emit_ptr_offset(proc, ir_dynamic_array_elem(proc, base), low);
|
||||||
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
||||||
irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int);
|
irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int);
|
||||||
|
if (add_one_to_len) len = ir_emit_arith(proc, Token_Add, len, v_one, t_int);
|
||||||
|
if (add_one_to_cap) cap = ir_emit_arith(proc, Token_Add, cap, v_one, t_int);
|
||||||
|
|
||||||
irValue *slice = ir_add_local_generated(proc, slice_type);
|
irValue *slice = ir_add_local_generated(proc, slice_type);
|
||||||
ir_fill_slice(proc, slice, elem, len, cap);
|
ir_fill_slice(proc, slice, elem, len, cap);
|
||||||
return ir_addr(slice);
|
return ir_addr(slice);
|
||||||
@@ -4974,6 +4986,9 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
irValue *elem = ir_emit_ptr_offset(proc, ir_array_elem(proc, addr), low);
|
irValue *elem = ir_emit_ptr_offset(proc, ir_array_elem(proc, addr), low);
|
||||||
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
||||||
irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int);
|
irValue *cap = ir_emit_arith(proc, Token_Sub, max, low, t_int);
|
||||||
|
if (add_one_to_len) len = ir_emit_arith(proc, Token_Add, len, v_one, t_int);
|
||||||
|
if (add_one_to_cap) cap = ir_emit_arith(proc, Token_Add, cap, v_one, t_int);
|
||||||
|
|
||||||
irValue *slice = ir_add_local_generated(proc, slice_type);
|
irValue *slice = ir_add_local_generated(proc, slice_type);
|
||||||
ir_fill_slice(proc, slice, elem, len, cap);
|
ir_fill_slice(proc, slice, elem, len, cap);
|
||||||
return ir_addr(slice);
|
return ir_addr(slice);
|
||||||
@@ -4982,17 +4997,16 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
case Type_Basic: {
|
case Type_Basic: {
|
||||||
GB_ASSERT(type == t_string);
|
GB_ASSERT(type == t_string);
|
||||||
if (high == NULL) high = ir_string_len(proc, base);
|
if (high == NULL) high = ir_string_len(proc, base);
|
||||||
if (max == NULL) max = ir_string_len(proc, base);
|
// if (max == NULL) max = ir_string_len(proc, base);
|
||||||
|
|
||||||
ir_emit_slice_bounds_check(proc, se->open, low, high, max, true);
|
ir_emit_slice_bounds_check(proc, se->open, low, high, NULL, true);
|
||||||
|
|
||||||
irValue *elem = ir_emit_ptr_offset(proc, ir_string_elem(proc, base), low);
|
irValue *elem = ir_emit_ptr_offset(proc, ir_string_elem(proc, base), low);
|
||||||
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
irValue *len = ir_emit_arith(proc, Token_Sub, high, low, t_int);
|
||||||
|
if (add_one_to_len) len = ir_emit_arith(proc, Token_Add, len, v_one, t_int);
|
||||||
|
|
||||||
irValue *str = ir_add_local_generated(proc, t_string);
|
irValue *str = ir_add_local_generated(proc, t_string);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, str, 0), elem);
|
ir_fill_string(proc, str, elem, len);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, str, 1), len);
|
|
||||||
|
|
||||||
return ir_addr(str);
|
return ir_addr(str);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user