OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / go-append.c
1 /* go-append.c -- the go builtin append function.
2
3    Copyright 2010 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 "go-assert.h"
8 #include "go-type.h"
9 #include "array.h"
10 #include "runtime.h"
11 #include "malloc.h"
12
13 struct __go_open_array
14 __go_append (const struct __go_slice_type *type,
15              struct __go_open_array a, struct __go_open_array b)
16 {
17   size_t element_size;
18   unsigned int ucount;
19   int count;
20
21   if (b.__values == NULL || b.__count == 0)
22     return a;
23
24   __go_assert (type->__common.__code == GO_SLICE);
25   element_size = type->__element_type->__size;
26
27   ucount = (unsigned int) a.__count + (unsigned int) b.__count;
28   count = (int) ucount;
29   __go_assert (ucount == (unsigned int) count && count >= a.__count);
30   if (count > a.__capacity)
31     {
32       int m;
33       struct __go_open_array n;
34
35       m = a.__capacity;
36       if (m == 0)
37         m = b.__count;
38       else
39         {
40           do
41             {
42               if (a.__count < 1024)
43                 m += m;
44               else
45                 m += m / 4;
46             }
47           while (m < count);
48         }
49
50       n.__values = __go_alloc (m * element_size);
51       n.__count = a.__count;
52       n.__capacity = m;
53       __builtin_memcpy (n.__values, a.__values, n.__count * element_size);
54
55       a = n;
56     }
57
58   __builtin_memmove ((char *) a.__values + a.__count * element_size,
59                      b.__values, b.__count * element_size);
60   a.__count = count;
61   return a;
62 }