[pypy-commit] pypy py3k: merge default

pjenvey noreply at buildbot.pypy.org
Thu May 23 02:09:24 CEST 2013


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r64499:34adaf2e34d5
Date: 2013-05-22 16:57 -0700
http://bitbucket.org/pypy/pypy/changeset/34adaf2e34d5/

Log:	merge default

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -31,3 +31,6 @@
 
 .. branch: remove-tuple-smm
 Remove multi-methods on tuple
+
+.. branch: remove-iter-smm
+Remove multi-methods on iterators
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -1,20 +1,17 @@
 """Generic iterator implementations"""
+
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.gateway import interp2app, interpindirect2app
 from pypy.interpreter.error import OperationError
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stdtypedef import StdTypeDef
 
 
-class W_AbstractIterObject(W_Object):
-    __slots__ = ()
-
-class W_AbstractSeqIterObject(W_AbstractIterObject):
-    from pypy.objspace.std.itertype import iter_typedef as typedef
-
-    def __init__(w_self, w_seq, index=0):
+class W_AbstractSeqIterObject(W_Root):
+    def __init__(self, w_seq, index=0):
         if index < 0:
             index = 0
-        w_self.w_seq = w_seq
-        w_self.index = index
+        self.w_seq = w_seq
+        self.index = index
 
     def getlength(self, space):
         if self.w_seq is None:
@@ -26,102 +23,155 @@
             w_len = space.wrap(0)
         return w_len
 
+    def descr_iter(self, space):
+        return self
+
+    def descr_next(self, space):
+        raise NotImplementedError
+
+    def descr_reduce(self, space):
+        """
+        XXX to do: remove this __reduce__ method and do
+        a registration with copy_reg, instead.
+        """
+        from pypy.interpreter.mixedmodule import MixedModule
+        w_mod = space.getbuiltinmodule('_pickle_support')
+        mod = space.interp_w(MixedModule, w_mod)
+        new_inst = mod.get('seqiter_new')
+        tup = [self.w_seq, space.wrap(self.index)]
+        return space.newtuple([new_inst, space.newtuple(tup)])
+
+    def descr_length_hint(self, space):
+        return self.getlength(space)
+
+W_AbstractSeqIterObject.typedef = StdTypeDef(
+    "sequenceiterator",
+    __doc__ = '''iter(collection) -> iterator
+iter(callable, sentinel) -> iterator
+
+Get an iterator from an object.  In the first form, the argument must
+supply its own iterator, or be a sequence.
+In the second form, the callable is called until it returns the sentinel.''',
+    __iter__ = interp2app(W_AbstractSeqIterObject.descr_iter),
+    next = interpindirect2app(W_AbstractSeqIterObject.descr_next),
+    __reduce__ = interp2app(W_AbstractSeqIterObject.descr_reduce),
+    __length_hint__ = interp2app(W_AbstractSeqIterObject.descr_length_hint),
+)
+W_AbstractSeqIterObject.typedef.acceptable_as_base_class = False
+
+
 class W_SeqIterObject(W_AbstractSeqIterObject):
     """Sequence iterator implementation for general sequences."""
 
-class W_FastListIterObject(W_AbstractSeqIterObject): # XXX still needed
-    """Sequence iterator specialized for lists.
-    """
+    def descr_next(self, space):
+        if self.w_seq is None:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        try:
+            w_item = space.getitem(self.w_seq, space.wrap(self.index))
+        except OperationError, e:
+            self.w_seq = None
+            if not e.match(space, space.w_IndexError):
+                raise
+            raise OperationError(space.w_StopIteration, space.w_None)
+        self.index += 1
+        return w_item
+
+
+class W_FastListIterObject(W_AbstractSeqIterObject):
+    """Sequence iterator specialized for lists."""
+
+    def descr_next(self, space):
+        from pypy.objspace.std.listobject import W_ListObject
+        w_seq = self.w_seq
+        if w_seq is None:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        assert isinstance(w_seq, W_ListObject)
+        index = self.index
+        try:
+            w_item = w_seq.getitem(index)
+        except IndexError:
+            self.w_seq = None
+            raise OperationError(space.w_StopIteration, space.w_None)
+        self.index = index + 1
+        return w_item
+
 
 class W_FastTupleIterObject(W_AbstractSeqIterObject):
     """Sequence iterator specialized for tuples, accessing directly
     their RPython-level list of wrapped objects.
     """
-    def __init__(w_self, w_seq, wrappeditems):
-        W_AbstractSeqIterObject.__init__(w_self, w_seq)
-        w_self.tupleitems = wrappeditems
+    def __init__(self, w_seq, wrappeditems):
+        W_AbstractSeqIterObject.__init__(self, w_seq)
+        self.tupleitems = wrappeditems
 
