// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime
#include "runtime.h"
#include "arch_GOARCH.h"
#include "type.h"
#include "typekind.h"
#include "malloc.h"
#include "race.h"
#include "stack.h"
#include "../../cmd/ld/textflag.h"

enum
{
	debug = 0
};

static	void	makeslice1(SliceType*, intgo, intgo, Slice*);
static	void	growslice1(SliceType*, Slice, intgo, Slice *);

// see also unsafe·NewArray
func makeslice(t *SliceType, len int64, cap int64) (ret Slice) {
	// NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
	// but it produces a 'len out of range' error instead of a 'cap out of range' error
	// when someone does make([]T, bignumber). 'cap out of range' is true too,
	// but since the cap is only being supplied implicitly, saying len is clearer.
	// See issue 4085.
	if(len < 0 || (intgo)len != len || t->elem->size > 0 && len > MaxMem / t->elem->size)
		runtime·panicstring("makeslice: len out of range");

	if(cap < len || (intgo)cap != cap || t->elem->size > 0 && cap > MaxMem / t->elem->size)
		runtime·panicstring("makeslice: cap out of range");

	makeslice1(t, len, cap, &ret);

	if(debug) {
		runtime·printf("makeslice(%S, %D, %D); ret=",
			*t->string, len, cap);
		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.
uintptr runtime·zerobase;

static void
makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret)
{
	ret->len = len;
	ret->cap = cap;
	ret->array = runtime·cnewarray(t->elem, cap);
}

// growslice(type *Type, x, []T, n int64) []T
func growslice(t *SliceType, old Slice, n int64) (ret Slice) {
	int64 cap;
	void *pc;

	if(n < 1)
		runtime·panicstring("growslice: invalid n");

	cap = old.cap + n;

	if((intgo)cap != cap || cap < (int64)old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size))
		runtime·panicstring("growslice: cap out of range");

	if(raceenabled) {
		pc = runtime·getcallerpc(&t);
		runtime·racereadrangepc(old.array, old.len*t->elem->size, pc, runtime·growslice);
	}

	growslice1(t, old, cap, &ret);

	if(debug) {
		runtime·printf("growslice(%S,", *t->string);
		runtime·printslice(old);
		runtime·printf(", new cap=%D) =", cap);
		runtime·printslice(ret);
	}
}

static void
growslice1(SliceType *t, Slice x, intgo newcap, Slice *ret)
{
	intgo newcap1;
	uintptr capmem, lenmem;
	int32 flag;
	Type *typ;

	typ = t->elem;
	if(typ->size == 0) {
		*ret = x;
		ret->cap = newcap;
		return;
	}

	newcap1 = x.cap;
	
	// Using newcap directly for m+m < newcap handles
	// both the case where m == 0 and also the case where
	// m+m/4 wraps around, in which case the loop
	// below might never terminate.
	if(newcap1+newcap1 < newcap)
		newcap1 = newcap;
	else {
		do {
			if(x.len < 1024)
				newcap1 += newcap1;
			else
				newcap1 += newcap1/4;
		} while(newcap1 < newcap);
	}

	if(newcap1 > MaxMem/typ->size)
		runtime·panicstring("growslice: cap out of range");
	capmem = runtime·roundupsize(newcap1*typ->size);
	flag = FlagNoZero;
	if(typ->kind&KindNoPointers)
		flag |= FlagNoScan;
	// Here we allocate with FlagNoZero but potentially w/o FlagNoScan,
	// GC must not see this blocks until memclr below.
	m->locks++;
	ret->array = runtime·mallocgc(capmem, (uintptr)typ|TypeInfo_Array, flag);
	ret->len = x.len;
	ret->cap = capmem/typ->size;
	lenmem = x.len*typ->size;
	runtime·memmove(ret->array, x.array, lenmem);
	runtime·memclr(ret->array+lenmem, capmem-lenmem);
	m->locks--;
	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
		g->stackguard0 = StackPreempt;
}

#pragma textflag NOSPLIT
func copy(to Slice, fm Slice, width uintptr) (ret int) {
	void *pc;

	if(fm.len == 0 || to.len == 0 || width == 0) {
		ret = 0;
		goto out;
	}

	ret = fm.len;
	if(to.len < ret)
		ret = to.len;

	if(raceenabled) {
		pc = runtime·getcallerpc(&to);
		runtime·racewriterangepc(to.array, ret*width, pc, runtime·copy);
		runtime·racereadrangepc(fm.array, ret*width, pc, runtime·copy);
	}

	if(ret == 1 && width == 1) {	// common case worth about 2x to do here
		*to.array = *fm.array;	// known to be a byte pointer
	} else {
		runtime·memmove(to.array, fm.array, ret*width);
	}

out:

	if(debug) {
		runtime·prints("main·copy: to=");
		runtime·printslice(to);
		runtime·prints("; fm=");
		runtime·printslice(fm);
		runtime·prints("; width=");
		runtime·printint(width);
		runtime·prints("; ret=");
		runtime·printint(ret);
		runtime·prints("\n");
	}
}

#pragma textflag NOSPLIT
func slicestringcopy(to Slice, fm String) (ret int) {
	void *pc;

	if(fm.len == 0 || to.len == 0) {
		ret = 0;
		goto out;
	}

	ret = fm.len;
	if(to.len < ret)
		ret = to.len;

	if(raceenabled) {
		pc = runtime·getcallerpc(&to);
		runtime·racewriterangepc(to.array, ret, pc, runtime·slicestringcopy);
	}

	runtime·memmove(to.array, fm.str, ret);

out:;
}

func printslice(a Slice) {
	runtime·prints("[");
	runtime·printint(a.len);
	runtime·prints("/");
	runtime·printint(a.cap);
	runtime·prints("]");
	runtime·printpointer(a.array);
}
