[pypy-svn] r50594 - in pypy/branch/applevel-ctypes2/pypy/module/_rawffi: . test

arigo at codespeak.net arigo at codespeak.net
Mon Jan 14 15:07:55 CET 2008


Author: arigo
Date: Mon Jan 14 15:07:54 2008
New Revision: 50594

Modified:
   pypy/branch/applevel-ctypes2/pypy/module/_rawffi/__init__.py
   pypy/branch/applevel-ctypes2/pypy/module/_rawffi/array.py
   pypy/branch/applevel-ctypes2/pypy/module/_rawffi/interp_rawffi.py
   pypy/branch/applevel-ctypes2/pypy/module/_rawffi/structure.py
   pypy/branch/applevel-ctypes2/pypy/module/_rawffi/test/test__rawffi.py
Log:
(fijal, arigo)  Finish _rawffi.


Modified: pypy/branch/applevel-ctypes2/pypy/module/_rawffi/__init__.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_rawffi/__init__.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_rawffi/__init__.py	Mon Jan 14 15:07:54 2008
@@ -19,6 +19,7 @@
         '_get_type'          : 'interp_rawffi._w_get_type',
         'sizeof'             : 'interp_rawffi.sizeof',
         'alignment'          : 'interp_rawffi.alignment',
+        'charp2string'       : 'interp_rawffi.charp2string',
         #'CallbackPtr'        : 'callback.W_CallbackPtr',
     }
 

Modified: pypy/branch/applevel-ctypes2/pypy/module/_rawffi/array.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_rawffi/array.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_rawffi/array.py	Mon Jan 14 15:07:54 2008
@@ -104,8 +104,7 @@
 
     def getitem(self, space, num):
         if num >= self.length or num < 0:
-            raise OperationError(space.w_ValueError, space.wrap(
-                "Getting element %d of array sized %d" % (num, self.length)))
+            raise OperationError(space.w_IndexError, space.w_None)
         return wrap_value(space, get_elem, self.ll_buffer, num, self.shape.of)
     getitem.unwrap_spec = ['self', ObjSpace, int]
 

Modified: pypy/branch/applevel-ctypes2/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_rawffi/interp_rawffi.py	Mon Jan 14 15:07:54 2008
@@ -1,4 +1,4 @@
-
+import sys
 from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \
      Arguments
 from pypy.interpreter.error import OperationError, wrap_oserror
@@ -80,7 +80,7 @@
         return TYPEMAP[key]
     except KeyError:
         raise OperationError(space.w_ValueError, space.wrap(
-            "Uknown type letter %s" % (key,)))
+            "Unknown type letter %s" % (key,)))
     return lltype.nullptr(FFI_TYPE_P.TO)
 
 def _w_get_type(space, key):
