[pypy-commit] pypy dynamic-specialized-tuple: finish tuple API and start on using new untyped storage stuff
alex_gaynor
noreply at buildbot.pypy.org
Tue Mar 13 09:07:15 CET 2012
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: dynamic-specialized-tuple
Changeset: r53425:cef45a443ffd
Date: 2012-03-12 23:42 -0700
http://bitbucket.org/pypy/pypy/changeset/cef45a443ffd/
Log: finish tuple API and start on using new untyped storage stuff
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
@@ -5,10 +5,12 @@
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.rlib.rarithmetic import intmask
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
+from pypy.objspace.std.slicetype import unwrap_start_stop
from pypy.objspace.std import slicetype
from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
+
class W_AbstractTupleObject(W_Object):
__slots__ = ()
@@ -102,6 +104,9 @@
def getitem__Tuple_Slice(space, w_tuple, w_slice):
length = w_tuple.length()
start, stop, step, slicelength = w_slice.indices4(space, length)
+ return getslice(space, w_tuple, slicelength, start, stop, step)
+
+def getslice(space, w_tuple, slicelength, start, stop, step):
assert slicelength >= 0
subitems = [None] * slicelength
for i in range(slicelength):
@@ -109,6 +114,10 @@
start += step
return space.newtuple(subitems)
+def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop):
+ start, stop = normalize_simple_slice(space, w_tuple.length(), w_start, w_stop)
+ return getslice(space, w_tuple, stop - start, start, stop, 1)
+
def contains__Tuple_ANY(space, w_tuple, w_obj):
for i in xrange(w_tuple.length()):
if space.eq_w(w_tuple.getitem(space, i), w_obj):
@@ -143,13 +152,36 @@
return space.w_True
def lt__Tuple_Tuple(space, w_tuple1, w_tuple2):
- pass
+ ncmp = min(w_tuple1.length(), w_tuple2.length())
+ # Search for the first index where items are different
+ for i in range(ncmp):
+ w_obj1 = w_tuple1.getitem(space, i)
+ w_obj2 = w_tuple2.getitem(space, i)
+ if not space.eq_w(w_obj1, w_obj2):
+ return space.lt(w_obj1, w_obj2)
+ # No more items to compare -- compare sizes
+ return space.newbool(w_tuple1.length() < w_tuple2.length())
def gt__Tuple_Tuple(space, w_tuple1, w_tuple2):
- pass
+ ncmp = min(w_tuple1.length(), w_tuple2.length())
+ # Search for the first index where items are different
+ for i in range(ncmp):
+ w_obj1 = w_tuple1.getitem(space, i)
+ w_obj2 = w_tuple2.getitem(space, i)
+ if not space.eq_w(w_obj1, w_obj2):
+ return space.gt(w_obj1, w_obj2)
+ # No more items to compare -- compare sizes
+ return space.newbool(w_tuple1.length() > w_tuple2.length())
def repr__Tuple(space, w_tuple):
- pass
+ repr = "("
+ if w_tuple.length() == 1:
+ repr += space.str_w(space.repr(w_tuple.getitem(space, 0)))
+ repr += ",)"
+ return space.wrap(repr)
+ repr += ", ".join([space.str_w(space.repr(w_tuple.getitem(space, i))) for i in xrange(w_tuple.length())])
+ repr += ")"
+ return space.wrap(repr)
def hash_items(space, w_tuple):
# this is the CPython 2.4 algorithm (changed from 2.3)
@@ -171,13 +203,25 @@
pass
def getnewargs__Tuple(space, w_tuple):
- pass
+ return space.newtuple([space.newtuple(w_tuple.tolist(space))])
def tuple_count__Tuple_ANY(space, w_tuple, w_obj):
- pass
+ count = 0
+ for i in xrange(w_tuple.length()):
+ count += space.eq_w(w_tuple.getitem(space, i), w_obj)
+ return space.wrap(count)
def tuple_index__Tuple_ANY_ANY_ANY(space, w_tuple, w_obj, w_start, w_stop):
- pass
+ length = w_tuple.length()
+ start, stop = unwrap_start_stop(space, length, w_start, w_stop)
+
+ for i in xrange(start, min(stop, length)):
+ w_value = w_tuple.getitem(space, i)
+ if space.eq_w(w_value, 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)
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,4 +1,5 @@
import sys
+from pypy.rlib.rerased_raw import UntypedStorage, INT, INSTANCE
from pypy.interpreter import gateway
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
@@ -13,22 +14,31 @@
make_tuple(space, w_tuple, list_w)
return w_tuple
+def get_char_from_obj(space, w_obj):
+ if space.is_w(space.type(w_obj), space.w_int):
+ return INT
+ else:
+ return INSTANCE
+
+def store_obj(space, storage, idx, w_obj):
+ if space.is_w(space.type(w_obj), space.w_int):
+ w_tuple.storage.setint(idx, space.int_w(w_obj))
+ else:
+ w_tuple.storage.setinstance(idx, w_obj)
+
def make_tuple(space, w_tuple, list_w):
from pypy.objspace.std.tupleobject import W_TupleObject, get_shape_cache
- cache = get_shape_cache(space)
- if len(list_w) > MAXIMUM_SPECIALIZED_SIZE:
- W_TupleObject.__init__(w_tuple, cache.large_shape, list_w)
- else:
- types = []
- items = []
- for w_item in list_w:
- types.append(cache.object_shapetype)
- items.append(w_item)
+ shape_chars = ["\x00"] * len(list_w)
+ for i, w_item in enumerate(list_w):
+ shape_chars[i] = get_char_from_obj(space, w_item)
- shape = cache.find_shape(types)
- W_TupleObject.__init__(w_tuple, shape, items)
- return W_TupleObject(shape, items)
+ shape = space.str_w(space.new_interned_str("".join(shape_chars)))
+ storage = UntypedStorage(shape)
+ for i, w_item in enumerate(list_w):
+ store_obj(space, storage, i, w_item)
+ W_TupleObject.__init__(w_tuple, storage)
+ return w_tuple
tuple_count = SMM("count", 2,
doc="count(obj) -> number of times obj appears in the tuple")
More information about the pypy-commit
mailing list