[pypy-svn] r45315 - in pypy/dist/pypy: rpython/lltypesystem rpython/lltypesystem/test translator/c

fijal at codespeak.net fijal at codespeak.net
Wed Jul 25 10:31:09 CEST 2007


Author: fijal
Date: Wed Jul 25 10:31:08 2007
New Revision: 45315

Modified:
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/rffi.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
   pypy/dist/pypy/translator/c/database.py
Log:
Support for OpaqueType which is declared itself in C, quite useful
when accessing opaquenodes from rffi.


Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Wed Jul 25 10:31:08 2007
@@ -451,9 +451,10 @@
 class OpaqueType(ContainerType):
     _gckind = 'raw'
     
-    def __init__(self, tag):
+    def __init__(self, tag, hints={}):
         self.tag = tag
         self.__name__ = tag
+        self.hints = frozendict(hints)
 
     def __str__(self):
         return "%s (opaque)" % self.tag

Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rffi.py	Wed Jul 25 10:31:08 2007
@@ -93,6 +93,13 @@
     c_fields = [('c_' + key, value) for key, value in fields]
     return lltype.Ptr(lltype.Struct(name, *c_fields, **kwds))
 
+def COpaque(name, hints=None):
+    if hints is None:
+        hints = {}
+    hints['external'] = 'C'
+    hints['c_name'] = name
+    return lltype.Ptr(lltype.OpaqueType(name, hints))
+
 c_errno = CConstant('errno', lltype.Signed)
 
 # char, represented as a Python character
@@ -157,3 +164,4 @@
     lltype.free(ref, flavor='raw')
 
 cast = ll2ctypes.force_cast      # a forced, no-checking cast
+    

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py	Wed Jul 25 10:31:08 2007
@@ -210,3 +210,33 @@
     f1 = compile(f, [int])
     res = f1(-1)
     assert res == r_size_t(-1)
+
+def test_opaque_type():
+    h_source = py.code.Source("""
+    struct stuff {
+       char data[38];
+    };
+
+    char get(struct stuff* x)
+    {
+       x->data[13] = 'a';
+       return x->data[13];
+    }
+    """)
+    # if it doesn't segfault, than we probably malloced it :-)
+    h_file = udir.join("opaque.h")
+    h_file.write(h_source)
+
+    STUFFP = COpaque('stuff')
+
+    ll_get = llexternal('get', [STUFFP], lltype.Char, includes=['opaque.h'],
+                        include_dirs=[str(udir)])
+
+    def f():
+        ll_stuff = lltype.malloc(STUFFP.TO, flavor='raw')
+        result = ll_get(ll_stuff)
+        lltype.free(ll_stuff, flavor='raw')
+        return result
+
+    f1 = compile(f, [])
+    assert f1() == 'a'

Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/dist/pypy/translator/c/database.py	Wed Jul 25 10:31:08 2007
@@ -129,6 +129,8 @@
                 if who_asks is not None:
                     who_asks.dependencies[node] = True
                 return 'struct %s @' % node.name
+            elif T.hints.get('external', None) == 'C':
+                return 'struct %s @' % T.hints['c_name']
             else:
                 #raise Exception("don't know about opaque type %r" % (T,))
                 return 'struct %s @' % (



More information about the Pypy-commit mailing list