Author: Armin Rigo <[email protected]>
Branch: ffi-backend
Changeset: r56603:ffcc389bbd31
Date: 2012-08-06 11:45 +0200
http://bitbucket.org/pypy/pypy/changeset/ffcc389bbd31/

Log:    in-progress

diff --git a/lib_pypy/_rawffi.py b/lib_pypy/_rawffi.py
--- a/lib_pypy/_rawffi.py
+++ b/lib_pypy/_rawffi.py
@@ -19,11 +19,6 @@
 cffi_type_longdouble = _cffi_backend.new_primitive_type("long double")
 cffi_type_wchar_t = _cffi_backend.new_primitive_type("wchar_t")
 
-cffi_type_short_p  = _cffi_backend.new_pointer_type(cffi_type_short)
-cffi_type_ushort_p = _cffi_backend.new_pointer_type(cffi_type_ushort)
-cffi_type_long_p   = _cffi_backend.new_pointer_type(cffi_type_long)
-cffi_type_ulong_p  = _cffi_backend.new_pointer_type(cffi_type_ulong)
-
 cffi_types = {
     'c': cffi_type_char,
     'b': cffi_type_schar,
@@ -48,6 +43,20 @@
     '?' : cffi_type_uchar,
     }
 
+cffi_cache_ptr = {cffi_type_void: cffi_type_pointer}
+cffi_cache_array = {}
+cffi_types_ptr = {}
+cffi_types_array = {}
+
+for _tp, _type in cffi_types.items():
+    if _type not in cffi_cache_ptr:
+        cffi_cache_ptr[_type] = _cffi_backend.new_pointer_type(_type)
+    if _type not in cffi_cache_array:
+        cffi_cache_array[_type] = _cffi_backend.new_array_type(
+            cffi_cache_ptr[_type], None)
+    cffi_types_ptr[_tp] = cffi_cache_ptr[_type]
+    cffi_types_array[_tp] = cffi_cache_array[_type]
+
 # ____________________________________________________________
 
 def sizeof(tp_letter):
@@ -83,14 +92,14 @@
             return self._cache[key]
         except KeyError:
             pass
-        assert not argtypes
+        cffi_argtypes = [cffi_types[tp] for tp in argtypes]
         if restype is None:
             cffi_restype = cffi_type_void
         else:
             cffi_restype = cffi_types[restype]
         assert isinstance(name, str)
-        cffi_functype = _cffi_backend.new_function_type((), cffi_restype,
-                                                        False)  # XXX abi
+        cffi_functype = _cffi_backend.new_function_type(
+            tuple(cffi_argtypes), cffi_restype, False)  # XXX abi
         cfunc = self._cffi_library.load_function(cffi_functype, name)
         funcptr = FuncPtr(cfunc)
         self._cache[key] = funcptr
@@ -104,13 +113,66 @@
 
 class FuncPtr(object):
     def __init__(self, cfunc):
-        self.cfunc = cfunc
+        self._cfunc = cfunc
+
+    def __call__(self, *args):
+        return self._cfunc(*[arg._prepare_arg() for arg in args])
 
 # ____________________________________________________________
 
-class Array(DataInstance):
+class Array(object):
     def __init__(self, shape):
-        pass
+        self._cffi_item = cffi_types[shape]
+        self._cffi_ptr = cffi_types_ptr[shape]
+        self._cffi_array = cffi_types_array[shape]
+        self._shape = shape
+
+    def __call__(self, length, items=None, autofree=False):
+        # XXX cache 'array'?
+        array = _cffi_backend.new_array_type(self._cffi_ptr, length)
+        return ArrayInstance(_cffi_backend.newp(array, items), self._shape)
+
+_array_of_pointers = Array('P')
+
+class ArrayInstance(DataInstance):
+    def __init__(self, cdata, shape):
+        self._cdata = cdata
+        self._shape = shape
+
+    def byptr(self):
+        return _array_of_pointers(1, [self._cdata])
+
+    def __getitem__(self, index):
+        return self._cdata[index]
+
+    def __setitem__(self, index, value):
+        self._cdata[index] = value
+
+    def __getslice__(self, i, j):
+        if self._shape != 'c':
+            raise TypeError("only 'c' arrays support slicing")
+        if i < 0: i = 0
+        if j > len(self._cdata): j = len(self._cdata)
+        if i > j: j = i
+        return _cffi_backend.buffer(self._cdata + i, j - i)[:]
+
+    def __setslice__(self, i, j, value):
+        if self._shape != 'c':
+            raise TypeError("only 'c' arrays support slicing")
+        if i < 0: i = 0
+        if j > len(self._cdata): j = len(self._cdata)
+        if i > j: j = i
+        _cffi_backend.buffer(self._cdata + i, j - i)[:] = value
+
+    def _prepare_arg(self):
+        if len(self._cdata) != 1:
+            return TypeError("Argument should be an array of length 1, "
+                             "got length %d" % len(self._cdata))
+        # XXX check type
+        return self._cdata[0]
+
+    def free(self):
+        pass  # XXX
 
 # ____________________________________________________________
 