-class W_ReverseSeqIterObject(W_Object):
-    from pypy.objspace.std.itertype import reverse_iter_typedef as typedef
+    def descr_next(self, space):
+        if self.tupleitems is None:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        index = self.index
+        try:
+            w_item = self.tupleitems[index]
+        except IndexError:
+            self.tupleitems = None
+            self.w_seq = None
+            raise OperationError(space.w_StopIteration, space.w_None)
+        self.index = index + 1
+        return w_item
 
-    def __init__(w_self, space, w_seq, index=-1):
-        w_self.w_seq = w_seq
-        w_self.w_len = space.len(w_seq)
-        w_self.index = space.int_w(w_self.w_len) + index
 
+class W_ReverseSeqIterObject(W_Root):
+    def __init__(self, space, w_seq, index=-1):
+        self.w_seq = w_seq
+        self.w_len = space.len(w_seq)
+        self.index = space.int_w(self.w_len) + index
 
-registerimplementation(W_SeqIterObject)
-registerimplementation(W_FastListIterObject)
-registerimplementation(W_FastTupleIterObject)
-registerimplementation(W_ReverseSeqIterObject)
+    def descr_reduce(self, space):
+        """
+        XXX to do: remove this __reduce__ method and do
+        a registration with copy_reg, instead.
+        """
+        from pypy.interpreter.mixedmodule import MixedModule
+        w_mod = space.getbuiltinmodule('_pickle_support')
+        mod = space.interp_w(MixedModule, w_mod)
+        new_inst = mod.get('reverseseqiter_new')
+        tup = [self.w_seq, space.wrap(self.index)]
+        return space.newtuple([new_inst, space.newtuple(tup)])
 
-def iter__SeqIter(space, w_seqiter):
-    return w_seqiter
+    def descr_length_hint(self, space):
+        if self.w_seq is None:
+            return space.wrap(0)
+        index = self.index + 1
+        w_length = space.len(self.w_seq)
+        # if length of sequence is less than index :exhaust iterator
+        if space.is_true(space.gt(space.wrap(self.index), w_length)):
+            w_len = space.wrap(0)
+            self.w_seq = None
+        else:
+            w_len = space.wrap(index)
+        if space.is_true(space.lt(w_len, space.wrap(0))):
+            w_len = space.wrap(0)
+        return w_len
 
-def next__SeqIter(space, w_seqiter):
-    if w_seqiter.w_seq is None:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    try:
-        w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index))
-    except OperationError, e:
-        w_seqiter.w_seq = None
-        if not e.match(space, space.w_IndexError):
-            raise
-        raise OperationError(space.w_StopIteration, space.w_None)
-    w_seqiter.index += 1
-    return w_item
+    def descr_iter(self, space):
+        return self
 
+    def descr_next(self, space):
+        if self.w_seq is None or self.index < 0:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        try:
+            w_item = space.getitem(self.w_seq, space.wrap(self.index))
+            self.index -= 1
+        except OperationError, e:
+            self.w_seq = None
+            if not e.match(space, space.w_IndexError):
+                raise
+            raise OperationError(space.w_StopIteration, space.w_None)
+        return w_item
 
