Commits

David Schneider  committed d5e5cd5 Merge

merge default

  • Participants
  • Parent commits 8d3a772, 09e1146
  • Branches arm-backend-2

Comments (0)

Files changed (42)

File lib_pypy/_ctypes/__init__.py

     from _rawffi import FormatError
     from _rawffi import check_HRESULT as _check_HRESULT
 
+    try: from __pypy__ import builtinify
+    except ImportError: builtinify = lambda f: f
+
+    @builtinify
     def CopyComPointer(src, dst):
         from ctypes import c_void_p, cast
         if src:
         dst[0] = cast(src, c_void_p).value
         return 0
 
+    del builtinify
+
     LoadLibrary = dlopen
 
 from _rawffi import FUNCFLAG_STDCALL, FUNCFLAG_CDECL, FUNCFLAG_PYTHONAPI

File lib_pypy/_ctypes/basics.py

 import _ffi
 import sys
 
+try: from __pypy__ import builtinify
+except ImportError: builtinify = lambda f: f
+
 keepalive_key = str # XXX fix this when provided with test
 
 def ensure_objects(where):
     _b_base_ = property(_get_b_base)
     _b_needsfree_ = False
 
+@builtinify
 def sizeof(tp):
     if not isinstance(tp, _CDataMeta):
         if isinstance(tp, _CData):
                 type(tp).__name__,))
     return tp._sizeofinstances()
 
+@builtinify
 def alignment(tp):
     if not isinstance(tp, _CDataMeta):
         if isinstance(tp, _CData):
                 type(tp).__name__,))
     return tp._alignmentofinstances()
 
+@builtinify
 def byref(cdata):
     # "pointer" is imported at the end of this module to avoid circular
     # imports
     instance._buffer = self._ffiarray.fromaddress(address, lgt)
     return instance
 
+@builtinify
 def addressof(tp):
     return tp._buffer.buffer
 

File lib_pypy/_ctypes/dll.py

 import _rawffi
 
+try: from __pypy__ import builtinify
+except ImportError: builtinify = lambda f: f
+
+@builtinify
 def dlopen(name, mode):
     # XXX mode is ignored
     return _rawffi.CDLL(name)

File lib_pypy/_ctypes/function.py

 import traceback
 import warnings
 
+try: from __pypy__ import builtinify
+except ImportError: builtinify = lambda f: f
 
 # XXX this file needs huge refactoring I fear
 
     from _ctypes import COMError
     return COMError(errcode, None, None)
 
+@builtinify
 def call_function(func, args):
     "Only for debugging so far: So that we can call CFunction instances"
     funcptr = CFuncPtr(func)

File lib_pypy/_ctypes/pointer.py

 from _ctypes.array import Array, array_get_slice_params, array_slice_getitem,\
      array_slice_setitem
 
+try: from __pypy__ import builtinify
+except ImportError: builtinify = lambda f: f
+
 # This cache maps types to pointers to them.
 _pointer_type_cache = {}
 
 
     return result
 
+@builtinify
 def POINTER(cls):
     try:
         return _pointer_type_cache[cls]
         _pointer_type_cache[cls] = klass
     return klass
 
+@builtinify
 def pointer(inst):
     return POINTER(type(inst))(inst)
 

File pypy/conftest.py

 #
 option = None
 
+
+def braindead_deindent(self):
+    """monkeypatch that wont end up doing stupid in the python tokenizer"""
+    text = '\n'.join(self.lines)
+    short = py.std.textwrap.dedent(text)
+    newsource = py.code.Source()
+    newsource.lines[:] = short.splitlines()
+    return newsource
+
+py.code.Source.deindent = braindead_deindent
+
 def pytest_report_header():
     return "pytest-%s from %s" %(pytest.__version__, pytest.__file__)
 

File pypy/doc/whatsnew-head.rst

 .. branch: improve-rbigint
 Introduce __int128 on systems where it's supported and improve the speed of
 rlib/rbigint.py greatly.
+.. branch: translation-cleanup
+Start to clean up a bit the flow object space.
+.. branch: ffi-backend
+Support CFFI.  http://morepypy.blogspot.ch/2012/08/cffi-release-03.html
+.. branch: speedup-unpackiterable
+
 
 .. "uninteresting" branches that we should just ignore for the whatsnew:
 .. branch: slightly-shorter-c

File pypy/doc/windows.rst

 the name of a valid gcc-derivative compiler, i.e. x86_64-w64-mingw32-gcc for the 64 bit
 compiler creating a 64 bit target.
 
+You probably want to set the CPATH, LIBRARY_PATH, and PATH environment variable to
+the header files, lib or dlls, and dlls respectively of the locally installed packages 
+if they are not in the mingw directory heirarchy. 
+
 libffi for the mingw compiler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Since hacking on Pypy means running tests, you will need a way to specify
 the mingw compiler when hacking (as opposed to translating). As of
 March 2012, --cc is not a valid option for pytest.py. However if you set an
-environment variable CC it will allow you to choose a compiler.
+environment variable CC to the compliter exe, testing will use it.
 
 .. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
 .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds

File pypy/interpreter/argument.py

         if num_kwds:
             # kwds_mapping maps target indexes in the scope (minus input_argcount)
             # to positions in the keywords_w list
-            cnt = (co_argcount - input_argcount)
-            if cnt < 0:
-                cnt = 0
-            kwds_mapping = [0] * cnt
+            kwds_mapping = [0] * (co_argcount - input_argcount)
             # initialize manually, for the JIT :-(
             for i in range(len(kwds_mapping)):
                 kwds_mapping[i] = -1

File pypy/interpreter/baseobjspace.py

 
 UINT_MAX_32_BITS = r_uint(4294967295)
 
+unpackiterable_driver = jit.JitDriver(name = 'unpackiterable',
+                                      greens = ['tp'],
+                                      reds = ['items', 'w_iterator'])
 
 class W_Root(object):
     """This is the abstract root class of all wrapped objects that live
     def __spacebind__(self, space):
         return self
 
+class W_InterpIterable(W_Root):
+    def __init__(self, space, w_iterable):
+        self.w_iter = space.iter(w_iterable)
+        self.space = space
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        space = self.space
+        try:
+            return space.next(self.w_iter)
+        except OperationError, e:
+            if not e.match(space, space.w_StopIteration):
+                raise
+            raise StopIteration
+
 class InternalSpaceCache(Cache):
     """A generic cache for an object space.  Arbitrary information can
     be attached to the space by defining a function or class 'f' which
                                                       expected_length)
             return lst_w[:]     # make the resulting list resizable
 
+    def iteriterable(self, w_iterable):
+        return W_InterpIterable(self, w_iterable)
+
     @jit.dont_look_inside
     def _unpackiterable_unknown_length(self, w_iterator, w_iterable):
         # Unpack a variable-size list of unknown length.
             except MemoryError:
                 items = [] # it might have lied
         #
+        tp = self.type(w_iterator)
         while True:
+            unpackiterable_driver.jit_merge_point(tp=tp,
+                                                  w_iterator=w_iterator,
+                                                  items=items)
             try:
                 w_item = self.next(w_iterator)
             except OperationError, e:

File pypy/jit/backend/test/calling_convention_test.py

         F = lltype.Float
         S = lltype.SingleFloat
         I = lltype.Signed
-        floats = [random.random() - 0.5 for i in range(8)]
-        singlefloats = [r_singlefloat(random.random() - 0.5) for i in range(8)]
-        ints = [random.randrange(-99, 99) for i in range(8)]
+        floats = [random.random() - 0.5 for i in range(20)]
+        singlefloats = [r_singlefloat(random.random() - 0.5) for i in range(20)]
+        ints = [random.randrange(-99, 99) for i in range(20)]
         for repeat in range(100):
             args = []
             argvalues = []
             local_floats = list(floats)
             local_singlefloats = list(singlefloats)
             local_ints = list(ints)
-            for i in range(8):
-                case = random.randrange(0, 3)
-                if case == 0:
+            for i in range(random.randrange(4, 20)):
+                case = random.randrange(0, 6)
+                if case & 1: boxme = BoxInt
+                else:        boxme = ConstInt
+                if case < 2:
                     args.append(F)