diff --git a/lib_pypy/pypy_test/test__rawffi.py 
b/lib_pypy/pypy_test/test__rawffi.py
--- a/lib_pypy/pypy_test/test__rawffi.py
+++ b/lib_pypy/pypy_test/test__rawffi.py
@@ -1,4 +1,5 @@
 import os, sys, py
+from lib_pypy import _rawffi
 
 class TestFfi:
     def prepare_c_example():
@@ -217,11 +218,9 @@
         cls.lib_name = cls.prepare_c_example()
 
     def test_libload(self):
-        import _rawffi
         _rawffi.CDLL(self.libc_name)
 
     def test_libload_fail(self):
-        import _rawffi
         try:
             _rawffi.CDLL("xxxxx_this_name_does_not_exist_xxxxx")
         except OSError, e:
@@ -234,7 +233,6 @@
         if self.iswin32:
             skip("unix specific")
         skip("XXX in-progress")
-        import _rawffi
         # this should return *all* loaded libs, dlopen(NULL)
         dll = _rawffi.CDLL(None)
         # Assume CPython, or PyPy compiled with cpyext
@@ -242,11 +240,9 @@
         assert res[0] == 1
 
     def test_libc_load(self):
-        import _rawffi
         _rawffi.get_libc()
 
     def test_getattr(self):
-        import _rawffi
         libc = _rawffi.get_libc()
         func = libc.ptr('rand', [], 'i')
         assert libc.ptr('rand', [], 'i') is func # caching
@@ -257,7 +253,6 @@
     def test_byordinal(self):
         if not self.iswin32:
             skip("win32 specific")
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         # This will call the ordinal function numbered 1
         # my compiler seems to order them alphabetically:
