OSDN Git Service

Bring over accumulated bug fixes from mainline.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / iface.goc
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package runtime
6 #include "runtime.h"
7 #include "go-type.h"
8 #include "interface.h"
9
10 typedef struct __go_type_descriptor descriptor;
11 typedef const struct __go_type_descriptor const_descriptor;
12 typedef struct __go_interface interface;
13 typedef struct __go_empty_interface empty_interface;
14
15 // Compare two type descriptors.
16 func ifacetypeeq(a *descriptor, b *descriptor) (eq bool) {
17         eq = __go_type_descriptors_equal(a, b);
18 }
19
20 // Return the descriptor for an empty interface type.n
21 func efacetype(e empty_interface) (d *const_descriptor) {
22         return e.__type_descriptor;
23 }
24
25 // Return the descriptor for a non-empty interface type.
26 func ifacetype(i interface) (d *const_descriptor) {
27         if (i.__methods == nil) {
28                 return nil;
29         }
30         d = i.__methods[0];
31 }
32
33 // Convert an empty interface to an empty interface.
34 func ifaceE2E2(e empty_interface) (ret empty_interface, ok bool) {
35         if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
36                 runtime_panicstring("invalid interface value");
37         ret = e;
38         ok = ret.__type_descriptor != nil;
39 }
40
41 // Convert a non-empty interface to an empty interface.
42 func ifaceI2E2(i interface) (ret empty_interface, ok bool) {
43         if (i.__methods == nil) {
44                 ret.__type_descriptor = nil;
45                 ret.__object = nil;
46                 ok = 0;
47         } else {
48                 ret.__type_descriptor = i.__methods[0];
49                 ret.__object = i.__object;
50                 ok = 1;
51         }
52 }
53
54 // Convert an empty interface to a non-empty interface.
55 func ifaceE2I2(inter *descriptor, e empty_interface) (ret interface, ok bool) {
56         if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
57                 runtime_panicstring("invalid interface value");
58         if (e.__type_descriptor == nil) {
59                 ret.__methods = nil;
60                 ret.__object = nil;
61                 ok = 0;
62         } else {
63                 ret.__methods = __go_convert_interface_2(inter,
64                                                          e.__type_descriptor,
65                                                          1);
66                 ret.__object = e.__object;
67                 ok = ret.__methods != nil;
68         }
69 }
70
71 // Convert a non-empty interface to a non-empty interface.
72 func ifaceI2I2(inter *descriptor, i interface) (ret interface, ok bool) {
73         if (i.__methods == nil) {
74                 ret.__methods = nil;
75                 ret.__object = nil;
76                 ok = 0;
77         } else {
78                 ret.__methods = __go_convert_interface_2(inter,
79                                                          i.__methods[0], 1);
80                 ret.__object = i.__object;
81                 ok = ret.__methods != nil;
82         }
83 }
84
85 // Convert an empty interface to a pointer type.
86 func ifaceE2T2P(inter *descriptor, e empty_interface) (ret *void, ok bool) {
87         if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
88                 runtime_panicstring("invalid interface value");
89         if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
90                 ret = nil;
91                 ok = 0;
92         } else {
93                 ret = e.__object;
94                 ok = 1;
95         }
96 }
97
98 // Convert a non-empty interface to a pointer type.
99 func ifaceI2T2P(inter *descriptor, i interface) (ret *void, ok bool) {
100         if (i.__methods == nil
101             || !__go_type_descriptors_equal(inter, i.__methods[0])) {
102                 ret = nil;
103                 ok = 0;
104         } else {
105                 ret = i.__object;
106                 ok = 1;
107         }
108 }
109
110 // Convert an empty interface to a non-pointer type.
111 func ifaceE2T2(inter *descriptor, e empty_interface, ret *void) (ok bool) {
112         if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
113                 runtime_panicstring("invalid interface value");
114         if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
115                 __builtin_memset(ret, 0, inter->__size);
116                 ok = 0;
117         } else {
118                 __builtin_memcpy(ret, e.__object, inter->__size);
119                 ok = 1;
120         }
121 }
122
123 // Convert a non-empty interface to a non-pointer type.
124 func ifaceI2T2(inter *descriptor, i interface, ret *void) (ok bool) {
125         if (i.__methods == nil
126             || !__go_type_descriptors_equal(inter, i.__methods[0])) {
127                 __builtin_memset(ret, 0, inter->__size);
128                 ok = 0;
129         } else {
130                 __builtin_memcpy(ret, i.__object, inter->__size);
131                 ok = 1;
132         }
133 }
134
135 // Return whether we can convert an interface to a type.
136 func ifaceI2Tp(to *descriptor, from *descriptor) (ok bool) {
137         ok = __go_can_convert_to_interface(to, from);
138 }