[pypy-commit] pypy faster-rstruct-2: add rlib.buffer.RawBuffer, which automatically implements typed_read in terms of get_raw_address

antocuni pypy.commits at gmail.com
Tue May 9 12:47:57 EDT 2017


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct-2
Changeset: r91208:f01cd8ba4297
Date: 2017-05-09 18:36 +0200
http://bitbucket.org/pypy/pypy/changeset/f01cd8ba4297/

Log:	add rlib.buffer.RawBuffer, which automatically implements typed_read
	in terms of get_raw_address

diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -92,6 +92,24 @@
         raise CannotRead
 
 
+class RawBuffer(Buffer):
+    """
+    A buffer which is baked by a raw, non-movable memory area. It implementes
+    typed_read in terms of get_raw_address()
+
+    NOTE: this assumes that get_raw_address() is cheap. Do not use this as a
+    base class if get_raw_address() is potentially costly, like for example if
+    you call rgc.nonmoving_raw_ptr_for_resizable_list
+    """
+
+    @specialize.ll_and_arg(1)
+    def typed_read(self, TP, byte_offset):
+        """
+        Read the value of type TP starting at byte_offset. No bounds checks
+        """
+        ptr = self.get_raw_address()
+        return llop.raw_load(TP, ptr, byte_offset)
+
 
 class StringBuffer(Buffer):
     _attrs_ = ['readonly', 'value']
diff --git a/rpython/rlib/test/test_buffer.py b/rpython/rlib/test/test_buffer.py
--- a/rpython/rlib/test/test_buffer.py
+++ b/rpython/rlib/test/test_buffer.py
@@ -1,11 +1,26 @@
 import struct
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib.rarithmetic import r_singlefloat
-from rpython.rlib.buffer import StringBuffer, SubBuffer, Buffer
+from rpython.rlib.buffer import StringBuffer, SubBuffer, Buffer, RawBuffer
 from rpython.annotator.annrpython import RPythonAnnotator
 from rpython.annotator.model import SomeInteger
 from rpython.rtyper.test.tool import BaseRtypingTest
 
+class MyRawBuffer(RawBuffer):
+
+    def __init__(self, data):
+        self._buf = lltype.malloc(rffi.CCHARP.TO, len(data), flavor='raw')
+        for i, ch in enumerate(data):
+            self._buf[i] = ch
+
+    def get_raw_address(self):
+        return self._buf
+
+    def __del__(self):
+        lltype.free(self._buf, flavor='raw')
+        self._buf = None
+
+
 def test_string_buffer():
     buf = StringBuffer('hello world')
     assert buf.getitem(4) == 'o'
@@ -97,6 +112,14 @@
         return subbuf.typed_read(TYPE, offset)
 
 
+class TestRawBufferTypedReadDirect(BaseTypedReadTest):
+
+    def read(self, TYPE, data, offset):
+        buf = MyRawBuffer(data)
+        return buf.typed_read(TYPE, offset)
+    
+
+
 class TestCompiled(BaseTypedReadTest):
     cache = {}
 


More information about the pypy-commit mailing list