X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fffi.sgml;h=067f790183c822d1a6a43c4877436c243ed55642;hb=72f5cd2fbc56c266e92f974a4561fbe878628b63;hp=0cc2acaaa192999e3f5ce65ff6f189a4cc40f825;hpb=13df0a2862ab945e7e404bdacb0bb9c7479accad;p=ghc-hetmet.git
diff --git a/docs/ffi.sgml b/docs/ffi.sgml
index 0cc2aca..067f790 100644
--- a/docs/ffi.sgml
+++ b/docs/ffi.sgml
@@ -16,63 +16,12 @@ of which are capable of generating Haskell code that uses this FFI.
-Generally, the FFI consists of three parts:
-
-
-
-
-extensions to the base language Haskell 98 (most notably foreign
-import and foreign export declarations), which
-are specified in the present document,
-
-
-
-
-
-a low-level marshalling library, which is part of the
-Language part of the Haskell Extension
-Library (see ), and a
-
-
-
-
-
-a high-level marshalling library, which is still under development.
-
-
-
-
-Before diving into the details of the language extension coming with the FFI,
-let us briefly outline the two other components of the interface.
-
-
-
-The low-level marshalling library consists of a portion that is independent of
-the targeted foreign language and dedicated support for Haskell bindings to C
-libraries (special support for other languages may be added in the future).
-The language independent part is given by the module
-Foreign module (see ). It
-provides support for handling references to foreign structures, for passing
-references to Haskell structures out to foreign routines, and for storing
-primitive data types in raw memory blocks in a portable manner. The support
-for C libraries essentially provides Haskell representations for all basic
-types of C (see and ).
-
-
-
-The high-level library, of which the interface definition is not yet
-finalised, provides routines for marshalling complex Haskell structures as
-well as handling out and in-out parameters in a convenient, yet protable way.
-
-
-
-In the following, we will discuss the language extensions of the FFI (i.e. the
-first point above). They 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.
+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.
@@ -149,98 +98,41 @@ varid : small ( small | large | udigit | ' )*
-The name of the external function consists of two parts,
-one specifying its location, the other its name:
+The name of the external function is a string:
-
-
-ext_fun : ext_loc ext_name
- | ext_name
-
-ext_name : string
-ext_loc : string
-
-
-
+ext_fun : string
For example,
-
-
-foreign import stdcall "Advapi32" "RegCloseKey" regCloseKey :: Addr -> IO ()
+foreign import stdcall "RegCloseKey" regCloseKey :: Ptr a -> IO ()
-
-
-states that the external function named RegCloseKey at location
-Advapi32 should be bound to the Haskell name regCloseKey.
-For a Win32 Haskell implementation that supports the loading of DLLs
-on-the-fly, this declaration will most likely cause the run-time
-system to load the Advapi32.dll DLL before looking up the
-function RegCloseKey() therein to get at the function pointer
-to use when invoking regCloseKey.
-
+states that the external function named RegCloseKey should be bound to the Haskell name regCloseKey.
-Compiled implementations may do something completely different, i.e.,
-mangle "RegCloseKey" to convert it into an archive/import library
-symbol, that's assumed to be in scope when linking. The details of
-which are platform (and compiler command-line) dependent.
-
+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 location part is left out, the name of the external function
-specifies a symbol that is assumed to be in scope when linking.
-
-
-
-The location part can either contain an absolute `address' (i.e.,
-path) of the archive/DLL, or just its name, leaving it up to the
-underlying system (system meaning both RTS/compiler and OS) to resolve
-the name to its real location.
-
-
-
-An implementation is expected to be able to intelligently
-transform the ext_loc location to fit platform-specific
-practices for naming dynamic libraries. For instance, given the
-declaration
+If the Haskell name of the imported function is identical to the
+external name, the ext_fun can be
+omitted. e.g.:
-foreign import "Foo" "foo" foo :: Int -> Int -> IO ()
-
-
-
-
-
-an implementation should map Foo to "Foo.dll" on a Win32
-platform, and libFoo.so on ELF platforms. If the lookup of the
-dynamic library with this transformed location name should fail, the
-implementation should then attempt to use the original name before
-eventually giving up. As part of their documentation, implementations
-of foreign import should specify the exact details of how
-ext_locs are transformed and resolved, including the list of
-directories searched (and the order in which they are.)
-
-
-
-In the case the Haskell name of the imported function is identical to
-the external name, the ext_fun can be omitted. i.e.,
-
-
-
-
-
-foreign import sin :: Double -> IO Double
+foreign import sin :: Double -> IO Double
@@ -252,7 +144,7 @@ is identical to
-foreign import "sin" sin :: Double -> IO Double
+foreign import "sin" sin :: Double -> IO Double
@@ -374,7 +266,7 @@ function is restricted (as are the range of results coming back):
prim_type : IO prim_result
| prim_result
- | prim_arg '->' prim_type
+ | prim_arg '->' prim_type
@@ -396,28 +288,6 @@ have the same 'proof obligations' as when you make use of
The external function is strict in all its arguments.
-
-
-
-GHC only: The GHC FFI implementation provides one extension
-to prim_type:
-
-
-
-prim_type : ...
- | unsafe_arr_ty '->' prim_type
-
-unsafe_arr_ty : ByteArray a
- | MutableByteArray i s a
-
-
-
-GHC permits the passing of its byte array primitive types
-to external functions. There's some restrictions on when
-they can be used; see
-for more details.
-
-
@@ -441,12 +311,12 @@ argument types is restricted to the following set:
-prim_arg : ext_ty | new_ty | ForeignObj
+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
- | Addr | Char | StablePtr a
+ | Ptr a | Char | StablePtr a
| Bool
int_ty : Int | Int8 | Int16 | Int32 | Int64
@@ -475,23 +345,27 @@ for details.
-prim_arg represent the set of permissible argument types. In
-addition to ext_ty, ForeignObj is also included.
+prim_arg represent the set of permissible
+argument types. In addition to ext_ty,
+ForeignPtr is also included.
-The ForeignObj type represent values that are pointers to some
-external entity/object. It differs from the Addr type in that
-ForeignObjs are finalized, i.e., once the garbage collector
-determines that a ForeignObj is unreachable, it will invoke a
-finalising procedure attached to the ForeignObj to notify the
-outside world that we're through with using it.
+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 newtypes that wrap up a
+prim_arg type can also be passed to external
+functions.
@@ -511,46 +385,10 @@ constants/variables. A foreign import declaration that takes
arguments represent a binding to a function with no arguments.
-
-
-
-GHC only: GHC's implementation of the FFI provides
-two extensions:
-
-
-Support for passing heap allocated byte arrays to an external
-function
-
-
-prim_type : ...
- | prim_arg '->' prim_type
- | unsafe_arr_ty '->' prim_type
-
-unsafe_arr_ty : ByteArray a
- | MutableByteArray i s a
-
-
-
-GHC's ByteArray and MutableByteArray primitive types are
-(im)mutable chunks of memory allocated on the Haskell heap, and
-pointers to these can be passed to foreign imported external
-functions provided they are marked as unsafe. Since it is
-inherently unsafe to hand out references to objects in the Haskell
-heap if the external call may cause a garbage collection to happen,
-you have to annotate the foreign import declaration with
-the attribute unsafe. By doing so, the user explicitly states
-that the external function won't provoke a garbage collection,
-so passing out heap references to the external function is allright.
-
-
-
-
-
-
-Another GHC extension is the support for unboxed types:
+A GHC extension is the support for unboxed types:
@@ -575,11 +413,6 @@ be withdrawn sometime in the future.)
-
-
-
-
-
@@ -620,8 +453,9 @@ any error handling on top of an external function.
-Only external types (ext_ty) can be passed back, i.e., returning
-ForeignObjs is not supported/allowed.
+Only external types (ext_ty) can be passed
+back, i.e., returning ForeignPtrs is not
+supported/allowed.
@@ -775,21 +609,21 @@ defines the mapping between Haskell and C types.
-Addr
- HsAddr
+Ptr a
+ HsPtr
void* (6)
-ForeignObj
- HsForeignObj
+ForeignPtr a
+ HsForeignPtr
void* (7)
-StablePtr
+StablePtr a
HsStablePtr
void* (8)
@@ -858,8 +692,8 @@ loss of information (K&R, Appendix A6.8).
-Foreign objects are handled like Addr by the FFI, so there
-is again the guarantee that HsForeignObj is the same as
+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.
@@ -970,25 +804,27 @@ equal that of a normal C call. For instance, for the following decl,
-foreign import "mumble" mumble :: ForeignObj -> IO ()
+foreign import "mumble" mumble :: ForeignPtr a -> IO ()
-f :: Addr -> IO ()
+f :: Ptr a -> IO ()
f ptr = do
fo <- newForeignObj ptr myFinalizer
mumble fo
-The ForeignObj 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.
+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
+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.
@@ -1028,7 +864,7 @@ topdecl
: ...
..
| 'foreign' 'import' [callconv] 'dynamic' ['unsafe']
- varid :: Addr -> (prim_args -> IO prim_result)
+ varid :: Addr -> (prim_args -> IO prim_result)
@@ -1090,7 +926,7 @@ convention to use. For instance, the following export declaration:
-foreign export ccall "foo" bar :: Int -> Addr -> IO Double
+foreign export ccall "foo" bar :: Int -> Addr -> IO Double
@@ -1140,9 +976,9 @@ this is legal:
- f :: Num a => a -> a
- foreign export ccall "fInt" f :: Int -> Int
- foreign export ccall "fFloat" f :: Float -> Float
+ f :: Num a => a -> a
+ foreign export ccall "fInt" f :: Int -> Int
+ foreign export ccall "fFloat" f :: Float -> Float
@@ -1183,7 +1019,7 @@ function pointers though. To permit this, the FFI supports
topdecl
: ...
..
- | 'foreign' 'export' [callconv] 'dynamic' varid :: prim_type -> IO Addr
+ | 'foreign' 'export' [callconv] 'dynamic' varid :: prim_type -> IO Addr
@@ -1228,11 +1064,11 @@ To make it all a bit more concrete, here's an example:
-foreign export dynamic mkCallback :: (Int -> IO Int) -> IO Addr
+foreign export dynamic mkCallback :: (Int -> IO Int) -> IO Addr
-foreign import registerCallback :: Addr -> IO ()
+foreign import registerCallback :: Addr -> IO ()
-exportCallback :: (Int -> IO Int) -> IO ()
+exportCallback :: (Int -> IO Int) -> IO ()
exportCallback f = do
fx <- mkCallback f
registerCallback fx
@@ -1290,7 +1126,7 @@ point is also provided,
-Foreign.freeHaskellFunctionPtr :: Addr -> IO ()
+Foreign.freeHaskellFunctionPtr :: Addr -> IO ()
@@ -1344,9 +1180,11 @@ contain the address of the label freeAtLast.
-changed the C representation of Haskell_ForeignObj from
-(long*) to (void*) ANSI C guarantees that (void*)
-is the widest possible data pointer.
+changed the C representation of
+Haskell_ForeignPtr from
+(long*) to (void*) ANSI C
+guarantees that (void*) is the widest possible data
+pointer.