[pypy-commit] pypy reflex-support: allow passing of arrays through void*

wlav noreply at buildbot.pypy.org
Tue Jun 26 21:16:00 CEST 2012


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r55845:42827fbd6b63
Date: 2012-06-26 12:16 -0700
http://bitbucket.org/pypy/pypy/changeset/42827fbd6b63/

Log:	allow passing of arrays through void*

diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -524,9 +524,14 @@
 
     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))
diff --git a/pypy/module/cppyy/test/datatypes.h b/pypy/module/cppyy/test/datatypes.h
--- a/pypy/module/cppyy/test/datatypes.h
+++ b/pypy/module/cppyy/test/datatypes.h
@@ -104,6 +104,15 @@
     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;
diff --git a/pypy/module/cppyy/test/test_datatypes.py b/pypy/module/cppyy/test/test_datatypes.py
--- a/pypy/module/cppyy/test/test_datatypes.py
+++ b/pypy/module/cppyy/test/test_datatypes.py
@@ -207,12 +207,21 @@
         # 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):
diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -44,6 +44,12 @@
         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)
@@ -117,6 +123,9 @@
     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
 


More information about the pypy-commit mailing list