-def iter__FastTupleIter(space, w_seqiter):
-    return w_seqiter
-
-def next__FastTupleIter(space, w_seqiter):
-    if w_seqiter.tupleitems is None:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    index = w_seqiter.index
-    try:
-        w_item = w_seqiter.tupleitems[index]
-    except IndexError:
-        w_seqiter.tupleitems = None
-        w_seqiter.w_seq = None
-        raise OperationError(space.w_StopIteration, space.w_None)
-    w_seqiter.index = index + 1
-    return w_item
-
-
-def iter__FastListIter(space, w_seqiter):
-    return w_seqiter
-
-def next__FastListIter(space, w_seqiter):
-    from pypy.objspace.std.listobject import W_ListObject
-    w_seq = w_seqiter.w_seq
-    if w_seq is None:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    assert isinstance(w_seq, W_ListObject)
-    index = w_seqiter.index
-    try:
-        w_item = w_seq.getitem(index)
-    except IndexError:
-        w_seqiter.w_seq = None
-        raise OperationError(space.w_StopIteration, space.w_None)
-    w_seqiter.index = index + 1
-    return w_item
-
-
-def iter__ReverseSeqIter(space, w_seqiter):
-    return w_seqiter
-
-def next__ReverseSeqIter(space, w_seqiter):
-    if w_seqiter.w_seq is None or w_seqiter.index < 0:
-        raise OperationError(space.w_StopIteration, space.w_None)
-    try:
-        w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index))
-        w_seqiter.index -= 1
-    except OperationError, e:
-        w_seqiter.w_seq = None
-        if not e.match(space, space.w_IndexError):
-            raise
-        raise OperationError(space.w_StopIteration, space.w_None)
-    return w_item
-
-register_all(vars())
+W_ReverseSeqIterObject.typedef = StdTypeDef(
+    "reversesequenceiterator",
+    __iter__ = interp2app(W_ReverseSeqIterObject.descr_iter),
+    next = interp2app(W_ReverseSeqIterObject.descr_next),
+    __reduce__ = interp2app(W_ReverseSeqIterObject.descr_reduce),
+    __length_hint__ = interp2app(W_ReverseSeqIterObject.descr_length_hint),
+)
+W_ReverseSeqIterObject.typedef.acceptable_as_base_class = False
diff --git a/pypy/objspace/std/itertype.py b/pypy/objspace/std/itertype.py
deleted file mode 100644
--- a/pypy/objspace/std/itertype.py
+++ /dev/null
@@ -1,85 +0,0 @@
-from pypy.interpreter import gateway
-from pypy.objspace.std.stdtypedef import StdTypeDef
-from pypy.interpreter.error import OperationError
-
-# ____________________________________________________________
-
-def descr_seqiter__reduce__(w_self, space):
-    """
-    XXX to do: remove this __reduce__ method and do
-    a registration with copyreg, instead.
-    """
-
-    # cpython does not support pickling iterators but stackless python do
-    #msg = 'Pickling for iterators dissabled as cpython does not support it'
-    #raise OperationError(space.w_TypeError, space.wrap(msg))
-
-    from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
-    assert isinstance(w_self, W_AbstractSeqIterObject)
-    from pypy.interpreter.mixedmodule import MixedModule
-    w_mod    = space.getbuiltinmodule('_pickle_support')
-    mod      = space.interp_w(MixedModule, w_mod)
-    new_inst = mod.get('seqiter_new')
-    tup      = [w_self.w_seq, space.wrap(w_self.index)]
-    return space.newtuple([new_inst, space.newtuple(tup)])
-
-
-def descr_seqiter__length_hint__(space, w_self):
-    from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
-    assert isinstance(w_self, W_AbstractSeqIterObject)
-    return w_self.getlength(space)
-
-# ____________________________________________________________
-
-def descr_reverseseqiter__reduce__(w_self, space):
-    """
-    XXX to do: remove this __reduce__ method and do
-    a registration with copyreg, instead.
-    """
-    from pypy.objspace.std.iterobject import W_ReverseSeqIterObject
-    assert isinstance(w_self, W_ReverseSeqIterObject)
-    from pypy.interpreter.mixedmodule import MixedModule
-    w_mod    = space.getbuiltinmodule('_pickle_support')
-    mod      = space.interp_w(MixedModule, w_mod)
-    new_inst = mod.get('reverseseqiter_new')
-    tup      = [w_self.w_seq, space.wrap(w_self.index)]
-    return space.newtuple([new_inst, space.newtuple(tup)])
-
-
-def descr_reverseseqiter__length_hint__(space, w_self):
-    from pypy.objspace.std.iterobject import W_ReverseSeqIterObject
-    assert isinstance(w_self, W_ReverseSeqIterObject)
-    if w_self.w_seq is None:
-        return space.wrap(0)
-    index = w_self.index + 1
-    w_length = space.len(w_self.w_seq)
-    # if length of sequence is less than index :exhaust iterator
-    if space.is_true(space.gt(space.wrap(w_self.index), w_length)):
-        w_len = space.wrap(0)
-        w_self.w_seq = None
-    else:
-        w_len = space.wrap(index)
-    if space.is_true(space.lt(w_len, space.wrap(0))):
-        w_len = space.wrap(0)
-    return w_len
-
-# ____________________________________________________________
-iter_typedef = StdTypeDef("sequenceiterator",
-    __doc__ = '''iter(collection) -> iterator
-iter(callable, sentinel) -> iterator
-
-Get an iterator from an object.  In the first form, the argument must
-supply its own iterator, or be a sequence.
-In the second form, the callable is called until it returns the sentinel.''',
-
-    __reduce__ = gateway.interp2app(descr_seqiter__reduce__),
-    __length_hint__ = gateway.interp2app(descr_seqiter__length_hint__),
-    )
-iter_typedef.acceptable_as_base_class = False
-
-reverse_iter_typedef = StdTypeDef("reversesequenceiterator",
-
-    __reduce__ = gateway.interp2app(descr_reverseseqiter__reduce__),
-    __length_hint__ = gateway.interp2app(descr_reverseseqiter__length_hint__),
-    )
-reverse_iter_typedef.acceptable_as_base_class = False
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -1,5 +1,14 @@
+"""The builtin list implementation
+
+Lists optimize their storage by holding certain primitive datatypes in
+unwrapped form. For more information:
+
+http://morepypy.blogspot.com/2011/10/more-compact-lists-with-list-strategies.html
+
+"""
+
 import operator
-from sys import maxint
+import sys
 
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, operationerrfmt
@@ -18,11 +27,11 @@
 from pypy.objspace.std.stringobject import W_StringObject
 from pypy.objspace.std.tupleobject import W_AbstractTupleObject
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
-from pypy.objspace.std.util import negate, get_positive_index
-from rpython.rlib import rerased, jit, debug
+from pypy.objspace.std.util import get_positive_index, negate
+from rpython.rlib import debug, jit, rerased
 from rpython.rlib.listsort import make_timsort_class
