[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