[commit: ghc] master: users-guide: Document FFI safety guarantees (7de2c07)
git at git.haskell.org
git at git.haskell.org
Fri Jun 30 00:18:30 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/7de2c07d61d8ff952164ee8e6948c1415514ee6d/ghc
>---------------------------------------------------------------
commit 7de2c07d61d8ff952164ee8e6948c1415514ee6d
Author: Ben Gamari <bgamari.foss at gmail.com>
Date: Thu Jun 29 19:36:51 2017 -0400
users-guide: Document FFI safety guarantees
Test Plan: Read it
Reviewers: austin
Subscribers: simonmar, rwbarton, thomie
GHC Trac Issues: #13730, #8281
Differential Revision: https://phabricator.haskell.org/D3682
>---------------------------------------------------------------
7de2c07d61d8ff952164ee8e6948c1415514ee6d
docs/users_guide/ffi-chap.rst | 66 +++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 27 deletions(-)
diff --git a/docs/users_guide/ffi-chap.rst b/docs/users_guide/ffi-chap.rst
index 35557b8..616df29 100644
--- a/docs/users_guide/ffi-chap.rst
+++ b/docs/users_guide/ffi-chap.rst
@@ -23,6 +23,33 @@ features should be avoided where possible.
The FFI libraries are documented in the accompanying library
documentation; see for example the :base-ref:`Foreign <Foreign.html>` module.
+GHC differences to the FFI Addendum
+-----------------------------------
+
+Guaranteed call safety
+~~~~~~~~~~~~~~~~~~~~~~
+
+The FFI addendum stipulates that an implementation is free to implement an
+``unsafe`` call by performing a ``safe`` call (and therefore may run in an
+arbitrary thread and may be subject to concurrent garbage collection). This
+greatly constrains library authors since it implies that it is never safe to
+pass any heap object reference to a foreign function, even if invoked with an
+``unsafe`` call. For instance, it is often desireable to pass an unpinned
+``ByteArray#``\s directly to native code to avoid making an
+otherwise-unnecessary copy. However, this can only be done safely under
+``unsafe`` call semantics as otherwise the array may be moved by the garbage
+collector in the middle of the call.
+
+In previous releases, GHC would take advantage of the freedom afforded by the
+Addendum by performing ``safe`` foreign calls in place of ``unsafe`` calls in
+the bytecode interpreter. This meant that some packages which worked when
+compiled would fail under GHCi (e.g. :ghc-ticket:`13730`).
+
+However, since version 8.4 this is no longer the case: GHC **guarantees** that
+garbage collection will never occur during an ``unsafe`` call, even in the
+bytecode interpreter.
+
+
.. _ffi-ghcexts:
GHC extensions to the FFI Addendum
@@ -45,9 +72,7 @@ Newtype wrapping of the IO monad
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The FFI spec requires the IO monad to appear in various places, but it
-can sometimes be convenient to wrap the IO monad in a ``newtype``, thus:
-
-::
+can sometimes be convenient to wrap the IO monad in a ``newtype``, thus: ::
newtype MyIO a = MIO (IO a)
@@ -59,9 +84,8 @@ imports and exports will be automatically unwrapped if they are newtypes
(Section 3.2 of the FFI addendum). GHC extends the FFI by automatically
unwrapping any newtypes that wrap the IO monad itself. More precisely,
wherever the FFI specification requires an ``IO`` type, GHC will accept any
-newtype-wrapping of an ``IO`` type. For example, these declarations are OK:
-
-::
+newtype-wrapping of an ``IO`` type. For example, these declarations are
+OK: ::
foreign import foo :: Int -> MyIO Int
foreign import "dynamic" baz :: (Int -> MyIO Int) -> CInt -> MyIO Int
@@ -72,9 +96,7 @@ Primitive imports
~~~~~~~~~~~~~~~~~
GHC extends the FFI with an additional calling convention ``prim``,
-e.g.:
-
-::
+e.g.: ::
foreign import prim "foo" foo :: ByteArray# -> (# Int#, Int# #)
@@ -108,9 +130,7 @@ The problem is that it is not possible in general to interrupt a foreign
call safely. However, GHC does provide a way to interrupt blocking
system calls which works for most system calls on both Unix and Windows.
When the ``InterruptibleFFI`` extension is enabled, a foreign call can
-be annotated with ``interruptible`` instead of ``safe`` or ``unsafe``:
-
-::
+be annotated with ``interruptible`` instead of ``safe`` or ``unsafe``: ::
foreign import ccall interruptible
"sleep" sleepBlock :: CUint -> IO CUint
@@ -145,9 +165,7 @@ The CAPI calling convention
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``CApiFFI`` extension allows a calling convention of ``capi`` to be
-used in foreign declarations, e.g.
-
-::
+used in foreign declarations, e.g. ::
foreign import capi "header.h f" f :: CInt -> IO CInt
@@ -157,30 +175,26 @@ ABI, we instead call ``f`` using the C API defined in the header
CPP ``#define`` rather than a proper function.
When using ``capi``, it is also possible to import values, rather than
-functions. For example,
-
-::
+functions. For example, ::
foreign import capi "pi.h value pi" c_pi :: CDouble
will work regardless of whether ``pi`` is defined as
-::
+.. code-block:: c
const double pi = 3.14;
or with
-::
+.. code-block:: c
#define pi 3.14
In order to tell GHC the C type that a Haskell type corresponds to when
it is used with the CAPI, a ``CTYPE`` pragma can be used on the type
definition. The header which defines the type can optionally also be
-specified. The syntax looks like:
-
-::
+specified. The syntax looks like: ::
data {-# CTYPE "unistd.h" "useconds_t" #-} T = ...
newtype {-# CTYPE "useconds_t" #-} T = ...
@@ -188,7 +202,7 @@ specified. The syntax looks like:
``hs_thread_done()``
~~~~~~~~~~~~~~~~~~~~
-::
+.. code-block:: c
void hs_thread_done(void);
@@ -231,9 +245,7 @@ C programs.
For a plain ``foreign export``, the file ``M_stub.h`` contains a C
prototype for the foreign exported function. For example, if we compile
-the following module:
-
-::
+the following module: ::
module Foo where
More information about the ghc-commits
mailing list