-                    arg = local_floats.pop()
-                    argslist.append(boxfloat(arg))
-                elif case == 1:
+                    arg = arg1 = local_floats.pop()
+                    if case & 1: boxme = boxfloat
+                    else:        boxme = constfloat
+                elif case < 4:
                     args.append(S)
                     arg = local_singlefloats.pop()
-                    argslist.append(BoxInt(longlong.singlefloat2int(arg)))
+                    arg1 = longlong.singlefloat2int(arg)
                 else:
                     args.append(I)
-                    arg = local_ints.pop()
-                    argslist.append(BoxInt(arg))
+                    arg = arg1 = local_ints.pop()
+                argslist.append(boxme(arg1))
                 argvalues.append(arg)
             FUNC = self.FuncType(args, F)
             FPTR = self.Ptr(FUNC)

File pypy/jit/backend/x86/assembler.py

                     xmm_dst_locs.append(unused_xmm.pop())
                 else:
                     pass_on_stack.append(loc)
-            elif (argtypes is not None and argtypes[i-start] == 'S' and
-                  len(unused_xmm) > 0):
+            elif argtypes is not None and argtypes[i-start] == 'S':
                 # Singlefloat argument
-                if singlefloats is None: singlefloats = []
-                singlefloats.append((loc, unused_xmm.pop()))
+                if len(unused_xmm) > 0:
+                    if singlefloats is None: singlefloats = []
+                    singlefloats.append((loc, unused_xmm.pop()))
+                else:
+                    pass_on_stack.append(loc)
             else:
                 if len(unused_gpr) > 0:
                     src_locs.append(loc)
         # Load the singlefloat arguments from main regs or stack to xmm regs
         if singlefloats is not None:
             for src, dst in singlefloats:
+                if isinstance(src, ImmedLoc):
+                    self.mc.MOV(X86_64_SCRATCH_REG, src)
+                    src = X86_64_SCRATCH_REG
                 self.mc.MOVD(dst, src)
         # Finally remap the arguments in the main regs
         # If x is a register and is in dst_locs, then oups, it needs to

File pypy/jit/metainterp/warmspot.py

 from pypy.rlib.debug import fatalerror
 from pypy.rlib.rstackovf import StackOverflow
 from pypy.translator.simplify import get_functype
+from pypy.translator.backendopt import removenoops
 from pypy.translator.unsimplify import call_final_function
 
 from pypy.jit.metainterp import history, pyjitpl, gc, memmgr
         graph = copygraph(graph)
         [jmpp] = find_jit_merge_points([graph])
         graph.startblock = support.split_before_jit_merge_point(*jmpp)
+        # XXX this is incredibly obscure, but this is sometiems necessary
+        #     so we don't explode in checkgraph. for reasons unknown this
+        #     is not contanied within simplify_graph
+        removenoops.remove_same_as(graph)
         # a crash in the following checkgraph() means that you forgot
         # to list some variable in greens=[] or reds=[] in JitDriver,
         # or that a jit_merge_point() takes a constant as an argument.

File pypy/module/_cffi_backend/ctypefunc.py

 W_CTypePrimitiveFloat._get_ffi_type         = _primfloat_ffi_type
 W_CTypePrimitiveLongDouble._get_ffi_type    = _primlongdouble_ffi_type
 W_CTypePtrBase._get_ffi_type                = _ptr_ffi_type
-W_CTypeVoid._get_ffi_type                   = _void_ffi_type
+#W_CTypeVoid._get_ffi_type                  = _void_ffi_type -- special-cased
 # ----------
 
 
             return result
 
 
-    def fb_fill_type(self, ctype):
+    def fb_fill_type(self, ctype, is_result_type):
+        if is_result_type and isinstance(ctype, W_CTypeVoid):
+            return clibffi.ffi_type_void
         return ctype._get_ffi_type(self)
 
     def fb_struct_ffi_type(self, ctype):
         # But on 64-bit UNIX, these two structs are passed by value
         # differently: e.g. on x86-64, "b" ends up in register "rsi" in
         # the first case and "rdi" in the second case.
