1 -----------------------------------------------------------------------------
5 -- (c) The University of Glasgow 2008
7 -----------------------------------------------------------------------------
26 ----------------------------------------------------------------------------
28 type ForeignCallToken = C_ffi_cif
32 -> [PrimRep] -- arg types
33 -> PrimRep -- result type
34 -> IO (Ptr ForeignCallToken) -- token for making calls
35 -- (must be freed by caller)
36 prepForeignCall cconv arg_types result_type
38 let n_args = length arg_types
39 arg_arr <- mallocArray n_args
40 let init_arg (ty,n) = pokeElemOff arg_arr n (primRepToFFIType ty)
41 mapM_ init_arg (zip arg_types [0..])
42 cif <- mallocBytes (#const sizeof(ffi_cif))
43 let abi = convToABI cconv
44 let res_ty = primRepToFFIType result_type
45 r <- ffi_prep_cif cif abi (fromIntegral n_args) res_ty arg_arr
47 then ghcError (InstallationError
48 (printf "prepForeignCallFailed: %d" (show r)))
51 convToABI :: CCallConv -> C_ffi_abi
52 convToABI CCallConv = fFI_DEFAULT_ABI
53 #ifdef mingw32_HOST_OS
54 convToABI StdCallConv = fFI_STDCALL
56 convToABI _ = panic "convToABI: convention not supported"
58 -- c.f. DsForeign.primTyDescChar
59 primRepToFFIType :: PrimRep -> Ptr C_ffi_type
62 VoidRep -> ffi_type_void
64 WordRep -> unsigned_word
65 Int64Rep -> ffi_type_sint64
66 Word64Rep -> ffi_type_uint64
67 AddrRep -> ffi_type_pointer
68 FloatRep -> ffi_type_float
69 DoubleRep -> ffi_type_double
70 _ -> panic "primRepToFFIType"
72 (signed_word, unsigned_word)
73 | wORD_SIZE == 4 = (ffi_type_sint32, ffi_type_uint32)
74 | wORD_SIZE == 8 = (ffi_type_sint64, ffi_type_uint64)
75 | otherwise = panic "primTyDescChar"
81 type C_ffi_status = (#type ffi_status)
82 type C_ffi_abi = (#type ffi_abi)
84 foreign import ccall "&ffi_type_void" ffi_type_void :: Ptr C_ffi_type
85 --foreign import ccall "&ffi_type_uint8" ffi_type_uint8 :: Ptr C_ffi_type
86 --foreign import ccall "&ffi_type_sint8" ffi_type_sint8 :: Ptr C_ffi_type
87 --foreign import ccall "&ffi_type_uint16" ffi_type_uint16 :: Ptr C_ffi_type
88 --foreign import ccall "&ffi_type_sint16" ffi_type_sint16 :: Ptr C_ffi_type
89 foreign import ccall "&ffi_type_uint32" ffi_type_uint32 :: Ptr C_ffi_type
90 foreign import ccall "&ffi_type_sint32" ffi_type_sint32 :: Ptr C_ffi_type
91 foreign import ccall "&ffi_type_uint64" ffi_type_uint64 :: Ptr C_ffi_type
92 foreign import ccall "&ffi_type_sint64" ffi_type_sint64 :: Ptr C_ffi_type
93 foreign import ccall "&ffi_type_float" ffi_type_float :: Ptr C_ffi_type
94 foreign import ccall "&ffi_type_double" ffi_type_double :: Ptr C_ffi_type
95 foreign import ccall "&ffi_type_pointer"ffi_type_pointer :: Ptr C_ffi_type
97 fFI_OK :: C_ffi_status
98 fFI_OK = (#const FFI_OK)
99 --fFI_BAD_ABI :: C_ffi_status
100 --fFI_BAD_ABI = (#const FFI_BAD_ABI)
101 --fFI_BAD_TYPEDEF :: C_ffi_status
102 --fFI_BAD_TYPEDEF = (#const FFI_BAD_TYPEDEF)
104 fFI_DEFAULT_ABI :: C_ffi_abi
105 fFI_DEFAULT_ABI = (#const FFI_DEFAULT_ABI)
106 #ifdef mingw32_HOST_OS
107 fFI_STDCALL :: C_ffi_abi
108 fFI_STDCALL = (#const FFI_STDCALL)
111 -- ffi_status ffi_prep_cif(ffi_cif *cif,
113 -- unsigned int nargs,
115 -- ffi_type **atypes);
117 foreign import ccall "ffi_prep_cif"
118 ffi_prep_cif :: Ptr C_ffi_cif -- cif
121 -> Ptr C_ffi_type -- result type
122 -> Ptr (Ptr C_ffi_type) -- arg types
127 -- void ffi_call(ffi_cif *cif,
132 -- foreign import ccall "ffi_call"
133 -- ffi_call :: Ptr C_ffi_cif -- cif
134 -- -> FunPtr (IO ()) -- function to call
135 -- -> Ptr () -- put result here
136 -- -> Ptr (Ptr ()) -- arg values