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*.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-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.
-
-
-
-
-
-