+        #
+        # Another reason for 'custom_field_pos' would be anonymous
+        # nested structures: we lost the information about having it
+        # here, so better safe (and forbid it) than sorry (and maybe
+        # crash).
         space = self.space
         if ctype.custom_field_pos:
             raise OperationError(space.w_TypeError,
                 raise OperationError(space.w_NotImplementedError,
                     space.wrap("cannot pass as argument a struct "
                                "with bit fields"))
-            ffi_subtype = self.fb_fill_type(cf.ctype)
+            ffi_subtype = self.fb_fill_type(cf.ctype, False)
             if elements:
                 elements[i] = ffi_subtype
 
         self.atypes = rffi.cast(FFI_TYPE_PP, atypes)
 
         # next comes the result type data
-        self.rtype = self.fb_fill_type(self.fresult)
+        self.rtype = self.fb_fill_type(self.fresult, True)
 
         # next comes each argument's type data
         for i, farg in enumerate(self.fargs):
-            atype = self.fb_fill_type(farg)
+            atype = self.fb_fill_type(farg, False)
             if self.atypes:
                 self.atypes[i] = atype
 

File pypy/module/_cffi_backend/ctypestruct.py

     def is_bitfield(self):
         return self.bitshift >= 0
 
+    def make_shifted(self, offset):
+        return W_CField(self.ctype, offset + self.offset,
+                        self.bitshift, self.bitsize)
+
     def read(self, cdata):
         cdata = rffi.ptradd(cdata, self.offset)
         if self.bitshift == self.BS_REGULAR:

File pypy/module/_cffi_backend/newtype.py

             if not is_union:
                 prev_bit_position += fbitsize
         #
-        fld = ctypestruct.W_CField(ftype, offset, bitshift, fbitsize)
-        fields_list.append(fld)
-        fields_dict[fname] = fld
+        if (len(fname) == 0 and
+            isinstance(ftype, ctypestruct.W_CTypeStructOrUnion)):
+            # a nested anonymous struct or union
+            srcfield2names = {}
+            for name, srcfld in ftype.fields_dict.items():
+                srcfield2names[srcfld] = name
+            for srcfld in ftype.fields_list:
+                fld = srcfld.make_shifted(offset)
+                fields_list.append(fld)
+                try:
+                    fields_dict[srcfield2names[srcfld]] = fld
+                except KeyError:
+                    pass
+            # always forbid such structures from being passed by value
+            custom_field_pos = True
+        else:
+            # a regular field
+            fld = ctypestruct.W_CField(ftype, offset, bitshift, fbitsize)
+            fields_list.append(fld)
+            fields_dict[fname] = fld
         #
         if maxsize < ftype.size:
             maxsize = ftype.size
     if is_union:
         assert offset == 0
         offset = maxsize
-    else:
-        if offset == 0:
-            offset = 1
-        offset = (offset + alignment - 1) & ~(alignment-1)
+    offset = (offset + alignment - 1) & ~(alignment-1)
 
+    # Like C, if the size of this structure would be zero, we compute it
+    # as 1 instead.  But for ctypes support, we allow the manually-
+    # specified totalsize to be zero in this case.
     if totalsize < 0:
-        totalsize = offset
+        totalsize = offset or 1
     elif totalsize < offset:
         raise operationerrfmt(space.w_TypeError,
                      "%s cannot be of size %d: there are fields at least "

File pypy/module/_cffi_backend/test/_backend_test_c.py

     readbuf = str
     bufchar = lambda x: x
     bytechr = chr
+    class U(object):
+        def __add__(self, other):
+            return eval('u'+repr(other).replace(r'\\u', r'\u')
+                                       .replace(r'\\U', r'\U'))
+    u = U()
 else:
     type_or_class = "class"
     long = int
     readbuf = lambda buf: buf.tobytes()
     bufchar = ord
     bytechr = lambda n: bytes([n])
+    u = ""
 
 def size_of_int():
     BInt = new_primitive_type("int")
         py.test.raises(TypeError, cast, p, None)
         assert long(cast(p, min - 1)) == max
         assert int(cast(p, b'\x08')) == 8
-        assert int(cast(p, u'\x08')) == 8
+        assert int(cast(p, u+'\x08')) == 8
     for name in ['char', 'short', 'int', 'long', 'long long']:
         p = new_primitive_type('unsigned ' + name)
         size = sizeof(p)
         assert int(cast(p, max + 1)) == 0
         assert long(cast(p, -1)) == max
         assert int(cast(p, b'\xFE')) == 254
-        assert int(cast(p, u'\xFE')) == 254
+        assert int(cast(p, u+'\xFE')) == 254
 
 def test_no_float_on_int_types():
     p = new_primitive_type('long')
         assert cast(p, -1.1) != cast(p, -1.1)
         assert repr(float(cast(p, -0.0))) == '-0.0'
         assert float(cast(p, b'\x09')) == 9.0
-        assert float(cast(p, u'\x09')) == 9.0
+        assert float(cast(p, u+'\x09')) == 9.0
         assert float(cast(p, True)) == 1.0
         py.test.raises(TypeError, cast, p, None)
 
     assert p[0] == b'A'
     py.test.raises(TypeError, newp, BPtr, 65)
     py.test.raises(TypeError, newp, BPtr, b"foo")
-    py.test.raises(TypeError, newp, BPtr, u"foo")
+    py.test.raises(TypeError, newp, BPtr, u+"foo")
     c = cast(BChar, b'A')
     assert str(c) == repr(c)
     assert int(c) == ord(b'A')
     py.test.raises(TypeError, cast, BChar, b'foo')
-    py.test.raises(TypeError, cast, BChar, u'foo')
+    py.test.raises(TypeError, cast, BChar, u+'foo')
 
 def test_reading_pointer_to_pointer():
     BVoidP = new_pointer_type(new_void_type())
     BFunc = new_function_type((BInt, BInt), BVoid, False)
     assert repr(BFunc) == "<ctype 'void(*)(int, int)'>"
 
+def test_function_void_arg():
+    BVoid = new_void_type()
+    BInt = new_primitive_type("int")
+    py.test.raises(TypeError, new_function_type, (BVoid,), BInt, False)
+
 def test_call_function_0():
     BSignedChar = new_primitive_type("signed char")
     BFunc0 = new_function_type((BSignedChar, BSignedChar), BSignedChar, False)
     #
     py.test.raises(TypeError, f, 123456)
     py.test.raises(TypeError, f, "foo")
-    py.test.raises(TypeError, f, u"bar")
+    py.test.raises(TypeError, f, u+"bar")
 
 def test_call_function_7():
     BChar = new_primitive_type("char")
     BStructPtr = new_pointer_type(BStruct)
     complete_struct_or_union(BStruct, [('a1', BChar, -1),
                                        ('a2', BShort, -1)])
-    BFunc18 = new_function_type((BStructPtr,), BShort, False)
-    f = cast(BFunc18, _testfunc(20))
+    BFunc20 = new_function_type((BStructPtr,), BShort, False)
+    f = cast(BFunc20, _testfunc(20))
     x = newp(BStructPtr, {'a1': b'A', 'a2': -4042})
     # test the exception that allows us to pass a 'struct foo' where the
     # function really expects a 'struct foo *'.
     assert res == -4042 + ord(b'A')
     assert res == f(x)
 
+def test_call_function_21():
+    BInt = new_primitive_type("int")
+    BStruct = new_struct_type("foo")
+    complete_struct_or_union(BStruct, [('a', BInt, -1),
+                                       ('b', BInt, -1),
+                                       ('c', BInt, -1),
+                                       ('d', BInt, -1),
+                                       ('e', BInt, -1),
+                                       ('f', BInt, -1),
+                                       ('g', BInt, -1),
+                                       ('h', BInt, -1),
+                                       ('i', BInt, -1),
+                                       ('j', BInt, -1)])
+    BFunc21 = new_function_type((BStruct,), BInt, False)
+    f = cast(BFunc21, _testfunc(21))
+    res = f(range(13, 3, -1))
+    lst = [(n << i) for (i, n) in enumerate(range(13, 3, -1))]
+    assert res == sum(lst)
+
 def test_call_function_9():
     BInt = new_primitive_type("int")
     BFunc9 = new_function_type((BInt,), BInt, True)    # vararg
     assert s.a == -10
     assert s.b == 1E-42
 
+def test_callback_returning_big_struct():
+    BInt = new_primitive_type("int")
+    BStruct = new_struct_type("foo")
+    BStructPtr = new_pointer_type(BStruct)
+    complete_struct_or_union(BStruct, [('a', BInt, -1),
+                                       ('b', BInt, -1),
+                                       ('c', BInt, -1),
+                                       ('d', BInt, -1),
+                                       ('e', BInt, -1),
+                                       ('f', BInt, -1),
+                                       ('g', BInt, -1),
+                                       ('h', BInt, -1),
+                                       ('i', BInt, -1),
+                                       ('j', BInt, -1)])
+    def cb():
+        return newp(BStructPtr, range(13, 3, -1))[0]
+    BFunc = new_function_type((), BStruct)
+    f = callback(BFunc, cb)
+    s = f()
+    assert typeof(s) is BStruct
+    assert repr(s) in ["<cdata 'struct foo' owning 40 bytes>",
+                       "<cdata 'struct foo' owning 80 bytes>"]
+    for i, name in enumerate("abcdefghij"):
+        assert getattr(s, name) == 13 - i
+
 def test_callback_returning_void():
     BVoid = new_void_type()
     BFunc = new_function_type((), BVoid, False)
     assert f(255) == b'\xFF'
 
 def _hacked_pypy_uni4():
-    pyuni4 = {1: True, 2: False}[len(u'\U00012345')]
+    pyuni4 = {1: True, 2: False}[len(u+'\U00012345')]
     return 'PY_DOT_PY' in globals() and not pyuni4
 
 def test_callback_returning_wchar_t():
     BWChar = new_primitive_type("wchar_t")
     def cb(n):
         if n == -1:
-            return u'\U00012345'
+            return u+'\U00012345'
         if n == -2:
             raise ValueError
         return unichr(n)
     f = callback(BFunc, cb)
     assert f(0) == unichr(0)
     assert f(255) == unichr(255)
-    assert f(0x1234) == u'\u1234'
+    assert f(0x1234) == u+'\u1234'
     if sizeof(BWChar) == 4 and not _hacked_pypy_uni4():
-        assert f(-1) == u'\U00012345'
-    assert f(-2) == u'\x00'   # and an exception printed to stderr
+        assert f(-1) == u+'\U00012345'
+    assert f(-2) == u+'\x00'   # and an exception printed to stderr
 
 def test_struct_with_bitfields():
     BLong = new_primitive_type("long")
 
 def test_string_wchar():
     BWChar = new_primitive_type("wchar_t")
-    assert string(cast(BWChar, 42)) == u'*'
-    assert string(cast(BWChar, 0x4253)) == u'\u4253'
-    assert string(cast(BWChar, 0)) == u'\x00'
+    assert string(cast(BWChar, 42)) == u+'*'
+    assert string(cast(BWChar, 0x4253)) == u+'\u4253'
+    assert string(cast(BWChar, 0)) == u+'\x00'
     BArray = new_array_type(new_pointer_type(BWChar), None)
-    a = newp(BArray, [u'A', u'B', u'C'])
-    assert type(string(a)) is unicode and string(a) == u'ABC'
+    a = newp(BArray, [u+'A', u+'B', u+'C'])
+    assert type(string(a)) is unicode and string(a) == u+'ABC'
     if 'PY_DOT_PY' not in globals() and sys.version_info < (3,):
-        assert string(a, 8).startswith(u'ABC') # may contain additional garbage
+        assert string(a, 8).startswith(u+'ABC') # may contain additional garbage
 
 def test_string_typeerror():
     BShort = new_primitive_type("short")
 def test_wchar():
     BWChar = new_primitive_type("wchar_t")
     BInt = new_primitive_type("int")
-    pyuni4 = {1: True, 2: False}[len(u'\U00012345')]
+    pyuni4 = {1: True, 2: False}[len(u+'\U00012345')]
     wchar4 = {2: False, 4: True}[sizeof(BWChar)]
     assert str(cast(BWChar, 0x45)) == "<cdata 'wchar_t' %s'E'>" % (
         mandatory_u_prefix,)
     complete_struct_or_union(BStruct, [('a1', BWChar, -1),
                                        ('a2', BWCharP, -1)])
     s = newp(BStructPtr)
-    s.a1 = u'\x00'
-    assert s.a1 == u'\x00'
+    s.a1 = u+'\x00'
+    assert s.a1 == u+'\x00'
     py.test.raises(TypeError, "s.a1 = b'a'")
     py.test.raises(TypeError, "s.a1 = bytechr(0xFF)")
-    s.a1 = u'\u1234'
-    assert s.a1 == u'\u1234'
+    s.a1 = u+'\u1234'
+    assert s.a1 == u+'\u1234'
     if pyuni4:
         assert wchar4
-        s.a1 = u'\U00012345'
-        assert s.a1 == u'\U00012345'
+        s.a1 = u+'\U00012345'
+        assert s.a1 == u+'\U00012345'
     elif wchar4:
         if not _hacked_pypy_uni4():
             s.a1 = cast(BWChar, 0x12345)
-            assert s.a1 == u'\ud808\udf45'
-            s.a1 = u'\ud807\udf44'
-            assert s.a1 == u'\U00011f44'
+            assert s.a1 == u+'\ud808\udf45'
+            s.a1 = u+'\ud807\udf44'
+            assert s.a1 == u+'\U00011f44'
     else:
-        py.test.raises(TypeError, "s.a1 = u'\U00012345'")
+        py.test.raises(TypeError, "s.a1 = u+'\U00012345'")
     #
     BWCharArray = new_array_type(BWCharP, None)
-    a = newp(BWCharArray, u'hello \u1234 world')
+    a = newp(BWCharArray, u+'hello \u1234 world')
     assert len(a) == 14   # including the final null
-    assert string(a) == u'hello \u1234 world'
-    a[13] = u'!'
-    assert string(a) == u'hello \u1234 world!'
+    assert string(a) == u+'hello \u1234 world'
+    a[13] = u+'!'
+    assert string(a) == u+'hello \u1234 world!'
     assert str(a) == repr(a)
-    assert a[6] == u'\u1234'
-    a[6] = u'-'
-    assert string(a) == u'hello - world!'
+    assert a[6] == u+'\u1234'
+    a[6] = u+'-'
+    assert string(a) == u+'hello - world!'
     assert str(a) == repr(a)
     #
     if wchar4 and not _hacked_pypy_uni4():
-        u = u'\U00012345\U00012346\U00012347'
-        a = newp(BWCharArray, u)
+        u1 = u+'\U00012345\U00012346\U00012347'
+        a = newp(BWCharArray, u1)
         assert len(a) == 4
-        assert string(a) == u
+        assert string(a) == u1
         assert len(list(a)) == 4
-        expected = [u'\U00012345', u'\U00012346', u'\U00012347', unichr(0)]
+        expected = [u+'\U00012345', u+'\U00012346', u+'\U00012347', unichr(0)]
         assert list(a) == expected
         got = [a[i] for i in range(4)]
         assert got == expected
     w = cast(BWChar, 'a')
     assert repr(w) == "<cdata 'wchar_t' %s'a'>" % mandatory_u_prefix
     assert str(w) == repr(w)
-    assert string(w) == u'a'
+    assert string(w) == u+'a'
     assert int(w) == ord('a')
     w = cast(BWChar, 0x1234)
     assert repr(w) == "<cdata 'wchar_t' %s'\u1234'>" % mandatory_u_prefix
     assert str(w) == repr(w)
-    assert string(w) == u'\u1234'
+    assert string(w) == u+'\u1234'
     assert int(w) == 0x1234
-    w = cast(BWChar, u'\u8234')
+    w = cast(BWChar, u+'\u8234')
     assert repr(w) == "<cdata 'wchar_t' %s'\u8234'>" % mandatory_u_prefix
     assert str(w) == repr(w)
-    assert string(w) == u'\u8234'
+    assert string(w) == u+'\u8234'
     assert int(w) == 0x8234
-    w = cast(BInt, u'\u1234')
+    w = cast(BInt, u+'\u1234')
     assert repr(w) == "<cdata 'int' 4660>"
     if wchar4 and not _hacked_pypy_uni4():
-        w = cast(BWChar, u'\U00012345')
+        w = cast(BWChar, u+'\U00012345')
         assert repr(w) == "<cdata 'wchar_t' %s'\U00012345'>" % (
             mandatory_u_prefix,)
         assert str(w) == repr(w)
-        assert string(w) == u'\U00012345'
+        assert string(w) == u+'\U00012345'
         assert int(w) == 0x12345
-        w = cast(BInt, u'\U00012345')
+        w = cast(BInt, u+'\U00012345')
         assert repr(w) == "<cdata 'int' 74565>"
-    py.test.raises(TypeError, cast, BInt, u'')
-    py.test.raises(TypeError, cast, BInt, u'XX')
-    assert int(cast(BInt, u'a')) == ord('a')
+    py.test.raises(TypeError, cast, BInt, u+'')
+    py.test.raises(TypeError, cast, BInt, u+'XX')
+    assert int(cast(BInt, u+'a')) == ord('a')
     #
-    a = newp(BWCharArray, u'hello - world')
+    a = newp(BWCharArray, u+'hello - world')
     p = cast(BWCharP, a)
-    assert string(p) == u'hello - world'
-    p[6] = u'\u2345'
-    assert string(p) == u'hello \u2345 world'
+    assert string(p) == u+'hello - world'
+    p[6] = u+'\u2345'
+    assert string(p) == u+'hello \u2345 world'
     #
-    s = newp(BStructPtr, [u'\u1234', p])
-    assert s.a1 == u'\u1234'
+    s = newp(BStructPtr, [u+'\u1234', p])
+    assert s.a1 == u+'\u1234'
     assert s.a2 == p
     assert str(s.a2) == repr(s.a2)
-    assert string(s.a2) == u'hello \u2345 world'
+    assert string(s.a2) == u+'hello \u2345 world'
     #
     q = cast(BWCharP, 0)
     assert str(q) == repr(q)
         return len(string(p))
     BFunc = new_function_type((BWCharP,), BInt, False)
     f = callback(BFunc, cb, -42)
-    assert f(u'a\u1234b') == 3
+    assert f(u+'a\u1234b') == 3
     #
     if wchar4 and not pyuni4 and not _hacked_pypy_uni4():
         # try out-of-range wchar_t values
             assert repr(p.a1).startswith("<cdata 'long *' 0x")
         else:
             assert repr(p.a1).startswith("<cdata 'long[%d]' 0x" % length)
+
+def test_nested_anonymous_struct():
+    BInt = new_primitive_type("int")
+    BChar = new_primitive_type("char")
+    BStruct = new_struct_type("foo")
+    BInnerStruct = new_struct_type("foo")
+    complete_struct_or_union(BInnerStruct, [('a1', BInt, -1),
+                                            ('a2', BChar, -1)])
+    complete_struct_or_union(BStruct, [('', BInnerStruct, -1),
+                                       ('a3', BChar, -1)])
+    assert sizeof(BInnerStruct) == sizeof(BInt) * 2   # with alignment
+    assert sizeof(BStruct) == sizeof(BInt) * 3        # 'a3' is placed after
+    d = _getfields(BStruct)
+    assert len(d) == 3
+    assert d[0][0] == 'a1'
+    assert d[0][1].type is BInt
+    assert d[0][1].offset == 0
+    assert d[0][1].bitshift == -1
+    assert d[0][1].bitsize == -1
+    assert d[1][0] == 'a2'
+    assert d[1][1].type is BChar
+    assert d[1][1].offset == sizeof(BInt)
+    assert d[1][1].bitshift == -1
+    assert d[1][1].bitsize == -1
+    assert d[2][0] == 'a3'
+    assert d[2][1].type is BChar
+    assert d[2][1].offset == sizeof(BInt) * 2
+    assert d[2][1].bitshift == -1
+    assert d[2][1].bitsize == -1
+
+def test_sizeof_union():
+    # a union has the largest alignment of its members, and a total size
+    # that is the largest of its items *possibly further aligned* if
+    # another smaller item has a larger alignment...
+    BChar = new_primitive_type("char")
+    BShort = new_primitive_type("short")
+    assert sizeof(BShort) == alignof(BShort) == 2
+    BStruct = new_struct_type("foo")
+    complete_struct_or_union(BStruct, [('a1', BChar),
+                                       ('a2', BChar),
+                                       ('a3', BChar)])
+    assert sizeof(BStruct) == 3 and alignof(BStruct) == 1
+    BUnion = new_union_type("u")
+    complete_struct_or_union(BUnion, [('s', BStruct),
+                                      ('i', BShort)])
+    assert sizeof(BUnion) == 4
+    assert alignof(BUnion) == 2

File pypy/module/_cffi_backend/test/_test_lib.c

     return ptr->a1 + ptr->a2;
 }
 
+struct _testfunc21_s { int a, b, c, d, e, f, g, h, i, j; };
+static int _testfunc21(struct _testfunc21_s inlined)
+{
+    return ((inlined.a << 0) +
+            (inlined.b << 1) +
+            (inlined.c << 2) +
+            (inlined.d << 3) +
+            (inlined.e << 4) +
+            (inlined.f << 5) +
+            (inlined.g << 6) +
+            (inlined.h << 7) +
+            (inlined.i << 8) +
+            (inlined.j << 9));
+}
+
 DLLEXPORT void *gettestfunc(int num)
 {
     void *f;
     case 18: f = &_testfunc18; break;
     case 19: f = &_testfunc19; break;
     case 20: f = &_testfunc20; break;
+    case 21: f = &_testfunc21; break;
     default:
         return NULL;
     }

File pypy/module/_cffi_backend/test/test_c.py

 from __future__ import with_statement
 """
 This file is OBSCURE.  Really.  The purpose is to avoid copying and changing
-'test_c.py' from cffi/c/.
+'test_c.py' from cffi/c/ in the original CFFI repository:
+    https://bitbucket.org/cffi/cffi
+
+Adding a test here involves:
+1. add a test to cffi/c/test.py
+   - if you need a C function to call, add it into _cffi_backend.c
+     as a testfuncNN().
+2. have it pass when you run 'py.test test_c.py' in cffi
+3. check in and (if you can) push the changes
+4. copy test_c.py into _backend_test.py here, killing the few lines of header
+   - if you added a C function, it goes into _test_lib.c here
+   - if you could complete step 3, try running 'py.test test_file.py' here
+5. make the test pass in pypy ('py.test test_c.py')
 """
 import py, sys, ctypes
 if sys.version_info < (2, 6):

File pypy/module/_io/interp_iobase.py

             try:
                 space.call_method(w_iobase, 'flush')
             except OperationError, e:
-                # if it's an IOError or ValueError, ignore it (ValueError is
-                # raised if by chance we are trying to flush a file which has
-                # already been closed)
-                if not (e.match(space, space.w_IOError) or
-                        e.match(space, space.w_ValueError)):
-                    raise
-        
+                # Silencing all errors is bad, but getting randomly
+                # interrupted here is equally as bad, and potentially
+                # more frequent (because of shutdown issues).
+                pass 
+
 
 class AutoFlusher(object):
     

File pypy/module/_multiprocessing/test/test_semaphore.py

         kind = self.SEMAPHORE
         value = 1
         maxvalue = 1
+        # the following line gets OSError: [Errno 38] Function not implemented
+        # if /dev/shm is not mounted on Linux
         sem = SemLock(kind, value, maxvalue)
         assert sem.kind == kind
         assert sem.maxvalue == maxvalue
         kind = self.RECURSIVE
         value = 1
         maxvalue = 1
+        # the following line gets OSError: [Errno 38] Function not implemented
+        # if /dev/shm is not mounted on Linux
         sem = SemLock(kind, value, maxvalue)
 
         sem.acquire()

File pypy/module/itertools/interp_itertools.py

File contents unchanged.

File pypy/module/itertools/test/test_itertools.py

         list(it)
         assert repr(it) == "repeat('foobar', 0)"
 
+    def test_repeat_len(self):
+        import itertools
+
+        r = itertools.repeat('a', 15)
+        r.next()
+        raises(TypeError, "len(itertools.repeat('xkcd'))")
+
     def test_takewhile(self):
         import itertools
 

File pypy/module/micronumpy/strides.py

     return rstrides, rbackstrides
 
 def is_single_elem(space, w_elem, is_rec_type):
+    from pypy.module.micronumpy.interp_numarray import BaseArray
     if (is_rec_type and space.isinstance_w(w_elem, space.w_tuple)):
         return True
-    if space.issequence_w(w_elem):
+    if (space.isinstance_w(w_elem, space.w_tuple) or
+        isinstance(w_elem, BaseArray) or    
+        space.isinstance_w(w_elem, space.w_list)):
         return False
     return True
 

File pypy/module/micronumpy/test/test_numarray.py

         assert _to_coords(5, 'F') == [1, 2, 0]
         assert _to_coords(13, 'F') == [1, 0, 2]
 
+    def test_find_shape(self):
+        from pypy.module.micronumpy.strides import find_shape_and_elems
+
+        space = self.space
+        shape, elems = find_shape_and_elems(space,
+                                            space.newlist([space.wrap("a"),
+                                                           space.wrap("b")]),
+                                            None)
+        assert shape == [2]
+        assert space.str_w(elems[0]) == "a"
+        assert space.str_w(elems[1]) == "b"
+        
+
 class AppTestNumArray(BaseNumpyAppTest):
     def w_CustomIndexObject(self, index):
         class CustomIndexObject(object):

File pypy/module/test_lib_pypy/ctypes_tests/test_pointers.py

         TwoOutArgs(a, byref(b), c, byref(d))
         assert b.value == 7
         assert d.value == 11
+
+    def test_byref_cannot_be_bound(self):
+        class A(object):
+            _byref = byref
+        A._byref(c_int(5))

File pypy/objspace/flow/operation.py

     ('div_ovf',         div_ovf),
     ('mod_ovf',         mod_ovf),
     ('lshift_ovf',      lshift_ovf),
-    ]
+]
+if hasattr(__builtin__, 'next'):
+    Table.append(('next', __builtin__.next))
 
 def setup():
     # insert all operators
         name = line[0]
         if hasattr(operator, name):
             Table.append((name, getattr(operator, name)))