-from rpython.rlib.objectmodel import (instantiate, newlist_hint, specialize,
-    resizelist_hint)
+from rpython.rlib.objectmodel import (
+    instantiate, newlist_hint, resizelist_hint, specialize)
 from rpython.tool.sourcetools import func_with_new_name
 
 __all__ = ['W_ListObject', 'make_range_list', 'make_empty_list_with_size']
@@ -133,26 +142,26 @@
 
 
 class W_ListObject(W_Root):
-    def __init__(w_self, space, wrappeditems, sizehint=-1):
+
+    def __init__(self, space, wrappeditems, sizehint=-1):
         assert isinstance(wrappeditems, list)
-        w_self.space = space
+        self.space = space
         if space.config.objspace.std.withliststrategies:
-            w_self.strategy = get_strategy_from_list_objects(space,
-                                                             wrappeditems,
-                                                             sizehint)
+            self.strategy = get_strategy_from_list_objects(space, wrappeditems,
+                                                           sizehint)
         else:
-            w_self.strategy = space.fromcache(ObjectListStrategy)
-        w_self.init_from_list_w(wrappeditems)
+            self.strategy = space.fromcache(ObjectListStrategy)
+        self.init_from_list_w(wrappeditems)
 
     @staticmethod
     def from_storage_and_strategy(space, storage, strategy):
-        w_self = instantiate(W_ListObject)
-        w_self.space = space
-        w_self.strategy = strategy
-        w_self.lstorage = storage
+        self = instantiate(W_ListObject)
+        self.space = space
+        self.strategy = strategy
+        self.lstorage = storage
         if not space.config.objspace.std.withliststrategies:
-            w_self.switch_to_object_strategy()
-        return w_self
+            self.switch_to_object_strategy()
+        return self
 
     @staticmethod
     def newlist_str(space, list_s):
@@ -162,10 +171,10 @@
         storage = strategy.erase(list_s)
         return W_ListObject.from_storage_and_strategy(space, storage, strategy)
 
-    def __repr__(w_self):
+    def __repr__(self):
         """ representation for debugging purposes """
-        return "%s(%s, %s)" % (w_self.__class__.__name__, w_self.strategy,
-                               w_self.lstorage._x)
+        return "%s(%s, %s)" % (self.__class__.__name__, self.strategy,
+                               self.lstorage._x)
 
     def unwrap(w_list, space):
         # for tests only!
