1. Laurence Tratt
  2. pypy

Commits

wlav  committed 42827fb

allow passing of arrays through void*

  • Participants
  • Parent commits d02e109
  • Branches reflex-support

Comments (0)

Files changed (4)

File pypy/module/cppyy/converter.py

View file
  • Ignore whitespace
 
     def convert_argument(self, space, w_obj, address, call_local):
         x = rffi.cast(rffi.VOIDPP, address)
-        x[0] = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj))
         ba = rffi.cast(rffi.CCHARP, address)
-        ba[capi.c_function_arg_typeoffset()] = 'a'
+        try:
+            buf = space.buffer_w(w_obj)
+            x[0] = rffi.cast(rffi.VOIDP, buf.get_raw_address())
+            ba[capi.c_function_arg_typeoffset()] = 'o'
+        except (OperationError, ValueError):
+            x[0] = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj))
+            ba[capi.c_function_arg_typeoffset()] = 'a'
 
     def convert_argument_libffi(self, space, w_obj, argchain, call_local):
         argchain.arg(get_rawobject(space, w_obj))

File pypy/module/cppyy/test/datatypes.h

View file
  • Ignore whitespace
     float*          pass_array(float*);
     double*         pass_array(double*);
 
+    short*          pass_void_array_h(void* a) { return pass_array((short*)a); }
+    unsigned short* pass_void_array_H(void* a) { return pass_array((unsigned short*)a); }
+    int*            pass_void_array_i(void* a) { return pass_array((int*)a); }
+    unsigned int*   pass_void_array_I(void* a) { return pass_array((unsigned int*)a); }
+    long*           pass_void_array_l(void* a) { return pass_array((long*)a); }
+    unsigned long*  pass_void_array_L(void* a) { return pass_array((unsigned long*)a); }
+    float*          pass_void_array_f(void* a) { return pass_array((float*)a); }
+    double*         pass_void_array_d(void* a) { return pass_array((double*)a); }
+
 public:
 // basic types
     bool                 m_bool;

File pypy/module/cppyy/test/test_datatypes.py

View file
  • Ignore whitespace
         # test arrays in mixed order, to give overload resolution a workout
         for t in ['d', 'i', 'f', 'H', 'I', 'h', 'L', 'l' ]:
             b = array.array(t, a)
+
+            # typed passing
             ca = c.pass_array(b)
             assert type(ca[0]) == type(b[0])
             assert len(b) == self.N
             for i in range(self.N):
                 assert ca[i] == b[i]
 
+            # void* passing
+            ca = eval('c.pass_void_array_%s(b)' % t)
+            assert type(ca[0]) == type(b[0])
+            assert len(b) == self.N
+            for i in range(self.N):
+                assert ca[i] == b[i]
+
         c.destruct()
 
     def test05_class_read_access(self):

File pypy/module/cppyy/test/test_zjit.py

View file
  • Ignore whitespace
         self.__name__ = name
     def getname(self, space, name):
         return self.name
+class FakeBuffer(FakeBase):
+    typedname = "buffer"
+    def __init__(self, val):
+        self.val = val
+    def get_raw_address(self):
+        raise ValueError("no raw buffer")
 class FakeException(FakeType):
     def __init__(self, name):
         FakeType.__init__(self, name)
     def interpclass_w(self, w_obj):
         return w_obj
 
+    def buffer_w(self, w_obj):
+        return FakeBuffer(w_obj)
+
     def exception_match(self, typ, sub):
         return typ is sub