-    Table.append(('next', __builtin__.next))
     # build the dictionaries
     for name, func in Table:
         if name not in FunctionByName:

File pypy/objspace/std/celldict.py

 """
 
 from pypy.interpreter.baseobjspace import W_Root
-from pypy.objspace.std.dictmultiobject import IteratorImplementation
+from pypy.objspace.std.dictmultiobject import create_iterator_classes
 from pypy.objspace.std.dictmultiobject import DictStrategy, _never_equal_to_string
 from pypy.objspace.std.dictmultiobject import ObjectDictStrategy
 from pypy.rlib import jit, rerased
         w_res = self.getdictvalue_no_unwrapping(w_dict, key)
         return unwrap_cell(w_res)
 
-    def iter(self, w_dict):
-        return ModuleDictIteratorImplementation(self.space, self, w_dict)
-
     def w_keys(self, w_dict):
         space = self.space
         l = self.unerase(w_dict.dstorage).keys()
         w_dict.strategy = strategy
         w_dict.dstorage = strategy.erase(d_new)
 
-class ModuleDictIteratorImplementation(IteratorImplementation):
-    def __init__(self, space, strategy, dictimplementation):
-        IteratorImplementation.__init__(
-            self, space, strategy, dictimplementation)
-        dict_w = strategy.unerase(dictimplementation.dstorage)
-        self.iterator = dict_w.iteritems()
+    def getiterkeys(self, w_dict):
+        return self.unerase(w_dict.dstorage).iterkeys()
+    def getitervalues(self, w_dict):
+        return self.unerase(w_dict.dstorage).itervalues()
+    def getiteritems(self, w_dict):
+        return self.unerase(w_dict.dstorage).iteritems()
+    def wrapkey(space, key):
+        return space.wrap(key)
+    def wrapvalue(space, value):
+        return unwrap_cell(value)
 
-    def next_entry(self):
-        for key, cell in self.iterator:
-            return (self.space.wrap(key), unwrap_cell(cell))
-        else:
-            return None, None
+create_iterator_classes(ModuleDictStrategy)

File pypy/objspace/std/dictmultiobject.py

 from pypy.interpreter.argument import Signature
 from pypy.interpreter.error import OperationError, operationerrfmt
 
-from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize
+from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize,\
+     newlist_hint
 from pypy.rlib.debug import mark_dict_non_null
+from pypy.tool.sourcetools import func_with_new_name
 
 from pypy.rlib import rerased
 from pypy.rlib import jit
     dict_methods = "setitem setitem_str getitem \
                     getitem_str delitem length \
                     clear w_keys values \
-                    items iter setdefault \
+                    items iterkeys itervalues iteritems setdefault \
                     popitem listview_str listview_int".split()
 
     def make_method(method):
         f.func_name = method
         return f
 
+    def view_as_kwargs(self):
+        return self.strategy.view_as_kwargs(self)
+
     for method in dict_methods:
         setattr(W_DictMultiObject, method, make_method(method))
 
         raise NotImplementedError
 
     def w_keys(self, w_dict):
-        iterator = self.iter(w_dict)
-        result = []
+        iterator = self.iterkeys(w_dict)
+        result = newlist_hint(self.length(w_dict))
         while 1:
-            w_key, w_value = iterator.next()
+            w_key = iterator.next_key()
             if w_key is not None:
                 result.append(w_key)
             else:
                 return self.space.newlist(result)
 
     def values(self, w_dict):
-        iterator = self.iter(w_dict)
-        result = []
+        iterator = self.itervalues(w_dict)
+        result = newlist_hint(self.length(w_dict))
         while 1:
-            w_key, w_value = iterator.next()
+            w_value = iterator.next_value()
             if w_value is not None:
                 result.append(w_value)
             else:
                 return result
 
     def items(self, w_dict):
-        iterator = self.iter(w_dict)
-        result = []
+        iterator = self.iteritems(w_dict)
+        result = newlist_hint(self.length(w_dict))
         while 1:
-            w_key, w_value = iterator.next()
+            w_key, w_value = iterator.next_item()
             if w_key is not None:
                 result.append(self.space.newtuple([w_key, w_value]))
             else:
         # will take longer and longer.  But all interesting strategies
         # provide a better one.
         space = self.space
-        iterator = self.iter(w_dict)
-        w_key, w_value = iterator.next()
+        iterator = self.iteritems(w_dict)
+        w_key, w_value = iterator.next_item()
         self.delitem(w_dict, w_key)
         return (w_key, w_value)
 
     def length(self, w_dict):
         return 0
 
-    def iter(self, w_dict):
-        return EmptyIteratorImplementation(self.space, self, w_dict)
-
     def clear(self, w_dict):
         return
 
     def view_as_kwargs(self, w_dict):
         return ([], [])
 
-registerimplementation(W_DictMultiObject)
+    # ---------- iterator interface ----------------
 
-# DictImplementation lattice
-# XXX fix me
+    def getiterkeys(self, w_dict):
+        return iter([None])
+    getitervalues = getiterkeys
+    def getiteritems(self, w_dict):
+        return iter([(None, None)])
 
 # Iterator Implementation base classes
 
-class IteratorImplementation(object):
-    def __init__(self, space, strategy, implementation):
-        self.space = space
-        self.strategy = strategy
-        self.dictimplementation = implementation
-        self.len = implementation.length()
-        self.pos = 0
-
+def _new_next(TP):
+    if TP == 'key' or TP == 'value':
+        EMPTY = None
+    else:
+        EMPTY = None, None
+    
     def next(self):
         if self.dictimplementation is None:
-            return None, None
+            return EMPTY
         if self.len != self.dictimplementation.length():
             self.len = -1   # Make this error state sticky
             raise OperationError(self.space.w_RuntimeError,
                      self.space.wrap("dictionary changed size during iteration"))
         # look for the next entry
         if self.pos < self.len:
-            result = self.next_entry()
+            result = getattr(self, 'next_' + TP + '_entry')()
             self.pos += 1
             if self.strategy is self.dictimplementation.strategy:
                 return result      # common case
                 # length of the dict.  The (key, value) pair in 'result'
                 # might be out-of-date.  We try to explicitly look up
                 # the key in the dict.
+                if TP == 'key' or TP == 'value':
+                    return result
                 w_key = result[0]
                 w_value = self.dictimplementation.getitem(w_key)
                 if w_value is None:
                 return (w_key, w_value)
         # no more entries
         self.dictimplementation = None
-        return None, None
+        return EMPTY
+    return func_with_new_name(next, 'next_' + TP)
 
-    def next_entry(self):
-        """ Purely abstract method
-        """
-        raise NotImplementedError
+class BaseIteratorImplementation(object):
+    def __init__(self, space, strategy, implementation):
+        self.space = space
+        self.strategy = strategy
+        self.dictimplementation = implementation
+        self.len = implementation.length()
+        self.pos = 0
 
     def length(self):
         if self.dictimplementation is not None:
             return self.len - self.pos
         return 0
 
-class EmptyIteratorImplementation(IteratorImplementation):
-    def next(self):
-        return (None, None)
+class BaseKeyIterator(BaseIteratorImplementation):
+    next_key = _new_next('key')
 
+class BaseValueIterator(BaseIteratorImplementation):
+    next_value = _new_next('value')
+
+class BaseItemIterator(BaseIteratorImplementation):
+    next_item = _new_next('item')
+
+def create_iterator_classes(dictimpl, override_next_item=None):
+    if not hasattr(dictimpl, 'wrapkey'):
+        wrapkey = lambda space, key : key
+    else:
+        wrapkey = dictimpl.wrapkey.im_func
+    if not hasattr(dictimpl, 'wrapvalue'):
+        wrapvalue = lambda space, key : key
+    else:
+        wrapvalue = dictimpl.wrapvalue.im_func
+    
+    class IterClassKeys(BaseKeyIterator):
+        def __init__(self, space, strategy, impl):
+            self.iterator = strategy.getiterkeys(impl)
+            BaseIteratorImplementation.__init__(self, space, strategy, impl)
+
+        def next_key_entry(self):
+            for key in self.iterator:
+                return wrapkey(self.space, key)
+            else:
+                return None
+
+    class IterClassValues(BaseValueIterator):
+        def __init__(self, space, strategy, impl):
+            self.iterator = strategy.getitervalues(impl)
+            BaseIteratorImplementation.__init__(self, space, strategy, impl)
+
+        def next_value_entry(self):
+            for value in self.iterator:
+                return wrapvalue(self.space, value)
+            else:
+                return None
+
+    class IterClassItems(BaseItemIterator):
+        def __init__(self, space, strategy, impl):
+            self.iterator = strategy.getiteritems(impl)
+            BaseIteratorImplementation.__init__(self, space, strategy, impl)
+
+        if override_next_item is not None:
+            next_item_entry = override_next_item
+        else:
+            def next_item_entry(self):
+                for key, value in self.iterator:
+                    return (wrapkey(self.space, key),
+                            wrapvalue(self.space, value))
+                else:
+                    return None, None
+
+    def iterkeys(self, w_dict):
+        return IterClassKeys(self.space, self, w_dict)
+
+    def itervalues(self, w_dict):
+        return IterClassValues(self.space, self, w_dict)
+
+    def iteritems(self, w_dict):
+        return IterClassItems(self.space, self, w_dict)
+    dictimpl.iterkeys = iterkeys
+    dictimpl.itervalues = itervalues
+    dictimpl.iteritems = iteritems
+
+create_iterator_classes(EmptyDictStrategy)
+
+registerimplementation(W_DictMultiObject)
+
+# DictImplementation lattice
+# XXX fix me
 
 
 # concrete subclasses of the above
         w_dict.strategy = strategy
         w_dict.dstorage = strategy.erase(d_new)
 
+    # --------------- iterator interface -----------------
+
+    def getiterkeys(self, w_dict):
+        return self.unerase(w_dict.dstorage).iterkeys()
+    def getitervalues(self, w_dict):
+        return self.unerase(w_dict.dstorage).itervalues()
+    def getiteritems(self, w_dict):
+        return self.unerase(w_dict.dstorage).iteritems()
+
 class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
 
     erase, unerase = rerased.new_erasing_pair("object")
     def _never_equal_to(self, w_lookup_type):
         return False
 
-    def iter(self, w_dict):
-        return ObjectIteratorImplementation(self.space, self, w_dict)
-
     def w_keys(self, w_dict):
         return self.space.newlist(self.unerase(w_dict.dstorage).keys())
 
+create_iterator_classes(ObjectDictStrategy)
 
 class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
 
     def listview_str(self, w_dict):
         return self.unerase(w_dict.dstorage).keys()
 
-    def iter(self, w_dict):
-        return StrIteratorImplementation(self.space, self, w_dict)
-
     def w_keys(self, w_dict):
         return self.space.newlist_str(self.listview_str(w_dict))
 
+    def wrapkey(space, key):
+        return space.wrap(key)
+
     @jit.look_inside_iff(lambda self, w_dict:
                          w_dict_unrolling_heuristic(w_dict))
     def view_as_kwargs(self, w_dict):
             i += 1
         return keys, values
 
-class _WrappedIteratorMixin(object):
-    _mixin_ = True
+create_iterator_classes(StringDictStrategy)
 
-    def __init__(self, space, strategy, dictimplementation):
-        IteratorImplementation.__init__(self, space, strategy, dictimplementation)
-        self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
-
-    def next_entry(self):
-        # note that this 'for' loop only runs once, at most
-        for key, w_value in self.iterator:
-            return self.space.wrap(key), w_value
-        else:
-            return None, None
-
-class _UnwrappedIteratorMixin:
-    _mixin_ = True
-
-    def __init__(self, space, strategy, dictimplementation):
-        IteratorImplementation.__init__(self, space, strategy, dictimplementation)
-        self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
-
-    def next_entry(self):
-        # note that this 'for' loop only runs once, at most
-        for w_key, w_value in self.iterator:
-            return w_key, w_value
-        else:
-            return None, None
-
-
-class StrIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
-    pass
 
 class IntDictStrategy(AbstractTypedStrategy, DictStrategy):
     erase, unerase = rerased.new_erasing_pair("int")
                 space.is_w(w_lookup_type, space.w_unicode)
                 )
 
-    def iter(self, w_dict):
-        return IntIteratorImplementation(self.space, self, w_dict)
-
     def listview_int(self, w_dict):
         return self.unerase(w_dict.dstorage).keys()
 
+    def wrapkey(space, key):
+        return space.wrap(key)
+
     # XXX there is no space.newlist_int yet to implement w_keys more efficiently
 
-class IntIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
-    pass
-
-class ObjectIteratorImplementation(_UnwrappedIteratorMixin, IteratorImplementation):
-    pass
+create_iterator_classes(IntDictStrategy)
 
 init_signature = Signature(['seq_or_map'], None, 'kwargs')
 init_defaults = [None]
                 w_dict.setitem(w_key, w_value)
 
 def update1_dict_dict(space, w_dict, w_data):
-    iterator = w_data.iter()
+    iterator = w_data.iteritems()
     while 1:
-        w_key, w_value = iterator.next()
+        w_key, w_value = iterator.next_item()
         if w_key is None:
             break
         w_dict.setitem(w_key, w_value)
 dict_has_key__DictMulti_ANY = contains__DictMulti_ANY
 
 def iter__DictMulti(space, w_dict):
-    return W_DictMultiIterObject(space, w_dict.iter(), KEYSITER)
+    return W_DictMultiIterKeysObject(space, w_dict.iterkeys())
 
 def eq__DictMulti_DictMulti(space, w_left, w_right):
     if space.is_w(w_left, w_right):
 
     if w_left.length() != w_right.length():
         return space.w_False
-    iteratorimplementation = w_left.iter()
+    iteratorimplementation = w_left.iteritems()
     while 1:
-        w_key, w_val = iteratorimplementation.next()
+        w_key, w_val = iteratorimplementation.next_item()
         if w_key is None:
             break
         w_rightval = w_right.getitem(w_key)
     returns the smallest key in acontent for which b's value is different or absent and this value """
     w_smallest_diff_a_key = None
     w_its_value = None
