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"
20 /* The functions in this file are only called from reflect_call. As
21 reflect_call calls a libffi function, which will be compiled
22 without -fsplit-stack, it will always run with a large stack. */
24 static ffi_type
*go_array_to_ffi (const struct __go_array_type
*)
25 __attribute__ ((no_split_stack
));
26 static ffi_type
*go_slice_to_ffi (const struct __go_slice_type
*)
27 __attribute__ ((no_split_stack
));
28 static ffi_type
*go_struct_to_ffi (const struct __go_struct_type
*)
29 __attribute__ ((no_split_stack
));
30 static ffi_type
*go_string_to_ffi (void) __attribute__ ((no_split_stack
));
31 static ffi_type
*go_interface_to_ffi (void) __attribute__ ((no_split_stack
));
32 static ffi_type
*go_complex_to_ffi (ffi_type
*)
33 __attribute__ ((no_split_stack
, unused
));
34 static ffi_type
*go_type_to_ffi (const struct __go_type_descriptor
*)
35 __attribute__ ((no_split_stack
));
36 static ffi_type
*go_func_return_ffi (const struct __go_func_type
*)
37 __attribute__ ((no_split_stack
));
38 static void go_func_to_cif (const struct __go_func_type
*, _Bool
, _Bool
,
40 __attribute__ ((no_split_stack
));
41 static size_t go_results_size (const struct __go_func_type
*)
42 __attribute__ ((no_split_stack
));
43 static void go_set_results (const struct __go_func_type
*, unsigned char *,
45 __attribute__ ((no_split_stack
));
47 /* Return an ffi_type for a Go array type. The libffi library does
48 not have any builtin support for passing arrays as values. We work
49 around this by pretending that the array is a struct. */
52 go_array_to_ffi (const struct __go_array_type
*descriptor
)
59 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
60 ret
->type
= FFI_TYPE_STRUCT
;
61 len
= descriptor
->__len
;
62 ret
->elements
= (ffi_type
**) __go_alloc ((len
+ 1) * sizeof (ffi_type
*));
63 element
= go_type_to_ffi (descriptor
->__element_type
);
64 for (i
= 0; i
< len
; ++i
)
65 ret
->elements
[i
] = element
;
66 ret
->elements
[len
] = NULL
;
70 /* Return an ffi_type for a Go slice type. This describes the
71 __go_open_array type defines in array.h. */
75 const struct __go_slice_type
*descriptor
__attribute__ ((unused
)))
80 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
81 ret
->type
= FFI_TYPE_STRUCT
;
82 ret
->elements
= (ffi_type
**) __go_alloc (4 * sizeof (ffi_type
*));
83 ret
->elements
[0] = &ffi_type_pointer
;
84 ffi_intgo
= sizeof (intgo
) == 4 ? &ffi_type_sint32
: &ffi_type_sint64
;
85 ret
->elements
[1] = ffi_intgo
;
86 ret
->elements
[2] = ffi_intgo
;
87 ret
->elements
[3] = NULL
;
91 /* Return an ffi_type for a Go struct type. */
94 go_struct_to_ffi (const struct __go_struct_type
*descriptor
)
98 const struct __go_struct_field
*fields
;
101 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
102 ret
->type
= FFI_TYPE_STRUCT
;
103 field_count
= descriptor
->__fields
.__count
;
104 fields
= (const struct __go_struct_field
*) descriptor
->__fields
.__values
;
105 ret
->elements
= (ffi_type
**) __go_alloc ((field_count
+ 1)
106 * sizeof (ffi_type
*));
107 for (i
= 0; i
< field_count
; ++i
)
108 ret
->elements
[i
] = go_type_to_ffi (fields
[i
].__type
);
109 ret
->elements
[field_count
] = NULL
;
113 /* Return an ffi_type for a Go string type. This describes the String
117 go_string_to_ffi (void)
122 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
123 ret
->type
= FFI_TYPE_STRUCT
;
124 ret
->elements
= (ffi_type
**) __go_alloc (3 * sizeof (ffi_type
*));
125 ret
->elements
[0] = &ffi_type_pointer
;
126 ffi_intgo
= sizeof (intgo
) == 4 ? &ffi_type_sint32
: &ffi_type_sint64
;
127 ret
->elements
[1] = ffi_intgo
;
128 ret
->elements
[2] = NULL
;
132 /* Return an ffi_type for a Go interface type. This describes the
133 __go_interface and __go_empty_interface structs. */
136 go_interface_to_ffi (void)
140 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
141 ret
->type
= FFI_TYPE_STRUCT
;
142 ret
->elements
= (ffi_type
**) __go_alloc (3 * sizeof (ffi_type
*));
143 ret
->elements
[0] = &ffi_type_pointer
;
144 ret
->elements
[1] = &ffi_type_pointer
;
145 ret
->elements
[2] = NULL
;
149 /* Return an ffi_type for a Go complex type. */
152 go_complex_to_ffi (ffi_type
*float_type
)
156 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
157 ret
->type
= FFI_TYPE_STRUCT
;
158 ret
->elements
= (ffi_type
**) __go_alloc (3 * sizeof (ffi_type
*));
159 ret
->elements
[0] = float_type
;
160 ret
->elements
[1] = float_type
;
161 ret
->elements
[2] = NULL
;
165 /* Return an ffi_type for a type described by a
166 __go_type_descriptor. */
169 go_type_to_ffi (const struct __go_type_descriptor
*descriptor
)
171 switch (descriptor
->__code
& GO_CODE_MASK
)
174 if (sizeof (_Bool
) == 1)
175 return &ffi_type_uint8
;
176 else if (sizeof (_Bool
) == sizeof (int))
177 return &ffi_type_uint
;
180 if (sizeof (float) == 4)
181 return &ffi_type_float
;
184 if (sizeof (double) == 8)
185 return &ffi_type_double
;
189 runtime_throw("the libffi library does not support Complex64 type with "
190 "reflect.Call or runtime.SetFinalizer");
192 if (sizeof (float) == 4)
193 return go_complex_to_ffi (&ffi_type_float
);
198 runtime_throw("the libffi library does not support Complex128 type with "
199 "reflect.Call or runtime.SetFinalizer");
201 if (sizeof (double) == 8)
202 return go_complex_to_ffi (&ffi_type_double
);
206 return &ffi_type_sint16
;
208 return &ffi_type_sint32
;
210 return &ffi_type_sint64
;
212 return &ffi_type_sint8
;
214 return sizeof (intgo
) == 4 ? &ffi_type_sint32
: &ffi_type_sint64
;
216 return &ffi_type_uint16
;
218 return &ffi_type_uint32
;
220 return &ffi_type_uint64
;
222 return &ffi_type_uint8
;
224 return sizeof (uintgo
) == 4 ? &ffi_type_uint32
: &ffi_type_uint64
;
226 if (sizeof (void *) == 2)
227 return &ffi_type_uint16
;
228 else if (sizeof (void *) == 4)
229 return &ffi_type_uint32
;
230 else if (sizeof (void *) == 8)
231 return &ffi_type_uint64
;
234 return go_array_to_ffi ((const struct __go_array_type
*) descriptor
);
236 return go_slice_to_ffi ((const struct __go_slice_type
*) descriptor
);
238 return go_struct_to_ffi ((const struct __go_struct_type
*) descriptor
);
240 return go_string_to_ffi ();
242 return go_interface_to_ffi ();
247 case GO_UNSAFE_POINTER
:
248 /* These types are always pointers, and for FFI purposes nothing
250 return &ffi_type_pointer
;
256 /* Return the return type for a function, given the number of out
257 parameters and their types. */
260 go_func_return_ffi (const struct __go_func_type
*func
)
263 const struct __go_type_descriptor
**types
;
267 count
= func
->__out
.__count
;
269 return &ffi_type_void
;
271 types
= (const struct __go_type_descriptor
**) func
->__out
.__values
;
274 return go_type_to_ffi (types
[0]);
276 ret
= (ffi_type
*) __go_alloc (sizeof (ffi_type
));
277 ret
->type
= FFI_TYPE_STRUCT
;
278 ret
->elements
= (ffi_type
**) __go_alloc ((count
+ 1) * sizeof (ffi_type
*));
279 for (i
= 0; i
< count
; ++i
)
280 ret
->elements
[i
] = go_type_to_ffi (types
[i
]);
281 ret
->elements
[count
] = NULL
;
285 /* Build an ffi_cif structure for a function described by a
286 __go_func_type structure. */
289 go_func_to_cif (const struct __go_func_type
*func
, _Bool is_interface
,
290 _Bool is_method
, ffi_cif
*cif
)
293 const struct __go_type_descriptor
**in_types
;
301 num_params
= func
->__in
.__count
;
302 in_types
= ((const struct __go_type_descriptor
**)
303 func
->__in
.__values
);
305 num_args
= num_params
+ (is_interface
? 1 : 0);
306 args
= (ffi_type
**) __go_alloc (num_args
* sizeof (ffi_type
*));
311 args
[0] = &ffi_type_pointer
;
316 args
[0] = &ffi_type_pointer
;
319 for (; i
< num_params
; ++i
)
320 args
[i
+ off
] = go_type_to_ffi (in_types
[i
]);
322 rettype
= go_func_return_ffi (func
);
324 status
= ffi_prep_cif (cif
, FFI_DEFAULT_ABI
, num_args
, rettype
, args
);
325 __go_assert (status
== FFI_OK
);
328 /* Get the total size required for the result parameters of a
332 go_results_size (const struct __go_func_type
*func
)
335 const struct __go_type_descriptor
**types
;
340 count
= func
->__out
.__count
;
344 types
= (const struct __go_type_descriptor
**) func
->__out
.__values
;
346 /* A single integer return value is always promoted to a full
350 switch (types
[0]->__code
& GO_CODE_MASK
)
361 return sizeof (ffi_arg
);
370 for (i
= 0; i
< count
; ++i
)
374 align
= types
[i
]->__field_align
;
375 if (align
> maxalign
)
377 off
= (off
+ align
- 1) & ~ (align
- 1);
378 off
+= types
[i
]->__size
;
381 off
= (off
+ maxalign
- 1) & ~ (maxalign
- 1);
386 /* Copy the results of calling a function via FFI from CALL_RESULT
387 into the addresses in RESULTS. */
390 go_set_results (const struct __go_func_type
*func
, unsigned char *call_result
,
394 const struct __go_type_descriptor
**types
;
398 count
= func
->__out
.__count
;
402 types
= (const struct __go_type_descriptor
**) func
->__out
.__values
;
404 /* A single integer return value is always promoted to a full
408 switch (types
[0]->__code
& GO_CODE_MASK
)
422 unsigned char buf
[sizeof (ffi_arg
)];
427 __builtin_memcpy (&u
.buf
, call_result
, sizeof (ffi_arg
));
430 switch (types
[0]->__size
)
437 __builtin_memcpy (results
[0], &b
, 1);
446 __builtin_memcpy (results
[0], &s
, 2);
455 __builtin_memcpy (results
[0], &w
, 4);
464 __builtin_memcpy (results
[0], &d
, 8);
480 for (i
= 0; i
< count
; ++i
)
485 align
= types
[i
]->__field_align
;
486 size
= types
[i
]->__size
;
487 off
= (off
+ align
- 1) & ~ (align
- 1);
488 __builtin_memcpy (results
[i
], call_result
+ off
, size
);
493 /* Call a function. The type of the function is FUNC_TYPE, and the
494 closure is FUNC_VAL. PARAMS is an array of parameter addresses.
495 RESULTS is an array of result addresses.
497 If IS_INTERFACE is true this is a call to an interface method and
498 the first argument is the receiver, which is always a pointer.
499 This argument, the receiver, is not described in FUNC_TYPE.
501 If IS_METHOD is true this is a call to a method expression. The
502 first argument is the receiver. It is described in FUNC_TYPE, but
503 regardless of FUNC_TYPE, it is passed as a pointer.
505 If neither IS_INTERFACE nor IS_METHOD is true then we are calling a
506 function indirectly, and we must pass a closure pointer via
507 __go_set_closure. The pointer to pass is simply FUNC_VAL. */
510 reflect_call (const struct __go_func_type
*func_type
, FuncVal
*func_val
,
511 _Bool is_interface
, _Bool is_method
, void **params
,
515 unsigned char *call_result
;
517 __go_assert ((func_type
->__common
.__code
& GO_CODE_MASK
) == GO_FUNC
);
518 go_func_to_cif (func_type
, is_interface
, is_method
, &cif
);
520 call_result
= (unsigned char *) malloc (go_results_size (func_type
));
522 if (!is_interface
&& !is_method
)
523 __go_set_closure (func_val
);
524 ffi_call (&cif
, func_val
->fn
, call_result
, params
);
526 /* Some day we may need to free result values if RESULTS is
529 go_set_results (func_type
, call_result
, results
);
534 #else /* !defined(USE_LIBFFI) */
537 reflect_call (const struct __go_func_type
*func_type
__attribute__ ((unused
)),
538 FuncVal
*func_val
__attribute__ ((unused
)),
539 _Bool is_interface
__attribute__ ((unused
)),
540 _Bool is_method
__attribute__ ((unused
)),
541 void **params
__attribute__ ((unused
)),
542 void **results
__attribute__ ((unused
)))
544 /* Without FFI there is nothing we can do. */
545 runtime_throw("libgo built without FFI does not support "
546 "reflect.Call or runtime.SetFinalizer");
549 #endif /* !defined(USE_LIBFFI) */