Author: Manuel Jacob
Branch: remove-tuple-smm
Changeset: r64379:8d7578543296
Date: 2013-05-21 14:32 +0200
http://bitbucket.org/pypy/pypy/changeset/8d7578543296/
Log: Kill all tuple SMMs.
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,3 +1,4 @@
+import sys
from pypy.interpreter.error import OperationError
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
@@ -6,9 +7,12 @@
from rpython.rlib.rarithmetic import intmask
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
+from pypy.objspace.std.util import negate
+from pypy.objspace.std.stdtypedef import StdTypeDef
from rpython.rlib.debug import make_sure_not_resized
from rpython.rlib import jit
from rpython.tool.sourcetools import func_with_new_name
+from pypy.interpreter import gateway
UNROLL_CUTOFF = 10
@@ -24,8 +28,12 @@
raise NotImplementedError
+def tuple_unroll_condition(space, self, w_other):
+ return jit.loop_unrolling_heuristic(self, len(self.wrappeditems),
UNROLL_CUTOFF) or \
+ jit.loop_unrolling_heuristic(w_other, len(w_other.wrappeditems),
UNROLL_CUTOFF)
+
+
class W_TupleObject(W_AbstractTupleObject):
- from pypy.objspace.std.tupletype import tuple_typedef as typedef
_immutable_fields_ = ['wrappeditems[*]']
def __init__(w_self, wrappeditems):
@@ -47,132 +55,202 @@
def getitems_copy(self):
return self.wrappeditems[:] # returns a resizable list
+ @staticmethod
+ def descr_new(space, w_tupletype, w_sequence=None):
+ from pypy.objspace.std.tupleobject import W_TupleObject
+ if w_sequence is None:
+ tuple_w = []
+ elif (space.is_w(w_tupletype, space.w_tuple) and
+ space.is_w(space.type(w_sequence), space.w_tuple)):
+ return w_sequence
+ else:
+ tuple_w = space.fixedview(w_sequence)
+ w_obj = space.allocate_instance(W_TupleObject, w_tupletype)
+ W_TupleObject.__init__(w_obj, tuple_w)
+ return w_obj
+
+ def descr_repr(self, space):
+ items = self.wrappeditems
+ # XXX this is quite innefficient, still better than calling
+ # it via applevel
+ if len(items) == 1:
+ return space.wrap("(" + space.str_w(space.repr(items[0])) + ",)")
+ return space.wrap("(" +
+ (", ".join([space.str_w(space.repr(item)) for item in
items]))
+ + ")")
+
+ def descr_hash(self, space):
+ return space.wrap(hash_tuple(space, self.wrappeditems))
+
+ @jit.look_inside_iff(tuple_unroll_condition)
+ def descr_eq(self, space, w_other):
+ if not isinstance(w_other, W_TupleObject):
+ return space.w_NotImplemented
+ items1 = self.wrappeditems
+ items2 = w_other.wrappeditems
+ lgt1 = len(items1)
+ lgt2 = len(items2)
+ if lgt1 != lgt2:
+ return space.w_False
+ for i in range(lgt1):
+ item1 = items1[i]
+ item2 = items2[i]
+ if not space.eq_w(item1, item2):
+ return space.w_False
+ return space.w_True
+
+ descr_ne = negate(descr_eq)
+
+ def _make_tuple_comparison(name):
+ import operator
+ op = getattr(operator, name)
+
+ @jit.look_inside_iff(tuple_unroll_condition)
+ def compare_tuples(self, space, w_other):
+ if not isinstance(w_other, W_TupleObject):
+ return space.w_NotImplemented
+ items1 = self.wrappeditems
+ items2 = w_other.wrappeditems
+ ncmp = min(len(items1), len(items2))
+ # Search for the first index where items are different
+ for p in range(ncmp):
+ if not space.eq_w(items1[p], items2[p]):
+ return getattr(space, name)(items1[p], items2[p])
+ # No more items to compare -- compare sizes
+ return space.newbool(op(len(items1), len(items2)))
+ return func_with_new_name(compare_tuples, name + '__Tuple_Tuple')
+
+ descr_lt = _make_tuple_comparison('lt')
+ descr_le = _make_tuple_comparison('le')
+ descr_gt = _make_tuple_comparison('gt')
+ descr_ge = _make_tuple_comparison('ge')
+
+ def descr_len(self, space):
+ result = len(self.wrappeditems)
+ return wrapint(space, result)
+
+ def descr_iter(self, space):
+ from pypy.objspace.std import iterobject
+ return iterobject.W_FastTupleIterObject(self, self.wrappeditems)
+
+ @jit.look_inside_iff(lambda self, space, w_obj:
+ jit.loop_unrolling_heuristic(self, len(self.wrappeditems),
UNROLL_CUTOFF))
+ def descr_contains(self, space, w_obj):
+ for w_item in self.wrappeditems:
+ if space.eq_w(w_item, w_obj):
+ return space.w_True
+ return space.w_False
+
+ def descr_add(self, space, w_other):
+ if not isinstance(w_other, W_TupleObject):
+ return space.w_NotImplemented
+ items1 = self.wrappeditems
+ items2 = w_other.wrappeditems
+ return space.newtuple(items1 + items2)
+
+ def descr_mul(self, space, w_times):
+ try:
+ times = space.getindex_w(w_times, space.w_OverflowError)
+ except OperationError, e:
+ if e.match(space, space.w_TypeError):
+ raise FailedToImplement
+ raise
+ if times == 1 and space.type(self) == space.w_tuple:
+ return self
+ items = self.wrappeditems
+ return space.newtuple(items * times)
+
+ def descr_getitem(self, space, w_index):
+ if isinstance(w_index, W_SliceObject):
+ items = self.wrappeditems
+ length = len(items)
+ start, stop, step, slicelength = w_index.indices4(space, length)
+ assert slicelength >= 0
+ subitems = [None] * slicelength
+ for i in range(slicelength):
+ subitems[i] = items[start]
+ start += step
+ return space.newtuple(subitems)
+
+ # getindex_w should get a second argument space.w_IndexError,
+ # but that doesn't exist the first time this is called.
+ try:
+ w_IndexError = space.w_IndexError
+ except AttributeError:
+ w_IndexError = None
+ index = space.getindex_w(w_index, w_IndexError, "tuple index")
+ try:
+ return self.wrappeditems[index]
+ except IndexError:
+ raise OperationError(space.w_IndexError,
+ space.wrap("tuple index out of range"))
+
+ def descr_getslice(self, space, w_start, w_stop):
+ length = len(self.wrappeditems)
+ start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+ return space.newtuple(self.wrappeditems[start:stop])
+
+ def descr_getnewargs(self, space):
+ return space.newtuple([space.newtuple(self.wrappeditems)])
+
+ def descr_count(self, space, w_obj):
+ """count(obj) -> number of times obj appears in the tuple"""
+ count = 0
+ for w_item in self.wrappeditems:
+ if space.eq_w(w_item, w_obj):
+ count += 1
+ return space.wrap(count)
+
+ @gateway.unwrap_spec(w_start=gateway.WrappedDefault(0),
+ w_stop=gateway.WrappedDefault(sys.maxint))
+ def descr_index(self, space, w_obj, w_start, w_stop):
+ """index(obj, [start, [stop]]) -> first index that obj appears in the
+ tuple
+ """
+ length = len(self.wrappeditems)
+ start, stop = slicetype.unwrap_start_stop(space, length, w_start,
w_stop)
+ for i in range(start, min(stop, length)):
+ w_item = self.wrappeditems[i]
+ if space.eq_w(w_item, w_obj):
+ return space.wrap(i)
+ raise OperationError(space.w_ValueError,
+ space.wrap("tuple.index(x): x not in tuple"))
+
+W_TupleObject.typedef = StdTypeDef("tuple",
+ __doc__ = '''tuple() -> an empty tuple
+tuple(sequence) -> tuple initialized from sequence's items
+
+If the argument is a tuple, the return value is the same object.''',
+ __new__ = gateway.interp2app(W_TupleObject.descr_new),
+ __repr__ = gateway.interp2app(W_TupleObject.descr_repr),
+ __hash__ = gateway.interp2app(W_TupleObject.descr_hash),
+
+ __eq__ = gateway.interp2app(W_TupleObject.descr_eq),
+ __ne__ = gateway.interp2app(W_TupleObject.descr_ne),
+ __lt__ = gateway.interp2app(W_TupleObject.descr_lt),
+ __le__ = gateway.interp2app(W_TupleObject.descr_le),
+ __gt__ = gateway.interp2app(W_TupleObject.descr_gt),
+ __ge__ = gateway.interp2app(W_TupleObject.descr_ge),
+
+ __len__ = gateway.interp2app(W_TupleObject.descr_len),
+ __iter__ = gateway.interp2app(W_TupleObject.descr_iter),
+ __contains__ = gateway.interp2app(W_TupleObject.descr_contains),
+
+ __add__ = gateway.interp2app(W_TupleObject.descr_add),
+ __mul__ = gateway.interp2app(W_TupleObject.descr_mul),
+ __rmul__ = gateway.interp2app(W_TupleObject.descr_mul),
+
+ __getitem__ = gateway.interp2app(W_TupleObject.descr_getitem),
+ __getslice__ = gateway.interp2app(W_TupleObject.descr_getslice),
+
+ __getnewargs__ = gateway.interp2app(W_TupleObject.descr_getnewargs),
+ count = gateway.interp2app(W_TupleObject.descr_count),
+ index = gateway.interp2app(W_TupleObject.descr_index)
+)
+
registerimplementation(W_TupleObject)
-def len__Tuple(space, w_tuple):
- result = len(w_tuple.wrappeditems)
- return wrapint(space, result)
-
-def getitem__Tuple_ANY(space, w_tuple, w_index):
- # getindex_w should get a second argument space.w_IndexError,
- # but that doesn't exist the first time this is called.
- try:
- w_IndexError = space.w_IndexError
- except AttributeError:
- w_IndexError = None
- index = space.getindex_w(w_index, w_IndexError, "tuple index")
- try:
- return w_tuple.wrappeditems[index]
- except IndexError:
- raise OperationError(space.w_IndexError,
- space.wrap("tuple index out of range"))
-
-def getitem__Tuple_Slice(space, w_tuple, w_slice):
- items = w_tuple.wrappeditems
- length = len(items)
- start, stop, step, slicelength = w_slice.indices4(space, length)
- assert slicelength >= 0
- subitems = [None] * slicelength
- for i in range(slicelength):
- subitems[i] = items[start]
- start += step
- return space.newtuple(subitems)
-
-def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop):
- length = len(w_tuple.wrappeditems)
- start, stop = normalize_simple_slice(space, length, w_start, w_stop)
- return space.newtuple(w_tuple.wrappeditems[start:stop])
-
[email protected]_inside_iff(lambda space, w_tuple, w_obj:
- jit.loop_unrolling_heuristic(w_tuple, len(w_tuple.wrappeditems),
UNROLL_CUTOFF))
-def contains__Tuple_ANY(space, w_tuple, w_obj):
- for w_item in w_tuple.wrappeditems:
- if space.eq_w(w_item, w_obj):
- return space.w_True
- return space.w_False
-
-def iter__Tuple(space, w_tuple):
- from pypy.objspace.std import iterobject
- return iterobject.W_FastTupleIterObject(w_tuple, w_tuple.wrappeditems)
-
-def add__Tuple_Tuple(space, w_tuple1, w_tuple2):
- items1 = w_tuple1.wrappeditems
- items2 = w_tuple2.wrappeditems
- return space.newtuple(items1 + items2)
-
-def mul_tuple_times(space, w_tuple, w_times):
- try:
- times = space.getindex_w(w_times, space.w_OverflowError)
- except OperationError, e:
- if e.match(space, space.w_TypeError):
- raise FailedToImplement
- raise
- if times == 1 and space.type(w_tuple) == space.w_tuple:
- return w_tuple
- items = w_tuple.wrappeditems
- return space.newtuple(items * times)
-
-def mul__Tuple_ANY(space, w_tuple, w_times):
- return mul_tuple_times(space, w_tuple, w_times)
-
-def mul__ANY_Tuple(space, w_times, w_tuple):
- return mul_tuple_times(space, w_tuple, w_times)
-
-def tuple_unroll_condition(space, w_tuple1, w_tuple2):
- return jit.loop_unrolling_heuristic(w_tuple1, len(w_tuple1.wrappeditems),
UNROLL_CUTOFF) or \
- jit.loop_unrolling_heuristic(w_tuple2, len(w_tuple2.wrappeditems),
UNROLL_CUTOFF)
-
[email protected]_inside_iff(tuple_unroll_condition)
-def eq__Tuple_Tuple(space, w_tuple1, w_tuple2):
- items1 = w_tuple1.wrappeditems
- items2 = w_tuple2.wrappeditems
- lgt1 = len(items1)
- lgt2 = len(items2)
- if lgt1 != lgt2:
- return space.w_False
- for i in range(lgt1):
- item1 = items1[i]
- item2 = items2[i]
- if not space.eq_w(item1, item2):
- return space.w_False
- return space.w_True
-
-def _make_tuple_comparison(name):
- import operator
- op = getattr(operator, name)
-
- @jit.look_inside_iff(tuple_unroll_condition)
- def compare_tuples(space, w_tuple1, w_tuple2):
- items1 = w_tuple1.wrappeditems
- items2 = w_tuple2.wrappeditems
- ncmp = min(len(items1), len(items2))
- # Search for the first index where items are different
- for p in range(ncmp):
- if not space.eq_w(items1[p], items2[p]):
- return getattr(space, name)(items1[p], items2[p])
- # No more items to compare -- compare sizes
- return space.newbool(op(len(items1), len(items2)))
- return func_with_new_name(compare_tuples, name + '__Tuple_Tuple')
-
-lt__Tuple_Tuple = _make_tuple_comparison('lt')
-le__Tuple_Tuple = _make_tuple_comparison('le')
-gt__Tuple_Tuple = _make_tuple_comparison('gt')
-ge__Tuple_Tuple = _make_tuple_comparison('ge')
-
-def repr__Tuple(space, w_tuple):
- items = w_tuple.wrappeditems
- # XXX this is quite innefficient, still better than calling
- # it via applevel
- if len(items) == 1:
- return space.wrap("(" + space.str_w(space.repr(items[0])) + ",)")
- return space.wrap("(" +
- (", ".join([space.str_w(space.repr(item)) for item in items]))
- + ")")
-
-def hash__Tuple(space, w_tuple):
- return space.wrap(hash_tuple(space, w_tuple.wrappeditems))
-
@jit.look_inside_iff(lambda space, wrappeditems:
jit.loop_unrolling_heuristic(wrappeditems, len(wrappeditems),
UNROLL_CUTOFF))
def hash_tuple(space, wrappeditems):
@@ -188,25 +266,5 @@
x += 97531
return intmask(x)
-def getnewargs__Tuple(space, w_tuple):
- return space.newtuple([space.newtuple(w_tuple.wrappeditems)])
-
-def tuple_count__Tuple_ANY(space, w_tuple, w_obj):
- count = 0
- for w_item in w_tuple.wrappeditems:
- if space.eq_w(w_item, w_obj):
- count += 1
- return space.wrap(count)
-
-def tuple_index__Tuple_ANY_ANY_ANY(space, w_tuple, w_obj, w_start, w_stop):
- length = len(w_tuple.wrappeditems)
- start, stop = slicetype.unwrap_start_stop(space, length, w_start, w_stop)
- for i in range(start, min(stop, length)):
- w_item = w_tuple.wrappeditems[i]
- if space.eq_w(w_item, w_obj):
- return space.wrap(i)
- raise OperationError(space.w_ValueError,
- space.wrap("tuple.index(x): x not in tuple"))
-
from pypy.objspace.std import tupletype
-register_all(vars(), tupletype)
+tupletype.tuple_typedef = W_TupleObject.typedef
diff --git a/pypy/objspace/std/tupletype.py b/pypy/objspace/std/tupletype.py
--- a/pypy/objspace/std/tupletype.py
+++ b/pypy/objspace/std/tupletype.py
@@ -1,7 +1,4 @@
-import sys
-from pypy.interpreter import gateway
from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
def wraptuple(space, list_w):
from pypy.objspace.std.tupleobject import W_TupleObject
@@ -37,34 +34,3 @@
return W_SmallTupleObject8(list_w)
return W_TupleObject(list_w)
-tuple_count = SMM("count", 2,
- doc="count(obj) -> number of times obj appears in the tuple")
-
-tuple_index = SMM("index", 4, defaults=(0, sys.maxint),
- doc="index(obj, [start, [stop]]) -> first index that obj "
- "appears in the tuple")
-
-
-def descr__new__(space, w_tupletype, w_sequence=None):
- from pypy.objspace.std.tupleobject import W_TupleObject
- if w_sequence is None:
- tuple_w = []
- elif (space.is_w(w_tupletype, space.w_tuple) and
- space.is_w(space.type(w_sequence), space.w_tuple)):
- return w_sequence
- else:
- tuple_w = space.fixedview(w_sequence)
- w_obj = space.allocate_instance(W_TupleObject, w_tupletype)
- W_TupleObject.__init__(w_obj, tuple_w)
- return w_obj
-
-# ____________________________________________________________
-
-tuple_typedef = StdTypeDef("tuple",
- __doc__ = '''tuple() -> an empty tuple
-tuple(sequence) -> tuple initialized from sequence's items
-
-If the argument is a tuple, the return value is the same object.''',
- __new__ = gateway.interp2app(descr__new__),
- )
-tuple_typedef.registermethods(globals())
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit