1 /* go-reflect-chan.c -- channel reflection support for Go.
3 Copyright 2009 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. */
12 #include "go-assert.h"
17 /* This file implements support for reflection on channels. These
18 functions are called from reflect/value.go. */
20 extern uintptr_t makechan (const struct __go_type_descriptor
*, uint32_t)
21 asm ("libgo_reflect.reflect.makechan");
24 makechan (const struct __go_type_descriptor
*typ
, uint32_t size
)
26 struct __go_channel
*channel
;
29 channel
= __go_new_channel (typ
, size
);
31 ret
= __go_alloc (sizeof (void *));
32 __builtin_memcpy (ret
, &channel
, sizeof (void *));
33 return (uintptr_t) ret
;
36 extern _Bool
chansend (struct __go_channel_type
*, uintptr_t, uintptr_t, _Bool
)
37 asm ("libgo_reflect.reflect.chansend");
40 chansend (struct __go_channel_type
*ct
, uintptr_t ch
, uintptr_t val_i
,
43 struct __go_channel
*channel
= (struct __go_channel
*) ch
;
44 uintptr_t element_size
;
47 __go_assert (ct
->__common
.__code
== GO_CHAN
);
49 if (__go_is_pointer_type (ct
->__element_type
))
54 element_size
= ct
->__element_type
->__size
;
55 if (element_size
<= sizeof (uint64_t))
59 char b
[sizeof (uint64_t)];
63 __builtin_memset (u
.b
, 0, sizeof (uint64_t));
64 #ifndef WORDS_BIGENDIAN
65 __builtin_memcpy (u
.b
, pv
, element_size
);
67 __builtin_memcpy (u
.b
+ sizeof (uint64_t) - element_size
, pv
,
71 return __go_send_nonblocking_small (channel
, u
.v
);
74 __go_send_small (channel
, u
.v
, 0);
81 return __go_send_nonblocking_big (channel
, pv
);
84 __go_send_big (channel
, pv
, 0);
97 extern struct chanrecv_ret
chanrecv (struct __go_channel_type
*, uintptr_t,
99 asm ("libgo_reflect.reflect.chanrecv");
102 chanrecv (struct __go_channel_type
*ct
, uintptr_t ch
, _Bool nb
)
104 struct __go_channel
*channel
= (struct __go_channel
*) ch
;
106 uintptr_t element_size
;
107 struct chanrecv_ret ret
;
109 __go_assert (ct
->__common
.__code
== GO_CHAN
);
111 element_size
= ct
->__element_type
->__size
;
113 if (__go_is_pointer_type (ct
->__element_type
))
117 pv
= __go_alloc (element_size
);
118 ret
.val
= (uintptr_t) pv
;
121 if (element_size
<= sizeof (uint64_t))
125 char b
[sizeof (uint64_t)];
131 u
.v
= __go_receive_small_closed (channel
, 0, &ret
.received
);
136 struct __go_receive_nonblocking_small s
;
138 s
= __go_receive_nonblocking_small (channel
);
139 ret
.selected
= s
.__success
|| s
.__closed
;
140 ret
.received
= s
.__success
;
144 #ifndef WORDS_BIGENDIAN
145 __builtin_memcpy (pv
, u
.b
, element_size
);
147 __builtin_memcpy (pv
, u
.b
+ sizeof (uint64_t) - element_size
,
155 ret
.received
= __go_receive_big (channel
, pv
, 0);
163 got
= __go_receive_nonblocking_big (channel
, pv
, &closed
);
164 ret
.selected
= got
|| closed
;
172 extern void chanclose (uintptr_t) asm ("libgo_reflect.reflect.chanclose");
175 chanclose (uintptr_t ch
)
177 struct __go_channel
*channel
= (struct __go_channel
*) ch
;
179 __go_builtin_close (channel
);
182 extern int32_t chanlen (uintptr_t) asm ("libgo_reflect.reflect.chanlen");
185 chanlen (uintptr_t ch
)
187 struct __go_channel
*channel
= (struct __go_channel
*) ch
;
189 return (int32_t) __go_chan_len (channel
);
192 extern int32_t chancap (uintptr_t) asm ("libgo_reflect.reflect.chancap");
195 chancap (uintptr_t ch
)
197 struct __go_channel
*channel
= (struct __go_channel
*) ch
;
199 return (int32_t) __go_chan_cap (channel
);