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

fijal at codespeak.net fijal at codespeak.net
Wed Jul 25 11:40:06 CEST 2007


Author: fijal
Date: Wed Jul 25 11:40:06 2007
New Revision: 45316

Modified:
   pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/rffi.py
   pypy/dist/pypy/rpython/lltypesystem/rfficache.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py
   pypy/dist/pypy/translator/c/database.py
Log:
Implement opaque_type on top of ll2ctypes, so we are able to create
pointers to opaque structures and test it on top of cpython.

Few minor code changes (like more meta-programming)


Modified: pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	Wed Jul 25 11:40:06 2007
@@ -137,6 +137,10 @@
             cls = build_ctypes_struct(T)
         elif isinstance(T, lltype.Array):
             cls = build_ctypes_array(T)
+        elif isinstance(T, lltype.OpaqueType):
+            if T.hints.get('external', None) != 'C':
+                raise TypeError("%s is not external" % T)
+            cls = ctypes.c_char * T.hints['size']
         else:
             _setup_ctypes_cache()
             if T in _ctypes_cache:
@@ -311,6 +315,9 @@
                 convert_struct(container)
             elif isinstance(T.TO, lltype.Array):
                 convert_array(container)
+            elif isinstance(T.TO, lltype.OpaqueType):
+                container._storage = ctypes.create_string_buffer(
+                    T.TO.hints['size'])
             else:
                 raise NotImplementedError(T)
         storage = container._storage
@@ -352,6 +359,8 @@
             funcptr = lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'))
             make_callable_via_ctypes(funcptr, cfunc=cobj)
             return funcptr
+        elif isinstance(T.TO, lltype.OpaqueType):
+            container = lltype._opaque(T.TO)
         else:
             raise NotImplementedError(T)
         llobj = lltype._ptr(T, container, solid=True)

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 11:40:06 2007
@@ -1655,6 +1655,8 @@
         o = _struct(T, n, initialization=initialization)
     elif isinstance(T, Array):
         o = _array(T, n, initialization=initialization)
+    elif isinstance(T, OpaqueType):
+        o = _opaque(T, n, initialization=initialization)
     else:
         raise TypeError, "malloc for Structs and Arrays only"
     if T._gckind != 'gc' and not immortal and flavor.startswith('gc'):

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 11:40:06 2007
@@ -93,11 +93,14 @@
     c_fields = [('c_' + key, value) for key, value in fields]
     return lltype.Ptr(lltype.Struct(name, *c_fields, **kwds))
 
-def COpaque(name, hints=None):
+def COpaque(name, hints=None, **kwds):
     if hints is None:
         hints = {}
+    else:
+        hints = hints.copy()
     hints['external'] = 'C'
     hints['c_name'] = name
+    hints['size'] = platform.sizeof(name, **kwds)
     return lltype.Ptr(lltype.OpaqueType(name, hints))
 
 c_errno = CConstant('errno', lltype.Signed)

Modified: pypy/dist/pypy/rpython/lltypesystem/rfficache.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rfficache.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rfficache.py	Wed Jul 25 11:40:06 2007
@@ -10,7 +10,8 @@
 from pypy.rlib import rarithmetic
 from pypy.rpython.lltypesystem import lltype
 
-def ask_gcc(question, includes={}, add_source="", compiler_exe=None):
+def ask_gcc(question, includes={}, add_source="", include_dirs=[],
+            compiler_exe=None):
     if isinstance(includes, list):
         includes = dict.fromkeys(includes)
     from py.compat.subprocess import PIPE, Popen
@@ -33,14 +34,15 @@
     c_file = udir.join("gcctest.c")
     c_file.write(c_source)
 
-    c_exec = build_executable([str(c_file)], compiler_exe=compiler_exe)
+    c_exec = build_executable([str(c_file)], include_dirs=include_dirs,
+                              compiler_exe=compiler_exe)
     pipe = Popen(c_exec, stdout=PIPE)
     pipe.wait()
     return pipe.stdout.read()
 
 def sizeof_c_type(c_typename, **kwds):
     question = 'printf("%%d", sizeof(%s));' % (c_typename,);
