From cf1fd6e9500401a78ef0ecd5ce103d630f0b0f5d Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 19 Jan 2020 12:11:58 +0000 Subject: [PATCH] array: fix arr << arr bug --- vlib/builtin/array.v | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index cdba1f302a..c926c35ad0 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -66,19 +66,20 @@ fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) arra // Private function. Doubles array capacity if needed fn (a mut array) ensure_cap(required int) { - if required > a.cap { - mut cap := if a.cap == 0 { 2 } else { a.cap * 2 } - for required > cap && true { - cap *= 2 - } - if a.cap == 0 { - a.data = calloc(cap * a.element_size) - } - else { - a.data = C.realloc(a.data, cap * a.element_size) - } - a.cap = cap + if required <= a.cap { + return } + mut cap := if a.cap == 0 { 2 } else { a.cap * 2 } + for required > cap { + cap *= 2 + } + if a.cap == 0 { + a.data = calloc(cap * a.element_size) + } + else { + a.data = C.realloc(a.data, cap * a.element_size) + } + a.cap = cap } // array.repeat returns new array with the given array elements @@ -280,8 +281,16 @@ fn (a mut array) push(val voidptr) { // `val` is array.data // TODO make private, right now it's used by strings.Builder pub fn (a mut array) push_many(val voidptr, size int) { - a.ensure_cap(a.len + size) - C.memcpy(a.data + a.element_size * a.len, val, a.element_size * size) + // handle `arr << arr` + if a.data == val { + copy := a.clone() + a.ensure_cap(a.len + size) + //C.memcpy(a.data, copy.data, copy.element_size * copy.len) + C.memcpy(a.data + a.element_size * a.len, copy.data, a.element_size * size) + } else { + a.ensure_cap(a.len + size) + C.memcpy(a.data + a.element_size * a.len, val, a.element_size * size) + } a.len += size }