Commits

wlav committed 3496959

short array returns and short ptr data member access

Comments (0)

Files changed (3)

pypy/module/cppyy/converter.py

         return rffi.cast(rffi.VOIDP, x)
 
 
-class ShortPtrConverter(ArrayTypeConverter):
+class ShortArrayConverter(ArrayTypeConverter):
     _immutable_ = True
-    def convert_argument(self, space, w_obj):
-        assert 0, "not yet implemented"
-
     def from_memory(self, space, w_obj, offset):
         # read access, so no copy needed
         fieldptr = self._get_fieldptr(space, w_obj, offset)
         ptrval = rffi.cast(rffi.UINT, fieldptr)
         arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('h')))
+        return arr.fromaddress(space, fieldptr, self.size)
+
+    def to_memory(self, space, w_obj, w_value, offset):
+        # copy the full array (uses byte copy for now)
+        fieldptr = self._get_fieldptr(space, w_obj, offset)
+        buf = space.interp_w(Buffer, w_value.getslotvalue(2))
+        # TODO: get sizeof(short) from system
+        for i in range(min(self.size*2, buf.getlength())):
+            fieldptr[i] = buf.getitem(i)
+
+class LongArrayConverter(ArrayTypeConverter):
+    _immutable_ = True
+    def from_memory(self, space, w_obj, offset):
+        # read access, so no copy needed
+        fieldptr = self._get_fieldptr(space, w_obj, offset)
+        ptrval = rffi.cast(rffi.UINT, fieldptr)
+        arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('l')))
         return arr.fromaddress(space, ptrval, self.size)
 
     def to_memory(self, space, w_obj, w_value, offset):
+        # copy the full array (uses byte copy for now)
+        fieldptr = self._get_fieldptr(space, w_obj, offset)
+        buf = space.interp_w(Buffer, w_value.getslotvalue(2))
+        # TODO: get sizeof(long) from system
+        for i in range(min(self.size*4, buf.getlength())):
+            fieldptr[i] = buf.getitem(i)
+
+
+class ShortPtrConverter(ShortArrayConverter):
+    _immutable_ = True
+    def _get_fieldptr(self, space, w_obj, offset):
+        fieldptr = TypeConverter._get_fieldptr(self, space, w_obj, offset)
+        ptrptr = rffi.cast(rffi.LONGP, fieldptr)
+        return ptrptr[0]
+
+    def to_memory(self, space, w_obj, w_value, offset):
         # copy only the pointer value
         rawobject = get_rawobject(space, w_obj)
         byteptr = rffi.cast(rffi.LONGP, rawobject[offset])
         # TODO: now what ... ?? AFAICS, w_value is a pure python list, not an array?
 #        byteptr[0] = space.unwrap(space.id(w_value.getslotvalue(2)))
 
-class ShortArrayConverter(ShortPtrConverter):
+class LongPtrConverter(LongArrayConverter):
     _immutable_ = True
-    def to_memory(self, space, w_obj, w_value, offset):
-        # copy the full array (uses byte copy for now)
-        fieldptr = self._get_fieldptr(space, w_obj, offset)
-        buf = space.interp_w(Buffer, w_value.getslotvalue(2))
-        # TODO: get sizeof(short) from system
-        for i in range(min(self.size*2, buf.getlength())):
-            fieldptr[i] = buf.getitem(i)
-
-class LongPtrConverter(ArrayTypeConverter):
-    _immutable_ = True
-    def convert_argument(self, space, w_obj):
-        assert 0, "not yet implemented"
-
-    def from_memory(self, space, w_obj, offset):
-        # read access, so no copy needed
-        fieldptr = self._get_fieldptr(space, w_obj, offset)
-        ptrval = rffi.cast(rffi.UINT, fieldptr)
-        arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('l')))
-        return arr.fromaddress(space, ptrval, self.size)
+    def _get_fieldptr(self, space, w_obj, offset):
+        fieldptr = TypeConverter._get_fieldptr(self, space, w_obj, offset)
+        ptrptr = rffi.cast(rffi.LONGP, fieldptr)
+        return ptrptr[0]
 
     def to_memory(self, space, w_obj, w_value, offset):
         # copy only the pointer value
         # TODO: now what ... ?? AFAICS, w_value is a pure python list, not an array?
 #        byteptr[0] = space.unwrap(space.id(w_value.getslotvalue(2)))
 
-class LongArrayConverter(LongPtrConverter):
-    _immutable_ = True
-    def to_memory(self, space, w_obj, w_value, offset):
-        # copy the full array (uses byte copy for now)
-        fieldptr = self._get_fieldptr(space, w_obj, offset)
-        buf = space.interp_w(Buffer, w_value.getslotvalue(2))
-        # TODO: get sizeof(long) from system
-        for i in range(min(self.size*4, buf.getlength())):
-            fieldptr[i] = buf.getitem(i)
 
 
 class InstancePtrConverter(TypeConverter):

pypy/module/cppyy/executor.py

+import sys
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rlib import libffi
 
+from pypy.module._rawffi.interp_rawffi import unpack_simple_shape
+from pypy.module._rawffi.array import W_Array
+
 from pypy.module.cppyy import helper, capi
 
 
         raise FastCallNotPossible
 
 