@@ -221,7 +230,7 @@
         strategy and storage according to the other W_List"""
         self.strategy.copy_into(self, other)
 
-    def find(self, w_item, start=0, end=maxint):
+    def find(self, w_item, start=0, end=sys.maxint):
         """Find w_item in list[start:end]. If not found, raise ValueError"""
         return self.strategy.find(self, w_item, start, end)
 
@@ -570,14 +579,14 @@
         'L.remove(value) -- remove first occurrence of value'
         # needs to be safe against eq_w() mutating the w_list behind our back
         try:
-            i = self.find(w_value, 0, maxint)
+            i = self.find(w_value, 0, sys.maxint)
         except ValueError:
             raise OperationError(space.w_ValueError,
                                  space.wrap("list.remove(x): x not in list"))
         if i < self.length():  # otherwise list was mutated
             self.pop(i)
 
-    @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(maxint))
+    @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(sys.maxint))
     def descr_index(self, space, w_value, w_start, w_stop):
         '''L.index(value, [start, [stop]]) -> integer -- return
         first index of value'''
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -43,7 +43,6 @@
             from pypy.objspace.std.longtype   import long_typedef
             from pypy.objspace.std.unicodetype import unicode_typedef
             from pypy.objspace.std.nonetype import none_typedef
-            from pypy.objspace.std.itertype import iter_typedef
         self.pythontypes = [value for key, value in result.__dict__.items()
                             if not key.startswith('_')]   # don't look
 
@@ -80,6 +79,7 @@
         self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef)
         self.pythontypes.append(setobject.W_SetObject.typedef)
         self.pythontypes.append(setobject.W_FrozensetObject.typedef)
+        self.pythontypes.append(iterobject.W_AbstractSeqIterObject.typedef)
 
         # the set of implementation types
         self.typeorder = {
@@ -94,10 +94,6 @@
             longobject.W_LongObject: [],
             noneobject.W_NoneObject: [],
             complexobject.W_ComplexObject: [],
-            iterobject.W_SeqIterObject: [],
-            iterobject.W_FastListIterObject: [],
-            iterobject.W_FastTupleIterObject: [],
-            iterobject.W_ReverseSeqIterObject: [],
             unicodeobject.W_UnicodeObject: [],
             pypy.interpreter.pycode.PyCode: [],
             pypy.interpreter.special.Ellipsis: [],
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -20,6 +20,7 @@
 from pypy.objspace.std.dictmultiobject import W_DictMultiObject
 from pypy.objspace.std.floatobject import W_FloatObject
 from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.objspace.std.longobject import W_LongObject, newlong
 from pypy.objspace.std.noneobject import W_NoneObject
@@ -698,6 +699,8 @@
         self._interplevel_classes[self.w_list] = W_ListObject
         self._interplevel_classes[self.w_set] = W_SetObject
         self._interplevel_classes[self.w_tuple] = W_AbstractTupleObject
+        self._interplevel_classes[self.w_sequenceiterator] = \
+                W_AbstractSeqIterObject
 
     @specialize.memo()
     def _get_interplevel_cls(self, w_type):
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -18,18 +18,18 @@
 class W_BaseSetObject(W_Root):
     typedef = None
 
-    def __init__(w_self, space, w_iterable=None):
+    def __init__(self, space, w_iterable=None):
         """Initialize the set by taking ownership of 'setdata'."""
-        w_self.space = space
-        set_strategy_and_setdata(space, w_self, w_iterable)
+        self.space = space
+        set_strategy_and_setdata(space, self, w_iterable)
 
-    def __repr__(w_self):
+    def __repr__(self):
         """representation for debugging purposes"""
-        reprlist = [repr(w_item) for w_item in w_self.getkeys()]
-        return "<%s(%s)>" % (w_self.__class__.__name__, ', '.join(reprlist))
+        reprlist = [repr(w_item) for w_item in self.getkeys()]
+        return "<%s(%s)>" % (self.__class__.__name__, ', '.join(reprlist))
 
-    def from_storage_and_strategy(w_self, storage, strategy):
-        obj = w_self._newobj(w_self.space, None)
+    def from_storage_and_strategy(self, storage, strategy):
+        obj = self._newobj(self.space, None)
         assert isinstance(obj, W_BaseSetObject)
         obj.strategy = strategy
         obj.sstorage = storage
@@ -492,7 +492,7 @@
 
 
 class W_SetObject(W_BaseSetObject):
-    def _newobj(w_self, space, w_iterable):
+    def _newobj(self, space, w_iterable):
         """Make a new set by taking ownership of 'w_iterable'."""
         return W_SetObject(space, w_iterable)
 
@@ -562,7 +562,7 @@
 class W_FrozensetObject(W_BaseSetObject):
     hash = 0
 
-    def _newobj(w_self, space, w_iterable):
+    def _newobj(self, space, w_iterable):
         """Make a new frozenset by taking ownership of 'w_iterable'.""" 
         return W_FrozensetObject(space, w_iterable)
 
@@ -1418,9 +1418,9 @@
 
 class W_SetIterObject(W_Root):
 
-    def __init__(w_self, space, iterimplementation):
-        w_self.space = space
-        w_self.iterimplementation = iterimplementation
+    def __init__(self, space, iterimplementation):
+        self.space = space
+        self.iterimplementation = iterimplementation
 
     def descr_length_hint(self, space):
         return space.wrap(self.iterimplementation.length())
diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py
--- a/pypy/objspace/std/specialisedtupleobject.py
+++ b/pypy/objspace/std/specialisedtupleobject.py
@@ -14,13 +14,13 @@
 def make_specialised_class(typetuple):
     assert type(typetuple) == tuple
 
-    nValues = len(typetuple)
-    iter_n = unrolling_iterable(range(nValues))
+    typelen = len(typetuple)
+    iter_n = unrolling_iterable(range(typelen))
 
     class cls(W_AbstractTupleObject):
         def __init__(self, space, *values_w):
             self.space = space
-            assert len(values_w) == nValues
+            assert len(values_w) == typelen
             for i in iter_n:
                 w_obj = values_w[i]
                 val_type = typetuple[i]
@@ -37,10 +37,10 @@
                 setattr(self, 'value%s' % i, unwrapped)
 
         def length(self):
-            return nValues
+            return typelen
 
         def tolist(self):
-            list_w = [None] * nValues
+            list_w = [None] * typelen
             for i in iter_n:
                 value = getattr(self, 'value%s' % i)
                 if typetuple[i] != object:
@@ -54,7 +54,7 @@
         def descr_hash(self, space):
             mult = 1000003
             x = 0x345678
-            z = nValues
+            z = typelen
             for i in iter_n:
                 value = getattr(self, 'value%s' % i)
                 if typetuple[i] == object:
@@ -76,7 +76,7 @@
             if not isinstance(w_other, W_AbstractTupleObject):
                 return space.w_NotImplemented
             if not isinstance(w_other, cls):
-                if nValues != w_other.length():
+                if typelen != w_other.length():
                     return space.w_False
                 for i in iter_n:
                     myval = getattr(self, 'value%s' % i)
@@ -102,7 +102,7 @@
 
         def getitem(self, space, index):
             if index < 0:
-                index += nValues
+                index += typelen
             for i in iter_n:
                 if index == i:
                     value = getattr(self, 'value%s' % i)
diff --git a/pypy/objspace/std/test/test_lengthhint.py b/pypy/objspace/std/test/test_lengthhint.py
--- a/pypy/objspace/std/test/test_lengthhint.py
+++ b/pypy/objspace/std/test/test_lengthhint.py
@@ -80,7 +80,7 @@
         self._test_length_hint(self.space.wrap('P' * self.SIZE))
 
     def test_tuple(self):
-        self._test_length_hint(self.space.newtuple(self.ITEMS))
+        self._test_length_hint(self.space.wrap(tuple(self.ITEMS)))
 
     def test_reversed(self):
         # test the generic reversed iterator (w_foo lacks __reversed__)
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -1,8 +1,11 @@
+"""The builtin tuple implementation"""
+
 import sys
-from pypy.interpreter import gateway
+
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import interp2app, interpindirect2app
+from pypy.interpreter.gateway import (
+    WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
 from pypy.objspace.std import slicetype
 from pypy.objspace.std.inttype import wrapint
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
@@ -174,8 +177,7 @@
                 count += 1
         return space.wrap(count)
 
-    @gateway.unwrap_spec(w_start=gateway.WrappedDefault(0),
-                         w_stop=gateway.WrappedDefault(sys.maxint))
+    @unwrap_spec(w_start=WrappedDefault(0), w_stop=WrappedDefault(sys.maxint))
     @jit.look_inside_iff(lambda self, _1, _2, _3, _4: _unroll_condition(self))
     def descr_index(self, space, w_obj, w_start, w_stop):
         """index(obj, [start, [stop]]) -> first index that obj appears in the
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -21,6 +21,7 @@
     OS_NONE                     = 0    # normal case, no oopspec
     OS_ARRAYCOPY                = 1    # "list.ll_arraycopy"
     OS_STR2UNICODE              = 2    # "str.str2unicode"
