[pypy-commit] pypy default: Document more jit_libffi and add a helper.

arigo noreply at buildbot.pypy.org
Fri Aug 10 11:04:22 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r56684:f9f3683221fc
Date: 2012-08-10 11:04 +0200
http://bitbucket.org/pypy/pypy/changeset/f9f3683221fc/

Log:	Document more jit_libffi and add a helper.

diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -409,8 +409,7 @@
         self.fb_extra_fields(rawmem)
 
         # call libffi's ffi_prep_cif() function
-        res = clibffi.c_ffi_prep_cif(rawmem.cif, rawmem.abi,
-                                     rawmem.nargs, rawmem.rtype, rawmem.atypes)
-        if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
+        res = jit_libffi.jit_ffi_prep_cif(rawmem)
+        if res != clibffi.FFI_OK:
             raise OperationError(space.w_SystemError,
                 space.wrap("libffi failed to build this function type"))
diff --git a/pypy/rlib/jit_libffi.py b/pypy/rlib/jit_libffi.py
--- a/pypy/rlib/jit_libffi.py
+++ b/pypy/rlib/jit_libffi.py
@@ -11,16 +11,24 @@
 FFI_TYPE_STRUCT = clibffi.FFI_TYPE_STRUCT
 SIZE_OF_FFI_ARG = rffi.sizeof(clibffi.ffi_arg)
 
-# "cif_description" is a block of raw memory describing how to do the call.
-# It starts with a block of memory of type FFI_CIF, which is used by libffi
-# itself.  Following it, we find jit_libffi-specific information:
+# Usage: for each C function, make one CIF_DESCRIPTION block of raw
+# memory.  Initialize it by filling all its fields apart from 'cif'.
+# The 'atypes' points to an array of ffi_type pointers; a reasonable
+# place to locate this array's memory is in the same block of raw
+# memory, by allocating more than sizeof(CIF_DESCRIPTION).
+#
+# The four fields 'abi', 'nargs', 'rtype', 'atypes' are the same as
+# the arguments to ffi_prep_cif().
+#
+# Following this, we find jit_libffi-specific information:
 #
 #  - 'exchange_size': an integer that tells how big a buffer we must
-#    allocate for the call; this buffer should have enough room at the
-#    beginning for an array of pointers to the actual argument values,
-#    which is initialized internally by jit_ffi_call().
+#    allocate to do the call; this buffer should have enough room at the
+#    beginning for an array of NARGS pointers which is initialized
+#    internally by jit_ffi_call().
 #
 #  - 'exchange_result': the offset in that buffer for the result of the call.
+#    (this and the other offsets must be at least NARGS * sizeof(void*).)
 #
 #  - 'exchange_result_libffi': the actual offset passed to ffi_call().
 #    Differs on big-endian machines if the result is an integer type smaller
@@ -45,6 +53,18 @@
 CIF_DESCRIPTION_P = lltype.Ptr(CIF_DESCRIPTION)
 
 
+def jit_ffi_prep_cif(cif_description):
+    """Minimal wrapper around ffi_prep_cif().  Call this after
+    cif_description is initialized, in order to fill the last field: 'cif'.
+    """
+    res = clibffi.c_ffi_prep_cif(cif_description.cif,
+                                 cif_description.abi,
+                                 cif_description.nargs,
+                                 cif_description.rtype,
+                                 cif_description.atypes)
+    return rffi.cast(lltype.Signed, res)
+
+
 @jit.oopspec("libffi_call(cif_description, func_addr, exchange_buffer)")
 def jit_ffi_call(cif_description, func_addr, exchange_buffer):
     """Wrapper around ffi_call().  Must receive a CIF_DESCRIPTION_P that


More information about the pypy-commit mailing list