[pypy-commit] pypy rffi-parser: Expand the pseudo-header in api.py, handle forward refs and pointers

rlamy pypy.commits at gmail.com
Fri Dec 16 23:11:06 EST 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: rffi-parser
Changeset: r89106:cb24068cdac0
Date: 2016-12-17 04:10 +0000
http://bitbucket.org/pypy/pypy/changeset/cb24068cdac0/

Log:	Expand the pseudo-header in api.py, handle forward refs and pointers

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -602,8 +602,28 @@
                              % (cpyname, ))
 build_exported_objects()
 
-# update these for other platforms
-h = parse_source("typedef ssize_t Py_ssize_t;")
+h = parse_source("""
+typedef ssize_t Py_ssize_t;
+
+#define PyObject_HEAD  \
+    Py_ssize_t ob_refcnt;        \
+    Py_ssize_t ob_pypy_link;     \
+    struct _typeobject *ob_type;
+
+#define PyObject_VAR_HEAD		\
+	PyObject_HEAD			\
+	Py_ssize_t ob_size; /* Number of items in variable part */
+
+typedef struct _object {
+    PyObject_HEAD
+} PyObject;
+
+typedef struct {
+	PyObject_VAR_HEAD
+} PyVarObject;
+
+typedef struct _typeobject PyTypeObject;
+""")
 
 Py_ssize_t = h.definitions['Py_ssize_t']
 Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t)
@@ -613,16 +633,15 @@
 # Note: as a special case, "PyObject" is the pointer type in RPython,
 # corresponding to "PyObject *" in C.  We do that only for PyObject.
 # For example, "PyTypeObject" is the struct type even in RPython.
-PyTypeObject = lltype.ForwardReference()
+PyTypeObject = h.definitions['PyTypeObject'].OF
 PyTypeObjectPtr = lltype.Ptr(PyTypeObject)
-PyObjectStruct = lltype.ForwardReference()
+PyObjectStruct = h.definitions['PyObject'].OF
 PyObject = lltype.Ptr(PyObjectStruct)
 PyObjectFields = (("ob_refcnt", lltype.Signed),
                   ("ob_pypy_link", lltype.Signed),
                   ("ob_type", PyTypeObjectPtr))
 PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), )
-cpython_struct('PyObject', PyObjectFields, PyObjectStruct)
-PyVarObjectStruct = cpython_struct("PyVarObject", PyVarObjectFields)
+PyVarObjectStruct = h.definitions['PyVarObject'].OF
 PyVarObject = lltype.Ptr(PyVarObjectStruct)
 
 Py_buffer = cpython_struct(
diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py
--- a/pypy/module/cpyext/cparser.py
+++ b/pypy/module/cpyext/cparser.py
@@ -1,3 +1,4 @@
+from collections import OrderedDict
 from cffi import api, model
 from cffi.commontypes import COMMON_TYPES, resolve_common_type
 import pycparser
@@ -30,7 +31,7 @@
     # should not contain any string literal!
     csource = _r_comment.sub(' ', csource)
     # Remove the "#define FOO x" lines
-    macros = {}
+    macros = OrderedDict()
     for match in _r_define.finditer(csource):
         macroname, macrovalue = match.groups()
         macrovalue = macrovalue.replace('\\\n', '').strip()
@@ -695,12 +696,19 @@
             from pypy.module.cpyext.api import cpython_struct
             if obj in self.structs:
                 return self.structs[obj]
-            fields = zip(
-                obj.fldnames,
-                [self.convert_type(field) for field in obj.fldtypes])
-            result = DelayedStruct(obj.name, fields)
+            if obj.fldtypes is None:
+                result = lltype.ForwardReference()
+            else:
+                fields = zip(
+                    obj.fldnames,
+                    [self.convert_type(field) for field in obj.fldtypes])
+                result = DelayedStruct(obj.name, fields)
             self.structs[obj] = result
             return result
+        elif isinstance(obj, model.PointerType):
+            return lltype.Ptr(self.convert_type(obj.totype))
+        else:
+            raise NotImplementedError
 
 
 def parse_source(source):


More information about the pypy-commit mailing list