1 /* go-ffi.c -- convert Go type description to libffi.
2 
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.  */
6 
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 
11 #include "runtime.h"
12 #include "go-alloc.h"
13 #include "go-assert.h"
14 #include "go-type.h"
15 
16 #ifdef USE_LIBFFI
17 
18 #include "ffi.h"
19 
20 /* The functions in this file are only called from reflect_call and
21    reflect.ffi.  As these functions call libffi functions, which will
22    be compiled without -fsplit-stack, they will always run with a
23    large stack.  */
24 
25 static ffi_type *go_array_to_ffi (const struct __go_array_type *)
26   __attribute__ ((no_split_stack));
27 static ffi_type *go_slice_to_ffi (const struct __go_slice_type *)
28   __attribute__ ((no_split_stack));
29 static ffi_type *go_struct_to_ffi (const struct __go_struct_type *)
30   __attribute__ ((no_split_stack));
31 static ffi_type *go_string_to_ffi (void) __attribute__ ((no_split_stack));
32 static ffi_type *go_interface_to_ffi (void) __attribute__ ((no_split_stack));
33 static ffi_type *go_type_to_ffi (const struct __go_type_descriptor *)
34   __attribute__ ((no_split_stack));
35 static ffi_type *go_func_return_ffi (const struct __go_func_type *)
36   __attribute__ ((no_split_stack));
37 
38 /* Return an ffi_type for a Go array type.  The libffi library does
39    not have any builtin support for passing arrays as values.  We work
40    around this by pretending that the array is a struct.  */
41 
42 static ffi_type *
go_array_to_ffi(const struct __go_array_type * descriptor)43 go_array_to_ffi (const struct __go_array_type *descriptor)
44 {
45   ffi_type *ret;
46   uintptr_t len;
47   ffi_type *element;
48   uintptr_t i;
49 
50   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
51   ret->type = FFI_TYPE_STRUCT;
52   len = descriptor->__len;
53   if (len == 0)
54     {
55       /* The libffi library won't accept an empty struct.  */
56       ret->elements = (ffi_type **) __go_alloc (2 * sizeof (ffi_type *));
57       ret->elements[0] = &ffi_type_void;
58       ret->elements[1] = NULL;
59       return ret;
60     }
61   ret->elements = (ffi_type **) __go_alloc ((len + 1) * sizeof (ffi_type *));
62   element = go_type_to_ffi (descriptor->__element_type);
63   for (i = 0; i < len; ++i)
64     ret->elements[i] = element;
65   ret->elements[len] = NULL;
66   return ret;
67 }
68 
69 /* Return an ffi_type for a Go slice type.  This describes the
70    __go_open_array type defines in array.h.  */
71 
72 static ffi_type *
go_slice_to_ffi(const struct __go_slice_type * descriptor)73 go_slice_to_ffi (
74     const struct __go_slice_type *descriptor __attribute__ ((unused)))
75 {
76   ffi_type *ret;
77   ffi_type *ffi_intgo;
78 
79   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
80   ret->type = FFI_TYPE_STRUCT;
81   ret->elements = (ffi_type **) __go_alloc (4 * sizeof (ffi_type *));
82   ret->elements[0] = &ffi_type_pointer;
83   ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
84   ret->elements[1] = ffi_intgo;
85   ret->elements[2] = ffi_intgo;
86   ret->elements[3] = NULL;
87   return ret;
88 }
89 
90 /* Return an ffi_type for a Go struct type.  */
91 
92 static ffi_type *
go_struct_to_ffi(const struct __go_struct_type * descriptor)93 go_struct_to_ffi (const struct __go_struct_type *descriptor)
94 {
95   ffi_type *ret;
96   int field_count;
97   const struct __go_struct_field *fields;
98   int i;
99 
100   field_count = descriptor->__fields.__count;
101   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
102   ret->type = FFI_TYPE_STRUCT;
103   if (field_count == 0)
104     {
105       /* The libffi library won't accept an empty struct.  */
106       ret->elements = (ffi_type **) __go_alloc (2 * sizeof (ffi_type *));
107       ret->elements[0] = &ffi_type_void;
108       ret->elements[1] = NULL;
109       return ret;
110     }
111   fields = (const struct __go_struct_field *) descriptor->__fields.__values;
112   ret->elements = (ffi_type **) __go_alloc ((field_count + 1)
113 					    * sizeof (ffi_type *));
114   for (i = 0; i < field_count; ++i)
115     ret->elements[i] = go_type_to_ffi (fields[i].__type);
116   ret->elements[field_count] = NULL;
117   return ret;
118 }
119 
120 /* Return an ffi_type for a Go string type.  This describes the String
121    struct.  */
122 
123 static ffi_type *
go_string_to_ffi(void)124 go_string_to_ffi (void)
125 {
126   ffi_type *ret;
127   ffi_type *ffi_intgo;
128 
129   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
130   ret->type = FFI_TYPE_STRUCT;
131   ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
132   ret->elements[0] = &ffi_type_pointer;
133   ffi_intgo = sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
134   ret->elements[1] = ffi_intgo;
135   ret->elements[2] = NULL;
136   return ret;
137 }
138 
139 /* Return an ffi_type for a Go interface type.  This describes the
140    __go_interface and __go_empty_interface structs.  */
141 
142 static ffi_type *
go_interface_to_ffi(void)143 go_interface_to_ffi (void)
144 {
145   ffi_type *ret;
146 
147   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
148   ret->type = FFI_TYPE_STRUCT;
149   ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
150   ret->elements[0] = &ffi_type_pointer;
151   ret->elements[1] = &ffi_type_pointer;
152   ret->elements[2] = NULL;
153   return ret;
154 }
155 
156 
157 #ifndef FFI_TARGET_HAS_COMPLEX_TYPE
158 /* If libffi hasn't been updated for this target to support complex,
159    pretend complex is a structure.  Warning: This does not work for
160    all ABIs.  Eventually libffi should be updated for all targets
161    and this should go away.  */
162 
163 static ffi_type *go_complex_to_ffi (ffi_type *)
164   __attribute__ ((no_split_stack));
165 
166 static ffi_type *
go_complex_to_ffi(ffi_type * float_type)167 go_complex_to_ffi (ffi_type *float_type)
168 {
169   ffi_type *ret;
170 
171   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
172   ret->type = FFI_TYPE_STRUCT;
173   ret->elements = (ffi_type **) __go_alloc (3 * sizeof (ffi_type *));
174   ret->elements[0] = float_type;
175   ret->elements[1] = float_type;
176   ret->elements[2] = NULL;
177   return ret;
178 }
179 #endif
180 
181 /* Return an ffi_type for a type described by a
182    __go_type_descriptor.  */
183 
184 static ffi_type *
go_type_to_ffi(const struct __go_type_descriptor * descriptor)185 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
186 {
187   switch (descriptor->__code & GO_CODE_MASK)
188     {
189     case GO_BOOL:
190       if (sizeof (_Bool) == 1)
191 	return &ffi_type_uint8;
192       else if (sizeof (_Bool) == sizeof (int))
193 	return &ffi_type_uint;
194       abort ();
195     case GO_FLOAT32:
196       if (sizeof (float) == 4)
197 	return &ffi_type_float;
198       abort ();
199     case GO_FLOAT64:
200       if (sizeof (double) == 8)
201 	return &ffi_type_double;
202       abort ();
203     case GO_COMPLEX64:
204       if (sizeof (float) == 4)
205 	{
206 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE
207 	  return &ffi_type_complex_float;
208 #else
209 	  return go_complex_to_ffi (&ffi_type_float);
210 #endif
211 	}
212       abort ();
213     case GO_COMPLEX128:
214       if (sizeof (double) == 8)
215 	{
216 #ifdef FFI_TARGET_HAS_COMPLEX_TYPE
217 	  return &ffi_type_complex_double;
218 #else
219 	  return go_complex_to_ffi (&ffi_type_double);
220 #endif
221 	}
222       abort ();
223     case GO_INT16:
224       return &ffi_type_sint16;
225     case GO_INT32:
226       return &ffi_type_sint32;
227     case GO_INT64:
228       return &ffi_type_sint64;
229     case GO_INT8:
230       return &ffi_type_sint8;
231     case GO_INT:
232       return sizeof (intgo) == 4 ? &ffi_type_sint32 : &ffi_type_sint64;
233     case GO_UINT16:
234       return &ffi_type_uint16;
235     case GO_UINT32:
236       return &ffi_type_uint32;
237     case GO_UINT64:
238       return &ffi_type_uint64;
239     case GO_UINT8:
240       return &ffi_type_uint8;
241     case GO_UINT:
242       return sizeof (uintgo) == 4 ? &ffi_type_uint32 : &ffi_type_uint64;
243     case GO_UINTPTR:
244       if (sizeof (void *) == 2)
245 	return &ffi_type_uint16;
246       else if (sizeof (void *) == 4)
247 	return &ffi_type_uint32;
248       else if (sizeof (void *) == 8)
249 	return &ffi_type_uint64;
250       abort ();
251     case GO_ARRAY:
252       return go_array_to_ffi ((const struct __go_array_type *) descriptor);
253     case GO_SLICE:
254       return go_slice_to_ffi ((const struct __go_slice_type *) descriptor);
255     case GO_STRUCT:
256       return go_struct_to_ffi ((const struct __go_struct_type *) descriptor);
257     case GO_STRING:
258       return go_string_to_ffi ();
259     case GO_INTERFACE:
260       return go_interface_to_ffi ();
261     case GO_CHAN:
262     case GO_FUNC:
263     case GO_MAP:
264     case GO_PTR:
265     case GO_UNSAFE_POINTER:
266       /* These types are always pointers, and for FFI purposes nothing
267 	 else matters.  */
268       return &ffi_type_pointer;
269     default:
270       abort ();
271     }
272 }
273 
274 /* Return the return type for a function, given the number of out
275    parameters and their types.  */
276 
277 static ffi_type *
go_func_return_ffi(const struct __go_func_type * func)278 go_func_return_ffi (const struct __go_func_type *func)
279 {
280   int count;
281   const struct __go_type_descriptor **types;
282   ffi_type *ret;
283   int i;
284 
285   count = func->__out.__count;
286   if (count == 0)
287     return &ffi_type_void;
288 
289   types = (const struct __go_type_descriptor **) func->__out.__values;
290 
291   if (count == 1)
292     return go_type_to_ffi (types[0]);
293 
294   ret = (ffi_type *) __go_alloc (sizeof (ffi_type));
295   ret->type = FFI_TYPE_STRUCT;
296   ret->elements = (ffi_type **) __go_alloc ((count + 1) * sizeof (ffi_type *));
297   for (i = 0; i < count; ++i)
298     ret->elements[i] = go_type_to_ffi (types[i]);
299   ret->elements[count] = NULL;
300   return ret;
301 }
302 
303 /* Build an ffi_cif structure for a function described by a
304    __go_func_type structure.  */
305 
306 void
__go_func_to_cif(const struct __go_func_type * func,_Bool is_interface,_Bool is_method,ffi_cif * cif)307 __go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
308 		_Bool is_method, ffi_cif *cif)
309 {
310   int num_params;
311   const struct __go_type_descriptor **in_types;
312   size_t num_args;
313   ffi_type **args;
314   int off;
315   int i;
316   ffi_type *rettype;
317   ffi_status status;
318 
319   num_params = func->__in.__count;
320   in_types = ((const struct __go_type_descriptor **)
321 	      func->__in.__values);
322 
323   num_args = num_params + (is_interface ? 1 : 0);
324   args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
325   i = 0;
326   off = 0;
327   if (is_interface)
328     {
329       args[0] = &ffi_type_pointer;
330       off = 1;
331     }
332   else if (is_method)
333     {
334       args[0] = &ffi_type_pointer;
335       i = 1;
336     }
337   for (; i < num_params; ++i)
338     args[i + off] = go_type_to_ffi (in_types[i]);
339 
340   rettype = go_func_return_ffi (func);
341 
342   status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
343   __go_assert (status == FFI_OK);
344 }
345 
346 #endif /* defined(USE_LIBFFI) */
347