d0e8369c1f6c99ead51f2fa397677ac1ac5a10f2
[platform/upstream/gcc.git] / libgo / runtime / go-make-slice.c
1 /* go-make-slice.c -- make a slice.
2
3    Copyright 2011 The Go Authors. All rights reserved.
4    Use of this source code is governed by a BSD-style
5    license that can be found in the LICENSE file.  */
6
7 #include <stdint.h>
8
9 #include "go-alloc.h"
10 #include "go-assert.h"
11 #include "go-panic.h"
12 #include "go-type.h"
13 #include "array.h"
14 #include "runtime.h"
15 #include "malloc.h"
16
17 struct __go_open_array
18 __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len,
19                   uintptr_t cap)
20 {
21   const struct __go_slice_type* std;
22   int ilen;
23   int icap;
24   uintptr_t size;
25   struct __go_open_array ret;
26   unsigned int flag;
27
28   __go_assert (td->__code == GO_SLICE);
29   std = (const struct __go_slice_type *) td;
30
31   ilen = (int) len;
32   if (ilen < 0 || (uintptr_t) ilen != len)
33     __go_panic_msg ("makeslice: len out of range");
34
35   icap = (int) cap;
36   if (cap < len
37       || (uintptr_t) icap != cap
38       || (std->__element_type->__size > 0
39           && cap > (uintptr_t) -1U / std->__element_type->__size))
40     __go_panic_msg ("makeslice: cap out of range");
41
42   ret.__count = ilen;
43   ret.__capacity = icap;
44
45   size = cap * std->__element_type->__size;
46   flag = ((std->__element_type->__code & GO_NO_POINTERS) != 0
47           ? FlagNoPointers
48           : 0);
49   ret.__values = runtime_mallocgc (size, flag, 1, 1);
50
51   return ret;
52 }
53
54 struct __go_open_array
55 __go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len)
56 {
57   return __go_make_slice2 (td, len, len);
58 }