[pypy-commit] pypy ffi-backend: Port CFFI test and fix.

arigo noreply at buildbot.pypy.org
Sun Aug 5 10:54:22 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r56580:62a6638dc6c5
Date: 2012-08-05 10:54 +0200
http://bitbucket.org/pypy/pypy/changeset/62a6638dc6c5/

Log:	Port CFFI test and fix.

diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py
--- a/pypy/module/_cffi_backend/ctypearray.py
+++ b/pypy/module/_cffi_backend/ctypearray.py
@@ -69,7 +69,7 @@
         if i < 0:
             raise OperationError(space.w_IndexError,
                                  space.wrap("negative index not supported"))
-        if self.length != 0 and i >= w_cdata.get_array_length():
+        if i >= w_cdata.get_array_length():
             raise operationerrfmt(space.w_IndexError,
                 "index too large for cdata '%s' (expected %d < %d)",
                 self.name, i, w_cdata.get_array_length())
diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -149,10 +149,14 @@
 
 class W_CField(Wrappable):
     _immutable_ = True
+
+    BS_REGULAR     = -1
+    BS_EMPTY_ARRAY = -2
+
     def __init__(self, ctype, offset, bitshift, bitsize):
         self.ctype = ctype
         self.offset = offset
-        self.bitshift = bitshift
+        self.bitshift = bitshift # >= 0: bitshift; or BS_REGULAR/BS_EMPTY_ARRAY
         self.bitsize = bitsize
 
     def is_bitfield(self):
@@ -160,10 +164,15 @@
 
     def read(self, cdata):
         cdata = rffi.ptradd(cdata, self.offset)
-        if self.is_bitfield():
+        if self.bitshift == self.BS_REGULAR:
+            return self.ctype.convert_to_object(cdata)
+        elif self.bitshift == self.BS_EMPTY_ARRAY:
+            from pypy.module._cffi_backend import ctypearray
+            ctype = self.ctype
+            assert isinstance(ctype, ctypearray.W_CTypeArray)
+            return cdataobj.W_CData(ctype.space, cdata, ctype.ctptr)
+        else:
             return self.convert_bitfield_to_object(cdata)
-        else:
-            return self.ctype.convert_to_object(cdata)
 
     def write(self, cdata, w_ob):
         cdata = rffi.ptradd(cdata, self.offset)
diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -153,7 +153,10 @@
                 fbitsize == 8 * ftype.size and not
                 isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)):
             fbitsize = -1
-            bitshift = -1
+            if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0:
+                bitshift = ctypestruct.W_CField.BS_EMPTY_ARRAY
+            else:
+                bitshift = ctypestruct.W_CField.BS_REGULAR
             prev_bit_position = 0
         else:
             if (not (isinstance(ftype, ctypeprim.W_CTypePrimitiveSigned) or
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1828,15 +1828,16 @@
             assert repr(x).endswith("E+902>")
             assert float(x) == float("inf")
 
-def test_array_of_length_zero():
-    p = new_pointer_type(new_primitive_type("int"))
-    p0 = new_array_type(p, 0)
-    p3 = new_array_type(p, 3)
-    a1 = newp(p3, [61, 62, 63])
-    a2 = cast(p0, a1)
-    assert a2[0] == 61
-    assert a2[1] == 62
-    assert a2[2] == 63
-    a2[2] = 64
-    assert list(a1) == [61, 62, 64]
-    assert list(a2) == []
+def test_get_array_of_length_zero():
+    for length in [0, 5, 10]:
+        BLong = new_primitive_type("long")
+        BLongP = new_pointer_type(BLong)
+        BArray0 = new_array_type(BLongP, length)
+        BStruct = new_struct_type("foo")
+        BStructPtr = new_pointer_type(BStruct)
+        complete_struct_or_union(BStruct, [('a1', BArray0, -1)])
+        p = newp(BStructPtr, None)
+        if length == 0:
+            assert repr(p.a1).startswith("<cdata 'long *' 0x")
+        else:
+            assert repr(p.a1).startswith("<cdata 'long[%d]' 0x" % length)


More information about the pypy-commit mailing list