-    iteratorimplementation = w_a.iter()
+    iteratorimplementation = w_a.iteritems()
     while 1:
-        w_key, w_val = iteratorimplementation.next()
+        w_key, w_val = iteratorimplementation.next_item()
         if w_key is None:
             break
         if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)):
     return space.newlist(w_self.values())
 
 def dict_iteritems__DictMulti(space, w_self):
-    return W_DictMultiIterObject(space, w_self.iter(), ITEMSITER)
+    return W_DictMultiIterItemsObject(space, w_self.iteritems())
 
 def dict_iterkeys__DictMulti(space, w_self):
-    return W_DictMultiIterObject(space, w_self.iter(), KEYSITER)
+    return W_DictMultiIterKeysObject(space, w_self.iterkeys())
 
 def dict_itervalues__DictMulti(space, w_self):
-    return W_DictMultiIterObject(space, w_self.iter(), VALUESITER)
+    return W_DictMultiIterValuesObject(space, w_self.itervalues())
 
 def dict_viewitems__DictMulti(space, w_self):
     return W_DictViewItemsObject(space, w_self)
 # Iteration
 
 
-KEYSITER = 0
-ITEMSITER = 1
-VALUESITER = 2
-
-class W_DictMultiIterObject(W_Object):
+class W_DictMultiIterKeysObject(W_Object):
     from pypy.objspace.std.dicttype import dictiter_typedef as typedef
 
