[pypy-commit] pypy faster-rstruct-2: turn GCBuffer into a base class again :(, so that we will be able to provide default methods
antocuni
pypy.commits at gmail.com
Wed May 17 11:47:58 EDT 2017
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct-2
Changeset: r91322:7538ecbcf8b5
Date: 2017-05-17 17:42 +0200
http://bitbucket.org/pypy/pypy/changeset/7538ecbcf8b5/
Log: turn GCBuffer into a base class again :(, so that we will be able to
provide default methods
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -8,7 +8,7 @@
from rpython.rlib.rgc import (resizable_list_supporting_raw_ptr,
nonmoving_raw_ptr_for_resizable_list)
from rpython.rlib import jit
-from rpython.rlib.buffer import (Buffer, GCBuffer,
+from rpython.rlib.buffer import (GCBuffer,
get_gc_data_for_list_of_chars,
get_gc_data_offset_for_list_of_chars)
from pypy.interpreter.baseobjspace import W_Root
@@ -1258,8 +1258,8 @@
start += step
- at GCBuffer
-class BytearrayBuffer(Buffer):
+ at GCBuffer.decorate
+class BytearrayBuffer(GCBuffer):
_immutable_ = True
def __init__(self, ba, readonly=False):
@@ -1289,7 +1289,7 @@
if start != 0 or stop != len(data):
data = data[start:stop]
return "".join(data)
- return Buffer.getslice(self, start, stop, step, size)
+ return GCBuffer.getslice(self, start, stop, step, size)
def setslice(self, start, string):
# No bounds checks.
diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -32,9 +32,8 @@
Base class for buffers of bytes.
Most probably, you do NOT want to use this as a lone base class, but
- either inherit from RawBuffer or use the GCBuffer class decorator, so that
- you automatically get the proper implementation of typed_read and
- typed_write.
+ either inherit from RawBuffer or GCBuffer, so that you automatically get
+ the proper implementation of typed_read and typed_write.
"""
_attrs_ = ['readonly']
_immutable_ = True
@@ -133,13 +132,48 @@
return llop.raw_store(lltype.Void, ptr, byte_offset, value)
-def GCBuffer(buffercls):
+class GCBuffer(Buffer):
"""
- class decorator for a buffer which is baked by a GC-managed memory
- area. It implements typed_read and typed_write in terms of
- llop.gc_load_indexed and llop.gc_store_indexed.
+ Base class for a buffer which is baked by a GC-managed memory area. You
+ MUST also decorate the class with @GCBuffer.decorate: it implements
+ typed_read and typed_write in terms of llop.gc_load_indexed and
+ llop.gc_store_indexed.
+ """
+ _attrs_ = ['readonly', 'value']
+ _immutable_ = True
- The target class MUST provide the following methods:
+ @staticmethod
+ def decorate(targetcls):
+ """
+ Create and attach specialized versions of typed_{read,write}. We need to
+ do this becase the JIT codewriters mandates that base_ofs is an
+ RPython constant.
+ """
+ if targetcls.__bases__ != (GCBuffer,):
+ raise ValueError("@GCBuffer.decorate should be used only on "
+ "GCBuffer subclasses")
+
+ base_ofs = targetcls._get_gc_data_offset()
+ scale_factor = llmemory.sizeof(lltype.Char)
+
+ @specialize.ll_and_arg(1)
+ def typed_read(self, TP, byte_offset):
+ lldata = self._get_gc_data()
+ return llop.gc_load_indexed(TP, lldata, byte_offset,
+ scale_factor, base_ofs)
+
+ @specialize.ll_and_arg(1)
+ def typed_write(self, TP, byte_offset, value):
+ if self.readonly:
+ raise CannotWrite
+ lldata = self._get_gc_data()
+ value = lltype.cast_primitive(TP, value)
+ return llop.gc_store_indexed(lltype.Void, lldata, byte_offset, value,
+ scale_factor, base_ofs)
+
+ targetcls.typed_read = typed_read
+ targetcls.typed_write = typed_write
+ return targetcls
@staticmethod
def _get_gc_data_offset(self):
@@ -147,31 +181,16 @@
def _get_gc_data(self):
raise NotImplementedError
- """
- # We had to write this as a class decorator instead of a base class
- # because we need to produce specialized versions of typed_{read,write} in
- # which base_ofs is an RPython constant.
- base_ofs = buffercls._get_gc_data_offset()
- scale_factor = llmemory.sizeof(lltype.Char)
@specialize.ll_and_arg(1)
def typed_read(self, TP, byte_offset):
- lldata = self._get_gc_data()
- return llop.gc_load_indexed(TP, lldata, byte_offset,
- scale_factor, base_ofs)
+ raise NotImplementedError("You MUST decorate this class with "
+ "@GCBuffer.decorate")
@specialize.ll_and_arg(1)
def typed_write(self, TP, byte_offset, value):
- if self.readonly:
- raise CannotWrite
- lldata = self._get_gc_data()
- value = lltype.cast_primitive(TP, value)
- return llop.gc_store_indexed(lltype.Void, lldata, byte_offset, value,
- scale_factor, base_ofs)
-
- buffercls.typed_read = typed_read
- buffercls.typed_write = typed_write
- return buffercls
+ raise NotImplementedError("You MUST decorate this class with "
+ "@GCBuffer.decorate")
def get_gc_data_for_list_of_chars(data):
@@ -184,8 +203,8 @@
return llmemory.itemoffsetof(LIST.items.TO, 0)
- at GCBuffer
-class ByteBuffer(Buffer):
+ at GCBuffer.decorate
+class ByteBuffer(GCBuffer):
_immutable_ = True
def __init__(self, n):
@@ -212,8 +231,8 @@
return get_gc_data_offset_for_list_of_chars()
- at GCBuffer
-class StringBuffer(Buffer):
+ at GCBuffer.decorate
+class StringBuffer(GCBuffer):
_attrs_ = ['readonly', 'value']
_immutable_ = True
diff --git a/rpython/rlib/mutbuffer.py b/rpython/rlib/mutbuffer.py
--- a/rpython/rlib/mutbuffer.py
+++ b/rpython/rlib/mutbuffer.py
@@ -3,11 +3,11 @@
from rpython.rtyper.lltypesystem.rstr import STR, mallocstr
from rpython.rtyper.annlowlevel import llstr, hlstr
from rpython.rlib.objectmodel import specialize
-from rpython.rlib.buffer import Buffer, GCBuffer
+from rpython.rlib.buffer import GCBuffer
from rpython.rlib import jit
- at GCBuffer
-class MutableStringBuffer(Buffer):
+ at GCBuffer.decorate
+class MutableStringBuffer(GCBuffer):
"""
A writeable buffer to incrementally fill a string of a fixed size.
More information about the pypy-commit
mailing list