Author: Antonio Cuni <anto.c...@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 -@GCBuffer -class BytearrayBuffer(Buffer): +@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) -@GCBuffer -class ByteBuffer(Buffer): +@GCBuffer.decorate +class ByteBuffer(GCBuffer): _immutable_ = True def __init__(self, n): @@ -212,8 +231,8 @@ return get_gc_data_offset_for_list_of_chars() -@GCBuffer -class StringBuffer(Buffer): +@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 -@GCBuffer -class MutableStringBuffer(Buffer): +@GCBuffer.decorate +class MutableStringBuffer(GCBuffer): """ A writeable buffer to incrementally fill a string of a fixed size. _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit