1 /* go-reflect.c -- implement unsafe.Reflect and unsafe.Typeof 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. */
10 #include "interface.h"
13 #include "go-string.h"
16 /* For field alignment. */
21 struct __go_type_descriptor
*p
;
24 /* The type descriptors in the runtime package. */
26 extern const struct __go_type_descriptor ptr_bool_descriptor
27 asm ("__go_td_pN30_libgo_runtime.runtime.BoolType");
28 extern const struct __go_type_descriptor ptr_float_descriptor
29 asm ("__go_td_pN31_libgo_runtime.runtime.FloatType");
30 extern const struct __go_type_descriptor ptr_complex_descriptor
31 asm ("__go_td_pN33_libgo_runtime.runtime.ComplexType");
32 extern const struct __go_type_descriptor ptr_int_descriptor
33 asm ("__go_td_pN29_libgo_runtime.runtime.IntType");
34 extern const struct __go_type_descriptor ptr_uint_descriptor
35 asm ("__go_td_pN30_libgo_runtime.runtime.UintType");
36 extern const struct __go_type_descriptor ptr_string_descriptor
37 asm ("__go_td_pN32_libgo_runtime.runtime.StringType");
38 extern const struct __go_type_descriptor ptr_unsafe_pointer_decriptor
39 asm ("__go_td_pN39_libgo_runtime.runtime.UnsafePointerType");
40 extern const struct __go_type_descriptor ptr_array_descriptor
41 asm ("__go_td_pN31_libgo_runtime.runtime.ArrayType");
42 extern const struct __go_type_descriptor ptr_slice_descriptor
43 asm ("__go_td_pN31_libgo_runtime.runtime.SliceType");
44 extern const struct __go_type_descriptor ptr_chan_descriptor
45 asm ("__go_td_pN30_libgo_runtime.runtime.ChanType");
46 extern const struct __go_type_descriptor ptr_func_descriptor
47 asm ("__go_td_pN30_libgo_runtime.runtime.FuncType");
48 extern const struct __go_type_descriptor ptr_interface_descriptor
49 asm ("__go_td_pN35_libgo_runtime.runtime.InterfaceType");
50 extern const struct __go_type_descriptor ptr_map_descriptor
51 asm ("__go_td_pN29_libgo_runtime.runtime.MapType");
52 extern const struct __go_type_descriptor ptr_ptr_descriptor
53 asm ("__go_td_pN29_libgo_runtime.runtime.PtrType");
54 extern const struct __go_type_descriptor ptr_struct_descriptor
55 asm ("__go_td_pN32_libgo_runtime.runtime.StructType");
57 const struct __go_type_descriptor
*
58 get_descriptor (int code
)
63 return &ptr_bool_descriptor
;
66 return &ptr_float_descriptor
;
69 return &ptr_complex_descriptor
;
75 return &ptr_int_descriptor
;
82 return &ptr_uint_descriptor
;
84 return &ptr_string_descriptor
;
85 case GO_UNSAFE_POINTER
:
86 return &ptr_unsafe_pointer_decriptor
;
88 return &ptr_array_descriptor
;
90 return &ptr_slice_descriptor
;
92 return &ptr_chan_descriptor
;
94 return &ptr_func_descriptor
;
96 return &ptr_interface_descriptor
;
98 return &ptr_map_descriptor
;
100 return &ptr_ptr_descriptor
;
102 return &ptr_struct_descriptor
;
108 /* Implement unsafe.Reflect. */
112 struct __go_empty_interface rettype
;
116 struct reflect_ret
Reflect (struct __go_empty_interface
)
117 asm ("libgo_unsafe.unsafe.Reflect");
120 Reflect (struct __go_empty_interface e
)
122 struct reflect_ret ret
;
124 if (e
.__type_descriptor
== NULL
)
126 ret
.rettype
.__type_descriptor
= NULL
;
127 ret
.rettype
.__object
= NULL
;
134 ret
.rettype
.__type_descriptor
=
135 get_descriptor (e
.__type_descriptor
->__code
);
137 /* This memcpy is really just an assignment of a const pointer
138 to a non-const pointer. FIXME: We should canonicalize this
139 pointer, so that for a given type we always return the same
141 __builtin_memcpy (&ret
.rettype
.__object
, &e
.__type_descriptor
,
144 /* Make a copy of the value. */
145 size
= e
.__type_descriptor
->__size
;
146 if (size
<= sizeof (uint64_t))
147 ret
.addr
= __go_alloc (sizeof (uint64_t));
149 ret
.addr
= __go_alloc (size
);
150 if (__go_is_pointer_type (e
.__type_descriptor
))
151 *(void **) ret
.addr
= e
.__object
;
153 __builtin_memcpy (ret
.addr
, e
.__object
, size
);
159 /* Implement unsafe.Typeof. */
161 struct __go_empty_interface
Typeof (struct __go_empty_interface
)
162 asm ("libgo_unsafe.unsafe.Typeof");
164 struct __go_empty_interface
165 Typeof (const struct __go_empty_interface e
)
167 struct __go_empty_interface ret
;
169 if (e
.__type_descriptor
== NULL
)
171 ret
.__type_descriptor
= NULL
;
176 ret
.__type_descriptor
= get_descriptor (e
.__type_descriptor
->__code
);
178 /* This memcpy is really just an assignment of a const pointer
179 to a non-const pointer. FIXME: We should canonicalize this
180 pointer, so that for a given type we always return the same
182 __builtin_memcpy (&ret
.__object
, &e
.__type_descriptor
, sizeof (void *));