X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fffi.sgml;fp=docs%2Fffi.sgml;h=0000000000000000000000000000000000000000;hb=ed0437d445eb58eeabe90f294f45d46dbfe8c7ad;hp=bb5d78b9a257574a30b6eba9d976181bba7840bf;hpb=318f8bc4f99013961e5f168b1f1de8983ead7eb0;p=ghc-hetmet.git diff --git a/docs/ffi.sgml b/docs/ffi.sgml deleted file mode 100644 index bb5d78b..0000000 --- a/docs/ffi.sgml +++ /dev/null @@ -1,1343 +0,0 @@ - -Introduction - - - -The motivation behind this foreign function interface (FFI) specification is -to make it possible to describe in Haskell source code -the interface to foreign functionality in a Haskell system independent -manner. It builds on experiences made with the previous foreign function -interfaces provided by GHC and Hugs. However, the FFI specified in this -document is not in the market of trying to completely bridge the gap between -the actual type of an external function, and what is a -convenient type for that function to the Haskell -programmer. That is the domain of tools like HaskellDirect or GreenCard, both -of which are capable of generating Haskell code that uses this FFI. - - - -In the following, we will discuss the language extensions of the FFI. -The extensions can be split up into two complementary halves; one half -that provides Haskell constructs for importing foreign functionality -into Haskell, the other which lets you expose Haskell functions to the -outside world. We start with the former, how to import external -functionality into Haskell. - - - - - -Calling foreign functions - - - -To bind a Haskell variable name and type to an external function, we -introduce a new construct: foreign import. It defines the type of a Haskell function together with the name of an external function that actually implements it. The syntax of foreign import construct is as follows: - - - - - -topdecl - : ... - .. - | 'foreign' 'import' [callconv] [ext_fun] ['unsafe'] varid '::' prim_type - - - - - -A foreign import declaration is only allowed as a toplevel -declaration. It consists of two parts, one giving the Haskell type -(prim_type), Haskell name (varid) and a flag indicating whether the -primitive is unsafe, the other giving details of the name of the -external function (ext_fun) and its calling interface -(callconv.) - - - -Giving a Haskell name and type to an external entry point is clearly -an unsafe thing to do, as the external name will in most cases be -untyped. The onus is on the programmer using foreign import to -ensure that the Haskell type given correctly maps on to the -type of the external function. - specifies the mapping from -Haskell types to external types. - - - -Giving the external function a Haskell name - - - -The external function has to be given a Haskell name. The name -must be a Haskell varid, so the language rules regarding -variable names must be followed, i.e., it must start with a -lower case letter followed by a sequence of alphanumeric -(`in the Unicode sense') characters or '. - - - -Notice that with Haskell 98, underscore ('_') is included in -the character class small. - - - - - - - -varid : small ( small | large | udigit | ' )* - - - - - - -Naming the external function - - - -The name of the external function is a string: - - - -ext_fun : string - - -For example, - - - -foreign import stdcall "RegCloseKey" regCloseKey :: Ptr a -> IO () - - - -states that the external function named RegCloseKey should be bound to the Haskell name regCloseKey. - - -The details of where exactly the external name can be found, such as -whether or not it is dynamically linked, and which library it might -come from, are implementation dependent. This information is expected -to be provided using a compiler-specific method (eg. GHC uses either -packages or command-line options to specify libraries and extra -include files). - - -If the Haskell name of the imported function is identical to the -external name, the ext_fun can be -omitted. e.g.: - - - - - -foreign import sin :: Double -> IO Double - - - - - -is identical to - - - - - -foreign import "sin" sin :: Double -> IO Double - - - - - - - -Calling conventions - - - -The number of calling conventions supported is fixed: - - - - - -callconv : ccall | stdcall - - - - - - - - -ccall - - -The 'default' calling convention on a platform, i.e., the one -used to do (C) function calls. - - - -In the case of x86 platforms, the caller pushes function arguments -from right to left on the C stack before calling. The caller is -responsible for popping the arguments off of the C stack on return. - - - - -stdcall - - -A Win32 specific calling convention. The same as ccall, except -that the callee cleans up the C stack before returning. - - - -The stdcall is a Microsoft Win32 specific wrinkle; it's used -throughout the Win32 API, for instance. On platforms where -stdcall isn't meaningful, it should be treated as being equal -to ccall. - - - - - - - - - - -Some remarks: - - - - - -Interoperating well with external code is the name of the game here, -so the guiding principle when deciding on what calling conventions -to include in callconv is that there's a demonstrated need for -a particular calling convention. Should it emerge that the inclusion -of other calling conventions will generally improve the quality of -this Haskell FFI, they will be considered for future inclusion in -callconv. - - - - - -Supporting stdcall (and perhaps other platform-specific calling -conventions) raises the issue of whether a Haskell FFI should allow -the user to write platform-specific Haskell code. The calling -convention is clearly an integral part of an external function's -interface, so if the one used differs from the standard one specified -by the platform's ABI and that convention is used by a -non-trivial amount of external functions, the view of the FFI authors -is that a Haskell FFI should support it. - - - - - -For foreign import (and other foreign declarations), -supplying the calling convention is optional. If it isn't supplied, -it is treated as if ccall was specified. Users are encouraged -to leave out the specification of the calling convention, if possible. - - - - - - - - - - -External function types - - - -The range of types that can be passed as arguments to an external -function is restricted (as are the range of results coming back): - - - - - -prim_type : IO prim_result - | prim_result - | prim_arg '->' prim_type - - - - - - - - - - -If you associate a non-IO type with an external function, you -have the same 'proof obligations' as when you make use of -IOExts.unsafePerformIO in your Haskell programs. - - - - - -The external function is strict in all its arguments. - - - - - - - - - defines -prim_result; -defines prim_arg. - - - -Argument types - - - -The external function expects zero or more arguments. The set of legal -argument types is restricted to the following set: - - - - - -prim_arg : ext_ty | new_ty | ForeignPtr a - -new_ty : a Haskell newtype of a prim_arg. - -ext_ty : int_ty | word_ty | float_ty - | Ptr a | Char | StablePtr a - | Bool - -int_ty : Int | Int8 | Int16 | Int32 | Int64 -word_ty : Word8 | Word16 | Word32 | Word64 -float_ty : Float | Double - - - - - - - - - - -ext_ty represent the set of basic types supported by -C-like languages, although the numeric types are explicitly sized. - -The stable pointer StablePtr type looks out of place in -this list of C-like types, but it has a well-defined and simple -C mapping, see -for details. - - - - - - -prim_arg represent the set of permissible -argument types. In addition to ext_ty, -ForeignPtr is also included. - -The ForeignPtr type represent values that are -pointers to some external entity/object. It differs from the -Ptr type in that ForeignPtrs are -finalized, i.e., once the garbage collector -determines that a ForeignPtr is unreachable, it -will invoke a finalising procedure attached to the -ForeignPtr to notify the outside world that we're -through with using it. - - - - - - -Haskell newtypes that wrap up a -prim_arg type can also be passed to external -functions. - - - - - -Haskell type synonyms for any of the above can also be used -in foreign import declarations. Qualified names likewise, -i.e. Word.Word32 is legal. - - - - - - -foreign import does not support the binding to external -constants/variables. A foreign import declaration that takes no -arguments represent a binding to a function with no arguments. - - - - - -A GHC extension is the support for unboxed types: - - - -prim_arg : ... | unboxed_h_ty -ext_ty : .... | unboxed_ext_ty - -unboxed_ext_ty : Int# | Word# | Char# - | Float# | Double# | Addr# - | StablePtr# a -unboxed_h_ty : MutableByteArray# | ForeignObj# - | ByteArray# - - - -Clearly, if you want to be portable across Haskell systems, using -system-specific extensions such as this is not advisable; avoid -using them if you can. (Support for using unboxed types might -be withdrawn sometime in the future.) - - - - - - - - - - -Result type - - - -An external function is permitted to return the following -range of types: - - - - - -prim_result : ext_ty | new_ext_ty | () - -new_ext_ty : a Haskell newtype of an ext_ty. - - - - - -where () represents void / no result. - - - - - - - - -External functions cannot raise exceptions (IO exceptions or non-IO ones.) -It is the responsibility of the foreign import user to layer -any error handling on top of an external function. - - - - - -Only external types (ext_ty) can be passed -back, i.e., returning ForeignPtrs is not -supported/allowed. - - - - - -Haskell newtypes that wrap up ext_ty are also permitted. - - - - - - - - - - - - -Type mapping - - - -For the FFI to be of any practical use, the properties and sizes of -the various types that can be communicated between the Haskell world -and the outside, needs to be precisely defined. We do this by -presenting a mapping to C, as it is commonly used and most other -languages define a mapping to it. Table - -defines the mapping between Haskell and C types. - - - - - -Mapping of Haskell types to C types - - - - - - - - -Haskell type - C type - requirement - range (9) - - - - - -Char - HsChar - unspec. integral type - HS_CHAR_MIN .. HS_CHAR_MAX - - - -Int - HsInt - signed integral of unspec. size(4) - HS_INT_MIN .. -HS_INT_MAX - - - -Int8 (2) - HsInt8 - 8 bit signed integral - HS_INT8_MIN -.. -HS_INT8_MAX - - - -Int16 (2) - HsInt16 - 16 bit signed integral - HS_INT16_MIN -.. HS_INT16_MAX - - - -Int32 (2) - HsInt32 - 32 bit signed integral - HS_INT32_MIN .. -HS_INT32_MAX - - - -Int64 (2,3) - HsInt64 - 64 bit signed integral (3) - HS_INT64_MIN .. -HS_INT64_MAX - - - -Word8 (2) - HsWord8 - 8 bit unsigned integral - 0 .. -HS_WORD8_MAX - - - -Word16 (2) - HsWord16 - 16 bit unsigned integral - 0 .. -HS_WORD16_MAX - - - -Word32 (2) - HsWord32 - 32 bit unsigned integral - 0 .. -HS_WORD32_MAX - - - -Word64 (2,3) - HsWord64 - 64 bit unsigned integral (3) - 0 .. -HS_WORD64_MAX - - - -Float - HsFloat - floating point of unspec. size (5) - (10) - - - -Double - HsDouble - floating point of unspec. size (5) - (10) - - - -Bool - HsBool - unspec. integral type - (11) - - - -Ptr a - HsPtr - void* (6) - - - - -ForeignPtr a - HsForeignPtr - void* (7) - - - - -StablePtr a - HsStablePtr - void* (8) - - - - - - -
- -
- - -Some remarks: - - - - - -A Haskell system that implements the FFI will supply a header file -HsFFI.h that includes target platform specific definitions -for the above types and values. - - - - - -The sized numeric types Hs{Int,Word}{8,16,32,64} have -a 1-1 mapping to ISO C 99's {,u}int{8,16,32,64}_t. For systems -that doesn't support this revision of ISO C, a best-fit mapping -onto the supported C types is provided. - - - - - -An implementation which does not support 64 bit integral types -on the C side should implement Hs{Int,Word}64 as a struct. In -this case the bounds HS_INT64_{MIN,MAX} and HS_WORD64_MAX -are undefined. - - - - - -A valid Haskell representation of Int has to be equal to or -wider than 30 bits. The HsInt synonym is guaranteed to map -onto a C type that satisifies Haskell's requirement for Int. - - - - - -It is guaranteed that Hs{Float,Double} are one of C's -floating-point types float/double/long double. - - - - - -It is guaranteed that HsAddr is of the same size as void*, so -any other pointer type can be converted to and from HsAddr without any -loss of information (K&R, Appendix A6.8). - - - - - -Foreign objects are handled like Ptr by the FFI, so there -is again the guarantee that HsForeignPtr is the same as -void*. The separate name is meant as a reminder that there is -a finalizer attached to the object pointed to. - - - - - -Stable pointers are passed as addresses by the FFI, but this is -only because a void* is used as a generic container in most -APIs, not because they are real addresses. To make this special -case clear, a separate C type is used here. - - - - - -The bounds are preprocessor macros, so they can be used in -#if and for array bounds. - - - - - -Floating-point limits are a little bit more complicated, so -preprocessor macros mirroring ISO C's float.h are provided: - - -HS_{FLOAT,DOUBLE}_RADIX -HS_{FLOAT,DOUBLE}_ROUNDS -HS_{FLOAT,DOUBLE}_EPSILON -HS_{FLOAT,DOUBLE}_DIG -HS_{FLOAT,DOUBLE}_MANT_DIG -HS_{FLOAT,DOUBLE}_MIN -HS_{FLOAT,DOUBLE}_MIN_EXP -HS_{FLOAT,DOUBLE}_MIN_10_EXP -HS_{FLOAT,DOUBLE}_MAX -HS_{FLOAT,DOUBLE}_MAX_EXP -HS_{FLOAT,DOUBLE}_MAX_10_EXP - - - - - - - -It is guaranteed that Haskell's False/True map to -C's 0/1, respectively, and vice versa. The mapping of -any other integral value to Bool is left unspecified. - - - - - -To avoid name clashes, identifiers starting with Hs and -macros starting with HS_ are reserved for the FFI. - - - - - -GHC only: The GHC specific types ByteArray and -MutableByteArray both map to char*. - - - - - - - -
- - -Some <Literal>foreign import</Literal> wrinkles - - - - - - - - -By default, a foreign import function is safe. A safe -external function may cause a Haskell garbage collection as a result -of being called. This will typically happen when the imported -function end up calling Haskell functions that reside in the same -'Haskell world' (i.e., shares the same storage manager heap) -- see - for -details of how the FFI let's you call Haskell functions from the outside. - -If the programmer can guarantee that the imported function won't -call back into Haskell, the foreign import can be marked as -'unsafe' (see for details of -how to do this.) - -Unsafe calls are cheaper than safe ones, so distinguishing the two -classes of external calls may be worth your while if you're extra -conscious about performance. - - - - - - -A foreign imported function should clearly not need to know that -it is being called from Haskell. One consequence of this is that the -lifetimes of the arguments that are passed from Haskell must -equal that of a normal C call. For instance, for the following decl, - - - -foreign import "mumble" mumble :: ForeignPtr a -> IO () - -f :: Ptr a -> IO () -f ptr = do - fo <- newForeignObj ptr myFinalizer - mumble fo - - - -The ForeignPtr must live across the call to -mumble even if it is not subsequently -used/reachable. Why the insistence on this? Consider what happens if -mumble calls a function which calls back into the -Haskell world to execute a function, behind our back as it were. This -evaluation may possibly cause a garbage collection, with the result -that fo may end up being finalised. - -By guaranteeing that fo will be considered live -across the call to mumble, the unfortunate -situation where fo is finalised (and hence the -reference passed to mumble is suddenly no longer -valid) is avoided. - - - - - - - - - - - -
- - -Invoking external functions via a pointer - - - -A foreign import declaration imports an external -function into Haskell. (The name of the external function -is statically known, but the loading/linking of it may very well -be delayed until run-time.) A foreign import declaration is then -(approximately) just a type cast of an external function with a -statically known name. - - - -An extension of foreign import is the support for dynamic type -casts of external names/addresses: - - - - - -topdecl - : ... - .. - | 'foreign' 'import' [callconv] 'dynamic' ['unsafe'] - varid :: Addr -> (prim_args -> IO prim_result) - - - - - -i.e., identical to a foreign import declaration, but for the -specification of dynamic instead of the name of an external -function. The presence of dynamic indicates that when an -application of varid is evaluated, the function pointed to by its -first argument will be invoked, passing it the rest of varid's -arguments. - - - -What are the uses of this? Native invocation of COM methods, - - -Or the interfacing to any other software component technologies. - - -Haskell libraries that want to be dressed up as C libs (and hence may have -to support C callbacks), Haskell code that need to dynamically load -and execute code. - - - - - -Exposing Haskell functions - - - -So far we've provided the Haskell programmer with ways of importing -external functions into the Haskell world. The other half of the FFI -coin is how to expose Haskell functionality to the outside world. So, -dual to the foreign import declaration is foreign export: - - - - - -topdecl - : ... - .. - | 'foreign' 'export' callconv [ext_name] varid :: prim_type - - - - - -A foreign export declaration tells the compiler to expose a -locally defined Haskell function to the outside world, i.e., wrap -it up behind a calling interface that's useable from C. It is only -permitted at the toplevel, where you have to specify the type at -which you want to export the function, along with the calling -convention to use. For instance, the following export declaration: - - - - - -foreign export ccall "foo" bar :: Int -> Addr -> IO Double - - - - - -will cause a Haskell system to generate the following C callable -function: - - - - - -HsDouble foo(HsInt arg1, HsAddr arg2); - - - - - -When invoked, it will call the Haskell function bar, passing -it the two arguments that was passed to foo(). - - - - - - - - -The range of types that can be passed as arguments and results -is restricted, since varid has got a prim_type. - - - - - -It is not possible to directly export operator symbols. - - - - - -The type checker will verify that the type given for the -foreign export declaration is compatible with the type given to -function definition itself. The type in the foreign export may -be less general than that of the function itself. For example, -this is legal: - - - - f :: Num a => a -> a - foreign export ccall "fInt" f :: Int -> Int - foreign export ccall "fFloat" f :: Float -> Float - - - -These declarations export two C-callable procedures fInt and -fFloat, both of which are implemented by the (overloaded) -Haskell function f. - - - - - - -The foreign exported IO action must catch all exceptions, as -the FFI does not address how to signal Haskell exceptions to the -outside world. - - - - - - - - -Exposing Haskell function values - - - -The foreign export declaration gives the C programmer access to -statically defined Haskell functions. It does not allow you to -conveniently expose dynamically-created Haskell function values as C -function pointers though. To permit this, the FFI supports -dynamic foreign exports: - - - - - -topdecl - : ... - .. - | 'foreign' 'export' [callconv] 'dynamic' varid :: prim_type -> IO Addr - - - - - -A foreign export dynamic declaration declares a C function -pointer generator. Given a Haskell function value of some restricted -type, the generator wraps it up behind an externally callable interface, -returning an Addr to an externally callable (C) function pointer. - - - -When that function pointer is eventually called, the corresponding -Haskell function value is applied to the function pointer's arguments -and evaluated, returning the result (if any) back to the caller. - - - -The mapping between the argument to a foreign export dynamic -declaration and its corresponding C function pointer type, is as -follows: - - - - - -typedef cType[[Res]] (*Varid_FunPtr) - (cType[[Ty_1]] ,.., cType[[Ty_n]]); - - - - - -where cType[[]] is the Haskell to C type mapping presented -in . - - - -To make it all a bit more concrete, here's an example: - - - - - -foreign export dynamic mkCallback :: (Int -> IO Int) -> IO Addr - -foreign import registerCallback :: Addr -> IO () - -exportCallback :: (Int -> IO Int) -> IO () -exportCallback f = do - fx <- mkCallback f - registerCallback fx - - - - - -The exportCallback lets you register a Haskell function value as -a callback function to some external library. The C type of the -callback that the external library expects in registerCallback(), -is: - - -An FFI implementation is encouraged to generate the C typedef corresponding -to a foreign export dynamic declaration, but isn't required -to do so. - - - - - - - - -typedef HsInt (*mkCallback_FunPtr) (HsInt arg1); - - - - - -Creating the view of a Haskell closure as a C function pointer entails -registering the Haskell closure as a 'root' with the underlying -Haskell storage system, so that it won't be garbage collected. The FFI -implementation takes care of this, but when the outside world is -through with using a C function pointer generated by a foreign -export dynamic declaration, it needs to be explicitly freed. This is -done by calling: - - - - - -void freeHaskellFunctionPtr(void *ptr); - - - - - -In the event you need to free these function pointers from within -Haskell, a standard 'foreign import'ed binding of the above C entry -point is also provided, - - - - - -Foreign.freeHaskellFunctionPtr :: Addr -> IO () - - - - - - - -Code addresses - - - -The foreign import declaration allows us to invoke an external -function by name from within the comforts of the Haskell world, while -foreign import dynamic lets us invoke an external function by -address. However, there's no way of getting at the code address of -some particular external label though, which is at times useful, -e.g. for the construction of method tables for, say, Haskell COM -components. To support this, the FFI has got foreign labels: - - - - - -foreign label "freeAtLast" addrOf_freeAtLast :: Addr - - - - - -The meaning of this declaration is that addrOf_freeAtLast will now -contain the address of the label freeAtLast. - - - - - -