-    _immutable_fields_ = ["iteratorimplementation", "itertype"]
+    _immutable_fields_ = ["iteratorimplementation"]
 
-    def __init__(w_self, space, iteratorimplementation, itertype):
+    ignore_for_isinstance_cache = True
+
+    def __init__(w_self, space, iteratorimplementation):
         w_self.space = space
         w_self.iteratorimplementation = iteratorimplementation
-        w_self.itertype = itertype
 
-registerimplementation(W_DictMultiIterObject)
+registerimplementation(W_DictMultiIterKeysObject)
 
-def iter__DictMultiIterObject(space, w_dictiter):
+class W_DictMultiIterValuesObject(W_Object):
+    from pypy.objspace.std.dicttype import dictiter_typedef as typedef
+
+    _immutable_fields_ = ["iteratorimplementation"]
+
+    ignore_for_isinstance_cache = True
+
+    def __init__(w_self, space, iteratorimplementation):
+        w_self.space = space
+        w_self.iteratorimplementation = iteratorimplementation
+
+registerimplementation(W_DictMultiIterValuesObject)
+
+class W_DictMultiIterItemsObject(W_Object):
+    from pypy.objspace.std.dicttype import dictiter_typedef as typedef
+
+    _immutable_fields_ = ["iteratorimplementation"]
+
+    ignore_for_isinstance_cache = True
+
+    def __init__(w_self, space, iteratorimplementation):
+        w_self.space = space
+        w_self.iteratorimplementation = iteratorimplementation
+
+registerimplementation(W_DictMultiIterItemsObject)
+
+def iter__DictMultiIterKeysObject(space, w_dictiter):
     return w_dictiter
 
