Author: Armin Rigo <[email protected]>
Branch: static-callback
Changeset: r2388:e8bfa0e0f9c6
Date: 2015-11-13 16:32 +0100
http://bitbucket.org/cffi/cffi/changeset/e8bfa0e0f9c6/

Log:    in-progress

diff --git a/c/call_python.c b/c/call_python.c
--- a/c/call_python.c
+++ b/c/call_python.c
@@ -1,6 +1,51 @@
-
 
 static void _cffi_call_python(struct _cffi_callpy_s *callpy, char *args)
 {
+    /* Invoked by the helpers generated from CFFI_CALL_PYTHON in the cdef.
+
+       'callpy' is a static structure that describes which of the
+       CFFI_CALL_PYTHON is called.  It has got fields 'name' and
+       'type_index' describing the function, and more reserved fields
+       that are initially zero.  These reserved fields are set up by
+       ffi.call_python(), which invokes init_call_python() below.
+
+       'args' is a pointer to an array of 8-byte entries.  Each entry
+       contains an argument.  If an argument is less than 8 bytes, only
+       the part at the beginning of the entry is initialized.  If an
+       argument is 'long double' or a struct/union, then it is passed
+       by reference.
+
+       'args' is also used as the place to write the result to.  In all
+       cases, 'args' is at least 8 bytes in size.
+    */
+    save_errno();
+    {
+#ifdef WITH_THREAD
+    PyGILState_STATE state = PyGILState_Ensure();
+#endif
+    const struct _cffi_type_context_s *ctx;
+    ctx = (const struct _cffi_type_context_s *)callpy->reserved1;
+
+    if (ctx == NULL) {
+        /* uninitialized! */
+        PyObject *f = PySys_GetObject("stderr");
+        if (f != NULL) {
+            PyFile_WriteString("CFFI_CALL_PYTHON: function ", f);
+            PyFile_WriteString(callpy->name, f);
+            PyFile_WriteString("() called, but no code was attached "
+                               "to it yet with ffi.call_python('", f);
+            PyFile_WriteString(callpy->name, f);
+            PyFile_WriteString("').  Returning 0.\n", f);
+        }
+        memset(args, 0, callpy->size_of_result);
+        return;
+    }
+
     abort();
+
+#ifdef WITH_THREAD
+    PyGILState_Release(state);
+#endif
+    }
+    restore_errno();
 }
diff --git a/cffi/parse_c_type.h b/cffi/parse_c_type.h
--- a/cffi/parse_c_type.h
+++ b/cffi/parse_c_type.h
@@ -164,8 +164,8 @@
 struct _cffi_callpy_s {
     const char *name;
     int type_index;
-    int reserved1;
-    void *reserved2, *reserved3;
+    int size_of_result;
+    void *reserved1, *reserved2;
 };
 
 #ifdef _CFFI_INTERNAL
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -1121,8 +1121,14 @@
     def _generate_cpy_call_python_decl(self, tp, name):
         prnt = self._prnt
         type_index = self._typesdict[tp.as_raw_function()]
-        prnt('static struct _cffi_callpy_s _cffi_callpy__%s = { "%s", %d };' % 
(
-            name, name, type_index))
+        if isinstance(tp.result, model.VoidType):
+            size_of_result = '0'
+        else:
+            context = 'result of %s' % name
+            size_of_result = '(int)sizeof(%s)' % (
+                tp.result.get_c_name('', context),)
+        prnt('static struct _cffi_callpy_s _cffi_callpy__%s =' % name)
+        prnt('  { "%s", %d, %s };' % (name, type_index, size_of_result))
         prnt()
         #
         arguments = []
@@ -1146,8 +1152,7 @@
             size_of_a = 'sizeof(%s) > %d ? sizeof(%s) : %d' % (
                 tp.result.get_c_name(''), size_of_a,
                 tp.result.get_c_name(''), size_of_a)
-        context = 'result of %s' % name
-        prnt('static %s' % tp.result.get_c_name(name_and_arguments, context))
+        prnt('static %s' % tp.result.get_c_name(name_and_arguments))
         prnt('{')
         prnt('  char a[%s];' % size_of_a)
         prnt('  char *p = a;')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to