@@ -154,14 +154,6 @@
 buffer."""
 )
 
-def pack_pointer(space, add_arg, argdesc, w_arg, push_func):
-    arg = space.str_w(w_arg)
-    ll_str = lltype.malloc(rffi.CCHARP.TO, len(arg), flavor='raw')
-    for i in range(len(arg)):
-        ll_str[i] = arg[i]
-    push_func(add_arg, argdesc, ll_str)
-    return ll_str
-
 def make_size_checker(format, size, signed):
     min, max, _ = min_max_acc_method(size, signed)
 
@@ -206,7 +198,7 @@
                                            zero=True)
 
     def getbuffer(space, self):
-        return space.wrap(rffi.cast(rffi.INT, self.ll_buffer))
+        return space.wrap(rffi.cast(lltype.Signed, self.ll_buffer))
 
     def byptr(self, space):
         from pypy.module._rawffi.array import get_array_cache
@@ -270,48 +262,33 @@
 def wrap_value(space, func, add_arg, argdesc, tp):
     for c, ll_type in ll_typemap_iter:
         if tp == c:
-            if c == 's' or c == 'z':
-                ptr = func(add_arg, argdesc, rffi.CCHARP)
-                if not ptr:
-                    return space.w_None
-                return space.wrap(rffi.charp2str(ptr))
-            elif c == 'P' or c == 'O':
+            if c in TYPEMAP_PTR_LETTERS:
                 res = func(add_arg, argdesc, rffi.VOIDP)
-                if not res:
-                    return space.w_None
-                return space.wrap(rffi.cast(rffi.INT, res))
+                return space.wrap(rffi.cast(lltype.Signed, res))
             elif c == 'v':
                 func(add_arg, argdesc, ll_type)
                 return space.w_None
-            elif c == 'q' or c == 'Q' or c == 'L':
+            elif c == 'q' or c == 'Q' or c == 'L' or c == 'c':
                 return space.wrap(func(add_arg, argdesc, ll_type))
             elif c == 'f' or c == 'd':
                 return space.wrap(float(func(add_arg, argdesc, ll_type)))
-            elif c == 'c':
-                return space.wrap(chr(rffi.cast(rffi.INT, func(add_arg, argdesc,
-                                                               ll_type))))
             elif c == 'h' or c == 'H':
-                return space.wrap(rffi.cast(rffi.INT, func(add_arg, argdesc,
+                return space.wrap(rffi.cast(lltype.Signed, func(add_arg, argdesc,
                                                            ll_type)))
             else:
                 return space.wrap(intmask(func(add_arg, argdesc, ll_type)))
     return space.w_None
 wrap_value._annspecialcase_ = 'specialize:arg(1)'
 
-def ptr_call(ptr, some_arg, ll_type):
-    return ptr.call(ll_type)
-ptr_call._annspecialcase_ = 'specialize:arg(2)'
-
-def push(ptr, argdesc, value):
-    ptr.push_arg(value)
-push._annspecialcase_ = 'specialize:argtype(2)'
-
 class W_FuncPtr(Wrappable):
     def __init__(self, space, ptr, argtypes, restype):
         from pypy.module._rawffi.array import get_array_cache
         self.ptr = ptr
-        cache = get_array_cache(space)
-        self.resarray = cache.get_array_type(restype)
+        if restype != 'v':
+            cache = get_array_cache(space)
+            self.resarray = cache.get_array_type(restype)
+        else:
+            self.resarray = None
         self.argtypes = argtypes
 
     def call(self, space, args_w):
@@ -336,9 +313,13 @@
                 raise OperationError(space.w_TypeError, space.wrap(msg))
             args_ll.append(arg.ll_buffer)
             # XXX we could avoid the intermediate list args_ll
-        result = self.resarray.allocate(space, 1)
-        self.ptr.call(args_ll, result.ll_buffer)
-        return space.wrap(result)
+        if self.resarray is not None:
+            result = self.resarray.allocate(space, 1)
+            self.ptr.call(args_ll, result.ll_buffer)
+            return space.wrap(result)
+        else:
+            self.ptr.call(args_ll, lltype.nullptr(rffi.VOIDP.TO))
+            return space.w_None
     call.unwrap_spec = ['self', ObjSpace, 'args_w']
 
 W_FuncPtr.typedef = TypeDef(
@@ -362,3 +343,10 @@
 
 sizeof = _create_new_accessor('sizeof', 'c_size')
 alignment = _create_new_accessor('alignment', 'c_alignment')
+
+def charp2string(space, address, maxlength=sys.maxint):
+    if address == 0:
+        return space.w_None
+    s = rffi.charp2strn(rffi.cast(rffi.CCHARP, address), maxlength)
+    return space.wrap(s)
+charp2string.unwrap_spec = [ObjSpace, int, int]

Modified: pypy/branch/applevel-ctypes2/pypy/module/_rawffi/structure.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_rawffi/structure.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_rawffi/structure.py	Mon Jan 14 15:07:54 2008
@@ -127,7 +127,7 @@
             raise segfault_exception(space, "accessing NULL pointer")
         i = self.getindex(space, attr)
         _, c = self.shape.fields[i]
-        unwrap_value(space, push_field, self, i, c, w_value, None)
+        unwrap_value(space, push_field, self, i, c, w_value)
     setattr.unwrap_spec = ['self', ObjSpace, str, W_Root]
 
 

Modified: pypy/branch/applevel-ctypes2/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_rawffi/test/test__rawffi.py	Mon Jan 14 15:07:54 2008
@@ -97,11 +97,11 @@
            return x;
         }
 
+        static int prebuilt_array1[] = {3};
+
         int* allocate_array()
         {
-            int *res = (int*)malloc(sizeof(int));
-            res[0] = 3;
-            return res;
+            return prebuilt_array1;
         }
 
         '''))
@@ -150,52 +150,64 @@
         import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         char_check = lib.ptr('char_check', ['c', 'c'], 's')
-        assert char_check('y', 'x') == 'xxxxxx'
-        assert char_check('x', 'y') is None
+        A = _rawffi.Array('c')
+        arg1 = A(1)
+        arg2 = A(1)
+        arg1[0] = 'y'
+        arg2[0] = 'x'
+        res = char_check(arg1, arg2)
+        assert _rawffi.charp2string(res[0]) == 'xxxxxx'
+        res.free()
+        arg1[0] = 'x'
+        arg2[0] = 'y'
+        res = char_check(arg1, arg2)
+        assert res[0] == 0
+        assert _rawffi.charp2string(res[0]) is None
+        res.free()
+        arg1.free()
+        arg2.free()
 
     def test_short_addition(self):
         import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         short_add = lib.ptr('add_shorts', ['h', 'h'], 'H')
-        assert short_add(1, 2) == 3
-
-    def test_rand(self):
-        import _rawffi
-        libc = _rawffi.CDLL('libc.so.6')
-        func = libc.ptr('rand', [], 'i')
-        first = func()
-        count = 0
-        for i in range(100):
-            res = func()
-            if res == first:
-                count += 1
-        assert count != 100
+        A = _rawffi.Array('h')
+        arg1 = A(1)
+        arg2 = A(1)
+        arg1[0] = 1
+        arg2[0] = 2
+        res = short_add(arg1, arg2)
+        assert res[0] == 3
+        res.free()
+        arg1.free()
+        arg2.free()
 
     def test_pow(self):
         import _rawffi
         libm = _rawffi.CDLL('libm.so')
         pow = libm.ptr('pow', ['d', 'd'], 'd')
-        assert pow(2.0, 2.0) == 4.0
-        assert pow(3.0, 3.0) == 27.0
-        assert pow(2, 2) == 4.0
-        raises(TypeError, "pow('x', 2.0)")
-
-    def test_strlen(self):
-        import _rawffi
-        libc = _rawffi.CDLL('libc.so.6')
-        strlen = libc.ptr('strlen', ['s'], 'i')
-        assert strlen("dupa") == 4
-        assert strlen("zupa") == 4
-        strlen = libc.ptr('strlen', ['P'], 'i')
-        assert strlen("ddd\x00") == 3
-        strdup = libc.ptr('strdup', ['s'], 's')
-        assert strdup("xxx") == "xxx"
+        A = _rawffi.Array('d')
+        arg1 = A(1)
+        arg2 = A(1)
+        raises(TypeError, "arg1[0] = 'x'")
+        arg1[0] = 3
+        arg2[0] = 2.0
+        res = pow(arg1, arg2)
+        assert res[0] == 9.0
+        res.free()
+        arg1.free()
+        arg2.free()
 
     def test_time(self):
         import _rawffi
         libc = _rawffi.CDLL('libc.so.6')
         time = libc.ptr('time', ['P'], 'l')
-        assert time(None) != 0
+        arg = _rawffi.Array('P')(1)
+        arg[0] = 0
+        res = time(arg)
+        assert res[0] != 0
+        res.free()
+        arg.free()
 
     def test_gettimeofday(self):
         import _rawffi
@@ -203,13 +215,26 @@
         structure = struct_type()
         libc = _rawffi.CDLL('libc.so.6')
         gettimeofday = libc.ptr('gettimeofday', ['P', 'P'], 'i')
-        assert gettimeofday(structure, None) == 0
+
+        arg1 = structure.byptr()
+        arg2 = _rawffi.Array('P')(1)
+        res = gettimeofday(arg1, arg2)
+        assert res[0] == 0
+        res.free()
+
         struct2 = struct_type()
-        assert gettimeofday(struct2, None) == 0
+        arg1[0] = struct2
+        res = gettimeofday(arg1, arg2)
+        assert res[0] == 0
+        res.free()
+
         assert structure.tv_usec != struct2.tv_usec
         assert (structure.tv_sec == struct2.tv_sec) or (structure.tv_sec == struct2.tv_sec - 1)
         raises(AttributeError, "structure.xxx")
         structure.free()
+        struct2.free()
+        arg1.free()
+        arg2.free()
 
     def test_structreturn(self):
         import _rawffi
@@ -217,17 +242,22 @@
         x = X()
         x.x = 121
         Tm = _rawffi.Structure([('tm_sec', 'i'),
-                             ('tm_min', 'i'),
-                             ('tm_hour', 'i'),
-                             ("tm_mday", 'i'),
-                             ("tm_mon", 'i'),
-                             ("tm_year", 'i'),
-                             ("tm_wday", 'i'),
-                             ("tm_yday", 'i'),
-                             ("tm_isdst", 'i')])
+                                ('tm_min', 'i'),
+                                ('tm_hour', 'i'),
+                                ("tm_mday", 'i'),
+                                ("tm_mon", 'i'),
+                                ("tm_year", 'i'),
+                                ("tm_wday", 'i'),
+                                ("tm_yday", 'i'),
+                                ("tm_isdst", 'i')])
         libc = _rawffi.CDLL('libc.so.6')
         gmtime = libc.ptr('gmtime', ['P'], 'P')
-        t = Tm.fromaddress(gmtime(x))
+
+        arg = x.byptr()
+        res = gmtime(arg)
+        t = Tm.fromaddress(res[0])
+        res.free()
+        arg.free()
         assert t.tm_year == 70
         assert t.tm_sec == 1
         assert t.tm_min == 2      
@@ -238,18 +268,18 @@
         lib = _rawffi.CDLL(self.lib_name)
         inner = lib.ptr("inner_struct_elem", ['P'], 'c')
         X = _rawffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')])
-        next = X(next=None, x3='x')
+        next = X(next=0, x3='x')
         x = X(next=next, x1=1, x2=2, 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.fromaddress(x)
+        res = create_double_struct()
+        x = X.fromaddress(res[0])
         assert X.fromaddress(x.next).x2 == 3
         free_double_struct = lib.ptr("free_double_struct", ['P'], None)
-        free_double_struct(x)
-        
+        free_double_struct(res)
+        res.free()
 
     def test_array(self):
         import _rawffi
@@ -260,16 +290,17 @@
         a[8] = 3
         a[7] = 1
         a[6] = 2
-        assert get_array_elem(a, 9) == 0
-        assert get_array_elem(a, 8) == 3
-        assert get_array_elem(a, 7) == 1
-        assert get_array_elem(a, 6) == 2
+        arg1 = a.byptr()
+        arg2 = A(1)
+        for i, expected in enumerate([0, 0, 0, 0, 0, 0, 2, 1, 3, 0]):
+            arg2[0] = i
+            res = get_array_elem(arg1, arg2)
+            assert res[0] == expected
+            res.free()
+        arg1.free()
+        arg2.free()
         assert a[3] == 0
         a.free()
-        a = A([1, 2, 3, 4])
-        assert get_array_elem(a, 0) == 1
-        assert a[3] == 4
-        a.free()
 
     def test_array_of_structure(self):
         import _rawffi
@@ -280,10 +311,18 @@
         a = A(3)
         a[1] = x
         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.fromaddress(get_array_elem_s(a, 1)).x2 == 3
-        assert get_array_elem_s(a, 1) == x.buffer
+        arg1 = a.byptr()
+        arg2 = _rawffi.Array('i')(1)
+        res = get_array_elem_s(arg1, arg2)
+        assert res[0] == 0
+        res.free()
+        arg2[0] = 1
+        res = get_array_elem_s(arg1, arg2)
+        assert X.fromaddress(res[0]).x2 == 3
+        assert res[0] == x.buffer
+        res.free()
+        arg1.free()
+        arg2.free()
         x.free()
         a.free()
 
@@ -300,31 +339,27 @@
         raises(ValueError, _rawffi.Structure, [('x1', 'xx')])
         raises(ValueError, "_rawffi.Array('xx')")
 
-    def test_implicit_structure(self):
-        skip("Does not work yet")
-        import _rawffi
-        lib = _rawffi.CDLL(self.lib_name)
-        X = _rawffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'self')])
-        inner = lib.ptr("inner_struct_elem", [X], 'c')
-        x = X(next=X(next=None, x3='x'), x1=1, x2=2, x3='x')
-        assert x.next.x3 == 'x'
-        assert inner(x) == 'x'
-        create_double_struct = lib.ptr("create_double_struct", [], X)
-        x = create_double_struct()
-        assert x.next.x2 == 3
-        
-
     def test_longs_ulongs(self):
         import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         some_huge_value = lib.ptr('some_huge_value', [], 'q')
-        assert some_huge_value() == 1<<42
+        res = some_huge_value()
+        assert res[0] == 1<<42
+        res.free()
         some_huge_uvalue = lib.ptr('some_huge_uvalue', [], 'Q')
-        assert some_huge_uvalue() == 1<<42
-        x = lib.ptr('some_huge_value', ['Q'], None)
-        raises(ValueError, "x(-1)")
+        res = some_huge_uvalue()
+        assert res[0] == 1<<42
+        res.free()
+        arg1 = _rawffi.Array('Q')(1)
+        raises(ValueError, "arg1[0] = -1")
+        arg1.free()
         pass_ll = lib.ptr('pass_ll', ['q'], 'q')
-        assert pass_ll(1<<42) == 1<<42
+        arg1 = _rawffi.Array('q')(1)
+        arg1[0] = 1<<42
+        res = pass_ll(arg1)
+        assert res[0] == 1<<42
+        res.free()
+        arg1.free()
     
     def test_callback(self):
         skip("Not working")
@@ -363,10 +398,11 @@
         lib = _rawffi.CDLL(self.lib_name)
         alloc = lib.ptr('allocate_array', [], 'P')
         A = _rawffi.Array('i')
-        a = A.fromaddress(alloc(), 1)
+        res = alloc()
+        a = A.fromaddress(res[0], 1)
+        res.free()
         assert a[0] == 3
         assert A.fromaddress(a.buffer, 1)[0] == 3
-        # a.free() - don't free as ll2ctypes is complaining massively
 
     def test_shape(self):
         import _rawffi
@@ -393,6 +429,12 @@
         get_array_elem = lib.ptr('get_array_elem', ['P', 'i'], 'i')
         a = A(1)
         a[0] = 3
-        res = get_array_elem(a.buffer, 0)
-        assert res == 3
+        arg1 = _rawffi.Array('P')(1)
+        arg1[0] = a.buffer
+        arg2 = _rawffi.Array('i')(1)
+        res = get_array_elem(arg1, arg2)
+        assert res[0] == 3
+        res.free()
+        arg1.free()
+        arg2.free()
         a.free()



More information about the Pypy-commit mailing list