-def next__DictMultiIterObject(space, w_dictiter):
+def next__DictMultiIterKeysObject(space, w_dictiter):
     iteratorimplementation = w_dictiter.iteratorimplementation
-    w_key, w_value = iteratorimplementation.next()
+    w_key = iteratorimplementation.next_key()
     if w_key is not None:
-        itertype = w_dictiter.itertype
-        if itertype == KEYSITER:
-            return w_key
-        elif itertype == VALUESITER:
-            return w_value
-        elif itertype == ITEMSITER:
-            return space.newtuple([w_key, w_value])
-        else:
-            assert 0, "should be unreachable"
+        return w_key
+    raise OperationError(space.w_StopIteration, space.w_None)
+
+def iter__DictMultiIterValuesObject(space, w_dictiter):
+    return w_dictiter
+
+def next__DictMultiIterValuesObject(space, w_dictiter):
+    iteratorimplementation = w_dictiter.iteratorimplementation
+    w_value = iteratorimplementation.next_value()
+    if w_value is not None:
+        return w_value
+    raise OperationError(space.w_StopIteration, space.w_None)
+
+def iter__DictMultiIterItemsObject(space, w_dictiter):
+    return w_dictiter
+
+def next__DictMultiIterItemsObject(space, w_dictiter):
+    iteratorimplementation = w_dictiter.iteratorimplementation
+    w_key, w_value = iteratorimplementation.next_item()
+    if w_key is not None:
+        return space.newtuple([w_key, w_value])
     raise OperationError(space.w_StopIteration, space.w_None)
 
 # ____________________________________________________________
 
 def all_contained_in(space, w_dictview, w_otherview):
     w_iter = space.iter(w_dictview)
