1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 #define USE_LIBFFI_CLOSURES
17 #endif /* defined(USE_LIBFFI) */
19 /* Declare C functions with the names used to call from Go. */
27 struct ffi_ret
ffi(const struct __go_func_type
*ftyp
, FuncVal
*callback
)
28 __asm__ (GOSYM_PREFIX
"reflect.ffi");
30 void ffiFree(void *data
)
31 __asm__ (GOSYM_PREFIX
"reflect.ffiFree");
33 #ifdef USE_LIBFFI_CLOSURES
35 /* The function that we pass to ffi_prep_closure_loc. This calls the
36 Go callback function (passed in user_data) with the pointer to the
37 arguments and the results area. */
39 static void ffi_callback (ffi_cif
*, void *, void **, void *)
40 __asm__ ("reflect.ffi_callback");
43 ffi_callback (ffi_cif
* cif
__attribute__ ((unused
)), void *results
,
44 void **args
, void *user_data
)
50 void (*f
) (void *, void *);
52 /* This function is called from some series of FFI closure functions
53 called by a Go function. We want to see whether the caller of
54 the closure functions can recover. Look up the stack and skip
56 n
= runtime_callers (1, &locs
[0], sizeof locs
/ sizeof locs
[0], true);
57 for (i
= 0; i
< n
; i
++)
61 if (locs
[i
].function
.len
== 0)
63 if (locs
[i
].function
.len
< 4)
65 name
= locs
[i
].function
.str
;
66 if (name
[0] != 'f' || name
[1] != 'f' || name
[2] != 'i' || name
[3] != '_')
70 __go_makefunc_ffi_can_recover (locs
+ i
, n
- i
);
72 fv
= (FuncVal
*) user_data
;
73 __go_set_closure (fv
);
78 __go_makefunc_returning ();
81 /* Allocate an FFI closure and arrange to call ffi_callback. */
84 ffi (const struct __go_func_type
*ftyp
, FuncVal
*callback
)
91 cif
= (ffi_cif
*) __go_alloc (sizeof (ffi_cif
));
92 __go_func_to_cif (ftyp
, 0, 0, cif
);
93 data
= ffi_closure_alloc (sizeof (ffi_closure
), &code
);
95 runtime_panicstring ("ffi_closure_alloc failed");
96 if (ffi_prep_closure_loc (data
, cif
, ffi_callback
, callback
, code
)
98 runtime_panicstring ("ffi_prep_closure_loc failed");
105 /* Free the FFI closure. */
110 ffi_closure_free (data
);
113 #else /* !defined(USE_LIBFFI_CLOSURES) */
116 ffi(const struct __go_func_type
*ftyp
, FuncVal
*callback
)
118 runtime_panicstring ("libgo built without FFI does not support "
122 void ffiFree(void *data
)
124 runtime_panicstring ("libgo built without FFI does not support "