@@ -265,7 +260,6 @@
         assert lib.ptr(1, [], 'i')()[0] == 42
 
     def test_getchar(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         get_char = lib.ptr('get_char', ['P', 'H'], 'c')
         A = _rawffi.Array('c')
@@ -283,7 +277,6 @@
 
     def test_chararray_as_bytebuffer(self):
         # a useful extension to arrays of shape 'c': buffer-like slicing
-        import _rawffi
         A = _rawffi.Array('c')
         buf = A(10, autofree=True)
         buf[0] = '*'
@@ -293,7 +286,6 @@
         assert buf[:8] == '*' + '\x00'*6 + 'a'
 
     def test_returning_str(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         char_check = lib.ptr('char_check', ['c', 'c'], 's')
         A = _rawffi.Array('c')
@@ -318,7 +310,6 @@
         a.free()
 
     def test_returning_unicode(self):
-        import _rawffi
         A = _rawffi.Array('u')
         a = A(6, u'xx\x00\x00xx')
         res = _rawffi.wcharp2unicode(a.buffer)
@@ -327,7 +318,6 @@
         a.free()
 
     def test_raw_callable(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         get_raw_pointer = lib.ptr('get_raw_pointer', [], 'P')
         ptr = get_raw_pointer()
@@ -347,7 +337,6 @@
         ptr.free()
 
     def test_short_addition(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         short_add = lib.ptr('add_shorts', ['h', 'h'], 'H')
         A = _rawffi.Array('h')
@@ -361,7 +350,6 @@
         arg2.free()
 
     def test_pow(self):
-        import _rawffi
         libm = _rawffi.CDLL(self.libm_name)
         pow = libm.ptr('pow', ['d', 'd'], 'd')
         A = _rawffi.Array('d')
@@ -376,7 +364,6 @@
         arg2.free()
 
     def test_time(self):
-        import _rawffi
         libc = _rawffi.get_libc()
         try:
             time = libc.ptr('time', ['z'], 'l')  # 'z' instead of 'P' just for 
test
@@ -392,7 +379,6 @@
     def test_gettimeofday(self):
         if self.iswin32:
             skip("No gettimeofday on win32")
-        import _rawffi
         struct_type = _rawffi.Structure([('tv_sec', 'l'), ('tv_usec', 'l')])
         structure = struct_type()
         libc = _rawffi.get_libc()
@@ -417,7 +403,6 @@
         arg2.free()
 
     def test_structreturn(self):
-        import _rawffi
         X = _rawffi.Structure([('x', 'l')])
         x = X()
         x.x = 121
@@ -447,7 +432,6 @@
         x.free()
 
     def test_nested_structures(self):
-        import _rawffi
         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')])
@@ -470,7 +454,6 @@
         free_double_struct(res)
 
     def test_structure_bitfields(self):
-        import _rawffi
         X = _rawffi.Structure([('A', 'I', 1),
                                ('B', 'I', 2),
                                ('C', 'i', 2)])
@@ -492,20 +475,17 @@
         y.free()
 
     def test_invalid_bitfields(self):
-        import _rawffi
         raises(TypeError, _rawffi.Structure, [('A', 'c', 1)])
         raises(ValueError, _rawffi.Structure, [('A', 'I', 129)])
         raises(ValueError, _rawffi.Structure, [('A', 'I', -1)])
         raises(ValueError, _rawffi.Structure, [('A', 'I', 0)])
 
     def test_packed_structure(self):
-        import _rawffi
         Y = _rawffi.Structure([('a', 'c'),
                                ('b', 'i')], pack=1)
         assert Y.size == 5
 
     def test_array(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         A = _rawffi.Array('i')
         get_array_elem = lib.ptr('get_array_elem', ['P', 'i'], 'i')
@@ -525,7 +505,6 @@
         a.free()
 
     def test_array_of_structure(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         A = _rawffi.Array('P')
         X = _rawffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 
'P')])
@@ -548,7 +527,6 @@
         a.free()
 
     def test_bad_parameters(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         nothing = lib.ptr('nothing', [], None)
         assert nothing() is None
@@ -561,7 +539,6 @@
         raises(ValueError, "_rawffi.Array('xx')")
 
     def test_longs_ulongs(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         some_huge_value = lib.ptr('some_huge_value', [], 'q')
         res = some_huge_value()
@@ -577,7 +554,6 @@
         arg1.free()
     
     def test_callback(self):
-        import _rawffi
         import struct
         libc = _rawffi.get_libc()
         ll_to_sort = _rawffi.Array('i')(4)
@@ -613,7 +589,6 @@
         cb.free()
 
     def test_another_callback(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         runcallback = lib.ptr('runcallback', ['P'], 'q')
         def callback():
@@ -627,7 +602,6 @@
         cb.free()
 
     def test_void_returning_callback(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         runcallback = lib.ptr('runcallback', ['P'], None)
         called = []
@@ -643,7 +617,6 @@
         cb.free()
 
     def test_raising_callback(self):
-        import _rawffi, sys
         import StringIO
         lib = _rawffi.CDLL(self.lib_name)
         err = StringIO.StringIO()
@@ -668,7 +641,6 @@
 
 
     def test_setattr_struct(self):
-        import _rawffi
         X = _rawffi.Structure([('value1', 'i'), ('value2', 'i')])
         x = X()
         x.value1 = 1
@@ -682,13 +654,11 @@
         x.free()
 
     def test_sizes_and_alignments(self):
-        import _rawffi
         for k, (s, a) in self.sizes_and_alignments.iteritems():
             assert _rawffi.sizeof(k) == s
             assert _rawffi.alignment(k) == a
 
     def test_array_addressof(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         alloc = lib.ptr('allocate_array', [], 'P')
         A = _rawffi.Array('i')
@@ -698,7 +668,6 @@
         assert A.fromaddress(a.buffer, 1)[0] == 3
 
     def test_shape(self):
-        import _rawffi
         A = _rawffi.Array('i')
         a = A(1)
         assert a.shape is A
@@ -710,19 +679,16 @@
         s.free()
 
     def test_negative_pointers(self):
-        import _rawffi
         A = _rawffi.Array('P')
         a = A(1)
         a[0] = -1234
         a.free()
 
     def test_long_with_fromaddress(self):
-        import _rawffi
         addr = -1
         raises(ValueError, _rawffi.Array('u').fromaddress, addr, 100)
 
     def test_passing_raw_pointers(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         A = _rawffi.Array('i')
         get_array_elem = lib.ptr('get_array_elem', ['P', 'i'], 'i')
@@ -738,7 +704,7 @@
         a.free()
 
     def test_repr(self):
-        import _rawffi, struct
+        import struct
         isize = struct.calcsize("i")
         lsize = struct.calcsize("l")
         assert (repr(_rawffi.Array('i')) ==
@@ -761,7 +727,6 @@
         a.free()
 
     def test_wide_char(self):
-        import _rawffi, sys
         A = _rawffi.Array('u')
         a = A(3)
         a[0] = u'x'
@@ -784,7 +749,7 @@
         a.free()
 
     def test_truncate(self):
-        import _rawffi, struct
+        import struct
         a = _rawffi.Array('b')(1)
         a[0] = -5
         assert a[0] == -5
@@ -846,7 +811,6 @@
         a.free()
 
     def test_getaddressindll(self):
-        import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
         def getprimitive(typecode, name):
             addr = lib.getaddressindll(name)
@@ -867,7 +831,6 @@
         raises(ValueError, getprimitive, 'zzz', 'static_int')
 
     def test_segfault_exception(self):
-        import _rawffi
         S = _rawffi.Structure([('x', 'i')])
         s = S()
         s.x = 3
@@ -886,7 +849,6 @@
 
         # Even if the call corresponds to the specified signature,
         # the STDCALL calling convention may detect some errors
-        import _rawffi
         lib = _rawffi.CDLL('kernel32')
 
         f = lib.ptr('SetLastError', [], 'i')
@@ -910,7 +872,6 @@
         arg.free()
 
     def test_struct_byvalue(self):
-        import _rawffi, sys
         X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')])
         x_y = X_Y()
         lib = _rawffi.CDLL(self.lib_name)
@@ -925,7 +886,6 @@
         x_y.free()
 
     def test_callback_struct_byvalue(self):
-        import _rawffi, sys
         X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')])
         lib = _rawffi.CDLL(self.lib_name)
         op_x_y = lib.ptr('op_x_y', [(X_Y, 1), 'P'], 'l')
@@ -947,7 +907,6 @@
         assert res[0] == 420
 
     def test_ret_struct(self):
-        import _rawffi
         S2H = _rawffi.Structure([('x', 'h'), ('y', 'h')])
         s2h = S2H()
         lib = _rawffi.CDLL(self.lib_name)
@@ -978,7 +937,6 @@
         s2h.free()
 
     def test_ret_struct_containing_array(self):
-        import _rawffi
         AoI = _rawffi.Array('i')
         S2A = _rawffi.Structure([('bah', (AoI, 2))])
         lib = _rawffi.CDLL(self.lib_name)
@@ -992,7 +950,6 @@
         assert ok[0] == 1
 
     def test_buffer(self):
-        import _rawffi
         S = _rawffi.Structure((40, 1))
         s = S(autofree=True)
         b = buffer(s)
@@ -1014,7 +971,6 @@
         assert a[4] == 't'
 
     def test_union(self):
-        import _rawffi
         longsize = _rawffi.sizeof('l')
         S = _rawffi.Structure([('x', 'h'), ('y', 'l')], union=True)
         s = S(autofree=False)
@@ -1026,7 +982,6 @@
         s.free()
 
     def test_ffi_type(self):
-        import _rawffi
         EMPTY = _rawffi.Structure([])
         S2E = _rawffi.Structure([('bah', (EMPTY, 1))])
         S2E.get_ffi_type()     # does not hang
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to