[pypy-commit] pypy reflex-support: (arigo, wlav) allow pointer assignment on data members

wlav noreply at buildbot.pypy.org
Mon Jul 11 19:01:53 CEST 2011


Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r45462:8f72ce65c803
Date: 2011-07-11 09:58 -0700
http://bitbucket.org/pypy/pypy/changeset/8f72ce65c803/

Log:	(arigo, wlav) allow pointer assignment on data members

diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -43,6 +43,9 @@
         # May be overridden.  No bounds checks.
         return ''.join([self.getitem(i) for i in range(start, stop, step)])
 
+    def get_raw_address(self):
+        raise ValueError("no raw buffer")
+
     # __________ app-level support __________
 
     def descr_len(self, space):
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -162,6 +162,9 @@
     def setitem(self, index, char):
         self.data[index] = char
 
+    def get_raw_address(self):
+        return self.data
+
 
 def make_array(mytype):
     class W_Array(W_ArrayBase):
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
@@ -86,7 +86,7 @@
     def from_memory(self, space, w_obj, offset):
         # read access, so no copy needed
         address_value = self._get_raw_address(space, w_obj, offset)
-        address = rffi.cast(rffi.UINT, address_value)
+        address = rffi.cast(rffi.ULONG, address_value)
         cache = space.fromcache(ArrayCache)
         arr = getattr(cache, 'array_' + self.typecode)
         return arr.fromaddress(space, address, self.size)
@@ -100,13 +100,32 @@
             address[i] = buf.getitem(i)
 
 
-class PtrTypeConverter(ArrayTypeConverterMixin, TypeConverter):
+class PtrTypeConverter(TypeConverter):
     _immutable_ = True
 
-    def _get_raw_address(self, space, w_obj, offset):
-        address = TypeConverter._get_raw_address(self, space, w_obj, offset)
-        ptr2ptr = rffi.cast(rffi.LONGP, address)
-        return rffi.cast(rffi.CCHARP, ptr2ptr[0])
+    def __init__(self, space, array_size):
+        self.size = sys.maxint
+
+    def from_memory(self, space, w_obj, offset):
+        # read access, so no copy needed
+        address_value = self._get_raw_address(space, w_obj, offset)
+        address = rffi.cast(rffi.ULONGP, address_value)
+        cache = space.fromcache(ArrayCache)
+        arr = getattr(cache, 'array_' + self.typecode)
+        return arr.fromaddress(space, address[0], self.size)
+
+    @jit.dont_look_inside
+    def to_memory(self, space, w_obj, w_value, offset):
+        # copy only the pointer value
+        rawobject = get_rawobject(space, w_obj)
+        field_address = lltype.direct_ptradd(rawobject, offset)
+        byteptr = rffi.cast(rffi.CCHARPP, field_address)
+        buf = space.buffer_w(w_value)
+        try:
+            byteptr[0] = buf.get_raw_address()
+        except ValueError:
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("raw buffer interface not supported"))
 
 
 class VoidConverter(TypeConverter):
@@ -331,13 +350,6 @@
     typecode = 'h'
     typesize = 2
 
-    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 LongPtrConverter(PtrTypeConverter):
     _immutable_=True
     typecode = 'l'
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
@@ -5,7 +5,7 @@
 currpath = py.path.local(__file__).dirpath()
 shared_lib = str(currpath.join("datatypesDict.so"))
 
-space = gettestobjspace(usemodules=['cppyy'])
+space = gettestobjspace(usemodules=['cppyy', 'array'])
 
 def setup_module(mod):
     if sys.platform == 'win32':
@@ -178,11 +178,10 @@
             for i in range(self.N):
                 assert eval('c.m_%s_array[i]' % names[j]) == b[i]
 
-# TODO: be able to dissect array.array for its pointers
-#            exec 'c.m_%s_array2 = b' % names[j]  # pointer copies
-#            b[i] = 28
-#            for i in range(self.N):
-#                assert eval('c.m_%s_array2[i]' % names[j]) == b[i]
+            exec 'c.m_%s_array2 = b' % names[j]  # pointer copies
+            b[i] = 28
+            for i in range(self.N):
+                assert eval('c.m_%s_array2[i]' % names[j]) == b[i]
 
         c.destruct()
 


More information about the pypy-commit mailing list