OSDN Git Service

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