-    assert isinstance(w_iter, W_DictMultiIterObject)
 
     while True:
         try:

File pypy/objspace/std/dictproxyobject.py

 from pypy.objspace.std.model import registerimplementation, W_Object
 from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject, IteratorImplementation
+from pypy.objspace.std.dictmultiobject import W_DictMultiObject, create_iterator_classes
 from pypy.objspace.std.dictmultiobject import DictStrategy
 from pypy.objspace.std.typeobject import unwrap_cell
 from pypy.interpreter.error import OperationError, operationerrfmt
     def length(self, w_dict):
         return len(self.unerase(w_dict.dstorage).dict_w)
 
-    def iter(self, w_dict):
-        return DictProxyIteratorImplementation(self.space, self, w_dict)
-
     def keys(self, w_dict):
         space = self.space
         return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys())
         w_type.dict_w.clear()
         w_type.mutated(None)
 
-class DictProxyIteratorImplementation(IteratorImplementation):
-    def __init__(self, space, strategy, dictimplementation):
-        IteratorImplementation.__init__(
-            self, space, strategy, dictimplementation)
-        w_type = strategy.unerase(dictimplementation.dstorage)
-        self.iterator = w_type.dict_w.iteritems()
+    def getiterkeys(self, w_dict):
+        return self.unerase(w_dict.dstorage).dict_w.iterkeys()
+    def getitervalues(self, w_dict):
+        return self.unerase(w_dict.dstorage).dict_w.itervalues()
+    def getiteritems(self, w_dict):
+        return self.unerase(w_dict.dstorage).dict_w.iteritems()
+    def wrapkey(space, key):
+        return space.wrap(key)
+    def wrapvalue(space, value):
+        return unwrap_cell(space, value)
 
-    def next_entry(self):
-        for key, w_value in self.iterator:
-            return (self.space.wrap(key), unwrap_cell(self.space, w_value))
-        else:
-            return (None, None)
+create_iterator_classes(DictProxyStrategy)

File pypy/objspace/std/identitydict.py

 from pypy.rlib.debug import mark_dict_non_null
 from pypy.objspace.std.dictmultiobject import (AbstractTypedStrategy,
                                                DictStrategy,
-                                               IteratorImplementation,
-                                               _UnwrappedIteratorMixin)
+                                               create_iterator_classes)
 
 
 # this strategy is selected by EmptyDictStrategy.switch_to_correct_strategy
     def _never_equal_to(self, w_lookup_type):
         return False
 
-    def iter(self, w_dict):
-        return IdentityDictIteratorImplementation(self.space, self, w_dict)
-
     def w_keys(self, w_dict):
         return self.space.newlist(self.unerase(w_dict.dstorage).keys())
 
-
-class IdentityDictIteratorImplementation(_UnwrappedIteratorMixin, IteratorImplementation):
-    pass
+create_iterator_classes(IdentityDictStrategy)

File pypy/objspace/std/kwargsdict.py

 
 from pypy.rlib import rerased, jit
 from pypy.objspace.std.dictmultiobject import (DictStrategy,
+                                               create_iterator_classes,
                                                EmptyDictStrategy,
-                                               IteratorImplementation,
                                                ObjectDictStrategy,
                                                StringDictStrategy)
 
     def _never_equal_to(self, w_lookup_type):
         return False
 
-    def iter(self, w_dict):
-        return KwargsDictIterator(self.space, self, w_dict)
-
     def w_keys(self, w_dict):
         return self.space.newlist([self.space.wrap(key) for key in self.unerase(w_dict.dstorage)[0]])
 
         keys, values_w = self.unerase(w_dict.dstorage)
         return keys[:], values_w[:] # copy to make non-resizable
 
+    def getiterkeys(self, w_dict):
+        return iter(self.unerase(w_dict.dstorage)[0])
+    def getitervalues(self, w_dict):
+        return iter(self.unerase(w_dict.dstorage)[1])
+    def getiteritems(self, w_dict):
+        keys = self.unerase(w_dict.dstorage)[0]
+        return iter(range(len(keys)))
+    def wrapkey(space, key):
+        return space.wrap(key)
 
-class KwargsDictIterator(IteratorImplementation):
-    def __init__(self, space, strategy, dictimplementation):
-        IteratorImplementation.__init__(self, space, strategy, dictimplementation)
-        keys, values_w = strategy.unerase(self.dictimplementation.dstorage)
-        self.iterator = iter(range(len(keys)))
-        # XXX this potentially leaks
-        self.keys = keys
-        self.values_w = values_w
+def next_item(self):
+    strategy = self.strategy
+    assert isinstance(strategy, KwargsDictStrategy)
+    for i in self.iterator:
+        keys, values_w = strategy.unerase(
+            self.dictimplementation.dstorage)
+        return self.space.wrap(keys[i]), values_w[i]
+    else:
+        return None, None
 
-    def next_entry(self):
-        # note that this 'for' loop only runs once, at most
-        for i in self.iterator:
-            return self.space.wrap(self.keys[i]), self.values_w[i]
-        else:
-            return None, None
+create_iterator_classes(KwargsDictStrategy, override_next_item=next_item)

File pypy/objspace/std/listobject.py

         if is_W_IntObject(w_obj):
             start, step, length = self.unerase(w_list.lstorage)
             obj = self.unwrap(w_obj)
-            i = start
             if step > 0 and start <= obj <= start + (length - 1) * step and (start - obj) % step == 0:
                 return True
-            elif step < 0 and start + (length -1) * step <= obj <= start and (start - obj) % step == 0:
+            elif step < 0 and start + (length - 1) * step <= obj <= start and (start - obj) % step == 0:
                 return True
             else:
                 return False
         l = self.unerase(w_list.lstorage)
         start = l[0]
         step = l[1]
-        length  = l[2]
+        length = l[2]
         if wrap_items:
             r = [None] * length
         else:
 
     def getslice(self, w_list, start, stop, step, length):
         v = self.unerase(w_list.lstorage)
-        old_start = v[0]
         old_step = v[1]
-        old_length = v[2]
 
         new_start = self._getitem_unwrapped(w_list, start)
         new_step = old_step * step
             step = l[1]
             last_in_range = self._getitem_unwrapped(w_list, -1)
             if self.unwrap(w_item) - step == last_in_range:
-                new = self.erase((l[0],l[1],l[2]+1))
+                new = self.erase((l[0], l[1], l[2] + 1))
                 w_list.lstorage = new
                 return
 
 
     def contains(self, w_list, w_obj):
         if self.is_correct_type(w_obj):
-            obj = self.unwrap(w_obj)
+            return self._safe_contains(w_list, self.unwrap(w_obj))
+        return ListStrategy.contains(self, w_list, w_obj)
+
+    def _safe_contains(self, w_list, obj):
             l = self.unerase(w_list.lstorage)
             for i in l:
                 if i == obj:
                     return True
             return False
-        return ListStrategy.contains(self, w_list, w_obj)
 
     def length(self, w_list):
         return len(self.unerase(w_list.lstorage))
                 newsize = oldsize + delta
                 # XXX support this in rlist!
                 items += [self._none_value] * delta
-                lim = start+len2
+                lim = start + len2
                 i = newsize - 1
                 while i >= lim:
                     items[i] = items[i-delta]
                 # having to make a shallow copy in the case where
                 # the source and destination lists are the same list.
                 i = len2 - 1
-                start += i*step
+                start += i * step
                 while i >= 0:
                     items[start] = other_items[i]
                     start -= step
 
     def deleteslice(self, w_list, start, step, slicelength):
         items = self.unerase(w_list.lstorage)
-        if slicelength==0:
+        if slicelength == 0:
             return
 
         if step < 0:
-            start = start + step * (slicelength-1)
+            start = start + step * (slicelength - 1)
             step = -step
 
         if step == 1:
             i = start
 
             for discard in range(1, slicelength):
-                j = i+1
+                j = i + 1
                 i += step
                 while j < i:
                     items[j-discard] = items[j]
                     j += 1
 
-            j = i+1
+            j = i + 1
             while j < n:
                 items[j-slicelength] = items[j]
                 j += 1