diff options
Diffstat (limited to 'src/pkg/runtime/slice.c')
-rw-r--r-- | src/pkg/runtime/slice.c | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/src/pkg/runtime/slice.c b/src/pkg/runtime/slice.c index 70534279b..e5726c93b 100644 --- a/src/pkg/runtime/slice.c +++ b/src/pkg/runtime/slice.c @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. #include "runtime.h" +#include "arch_GOARCH.h" #include "type.h" #include "malloc.h" @@ -10,8 +11,7 @@ static int32 debug = 0; static void makeslice1(SliceType*, int32, int32, Slice*); static void growslice1(SliceType*, Slice, int32, Slice *); -static void appendslice1(SliceType*, Slice, Slice, Slice*); - void runtime·slicecopy(Slice to, Slice fm, uintptr width, int32 ret); + void runtime·copy(Slice to, Slice fm, uintptr width, int32 ret); // see also unsafe·NewArray // makeslice(typ *Type, len, cap int64) (ary []any); @@ -28,13 +28,18 @@ runtime·makeslice(SliceType *t, int64 len, int64 cap, Slice ret) if(debug) { runtime·printf("makeslice(%S, %D, %D); ret=", *t->string, len, cap); - runtime·printslice(ret); + runtime·printslice(ret); } } +// Dummy word to use as base pointer for make([]T, 0). +// Since you cannot take the address of such a slice, +// you can't tell that they all have the same base pointer. +static uintptr zerobase; + static void makeslice1(SliceType *t, int32 len, int32 cap, Slice *ret) -{ +{ uintptr size; size = cap*t->elem->size; @@ -42,7 +47,9 @@ makeslice1(SliceType *t, int32 len, int32 cap, Slice *ret) ret->len = len; ret->cap = cap; - if((t->elem->kind&KindNoPointers)) + if(cap == 0) + ret->array = (byte*)&zerobase; + else if((t->elem->kind&KindNoPointers)) ret->array = runtime·mallocgc(size, FlagNoPointers, 1, 1); else ret->array = runtime·mal(size); @@ -52,14 +59,31 @@ makeslice1(SliceType *t, int32 len, int32 cap, Slice *ret) void runtime·appendslice(SliceType *t, Slice x, Slice y, Slice ret) { - appendslice1(t, x, y, &ret); + int32 m; + uintptr w; + + m = x.len+y.len; + + if(m < x.len) + runtime·throw("append: slice overflow"); + + if(m > x.cap) + growslice1(t, x, m, &ret); + else + ret = x; + + w = t->elem->size; + runtime·memmove(ret.array + ret.len*w, y.array, y.len*w); + ret.len += y.len; + FLUSH(&ret); } -static void -appendslice1(SliceType *t, Slice x, Slice y, Slice *ret) + +// appendstr([]byte, string) []byte +void +runtime·appendstr(SliceType *t, Slice x, String y, Slice ret) { int32 m; - uintptr w; m = x.len+y.len; @@ -67,15 +91,16 @@ appendslice1(SliceType *t, Slice x, Slice y, Slice *ret) runtime·throw("append: slice overflow"); if(m > x.cap) - growslice1(t, x, m, ret); + growslice1(t, x, m, &ret); else - *ret = x; + ret = x; - w = t->elem->size; - runtime·memmove(ret->array + ret->len*w, y.array, y.len*w); - ret->len += y.len; + runtime·memmove(ret.array + ret.len, y.str, y.len); + ret.len += y.len; + FLUSH(&ret); } + // growslice(type *Type, x, []T, n int64) []T void runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret) @@ -96,9 +121,9 @@ runtime·growslice(SliceType *t, Slice old, int64 n, Slice ret) if(debug) { runtime·printf("growslice(%S,", *t->string); - runtime·printslice(old); + runtime·printslice(old); runtime·printf(", new cap=%D) =", cap); - runtime·printslice(ret); + runtime·printslice(ret); } } @@ -265,9 +290,9 @@ runtime·slicearray(byte* old, uint64 nel, uint64 lb, uint64 hb, uint64 width, S } } -// slicecopy(to any, fr any, wid uint32) int +// copy(to any, fr any, wid uint32) int void -runtime·slicecopy(Slice to, Slice fm, uintptr width, int32 ret) +runtime·copy(Slice to, Slice fm, uintptr width, int32 ret) { if(fm.len == 0 || to.len == 0 || width == 0) { ret = 0; @@ -307,11 +332,11 @@ runtime·slicestringcopy(Slice to, String fm, int32 ret) ret = 0; goto out; } - + ret = fm.len; if(to.len < ret) ret = to.len; - + runtime·memmove(to.array, fm.str, ret); out: |