1 /* go-reflect-call.c -- call 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. */
13 #include "go-assert.h"
17 /* The functions in this file are only called from reflect_call. As
18 reflect_call calls a libffi function, which will be compiled
19 without -fsplit-stack, it will always run with a large stack. */
21 static ffi_type
*go_array_to_ffi (const struct __go_array_type
*)
22 __attribute__ ((no_split_stack
));
23 static ffi_type
*go_slice_to_ffi (const struct __go_slice_type
*)
24 __attribute__ ((no_split_stack
));
25 static ffi_type
*go_struct_to_ffi (const struct __go_struct_type
*)
26 __attribute__ ((no_split_stack
));
27 static ffi_type
*go_string_to_ffi (void) __attribute__ ((no_split_stack
));
28 static ffi_type
*go_interface_to_ffi (void) __attribute__ ((no_split_stack
));
29 static ffi_type
*go_complex_to_ffi (ffi_type
*)
30 __attribute__ ((no_split_stack
));
31 static ffi_type
*go_type_to_ffi (const struct __go_type_descriptor
*)
32 __attribute__ ((no_split_stack
));
33 static ffi_type
*go_func_return_ffi (const struct __go_func_type
*)
34 __attribute__ ((no_split_stack
));
35 static void go_func_to_cif (const struct __go_func_type
*, _Bool
, _Bool
,
37 __attribute__ ((no_split_stack
));
38 static size_t go_results_size (const struct __go_func_type
*)
39 __attribute__ ((no_split_stack
));
40 static void go_set_results (const struct __go_func_type
*, unsigned char *,
42 __attribute__ ((no_split_stack
));
44 /* Return an ffi_type for a Go array type. The libffi library does
45 not have any builtin support for passing arrays as values. We work
46 around this by pretending that the array is a struct. */
49 go_array_to_ffi (const struct __go_array_type
*descriptor
)
56 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
57 ret
->type
= FFI_TYPE_STRUCT
;
58 len
= descriptor
->__len
;
59 ret
->elements
= (ffi_type
**) __go_alloc ((len
+ 1) * sizeof (ffi_type
*));
60 element
= go_type_to_ffi (descriptor
->__element_type
);
61 for (i
= 0; i
< len
; ++i
)
62 ret
->elements
[i
] = element
;
63 ret
->elements
[len
] = NULL
;
67 /* Return an ffi_type for a Go slice type. This describes the
68 __go_open_array type defines in array.h. */
72 const struct __go_slice_type
*descriptor
__attribute__ ((unused
)))
76 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
77 ret
->type
= FFI_TYPE_STRUCT
;
78 ret
->elements
= (ffi_type
**) __go_alloc (4 * sizeof (ffi_type
*));
79 ret
->elements
[0] = &ffi_type_pointer
;
80 ret
->elements
[1] = &ffi_type_sint
;
81 ret
->elements
[2] = &ffi_type_sint
;
82 ret
->elements
[3] = NULL
;
86 /* Return an ffi_type for a Go struct type. */
89 go_struct_to_ffi (const struct __go_struct_type
*descriptor
)
93 const struct __go_struct_field
*fields
;
96 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
97 ret
->type
= FFI_TYPE_STRUCT
;
98 field_count
= descriptor
->__fields
.__count
;
99 fields
= (const struct __go_struct_field
*) descriptor
->__fields
.__values
;
100 ret
->elements
= (ffi_type
**) __go_alloc ((field_count
+ 1)
101 * sizeof (ffi_type
*));
102 for (i
= 0; i
< field_count
; ++i
)
103 ret
->elements
[i
] = go_type_to_ffi (fields
[i
].__type
);
104 ret
->elements
[field_count
] = NULL
;
108 /* Return an ffi_type for a Go string type. This describes the
109 __go_string struct. */
112 go_string_to_ffi (void)
116 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
117 ret
->type
= FFI_TYPE_STRUCT
;
118 ret
->elements
= (ffi_type
**) __go_alloc (3 * sizeof (ffi_type
*));
119 ret
->elements
[0] = &ffi_type_pointer
;
120 ret
->elements
[1] = &ffi_type_sint
;
121 ret
->elements
[2] = NULL
;
125 /* Return an ffi_type for a Go interface type. This describes the
126 __go_interface and __go_empty_interface structs. */
129 go_interface_to_ffi (void)
133 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
134 ret
->type
= FFI_TYPE_STRUCT
;
135 ret
->elements
= (ffi_type
**) __go_alloc (3 * sizeof (ffi_type
*));
136 ret
->elements
[0] = &ffi_type_pointer
;
137 ret
->elements
[1] = &ffi_type_pointer
;
138 ret
->elements
[2] = NULL
;
142 /* Return an ffi_type for a Go complex type. */
145 go_complex_to_ffi (ffi_type
*float_type
)
149 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
150 ret
->type
= FFI_TYPE_STRUCT
;
151 ret
->elements
= (ffi_type
**) __go_alloc (3 * sizeof (ffi_type
*));
152 ret
->elements
[0] = float_type
;
153 ret
->elements
[1] = float_type
;
154 ret
->elements
[2] = NULL
;
158 /* Return an ffi_type for a type described by a
159 __go_type_descriptor. */
162 go_type_to_ffi (const struct __go_type_descriptor
*descriptor
)
164 switch (descriptor
->__code
& GO_CODE_MASK
)
167 if (sizeof (_Bool
) == 1)
168 return &ffi_type_uint8
;
169 else if (sizeof (_Bool
) == sizeof (int))
170 return &ffi_type_uint
;
173 if (sizeof (float) == 4)
174 return &ffi_type_float
;
177 if (sizeof (double) == 8)
178 return &ffi_type_double
;
181 if (sizeof (float) == 4)
182 return go_complex_to_ffi (&ffi_type_float
);
185 if (sizeof (double) == 8)
186 return go_complex_to_ffi (&ffi_type_double
);
189 return &ffi_type_sint16
;
191 return &ffi_type_sint32
;
193 return &ffi_type_sint64
;
195 return &ffi_type_sint8
;
197 return &ffi_type_sint
;
199 return &ffi_type_uint16
;
201 return &ffi_type_uint32
;
203 return &ffi_type_uint64
;
205 return &ffi_type_uint8
;
207 return &ffi_type_uint
;
209 if (sizeof (void *) == 2)
210 return &ffi_type_uint16
;
211 else if (sizeof (void *) == 4)
212 return &ffi_type_uint32
;
213 else if (sizeof (void *) == 8)
214 return &ffi_type_uint64
;
217 return go_array_to_ffi ((const struct __go_array_type
*) descriptor
);
219 return go_slice_to_ffi ((const struct __go_slice_type
*) descriptor
);
221 return go_struct_to_ffi ((const struct __go_struct_type
*) descriptor
);
223 return go_string_to_ffi ();
225 return go_interface_to_ffi ();
230 case GO_UNSAFE_POINTER
:
231 /* These types are always pointers, and for FFI purposes nothing
233 return &ffi_type_pointer
;
239 /* Return the return type for a function, given the number of out
240 parameters and their types. */
243 go_func_return_ffi (const struct __go_func_type
*func
)
246 const struct __go_type_descriptor
**types
;
250 count
= func
->__out
.__count
;
252 return &ffi_type_void
;
254 types
= (const struct __go_type_descriptor
**) func
->__out
.__values
;
257 return go_type_to_ffi (types
[0]);
259 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
260 ret
->type
= FFI_TYPE_STRUCT
;
261 ret
->elements
= (ffi_type
**) __go_alloc ((count
+ 1) * sizeof (ffi_type
*));
262 for (i
= 0; i
< count
; ++i
)
263 ret
->elements
[i
] = go_type_to_ffi (types
[i
]);
264 ret
->elements
[count
] = NULL
;
268 /* Build an ffi_cif structure for a function described by a
269 __go_func_type structure. */
272 go_func_to_cif (const struct __go_func_type
*func
, _Bool is_interface
,
273 _Bool is_method
, ffi_cif
*cif
)
276 const struct __go_type_descriptor
**in_types
;
284 num_params
= func
->__in
.__count
;
285 in_types
= ((const struct __go_type_descriptor
**)
286 func
->__in
.__values
);
288 num_args
= num_params
+ (is_interface
? 1 : 0);
289 args
= (ffi_type
**) __go_alloc (num_args
* sizeof (ffi_type
*));
294 args
[0] = &ffi_type_pointer
;
299 args
[0] = &ffi_type_pointer
;
302 for (; i
< num_params
; ++i
)
303 args
[i
+ off
] = go_type_to_ffi (in_types
[i
]);
305 rettype
= go_func_return_ffi (func
);
307 status
= ffi_prep_cif (cif
, FFI_DEFAULT_ABI
, num_args
, rettype
, args
);
308 __go_assert (status
== FFI_OK
);
311 /* Get the total size required for the result parameters of a
315 go_results_size (const struct __go_func_type
*func
)
318 const struct __go_type_descriptor
**types
;
323 count
= func
->__out
.__count
;
327 types
= (const struct __go_type_descriptor
**) func
->__out
.__values
;
331 for (i
= 0; i
< count
; ++i
)
335 align
= types
[i
]->__field_align
;
336 if (align
> maxalign
)
338 off
= (off
+ align
- 1) & ~ (align
- 1);
339 off
+= types
[i
]->__size
;
342 off
= (off
+ maxalign
- 1) & ~ (maxalign
- 1);
347 /* Copy the results of calling a function via FFI from CALL_RESULT
348 into the addresses in RESULTS. */
351 go_set_results (const struct __go_func_type
*func
, unsigned char *call_result
,
355 const struct __go_type_descriptor
**types
;
359 count
= func
->__out
.__count
;
363 types
= (const struct __go_type_descriptor
**) func
->__out
.__values
;
366 for (i
= 0; i
< count
; ++i
)
371 align
= types
[i
]->__field_align
;
372 size
= types
[i
]->__size
;
373 off
= (off
+ align
- 1) & ~ (align
- 1);
374 __builtin_memcpy (results
[i
], call_result
+ off
, size
);
379 /* Call a function. The type of the function is FUNC_TYPE, and the
380 address is FUNC_ADDR. PARAMS is an array of parameter addresses.
381 RESULTS is an array of result addresses. */
384 reflect_call (const struct __go_func_type
*func_type
, const void *func_addr
,
385 _Bool is_interface
, _Bool is_method
, void **params
,
389 unsigned char *call_result
;
391 __go_assert (func_type
->__common
.__code
== GO_FUNC
);
392 go_func_to_cif (func_type
, is_interface
, is_method
, &cif
);
394 call_result
= (unsigned char *) malloc (go_results_size (func_type
));
396 ffi_call (&cif
, func_addr
, call_result
, params
);
398 /* Some day we may need to free result values if RESULTS is
401 go_set_results (func_type
, call_result
, results
);