Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / runtime / go-reflect-call.c
blob610fabf545fe7a8bdc5cc73982d5c73dd952b779
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. */
7 #include <stdio.h>
8 #include <stdlib.h>
10 #include "ffi.h"
12 #include "go-alloc.h"
13 #include "go-assert.h"
14 #include "go-type.h"
15 #include "runtime.h"
17 /* Forward declaration. */
19 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *);
21 /* Return an ffi_type for a Go array type. The libffi library does
22 not have any builtin support for passing arrays as values. We work
23 around this by pretending that the array is a struct. */
25 static ffi_type *
26 go_array_to_ffi (const struct __go_array_type *descriptor)
28 ffi_type *ret;
29 uintptr_t len;
30 ffi_type *element;
31 uintptr_t i;
33 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
34 __builtin_memset (ret, 0, sizeof (ffi_type));
35 ret->type = FFI_TYPE_STRUCT;
36 len = descriptor->__len;
37 ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
38 element = go_type_to_ffi (descriptor->__element_type);
39 for (i = 0; i < len; ++i)
40 ret->elements[i] = element;
41 ret->elements[len] = NULL;
42 return ret;
45 /* Return an ffi_type for a Go slice type. This describes the
46 __go_open_array type defines in array.h. */
48 static ffi_type *
49 go_slice_to_ffi (
50 const struct __go_slice_type *descriptor __attribute__ ((unused)))
52 ffi_type *ret;
54 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
55 __builtin_memset (ret, 0, sizeof (ffi_type));
56 ret->type = FFI_TYPE_STRUCT;
57 ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
58 ret->elements[0] = &ffi_type_pointer;
59 ret->elements[1] = &ffi_type_sint;
60 ret->elements[2] = &ffi_type_sint;
61 ret->elements[3] = NULL;
62 return ret;
65 /* Return an ffi_type for a Go struct type. */
67 static ffi_type *
68 go_struct_to_ffi (const struct __go_struct_type *descriptor)
70 ffi_type *ret;
71 int field_count;
72 const struct __go_struct_field *fields;
73 int i;
75 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
76 __builtin_memset (ret, 0, sizeof (ffi_type));
77 ret->type = FFI_TYPE_STRUCT;
78 field_count = descriptor->__fields.__count;
79 fields = (const struct __go_struct_field *) descriptor->__fields.__values;
80 ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
81 * sizeof (ffi_type *));
82 for (i = 0; i < field_count; ++i)
83 ret->elements[i] = go_type_to_ffi (fields[i].__type);
84 ret->elements[field_count] = NULL;
85 return ret;
88 /* Return an ffi_type for a Go string type. This describes the
89 __go_string struct. */
91 static ffi_type *
92 go_string_to_ffi (void)
94 ffi_type *ret;
96 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
97 ret->type = FFI_TYPE_STRUCT;
98 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
99 ret->elements[0] = &ffi_type_pointer;
100 ret->elements[1] = &ffi_type_sint;
101 ret->elements[2] = NULL;
102 return ret;
105 /* Return an ffi_type for a Go interface type. This describes the
106 __go_interface and __go_empty_interface structs. */
108 static ffi_type *
109 go_interface_to_ffi (void)
111 ffi_type *ret;
113 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
114 ret->type = FFI_TYPE_STRUCT;
115 ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
116 ret->elements[0] = &ffi_type_pointer;
117 ret->elements[1] = &ffi_type_pointer;
118 ret->elements[2] = NULL;
119 return ret;
122 /* Return an ffi_type for a type described by a
123 __go_type_descriptor. */
125 static ffi_type *
126 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
128 switch (descriptor->__code)
130 case GO_BOOL:
131 if (sizeof (_Bool) == 1)
132 return &ffi_type_uint8;
133 else if (sizeof (_Bool) == sizeof (int))
134 return &ffi_type_uint;
135 abort ();
136 case GO_FLOAT32:
137 if (sizeof (float) == 4)
138 return &ffi_type_float;
139 abort ();
140 case GO_FLOAT64:
141 if (sizeof (double) == 8)
142 return &ffi_type_double;
143 abort ();
144 case GO_FLOAT:
145 return &ffi_type_float;
146 case GO_COMPLEX64:
147 case GO_COMPLEX128:
148 case GO_COMPLEX:
149 /* FIXME. */
150 abort ();
151 case GO_INT16:
152 return &ffi_type_sint16;
153 case GO_INT32:
154 return &ffi_type_sint32;
155 case GO_INT64:
156 return &ffi_type_sint64;
157 case GO_INT8:
158 return &ffi_type_sint8;
159 case GO_INT:
160 return &ffi_type_sint;
161 case GO_UINT16:
162 return &ffi_type_uint16;
163 case GO_UINT32:
164 return &ffi_type_uint32;
165 case GO_UINT64:
166 return &ffi_type_uint64;
167 case GO_UINT8:
168 return &ffi_type_uint8;
169 case GO_UINT:
170 return &ffi_type_uint;
171 case GO_UINTPTR:
172 if (sizeof (void *) == 2)
173 return &ffi_type_uint16;
174 else if (sizeof (void *) == 4)
175 return &ffi_type_uint32;
176 else if (sizeof (void *) == 8)
177 return &ffi_type_uint64;
178 abort ();
179 case GO_ARRAY:
180 return go_array_to_ffi ((const struct __go_array_type *) descriptor);
181 case GO_SLICE:
182 return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
183 case GO_STRUCT:
184 return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
185 case GO_STRING:
186 return go_string_to_ffi ();
187 case GO_INTERFACE:
188 return go_interface_to_ffi ();
189 case GO_CHAN:
190 case GO_FUNC:
191 case GO_MAP:
192 case GO_PTR:
193 case GO_UNSAFE_POINTER:
194 /* These types are always pointers, and for FFI purposes nothing
195 else matters. */
196 return &ffi_type_pointer;
197 default:
198 abort ();
202 /* Return the return type for a function, given the number of out
203 parameters and their types. */
205 static ffi_type *
206 go_func_return_ffi (const struct __go_func_type *func)
208 int count;
209 const struct __go_type_descriptor **types;
210 ffi_type *ret;
211 int i;
213 count = func->__out.__count;
214 if (count == 0)
215 return &ffi_type_void;
217 types = (const struct __go_type_descriptor **) func->__out.__values;
219 if (count == 1)
220 return go_type_to_ffi (types[0]);
222 ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
223 __builtin_memset (ret, 0, sizeof (ffi_type));
224 ret->type = FFI_TYPE_STRUCT;
225 ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
226 for (i = 0; i < count; ++i)
227 ret->elements[i] = go_type_to_ffi (types[i]);
228 ret->elements[count] = NULL;
229 return ret;
232 /* Build an ffi_cif structure for a function described by a
233 __go_func_type structure. */
235 static void
236 go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
237 ffi_cif *cif)
239 int num_params;
240 const struct __go_type_descriptor **in_types;
241 size_t num_args;
242 ffi_type **args;
243 int off;
244 int i;
245 ffi_type *rettype;
246 ffi_status status;
248 num_params = func->__in.__count;
249 in_types = ((const struct __go_type_descriptor **)
250 func->__in.__values);
252 num_args = num_params + (is_interface ? 1 : 0);
253 args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
254 if (is_interface)
255 args[0] = &ffi_type_pointer;
256 off = is_interface ? 1 : 0;
257 for (i = 0; i < num_params; ++i)
258 args[i + off] = go_type_to_ffi (in_types[i]);
260 rettype = go_func_return_ffi (func);
262 status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
263 __go_assert (status == FFI_OK);
266 /* Get the total size required for the result parameters of a
267 function. */
269 static size_t
270 go_results_size (const struct __go_func_type *func)
272 int count;
273 const struct __go_type_descriptor **types;
274 size_t off;
275 size_t maxalign;
276 int i;
278 count = func->__out.__count;
279 if (count == 0)
280 return 0;
282 types = (const struct __go_type_descriptor **) func->__out.__values;
284 off = 0;
285 maxalign = 0;
286 for (i = 0; i < count; ++i)
288 size_t align;
290 align = types[i]->__field_align;
291 if (align > maxalign)
292 maxalign = align;
293 off = (off + align - 1) & ~ (align - 1);
294 off += types[i]->__size;
297 off = (off + maxalign - 1) & ~ (maxalign - 1);
299 return off;
302 /* Copy the results of calling a function via FFI from CALL_RESULT
303 into the addresses in RESULTS. */
305 static void
306 go_set_results (const struct __go_func_type *func, unsigned char *call_result,
307 void **results)
309 int count;
310 const struct __go_type_descriptor **types;
311 size_t off;
312 int i;
314 count = func->__out.__count;
315 if (count == 0)
316 return;
318 types = (const struct __go_type_descriptor **) func->__out.__values;
320 off = 0;
321 for (i = 0; i < count; ++i)
323 size_t align;
324 size_t size;
326 align = types[i]->__field_align;
327 size = types[i]->__size;
328 off = (off + align - 1) & ~ (align - 1);
329 __builtin_memcpy (results[i], call_result + off, size);
330 off += size;
334 /* Call a function. The type of the function is FUNC_TYPE, and the
335 address is FUNC_ADDR. PARAMS is an array of parameter addresses.
336 RESULTS is an array of result addresses. */
338 void
339 reflect_call (const struct __go_func_type *func_type, const void *func_addr,
340 _Bool is_interface, void **params, void **results)
342 ffi_cif cif;
343 unsigned char *call_result;
345 __go_assert (func_type->__common.__code == GO_FUNC);
346 go_func_to_cif (func_type, is_interface, &cif);
348 call_result = (unsigned char *) malloc (go_results_size (func_type));
350 ffi_call (&cif, func_addr, call_result, params);
352 /* Some day we may need to free result values if RESULTS is
353 NULL. */
354 if (results != NULL)
355 go_set_results (func_type, call_result, results);
357 free (call_result);