[pypy-svn] r73250 - in pypy/trunk/pypy: module/pyexpat module/pyexpat/test rpython/lltypesystem rpython/lltypesystem/test translator/c

afa at codespeak.net afa at codespeak.net
Thu Apr 1 16:34:02 CEST 2010


Author: afa
Date: Thu Apr  1 16:34:00 2010
New Revision: 73250

Modified:
   pypy/trunk/pypy/module/pyexpat/interp_pyexpat.py
   pypy/trunk/pypy/module/pyexpat/test/test_build.py
   pypy/trunk/pypy/rpython/lltypesystem/rffi.py
   pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py
   pypy/trunk/pypy/translator/c/database.py
Log:
with headers like:
    typedef struct _opaque HANDLE;

Implement a way to use HANDLE in the generated C code:
    HANDLE = rffi.COpaquePtr(typedef='HANDLE')

Use it in pyexpat.


Modified: pypy/trunk/pypy/module/pyexpat/interp_pyexpat.py
==============================================================================
--- pypy/trunk/pypy/module/pyexpat/interp_pyexpat.py	(original)
+++ pypy/trunk/pypy/module/pyexpat/interp_pyexpat.py	Thu Apr  1 16:34:00 2010
@@ -33,7 +33,7 @@
      ])
 
 XML_Content_Ptr = lltype.Ptr(lltype.ForwardReference())
-XML_Parser = rffi.VOIDP # an opaque pointer
+XML_Parser = rffi.COpaquePtr(typedef='XML_Parser')
 
 class CConfigure:
     _compilation_info_ = eci
@@ -475,7 +475,7 @@
         global_storage.get_nonmoving_id(
             CallbackData(space, parser),
             id=rffi.cast(lltype.Signed, parser.itself))
-        XML_SetUserData(parser.itself, parser.itself)
+        XML_SetUserData(parser.itself, rffi.cast(rffi.VOIDP, parser.itself))
 
         # copy handlers from self
         for i in range(NB_HANDLERS):
@@ -621,7 +621,7 @@
     global_storage.get_nonmoving_id(
         CallbackData(space, parser),
         id=rffi.cast(lltype.Signed, parser.itself))
-    XML_SetUserData(parser.itself, parser.itself)
+    XML_SetUserData(parser.itself, rffi.cast(rffi.VOIDP, parser.itself))
 
     return space.wrap(parser)
 ParserCreate.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root]

Modified: pypy/trunk/pypy/module/pyexpat/test/test_build.py
==============================================================================
--- pypy/trunk/pypy/module/pyexpat/test/test_build.py	(original)
+++ pypy/trunk/pypy/module/pyexpat/test/test_build.py	Thu Apr  1 16:34:00 2010
@@ -18,6 +18,8 @@
 
 def test_build():
     def entry_point(argv):
+        parser = interp_pyexpat.XML_ParserCreate("test")
+        interp_pyexpat.XML_ParserFree(parser)
         res = interp_pyexpat.XML_ErrorString(3)
         os.write(1, rffi.charp2str(res))
         return 0

Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/rffi.py	Thu Apr  1 16:34:00 2010
@@ -448,7 +448,7 @@
     return lltype.Ptr(lltype.FuncType(args, res))
 CCallback._annspecialcase_ = 'specialize:memo'
 
-def COpaque(name, hints=None, compilation_info=None):
+def COpaque(name=None, ptr_typedef=None, hints=None, compilation_info=None):
     if compilation_info is None:
         compilation_info = ExternalCompilationInfo()
     if hints is None:
@@ -456,7 +456,10 @@
     else:
         hints = hints.copy()
     hints['external'] = 'C'
-    hints['c_name'] = name
+    if name is not None:
+        hints['c_name'] = name
+    if ptr_typedef is not None:
+        hints['c_pointer_typedef'] = ptr_typedef
     def lazy_getsize(cache={}):
         from pypy.rpython.tool import rffi_platform
         try:
@@ -470,7 +473,8 @@
     return lltype.OpaqueType(name, hints)
 
 def COpaquePtr(*args, **kwds):
-    return lltype.Ptr(COpaque(*args, **kwds))
+    typedef = kwds.pop('typedef', None)
+    return lltype.Ptr(COpaque(ptr_typedef=typedef, *args, **kwds))
 
 def CExternVariable(TYPE, name, eci, _CConstantClass=CConstant,
                     sandboxsafe=False, _nowrapper=False,

Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py	Thu Apr  1 16:34:00 2010
@@ -280,6 +280,28 @@
         f1 = self.compile(f, [])
         assert f1() == 'a'
 
+    def test_opaque_typedef(self):
+        code = """
+        #include <stddef.h>
+        struct stuff;
+        typedef struct stuff *stuff_ptr;
+        static int get(stuff_ptr ptr) { return (ptr != NULL); }
+        """
+
+        eci = ExternalCompilationInfo(
+            post_include_bits = [code]
+        )
+
+        STUFFP = COpaquePtr(typedef='stuff_ptr', compilation_info=eci)
+        ll_get = llexternal('get', [STUFFP], lltype.Signed,
+                            compilation_info=eci)
+
+        def f():
+            return ll_get(lltype.nullptr(STUFFP.TO))
+
+        f1 = self.compile(f, [])
+        assert f1() == 0
+
     def return_char(self, signed):
         ctype_pref = ["un", ""][signed]
         rffi_type = [UCHAR, SIGNEDCHAR][signed]

Modified: pypy/trunk/pypy/translator/c/database.py
==============================================================================
--- pypy/trunk/pypy/translator/c/database.py	(original)
+++ pypy/trunk/pypy/translator/c/database.py	Thu Apr  1 16:34:00 2010
@@ -101,6 +101,9 @@
         if isinstance(T, Primitive) or T == GCREF:
             return PrimitiveType[T]
         elif isinstance(T, Ptr):
+            if (isinstance(T.TO, OpaqueType) and
+                T.TO.hints.get('c_pointer_typedef') is not None):
+                return '%s @' % T.TO.hints['c_pointer_typedef']
             try:
                 node = self.gettypedefnode(T.TO)
             except NoCorrespondingNode:



More information about the Pypy-commit mailing list