[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