[pypy-svn] r50458 - in pypy/branch/applevel-ctypes2/pypy/module/_ffi: . test

fijal at codespeak.net fijal at codespeak.net
Wed Jan 9 15:54:08 CET 2008


Author: fijal
Date: Wed Jan  9 15:54:08 2008
New Revision: 50458

Modified:
   pypy/branch/applevel-ctypes2/pypy/module/_ffi/array.py
   pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py
   pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py
Log:
* Support for array.fromaddress
* Few fixes.


Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/array.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/array.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/array.py	Wed Jan  9 15:54:08 2008
@@ -43,6 +43,10 @@
                              w_item, None)
             return space.wrap(result)
 
+    def fromaddress(self, space, address, length):
+        return space.wrap(W_ArrayInstance(space, self, length, address))
+    fromaddress.unwrap_spec = ['self', ObjSpace, int, int]
+
 def descr_new_array(space, w_type, of):
     _get_type(space, of)
     return space.wrap(W_Array(space, of))
@@ -52,20 +56,25 @@
     __new__  = interp2app(descr_new_array, unwrap_spec=[ObjSpace, W_Root, str]),
     __call__ = interp2app(W_Array.descr_call,
                           unwrap_spec=['self', ObjSpace, W_Root]),
+    fromaddress = interp2app(W_Array.fromaddress),
     of = interp_attrproperty('of', W_Array),
 )
 W_Array.typedef.acceptable_as_base_class = False
 
 
 class W_ArrayInstance(Wrappable):
-    def __init__(self, space, shape, length):
+    def __init__(self, space, shape, length, address=0):
         self.ll_array = lltype.nullptr(rffi.VOIDP.TO)
         self.alloced = False
-        self.shape = shape
         self.length = length
-        size = shape.itemsize * length
-        self.ll_array = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
-                                      zero=True)
+        self.shape = shape
+        if address > 0:
+            self.ll_array = rffi.cast(rffi.VOIDP, address)
+        else:
+            size = shape.itemsize * length
+            self.ll_array = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
+                                          zero=True)
+
 
     # XXX don't allow negative indexes, nor slices
 

Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py	Wed Jan  9 15:54:08 2008
@@ -68,16 +68,14 @@
     def descr_call(self, space, __args__):
         args_w, kwargs_w = __args__.unpack()
         if args_w:
-            if len(args_w) > 1:
-                raise OperationError(
-                        space.w_TypeError,
-                        space.wrap("Can give at most one non-keyword argument"))
-            if kwargs_w:
-                raise OperationError(
-                        space.w_TypeError,
-                        space.wrap("Keyword arguments not allowed when passing address argument"))
-            return space.wrap(W_StructureInstance(space, self, args_w[0], None))
-        return space.wrap(W_StructureInstance(space, self, None, kwargs_w))
+            raise OperationError(
+                space.w_TypeError,
+                space.wrap("Structure accepts only keyword arguments as field initializers"))
+        return space.wrap(W_StructureInstance(space, self, 0, kwargs_w))
+
+    def fromaddress(self, space, address):
+        return space.wrap(W_StructureInstance(space, self, address, None))
+    fromaddress.unwrap_spec = ['self', ObjSpace, int]
 
 def descr_new_structure(space, w_type, w_fields):
     return space.wrap(W_Structure(space, w_fields))
@@ -87,6 +85,7 @@
     __new__     = interp2app(descr_new_structure),
     __call__ = interp2app(W_Structure.descr_call,
                           unwrap_spec=['self', ObjSpace, Arguments]),
+    fromaddress = interp2app(W_Structure.fromaddress)
 )
 W_Structure.typedef.acceptable_as_base_class = False
 
@@ -109,11 +108,11 @@
     return OperationError(w_exception, space.wrap(reason))
 
 class W_StructureInstance(Wrappable):
-    def __init__(self, space, shape, w_address, fieldinits_w):
+    def __init__(self, space, shape, address, fieldinits_w):
         self.free_afterwards = False
         self.shape = shape
-        if w_address is not None:
-            self.ll_buffer = rffi.cast(rffi.VOIDP, space.int_w(w_address))
+        if address != 0:
+            self.ll_buffer = rffi.cast(rffi.VOIDP, address)
         else:
             self.ll_buffer = lltype.malloc(rffi.VOIDP.TO, shape.size, flavor='raw',
                                            zero=True)

Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py	Wed Jan  9 15:54:08 2008
@@ -97,6 +97,13 @@
            return x;
         }
 
+        int* allocate_array()
+        {
+            int *res = (int*)malloc(sizeof(int));
+            res[0] = 3;
+            return res;
+        }
+
         '''))
         return compile_c_module([c_file], 'x', ExternalCompilationInfo())
     prepare_c_example = staticmethod(prepare_c_example)
@@ -211,10 +218,10 @@
                              ("tm_isdst", 'i')])
         libc = _ffi.CDLL('libc.so.6')
         gmtime = libc.ptr('gmtime', ['P'], 'P')
-        t = Tm(gmtime(x))
+        t = Tm.fromaddress(gmtime(x))
         assert t.tm_year == 70
         assert t.tm_sec == 1
-        assert t.tm_min == 2        
+        assert t.tm_min == 2      
         x.free()
 
     def test_nested_structures(self):
@@ -224,13 +231,13 @@
         X = _ffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')])
         next = X(next=None, x3='x')
         x = X(next=next, x1=1, x2=2, x3='x')
-        assert X(x.next).x3 == 'x'
+        assert X.fromaddress(x.next).x3 == 'x'
         x.free()
         next.free()
         create_double_struct = lib.ptr("create_double_struct", [], 'P')
         x = create_double_struct()
-        x = X(x)
-        assert X(x.next).x2 == 3
+        x = X.fromaddress(x)
+        assert X.fromaddress(x.next).x2 == 3
         free_double_struct = lib.ptr("free_double_struct", ['P'], None)
         free_double_struct(x)
         
@@ -266,7 +273,7 @@
         get_array_elem_s = lib.ptr('get_array_elem_s', ['P', 'i'], 'P')
         ptr1 = get_array_elem_s(a, 0)
         assert ptr1 is None
-        assert X(get_array_elem_s(a, 1)).x2 == 3
+        assert X.fromaddress(get_array_elem_s(a, 1)).x2 == 3
         assert get_array_elem_s(a, 1) == x.buffer
         x.free()
         a.free()
@@ -342,3 +349,11 @@
             assert _ffi.sizeof(k) == s
             assert _ffi.alignment(k) == a
 
+    def test_array_addressof(self):
+        import _ffi
+        lib = _ffi.CDLL(self.lib_name)
+        alloc = lib.ptr('allocate_array', [], 'P')
+        A = _ffi.Array('i')
+        a = A.fromaddress(alloc(), 1)
+        assert a[0] == 3
+        # a.free() - don't free as ll2ctypes is complaining massively



More information about the Pypy-commit mailing list