Jelajahi Sumber

Making slicing a little more robust

Ginger Bill 8 tahun lalu
induk
melakukan
4d0afc55c3
2 mengubah file dengan 33 tambahan dan 21 penghapusan
  1. 1 3
      core/_preload.odin
  2. 32 18
      src/ir.c

+ 1 - 3
core/_preload.odin

@@ -28,9 +28,7 @@ Calling_Convention :: enum {
 Type_Info_Record :: struct #ordered {
 	types:        []^Type_Info,
 	names:        []string,
-	offsets:      []int,    // offsets may not be used in tuples
-	// size:         int,
-	// align:        int,
+	offsets:      []int,  // offsets may not be used in tuples
 	packed:       bool,
 	ordered:      bool,
 	custom_align: bool,

+ 32 - 18
src/ir.c

@@ -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, 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;
 }
 
-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) {
@@ -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->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) {
-			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) {
 			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;
@@ -4925,7 +4932,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 			addr = base;
 			base = ir_emit_load(proc, base);
 		}
-
 		// TODO(bill): Cleanup like mad!
 
 		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 *len   = ir_emit_arith(proc, Token_Sub, high, 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);
 			ir_fill_slice(proc, slice, elem, len, cap);
 			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 *len   = ir_emit_arith(proc, Token_Sub, high, 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);
 			ir_fill_slice(proc, slice, elem, len, cap);
 			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 *len  = ir_emit_arith(proc, Token_Sub, high, 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);
 			ir_fill_slice(proc, slice, elem, len, cap);
 			return ir_addr(slice);
@@ -4982,17 +4997,16 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 		case Type_Basic: {
 			GB_ASSERT(type == t_string);
 			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 *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);
-			ir_emit_store(proc, ir_emit_struct_ep(proc, str, 0), elem);
-			ir_emit_store(proc, ir_emit_struct_ep(proc, str, 1), len);
-
+			ir_fill_string(proc, str, elem, len);
 			return ir_addr(str);
 		} break;
 		}