@@ -15,36 +15,40 @@ import Unison.Runtime.FFI.DLL
1515import Unison.Runtime.Foreign
1616import Unison.Type (ffiFuncRef , ffiSpecRef , ffiTypeRef )
1717
18- data FFType = I64 | U64 | D64 | Void
18+ data FFType = I16 | I32 | I64 | U16 | U32 | U64 | F32 | D64 | Void
1919 deriving (Eq , Ord , Show )
2020
2121instance BuiltinForeign FFType where
2222 foreignName = Tagged " FFI.Type"
2323 foreignRef = Tagged ffiTypeRef
2424
2525-- arguments and return type
26- data FFSpec = FFSpec [FFType ] ! FFType deriving (Eq , Ord , Show )
27-
28- ffArgs :: FFSpec -> [FFType ]
29- ffArgs (FFSpec as _) = as
26+ data FFSpec = FFSpec { ffArgs :: ! [FFType ], ffResult :: ! FFType }
27+ deriving (Eq , Ord , Show )
3028
3129instance BuiltinForeign FFSpec where
3230 foreignName = Tagged " FFI.Spec"
3331 foreignRef = Tagged ffiSpecRef
3432
3533data CSpec = CSpec
3634 { cInterface :: ! (ForeignPtr CIF ),
37- numArgs :: ! Int
35+ numArgs :: ! Int ,
36+ ffSpec :: ! FFSpec
3837 }
3938
4039data CDynFunc = forall a .
4140 CDynFunc
4241 { cName :: String ,
43- cResult :: ! FFType ,
4442 cSpec :: {-# UNPACK #-} ! CSpec ,
4543 cFun :: ! (FunPtr a )
4644 }
4745
46+ cffArgs :: CDynFunc -> [FFType ]
47+ cffArgs = ffArgs . ffSpec . cSpec
48+
49+ cffResult :: CDynFunc -> FFType
50+ cffResult = ffResult . ffSpec . cSpec
51+
4852instance Show CDynFunc where
4953 show f = " <" ++ cName f ++ " >"
5054
@@ -53,9 +57,14 @@ instance BuiltinForeign CDynFunc where
5357 foreignRef = Tagged ffiFuncRef
5458
5559encodeType :: FFType -> Ptr CType
60+ encodeType I16 = ffi_type_sint16
61+ encodeType I32 = ffi_type_sint32
5662encodeType I64 = ffi_type_sint64
63+ encodeType U16 = ffi_type_uint16
64+ encodeType U32 = ffi_type_uint32
5765encodeType U64 = ffi_type_uint64
5866encodeType D64 = ffi_type_double
67+ encodeType F32 = ffi_type_float
5968encodeType Void = ffi_type_void
6069
6170encodeTypes :: [FFType ] -> Ptr (Ptr CType ) -> IO ()
@@ -78,7 +87,7 @@ adjustSpec sp@(FFSpec as r)
7887
7988prepareSpec :: FFSpec -> IO CSpec
8089prepareSpec spec = do
81- FFSpec args ret <- adjustSpec spec
90+ ffSpec @ ( FFSpec args ret) <- adjustSpec spec
8291 let numArgs = length args
8392 n = fromIntegral numArgs
8493
@@ -91,11 +100,11 @@ prepareSpec spec = do
91100 unless (status == ffi_ok) $
92101 throwIO BadInit
93102
94- pure $ CSpec {cInterface, numArgs}
103+ pure $ CSpec {cInterface, numArgs, ffSpec }
95104
96105loadForeign :: DLL -> FFSpec -> String -> IO CDynFunc
97- loadForeign dll fspec@ ( FFSpec _ r) sym =
98- CDynFunc name r <$> prepareSpec fspec <*> getDLLSym dll sym
106+ loadForeign dll fspec sym =
107+ CDynFunc name <$> prepareSpec fspec <*> getDLLSym dll sym
99108 where
100109 name = getDLLPath dll ++ " $" ++ sym
101110
@@ -112,6 +121,6 @@ loadForeign dll fspec@(FFSpec _ r) sym =
112121--
113122-- Store.poke (castPtr (plusPtr p i)) <smaller-value>
114123callForeign :: CDynFunc -> Ptr (Ptr a ) -> Ptr r -> IO ()
115- callForeign (CDynFunc _ _ (CSpec cInterface _) fun) cArgs cRet =
124+ callForeign (CDynFunc _ (CSpec cInterface _ _) fun) cArgs cRet =
116125 withForeignPtr cInterface \ cif ->
117126 ffi_call cif fun (castPtr cRet) (castPtr cArgs)
0 commit comments