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