+class ArrayExecutor(FunctionExecutor):
+    _immutable_ = True
+
+
 class VoidExecutor(FunctionExecutor):
     _immutable_ = True
 
     def execute_libffi(self, space, libffifunc, argchain):
         return space.wrap(libffifunc.call(argchain, rffi.DOUBLE))
 
+
 class CStringExecutor(FunctionExecutor):
     _immutable_ = True
     def execute(self, space, func, cppthis, num_args, args):
         return space.wrap(result)
 
 
+class ShortArrayExecutor(ArrayExecutor):
+    _immutable_ = True
+    def execute(self, space, func, cppthis, num_args, args):
+        lresult = capi.c_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
+        spresult = rffi.cast(rffi.SHORTP, lresult)
+        arr = space.interp_w(W_Array, unpack_simple_shape(space, space.wrap('h')))
+        return arr.fromaddress(space, spresult, sys.maxint)
+
+
 class InstancePtrExecutor(FunctionExecutor):
     _immutable_ = True
     def __init__(self, space, name, cpptype):
 _executors["char"]                = CharExecutor
 _executors["unsigned char"]       = CharExecutor
 _executors["short int"]           = ShortExecutor
+_executors["short int*"]          = ShortArrayExecutor
 _executors["unsigned short int"]  = ShortExecutor
 _executors["int"]                 = LongExecutor
 _executors["unsigned int"]        = LongExecutor

pypy/module/cppyy/test/test_datatypes.py

         lib2 = cppyy.load_lib(self.shared_lib)
         assert self.datatypes is lib2
 
+    def test1ReadAccess( self ):
+        """Test read access to instance public data and verify values"""
+
+        import cppyy, sys
+        cppyy_test_data = cppyy.gbl.cppyy_test_data
+
+        c = cppyy_test_data()
+        assert isinstance(c, cppyy_test_data)
+
+        # reading boolean type
+        assert c.m_bool == False
+
+        # reading char types
+        assert c.m_char  == 'a'
+        assert c.m_uchar == 'c'
+
+        # reading integer types
+        assert c.m_short  == -11
+        assert c.m_ushort ==  11
+        assert c.m_int    == -22
+        assert c.m_uint   ==  22
+        assert c.m_long   == -33
+        assert c.m_ulong  ==  33
+
+        # reading floating point types
+        assert round(c.m_float  + 44., 5) == 0
+        assert round(c.m_double + 55., 8) == 0
+
+        # reding of array types
+        for i in range(self.N):
+            # reading of integer array types
+            assert c.m_short_array[i]       ==  -1*i
+            assert c.get_short_array()[i]   ==  -1*i
+            assert c.m_short_array2[i]      ==  -2*i
+            assert c.get_short_array2()[i]  ==  -2*i
+            """
+            assert c.m_ushort_array[i]      ==   3*i
+            assert c.get_ushort_array()[i]  ==   3*i
+            assert c.m_ushort_array2[i]     ==   4*i
+            assert c.get_ushort_array2()[i] ==   4*i
+            assert c.m_int_array[i]         ==  -5*i
+            assert c.get_int_array()[i]     ==  -5*i
+            assert c.m_int_array2[i]        ==  -6*i
+            assert c.get_int_array2()[i]    ==  -6*i
+            assert c.m_uint_array[i]        ==   7*i
+            assert c.get_uint_array()[i]    ==   7*i
+            assert c.m_uint_array2[i]       ==   8*i
+            assert c.get_uint_array2()[i]   ==   8*i
+
+            assert c.m_long_array[i]        ==  -9*i
+            assert c.get_long_array()[i]    ==  -9*i
+            assert c.m_long_array2[i]       == -10*i
+            assert c.get_long_array2()[i]   == -10*i
+            assert c.m_ulong_array[i]       ==  11*i
+            assert c.get_ulong_array()[i]   ==  11*i
+            assert c.m_ulong_array2[i]      ==  12*i
+            assert c.get_ulong_array2()[i]  ==  12*i
+
+            assert round(c.m_float_array[i]   + 13.*i, 5) == 0
+            assert round(c.m_float_array2[i]  + 14.*i, 5) == 0
+            assert round(c.m_double_array[i]  + 15.*i, 8) == 0
+            assert round(c.m_double_array2[i] + 16.*i, 8) == 0
+            """
+
+        """
+        # out-of-bounds checks
+        raises(IndexError, c.m_short_array.__getitem__,  self.N)
+        raises(IndexError, c.m_ushort_array.__getitem__, self.N)
+        raises(IndexError, c.m_int_array.__getitem__,    self.N)
+        raises(IndexError, c.m_uint_array.__getitem__,   self.N)
+        raises(IndexError, c.m_long_array.__getitem__,   self.N)
+        raises(IndexError, c.m_ulong_array.__getitem__,  self.N)
+        raises(IndexError, c.m_float_array.__getitem__,  self.N)
+        raises(IndexError, c.m_double_array.__getitem__, self.N)
+        """
+
+        c.destruct()
+
     def test2WriteAccess(self):
         """Test write access to instance public data and verify values"""
 
         raises(TypeError, c.m_double,  'c')
         raises(TypeError, c.m_int,     -1.)
         raises(TypeError, c.m_int,      1.)
+
+        c.destruct()