[pypy-svn] r51904 - in pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi: . test

pedronis at codespeak.net pedronis at codespeak.net
Wed Feb 27 16:37:15 CET 2008


Author: pedronis
Date: Wed Feb 27 16:37:13 2008
New Revision: 51904

Modified:
   pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/interp_rawffi.py
   pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/test/test__rawffi.py
Log:
started refactoring, now CDLL.ptr takes argtypes of the form:
letter or (W_Structure, 1)

changes test that pass accordingly.

ctypes is broken by this obviously!



Modified: pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/interp_rawffi.py	Wed Feb 27 16:37:13 2008
@@ -51,9 +51,10 @@
 }
 TYPEMAP_PTR_LETTERS = "POszZ"
 
-UNPACKED_TYPECODES = dict([(code, (code,
-                                   intmask(field_desc.c_size),
-                                   intmask(field_desc.c_alignment)))
+def size_alignment(ffi_type):
+    return intmask(ffi_type.c_size), intmask(ffi_type.c_alignment)
+
+UNPACKED_TYPECODES = dict([(code, (code,) + size_alignment(field_desc))
                            for code, field_desc in TYPEMAP.items()])
 
 LL_TYPEMAP = {
@@ -100,6 +101,26 @@
     except KeyError:
         raise OperationError(space.w_ValueError, space.wrap(
             "Unknown type letter %s" % (key,)))
+    
+def unpack_shape(space, w_shape, allow_void=False, shape=False):
+    resshape = None
+    if space.is_true(space.isinstance(w_shape, space.w_str)):
+        letter = space.str_w(w_shape)
+        if allow_void and letter == 'v':
+            return 'v', ffi_type_void, None
+        ffi_type = _get_type_(space, letter)
+        if shape:
+            from pypy.module._rawffi.array import get_array_cache
+            cache = get_array_cache(space)
+            resshape = cache.get_array_type(letter2tp(space, letter))
+    else:
+        letter = 'V'
+        w_shapetype, w_length = space.unpacktuple(w_shape, expected_length=2)
+        from pypy.module._rawffi.structure import W_Structure
+        resshape = space.interp_w(W_Structure, w_shapetype)
+        ffi_type = resshape.get_ffi_type()
+    return letter, ffi_type, resshape
+
 
 class W_CDLL(Wrappable):
     def __init__(self, space, name):
@@ -128,23 +149,13 @@
         if space.is_w(w_restype, space.w_None):
             resshape = None
             ffi_restype = ffi_type_void
-        elif space.is_true(space.isinstance(w_restype, space.w_str)):
-            tp_letter = space.str_w(w_restype)
-            if tp_letter == 'v':
-                resshape = None
-                ffi_restype = ffi_type_void
-            else:
-                from pypy.module._rawffi.array import get_array_cache
-                cache = get_array_cache(space)
-                resshape = cache.get_array_type(letter2tp(space, tp_letter))
-                ffi_restype = self.get_type(tp_letter)
         else:
-            from pypy.module._rawffi.structure import W_Structure
-            resshape = space.interp_w(W_Structure, w_restype)
-            ffi_restype = resshape.get_ffi_type()
-                
+            tp_letter, ffi_restype, resshape = unpack_shape(space, w_restype,
+                                                            allow_void=True,
+                                                            shape=True)                
         w = space.wrap
-        w_argtypes = space.newtuple(space.unpackiterable(w_argtypes))
+        argtypes_w = space.unpackiterable(w_argtypes)
+        w_argtypes = space.newtuple(argtypes_w)
         w_key = space.newtuple([w(name), w_argtypes, w(resshape)])
         try:
             return space.getitem(self.w_cache, w_key)
@@ -152,15 +163,17 @@
             if e.match(space, space.w_KeyError):
                 pass
             else:
-                raise
-        argtypes_w = space.unpackiterable(w_argtypes)
-        argtypes = [unpack_typecode(space, w_arg) for w_arg in argtypes_w]
-        ffi_argtypes = [self.get_arg_type(letter, argsize, argalignment)
-                                               for letter, argsize, argalignment
-                                                    in argtypes]
+                rais
+        argletters = []
+        ffi_argtypes = []
+        for w_arg in argtypes_w:
+            argletter, ffi_argtype, _ = unpack_shape(space, w_arg)
+            argletters.append(argletter)
+            ffi_argtypes.append(ffi_argtype)
+
         try:
             ptr = self.cdll.getrawpointer(name, ffi_argtypes, ffi_restype)
-            w_funcptr = W_FuncPtr(space, ptr, argtypes, resshape)
+            w_funcptr = W_FuncPtr(space, ptr, argletters, resshape)
             space.setitem(self.w_cache, w_key, w_funcptr)
             return w_funcptr
         except KeyError:
@@ -323,31 +336,32 @@
 wrap_value._annspecialcase_ = 'specialize:arg(1)'
 
 class W_FuncPtr(Wrappable):
-    def __init__(self, space, ptr, argtypes, resshape):
+    def __init__(self, space, ptr, argletters, resshape):
         self.ptr = ptr
+        self.argletters = argletters
         self.resshape = resshape
-        self.argtypes = argtypes
 
     def call(self, space, args_w):
         from pypy.module._rawffi.array import W_ArrayInstance
         from pypy.module._rawffi.structure import W_StructureInstance
         argnum = len(args_w)
-        if argnum != len(self.argtypes):
+        if argnum != len(self.argletters):
             msg = "Wrong number of argument: expected %d, got %d" % (
-                len(self.argtypes), argnum)
+                len(self.argletters), argnum)
             raise OperationError(space.w_TypeError, space.wrap(msg))
         args_ll = []
         for i in range(argnum):
-            argtype_letter, argtype_size, argtype_alignment = self.argtypes[i]
+            argletter = self.argletters[i]
             w_arg = args_w[i]
-            if argtype_letter == 'V': # by value object
+            if argletter == 'V': # by value object
                 arg = space.interp_w(W_StructureInstance, w_arg)
-                if (arg.shape.size != argtype_size or
-                    arg.shape.alignment != argtype_alignment):
+                xsize, xalignment = size_alignment(self.ptr.argtypes[i])
+                if (arg.shape.size != xsize or
+                    arg.shape.alignment != xalignment):
                     msg = ("Argument %d should be a structure of size %d and "
                            "alignment %d, "
                            "got instead size %d and alignment %d" %
-                           (i+1, argtype_size, argtype_alignment,
+                           (i+1, xsize, xalignment,
                             arg.shape.size, arg.shape.alignment))
                     raise OperationError(space.w_TypeError, space.wrap(msg))
             else:
@@ -357,11 +371,11 @@
                            "got length %d" % (i+1, arg.length))
                     raise OperationError(space.w_TypeError, space.wrap(msg))
                 letter = arg.shape.itemtp[0]
-                if letter != argtype_letter:
-                    if not (argtype_letter in TYPEMAP_PTR_LETTERS and
+                if letter != argletter:
+                    if not (argletter in TYPEMAP_PTR_LETTERS and
                             letter in TYPEMAP_PTR_LETTERS):
                         msg = "Argument %d should be typecode %s, got %s" % (
-                            i+1, argtype_letter, letter)
+                            i+1, argletter, letter)
                         raise OperationError(space.w_TypeError, space.wrap(msg))
             args_ll.append(arg.ll_buffer)
             # XXX we could avoid the intermediate list args_ll

Modified: pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/branch/rawffi-shape-cleanup/pypy/module/_rawffi/test/test__rawffi.py	Wed Feb 27 16:37:13 2008
@@ -644,7 +644,7 @@
         X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')])
         x_y = X_Y()
         lib = _rawffi.CDLL(self.lib_name)
-        sum_x_y = lib.ptr('sum_x_y', [X_Y.gettypecode()], 'l')
+        sum_x_y = lib.ptr('sum_x_y', [(X_Y, 1)], 'l')
         x_y.x = 200
         x_y.y = 220
         res = sum_x_y(x_y)
@@ -657,7 +657,7 @@
         S2H = _rawffi.Structure([('x', 'h'), ('y', 'h')])
         s2h = S2H()
         lib = _rawffi.CDLL(self.lib_name)
-        give = lib.ptr('give', ['h', 'h'], S2H)
+        give = lib.ptr('give', ['h', 'h'], (S2H, 1))
         a1 = _rawffi.Array('h')(1)
         a2 = _rawffi.Array('h')(1)
         a1[0] = 13
@@ -673,7 +673,7 @@
 
         s2h.x = 7
         s2h.y = 11
-        perturb = lib.ptr('perturb', [S2H.gettypecode()], S2H)
+        perturb = lib.ptr('perturb', [(S2H, 1)], (S2H, 1))
         res = perturb(s2h)
         assert isinstance(res, _rawffi.StructureInstance)
         assert res.shape is S2H



More information about the Pypy-commit mailing list