+    OS_SHRINK_ARRAY             = 3    # rgc.ll_shrink_array
     #
     OS_STR_CONCAT               = 22   # "stroruni.concat"
     OS_STR_SLICE                = 23   # "stroruni.slice"
@@ -82,8 +83,10 @@
     OS_JIT_FORCE_VIRTUAL        = 120
 
     # for debugging:
-    _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
-                        OS_RAW_MALLOC_VARSIZE_CHAR, OS_JIT_FORCE_VIRTUAL])
+    _OS_CANRAISE = set([
+        OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL, OS_RAW_MALLOC_VARSIZE_CHAR,
+        OS_JIT_FORCE_VIRTUAL, OS_SHRINK_ARRAY,
+    ])
 
     def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
                 write_descrs_fields, write_descrs_arrays,
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -398,6 +398,8 @@
             prepare = self._handle_libffi_call
         elif oopspec_name.startswith('math.sqrt'):
             prepare = self._handle_math_sqrt_call
+        elif oopspec_name.startswith('rgc.'):
+            prepare = self._handle_rgc_call
         else:
             prepare = self.prepare_builtin_call
         try:
@@ -1779,6 +1781,12 @@
         return self._handle_oopspec_call(op, args, EffectInfo.OS_MATH_SQRT,
                                          EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
 
+    def _handle_rgc_call(self, op, oopspec_name, args):
+        if oopspec_name == 'rgc.ll_shrink_array':
+            return self._handle_oopspec_call(op, args, EffectInfo.OS_SHRINK_ARRAY, EffectInfo.EF_CAN_RAISE)
+        else:
+            raise NotImplementedError(oopspec_name)
+
     def rewrite_op_jit_force_quasi_immutable(self, op):
         v_inst, c_fieldname = op.args
         descr1 = self.cpu.fielddescrof(v_inst.concretetype.TO,
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -136,6 +136,10 @@
         assert size <= MAX_CONST_LEN
         self._chars = [None] * size
 
+    def shrink(self, length):
+        assert length >= 0
+        del self._chars[length:]
+
     def setup_slice(self, longerlist, start, stop):
         assert 0 <= start <= stop <= len(longerlist)
         self._chars = longerlist[start:stop]
@@ -554,6 +558,9 @@
             if oopspecindex == EffectInfo.OS_STR2UNICODE:
                 if self.opt_call_str_STR2UNICODE(op):
                     return
+            if oopspecindex == EffectInfo.OS_SHRINK_ARRAY:
+                if self.opt_call_SHRINK_ARRAY(op):
+                    return
         self.emit_operation(op)
 
     optimize_CALL_PURE = optimize_CALL
@@ -721,6 +728,19 @@
             return True
         return False
 
+    def opt_call_SHRINK_ARRAY(self, op):
+        v1 = self.getvalue(op.getarg(1))
+        v2 = self.getvalue(op.getarg(2))
+        # If the index is constant, if the argument is virtual (we only support
+        # VStringPlainValue for now) we can optimize away the call.
+        if v2.is_constant() and v1.is_virtual() and isinstance(v1, VStringPlainValue):
+            length = v2.box.getint()
+            v1.shrink(length)
+            self.last_emitted_operation = REMOVED
+            self.make_equal_to(op.result, v1)
+            return True
+        return False
+
     def generate_modified_call(self, oopspecindex, args, result, mode):
         oopspecindex += mode.OS_offset
         cic = self.optimizer.metainterp_sd.callinfocollection
diff --git a/rpython/jit/metainterp/test/test_string.py b/rpython/jit/metainterp/test/test_string.py
--- a/rpython/jit/metainterp/test/test_string.py
+++ b/rpython/jit/metainterp/test/test_string.py
@@ -1,16 +1,14 @@
 import py
 
-from rpython.jit.codewriter.policy import StopAtXPolicy
-from rpython.jit.metainterp.test.support import LLJitMixin, OOJitMixin
+from rpython.jit.metainterp.test.support import LLJitMixin
 from rpython.rlib.debug import debug_print
-from rpython.rlib.jit import JitDriver, dont_look_inside, we_are_jitted,\
-     promote_string
-from rpython.rlib.rstring import StringBuilder
-from rpython.rtyper.ootypesystem import ootype
+from rpython.rlib.jit import (JitDriver, dont_look_inside, we_are_jitted,
+    promote_string)
+from rpython.rlib.rstring import StringBuilder, UnicodeBuilder
 
 
 class StringTests:
-    _str, _chr = str, chr
+    _str, _chr, _StringBuilder = str, chr, StringBuilder
 
     def test_eq_residual(self):
         _str = self._str
@@ -358,7 +356,7 @@
         s1 = self.meta_interp(f, [])
         s2 = f()
         for c1, c2 in zip(s1.chars, s2):
-            assert c1==c2
+            assert c1 == c2
 
     def test_virtual_strings_boxed(self):
         _str = self._str
@@ -516,6 +514,95 @@
         self.meta_interp(f, [0])
         self.check_resops(call=7)
 
+    def test_join_chars(self):
+        jitdriver = JitDriver(reds=['a', 'b', 'c', 'i'], greens=[])
+        _str = self._str
+
+        def f(a, b, c):
+            i = 0
+            while i < 10:
+                jitdriver.jit_merge_point(a=a, b=b, c=c, i=i)
+                x = []
+                if a:
+                    x.append(_str("a"))
+                if b:
+                    x.append(_str("b"))
+                if c:
+                    x.append(_str("c"))
+                i += len(_str("").join(x))
+            return i
+        res = self.meta_interp(f, [1, 1, 1])
+        assert res == f(True, True, True)
+        # The "".join should be unrolled, since the length of x is known since
+        # it is virtual, ensure there are no calls to ll_join_chars, or
+        # allocations.
+        self.check_resops({'jump': 1, 'guard_true': 5, 'int_lt': 2,
+                           'int_add': 2, 'int_is_true': 3})
+
+    def test_virtual_copystringcontent(self):
+        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
+        _str, _StringBuilder = self._str, self._StringBuilder
+
+        def main(n):
+            result = 0
+            while n >= 0:
+                jitdriver.jit_merge_point(n=n, result=result)
+                b = _StringBuilder(6)
+                b.append(_str("Hello!"))
+                result += ord(b.build()[0])
+                n -= 1
+            return result
+        res = self.meta_interp(main, [9])
+        assert res == main(9)
+
+    def test_virtual_copystringcontent2(self):
+        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
+        _str, _StringBuilder = self._str, self._StringBuilder
+
+        def main(n):
+            result = 0
+            while n >= 0:
+                jitdriver.jit_merge_point(n=n, result=result)
+                b = _StringBuilder(6)
+                b.append(_str("Hello!"))
+                result += ord((b.build() + _str("xyz"))[0])
+                n -= 1
+            return result
+        res = self.meta_interp(main, [9])
+        assert res == main(9)
+
+    def test_bytearray(self):
+        py.test.skip("implement it")
+
+        def f(i):
+            b = bytearray("abc")
+            b[1] = i
+            return b[1]
+
+        res = self.interp_operations(f, [13])
+        assert res == 13
+
+    def test_shrink_array(self):
+        jitdriver = JitDriver(reds=['result', 'n'], greens=[])
+        _str, _StringBuilder = self._str, self._StringBuilder
+
+        def f(n):
+            result = 0
+            while n >= 0:
+                jitdriver.jit_merge_point(n=n, result=result)
+                b = _StringBuilder(20)
+                b.append(_str("Testing!"))
+                result += len(b.build())
+                n -= 1
+            return result
+
+        res = self.meta_interp(f, [9])
+        assert res == f(9)
+        self.check_resops({
+            'jump': 1, 'guard_true': 2, 'int_ge': 2, 'int_add': 2, 'int_sub': 2
+        })
+
+
 #class TestOOtype(StringTests, OOJitMixin):
 #    CALL = "oosend"
 #    CALL_PURE = "oosend_pure"
@@ -524,8 +611,9 @@
     CALL = "call"
     CALL_PURE = "call_pure"
 
+
 class TestLLtypeUnicode(TestLLtype):
-    _str, _chr = unicode, unichr
+    _str, _chr, _StringBuilder = unicode, unichr, UnicodeBuilder
 
     def test_str2unicode(self):
         _str = self._str
@@ -569,64 +657,3 @@
         self.check_resops(call_pure=0, unicodesetitem=0, call=2,
                           newunicode=0, unicodegetitem=0,
                           copyunicodecontent=0)
-
-    def test_join_chars(self):
-        jitdriver = JitDriver(reds=['a', 'b', 'c', 'i'], greens=[])
-        def f(a, b, c):
-            i = 0
-            while i < 10:
-                jitdriver.jit_merge_point(a=a, b=b, c=c, i=i)
-                x = []
-                if a:
-                    x.append("a")
-                if b:
-                    x.append("b")
-                if c:
-                    x.append("c")
-                i += len("".join(x))
-            return i
-        res = self.meta_interp(f, [1, 1, 1])
-        assert res == f(True, True, True)
-        # The "".join should be unrolled, since the length of x is known since
-        # it is virtual, ensure there are no calls to ll_join_chars, or
-        # allocations.
-        self.check_resops({'jump': 1, 'guard_true': 5, 'int_lt': 2,
-                           'int_add': 2, 'int_is_true': 3})
-
-    def test_virtual_copystringcontent(self):
-        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
-        def main(n):
-            result = 0
-            while n >= 0:
-                jitdriver.jit_merge_point(n=n, result=result)
-                b = StringBuilder(6)
-                b.append("Hello!")
-                result += ord(b.build()[0])
-                n -= 1
-            return result
-        res = self.meta_interp(main, [9])
-        assert res == main(9)
-
-    def test_virtual_copystringcontent2(self):
-        jitdriver = JitDriver(reds=['n', 'result'], greens=[])
-        def main(n):
-            result = 0
-            while n >= 0:
-                jitdriver.jit_merge_point(n=n, result=result)
-                b = StringBuilder(6)
-                b.append("Hello!")
-                result += ord((b.build() + "xyz")[0])
-                n -= 1
-            return result
-        res = self.meta_interp(main, [9])
-        assert res == main(9)
-
-    def test_bytearray(self):
-        py.test.skip("implement it")
-        def f(i):
-            b = bytearray("abc")
-            b[1] = i
-            return b[1]
-
-        res = self.interp_operations(f, [13])
-        assert res == 13
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -183,6 +183,7 @@
             return True
     return False
 
+
 @jit.oopspec('list.ll_arraycopy(source, dest, source_start, dest_start, length)')
 @enforceargs(None, None, int, int, int)
 @specialize.ll()
@@ -229,6 +230,9 @@
     keepalive_until_here(source)
     keepalive_until_here(dest)
 
+
+ at jit.oopspec('rgc.ll_shrink_array(p, smallerlength)')
+ at specialize.ll()
 def ll_shrink_array(p, smallerlength):
     from rpython.rtyper.lltypesystem.lloperation import llop
     from rpython.rlib.objectmodel import keepalive_until_here
@@ -249,16 +253,15 @@
     ARRAY = getattr(TP, TP._arrayfld)
     offset = (llmemory.offsetof(TP, TP._arrayfld) +
               llmemory.itemoffsetof(ARRAY, 0))
-    source_addr = llmemory.cast_ptr_to_adr(p)    + offset
-    dest_addr   = llmemory.cast_ptr_to_adr(newp) + offset
+    source_addr = llmemory.cast_ptr_to_adr(p) + offset
+    dest_addr = llmemory.cast_ptr_to_adr(newp) + offset
     llmemory.raw_memcopy(source_addr, dest_addr,
                          llmemory.sizeof(ARRAY.OF) * smallerlength)
 
     keepalive_until_here(p)
     keepalive_until_here(newp)
     return newp
-ll_shrink_array._annspecialcase_ = 'specialize:ll'
-ll_shrink_array._jit_look_inside_ = False
+
 
 def no_collect(func):
     func._dont_inline_ = True
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -682,7 +682,7 @@
 
     @registering_if(os, 'getpid')
     def register_os_getpid(self):
-        return self.extdef_for_os_function_returning_int('getpid')
+        return self.extdef_for_os_function_returning_int('getpid', threadsafe=False)
 
     @registering_if(os, 'getgid')
     def register_os_getgid(self):


More information about the pypy-commit mailing list