-    return int(ask_gcc(question, **kwds)) * 8
+    return int(ask_gcc(question, **kwds))
 
 def c_ifdefined(c_def, **kwds):
     question = py.code.Source("""
@@ -54,6 +56,18 @@
     question = 'printf("%%d", %s);' % (c_def,)
     return int(ask_gcc(question, **kwds))
 
+def create_cache_access_method(acc_func, meth_name):
+    def method(self, name, **kwds):
+        try:
+            return self.cache[name]
+        except KeyError:
+            res = acc_func(name, **kwds)
+            self.cache[name] = res
+            self._store_cache()
+            return res
+    method.func_name = meth_name
+    return method
+
 class RffiCache(object):
     """ Class holding all of the c-level caches, eventually loaded from
     the file, like #ifdefs, typesizes, int-level #defines
@@ -85,7 +99,7 @@
         try:
             return self.types[name]
         except KeyError:
-            bits = sizeof_c_type(c_name, **kwds)
+            bits = sizeof_c_type(c_name, **kwds) * 8
             inttype = rarithmetic.build_int('r_' + name, signed, bits)
             self.cache[c_name] = bits
             self.type_names[name] = (c_name, signed)
@@ -95,23 +109,9 @@
             self._store_cache()
             return tp
 
-    def defined(self, name, **kwds):
-        try:
-            return self.cache[name]
-        except KeyError:
-            res = c_ifdefined(name, **kwds)
-            self.cache[name] = res
-            self._store_cache()
-            return res
-
-    def intdefined(self, name, **kwds):
-        try:
-            return self.cache[name]
-        except KeyError:
-            res = c_defined_int(name, **kwds)
-            self.cache[name] = res
-            self._store_cache()
-            return res
+    defined = create_cache_access_method(c_ifdefined, 'defined')
+    intdefined = create_cache_access_method(c_defined_int, 'intdefined')
+    sizeof = create_cache_access_method(sizeof_c_type, 'sizeof')
 
     # optimal way of caching it, would be to store file on __del__,
     # but since we cannot rely on __del__ having all modules, let's

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	Wed Jul 25 11:40:06 2007
@@ -226,6 +226,17 @@
         assert res2 == res2b
         assert res3 == res3b
 
+    def test_opaque_obj(self):
+        includes = ['sys/time.h', 'time.h']
+        TIMEVALP = rffi.COpaque('struct timeval', includes=includes)
+        TIMEZONEP = rffi.COpaque('struct timezone', includes=includes)
+        gettimeofday = rffi.llexternal('gettimeofday', [TIMEVALP, TIMEZONEP],
+                                       rffi.INT, includes=includes)
+        ll_timevalp = lltype.malloc(TIMEVALP.TO, flavor='raw')
+        ll_timezonep = lltype.malloc(TIMEZONEP.TO, flavor='raw')
+        res = gettimeofday(ll_timevalp, ll_timezonep)
+        assert res != -1
+
     def test_simple_cast(self):
         assert rffi.cast(rffi.SIGNEDCHAR, 0x123456) == 0x56
         assert rffi.cast(rffi.SIGNEDCHAR, 0x123481) == -127

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 11:40:06 2007
@@ -227,7 +227,8 @@
     h_file = udir.join("opaque.h")
     h_file.write(h_source)
 
-    STUFFP = COpaque('stuff')
+    STUFFP = COpaque('struct stuff', includes=['opaque.h'],
+                     include_dirs=[str(udir)])
 
     ll_get = llexternal('get', [STUFFP], lltype.Char, includes=['opaque.h'],
                         include_dirs=[str(udir)])

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py	Wed Jul 25 11:40:06 2007
@@ -5,7 +5,7 @@
 
 def test_sizeof_c_type():
     sizeofchar = sizeof_c_type('char')
-    assert sizeofchar == 8
+    assert sizeofchar == 1
 
 def test_c_ifdefined():
     assert c_ifdefined('X', add_source='#define X')
@@ -22,10 +22,12 @@
     assert cache.defined('STUFF')
     assert cache.intdefined('STUFFI', add_source='#define STUFFI 3') == 3
     assert cache.intdefined('STUFFI') == 3
+    assert cache.sizeof('short') == 2
     cache = RffiCache(udir.join('cache.py'))
     assert cache.intdefined('STUFFI') == 3
     assert cache.defined('STUFF')
     assert cache.inttype('uchar', 'unsigned char', False, compiler_exe='xxx')._type.BITS == 8
+    assert cache.sizeof('short', compiler_exe='xxx') == 2
 
 def test_types_present():
     for name in rffi.TYPES:

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 11:40:06 2007
@@ -130,7 +130,7 @@
                     who_asks.dependencies[node] = True
                 return 'struct %s @' % node.name
             elif T.hints.get('external', None) == 'C':
-                return 'struct %s @' % T.hints['c_name']
+                return '%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