[pypy-commit] pypy unroll-if-alt: merged default.

alex_gaynor noreply at buildbot.pypy.org
Wed Sep 14 20:26:16 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: unroll-if-alt
Changeset: r47271:a16809d0db00
Date: 2011-09-14 11:17 -0400
http://bitbucket.org/pypy/pypy/changeset/a16809d0db00/

Log:	merged default.

diff --git a/lib-python/2.7/ssl.py b/lib-python/2.7/ssl.py
--- a/lib-python/2.7/ssl.py
+++ b/lib-python/2.7/ssl.py
@@ -62,7 +62,6 @@
 from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
 from _ssl import SSLError
 from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
-from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
 from _ssl import RAND_status, RAND_egd, RAND_add
 from _ssl import \
      SSL_ERROR_ZERO_RETURN, \
@@ -74,6 +73,18 @@
      SSL_ERROR_WANT_CONNECT, \
      SSL_ERROR_EOF, \
      SSL_ERROR_INVALID_ERROR_CODE
+from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
+_PROTOCOL_NAMES = {
+    PROTOCOL_TLSv1: "TLSv1",
+    PROTOCOL_SSLv23: "SSLv23",
+    PROTOCOL_SSLv3: "SSLv3",
+}
+try:
+    from _ssl import PROTOCOL_SSLv2
+except ImportError:
+    pass
+else:
+    _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2"
 
 from socket import socket, _fileobject, _delegate_methods, error as socket_error
 from socket import getnameinfo as _getnameinfo
@@ -408,16 +419,7 @@
     return DER_cert_to_PEM_cert(dercert)
 
 def get_protocol_name(protocol_code):
-    if protocol_code == PROTOCOL_TLSv1:
-        return "TLSv1"
-    elif protocol_code == PROTOCOL_SSLv23:
-        return "SSLv23"
-    elif protocol_code == PROTOCOL_SSLv2:
-        return "SSLv2"
-    elif protocol_code == PROTOCOL_SSLv3:
-        return "SSLv3"
-    else:
-        return "<unknown>"
+    return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
 
 
 # a replacement for the old socket.ssl function
diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py
--- a/lib-python/2.7/test/test_ssl.py
+++ b/lib-python/2.7/test/test_ssl.py
@@ -58,32 +58,35 @@
 
 # Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
 def skip_if_broken_ubuntu_ssl(func):
-    # We need to access the lower-level wrapper in order to create an
-    # implicit SSL context without trying to connect or listen.
-    try:
-        import _ssl
-    except ImportError:
-        # The returned function won't get executed, just ignore the error
-        pass
-    @functools.wraps(func)
-    def f(*args, **kwargs):
+    if hasattr(ssl, 'PROTOCOL_SSLv2'):
+        # We need to access the lower-level wrapper in order to create an
+        # implicit SSL context without trying to connect or listen.
         try:
-            s = socket.socket(socket.AF_INET)
-            _ssl.sslwrap(s._sock, 0, None, None,
-                         ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
-        except ssl.SSLError as e:
-            if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
-                platform.linux_distribution() == ('debian', 'squeeze/sid', '')
-                and 'Invalid SSL protocol variant specified' in str(e)):
-                raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
-        return func(*args, **kwargs)
-    return f
+            import _ssl
+        except ImportError:
+            # The returned function won't get executed, just ignore the error
+            pass
+        @functools.wraps(func)
+        def f(*args, **kwargs):
+            try:
+                s = socket.socket(socket.AF_INET)
+                _ssl.sslwrap(s._sock, 0, None, None,
+                             ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
+            except ssl.SSLError as e:
+                if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
+                    platform.linux_distribution() == ('debian', 'squeeze/sid', '')
+                    and 'Invalid SSL protocol variant specified' in str(e)):
+                    raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
+            return func(*args, **kwargs)
+        return f
+    else:
+        return func
 
 
 class BasicSocketTests(unittest.TestCase):
 
     def test_constants(self):
-        ssl.PROTOCOL_SSLv2
+        #ssl.PROTOCOL_SSLv2
         ssl.PROTOCOL_SSLv23
         ssl.PROTOCOL_SSLv3
         ssl.PROTOCOL_TLSv1
@@ -964,7 +967,8 @@
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
-            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
+            if hasattr(ssl, 'PROTOCOL_SSLv2'):
+                try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
 
@@ -976,7 +980,8 @@
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
-            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
+            if hasattr(ssl, 'PROTOCOL_SSLv2'):
+                try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
 
diff --git a/lib-python/modified-2.7/ssl.py b/lib-python/modified-2.7/ssl.py
--- a/lib-python/modified-2.7/ssl.py
+++ b/lib-python/modified-2.7/ssl.py
@@ -62,7 +62,6 @@
 from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
 from _ssl import SSLError
 from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
-from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
 from _ssl import RAND_status, RAND_egd, RAND_add
 from _ssl import \
      SSL_ERROR_ZERO_RETURN, \
@@ -74,6 +73,18 @@
      SSL_ERROR_WANT_CONNECT, \
      SSL_ERROR_EOF, \
      SSL_ERROR_INVALID_ERROR_CODE
+from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
+_PROTOCOL_NAMES = {
+    PROTOCOL_TLSv1: "TLSv1",
+    PROTOCOL_SSLv23: "SSLv23",
+    PROTOCOL_SSLv3: "SSLv3",
+}
+try:
+    from _ssl import PROTOCOL_SSLv2
+except ImportError:
+    pass
+else:
+    _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2"
 
 from socket import socket, _fileobject, error as socket_error
 from socket import getnameinfo as _getnameinfo
@@ -400,16 +411,7 @@
     return DER_cert_to_PEM_cert(dercert)
 
 def get_protocol_name(protocol_code):
-    if protocol_code == PROTOCOL_TLSv1:
-        return "TLSv1"
-    elif protocol_code == PROTOCOL_SSLv23:
-        return "SSLv23"
-    elif protocol_code == PROTOCOL_SSLv2:
-        return "SSLv2"
-    elif protocol_code == PROTOCOL_SSLv3:
-        return "SSLv3"
-    else:
-        return "<unknown>"
+    return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
 
 
 # a replacement for the old socket.ssl function
diff --git a/lib-python/modified-2.7/test/test_ssl.py b/lib-python/modified-2.7/test/test_ssl.py
--- a/lib-python/modified-2.7/test/test_ssl.py
+++ b/lib-python/modified-2.7/test/test_ssl.py
@@ -58,32 +58,35 @@
 
 # Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
 def skip_if_broken_ubuntu_ssl(func):
-    # We need to access the lower-level wrapper in order to create an
-    # implicit SSL context without trying to connect or listen.
-    try:
-        import _ssl
-    except ImportError:
-        # The returned function won't get executed, just ignore the error
-        pass
-    @functools.wraps(func)
-    def f(*args, **kwargs):
+    if hasattr(ssl, 'PROTOCOL_SSLv2'):
+        # We need to access the lower-level wrapper in order to create an
+        # implicit SSL context without trying to connect or listen.
         try:
-            s = socket.socket(socket.AF_INET)
-            _ssl.sslwrap(s._sock, 0, None, None,
-                         ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
-        except ssl.SSLError as e:
-            if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
-                platform.linux_distribution() == ('debian', 'squeeze/sid', '')
-                and 'Invalid SSL protocol variant specified' in str(e)):
-                raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
-        return func(*args, **kwargs)
-    return f
+            import _ssl
+        except ImportError:
+            # The returned function won't get executed, just ignore the error
+            pass
+        @functools.wraps(func)
+        def f(*args, **kwargs):
+            try:
+                s = socket.socket(socket.AF_INET)
+                _ssl.sslwrap(s._sock, 0, None, None,
+                             ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
+            except ssl.SSLError as e:
+                if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
+                    platform.linux_distribution() == ('debian', 'squeeze/sid', '')
+                    and 'Invalid SSL protocol variant specified' in str(e)):
+                    raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
+            return func(*args, **kwargs)
+        return f
+    else:
+        return func
 
 
 class BasicSocketTests(unittest.TestCase):
 
     def test_constants(self):
-        ssl.PROTOCOL_SSLv2
+        #ssl.PROTOCOL_SSLv2
         ssl.PROTOCOL_SSLv23
         ssl.PROTOCOL_SSLv3
         ssl.PROTOCOL_TLSv1
@@ -966,7 +969,8 @@
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
-            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
+            if hasattr(ssl, 'PROTOCOL_SSLv2'):
+                try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
             try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
 
@@ -978,7 +982,8 @@
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
-            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
+            if hasattr(ssl, 'PROTOCOL_SSLv2'):
+                try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
             try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
 
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -48,23 +48,23 @@
     def switch(self, *args):
         "Switch execution to this greenlet, optionally passing the values "
         "given as argument(s).  Returns the value passed when switching back."
-        return self.__switch(_continulet.switch, args)
+        return self.__switch('switch', args)
 
     def throw(self, typ=GreenletExit, val=None, tb=None):
         "raise exception in greenlet, return value passed when switching back"
-        return self.__switch(_continulet.throw, typ, val, tb)
+        return self.__switch('throw', typ, val, tb)
 
-    def __switch(target, unbound_method, *args):
+    def __switch(target, methodname, *args):
         current = getcurrent()
         #
         while not target:
             if not target.__started:
-                if unbound_method != _continulet.throw:
+                if methodname == 'switch':
                     greenlet_func = _greenlet_start
                 else:
                     greenlet_func = _greenlet_throw
                 _continulet.__init__(target, greenlet_func, *args)
-                unbound_method = _continulet.switch
+                methodname = 'switch'
                 args = ()
                 target.__started = True
                 break
@@ -75,22 +75,8 @@
             target = target.parent
         #
         try:
-            if current.__main:
-                if target.__main:
-                    # switch from main to main
-                    if unbound_method == _continulet.throw:
-                        raise args[0], args[1], args[2]
-                    (args,) = args
-                else:
-                    # enter from main to target
-                    args = unbound_method(target, *args)
-            else:
-                if target.__main:
-                    # leave to go to target=main
-                    args = unbound_method(current, *args)
-                else:
-                    # switch from non-main to non-main
-                    args = unbound_method(current, *args, to=target)
+            unbound_method = getattr(_continulet, methodname)
+            args = unbound_method(current, *args, to=target)
         except GreenletExit, e:
             args = (e,)
         finally:
diff --git a/lib_pypy/stackless.py b/lib_pypy/stackless.py
--- a/lib_pypy/stackless.py
+++ b/lib_pypy/stackless.py
@@ -7,19 +7,12 @@
 
 import traceback
 import _continuation
-from functools import partial
 
 class TaskletExit(Exception):
     pass
 
 CoroutineExit = TaskletExit
 
-class GWrap(_continuation.continulet):
-    """This is just a wrapper around continulet to allow
-       to stick additional attributes to a continulet.
-       To be more concrete, we need a backreference to
-       the coroutine object"""
-
 
 class coroutine(object):
     "we can't have continulet as a base, because continulets can't be rebound"
@@ -42,12 +35,10 @@
            arguments *argl, **argd
         """
         if self._frame is None or not self._frame.is_pending():
-
-            def _func(c, *args, **kwargs):
-                return func(*args, **kwargs)
-            
-            run = partial(_func, *argl, **argd)
-            self._frame = frame = GWrap(run)
+            def run(c):
+                _tls.current_coroutine = self
+                return func(*argl, **argd)
+            self._frame = frame = _continuation.continulet(run)
         else:
             raise ValueError("cannot bind a bound coroutine")
 
@@ -58,16 +49,18 @@
            None is returned
         """
         current = _getcurrent()
-        current._jump_to(self)
-
-    def _jump_to(self, coroutine):
-        _tls.current_coroutine = coroutine
-        self._frame.switch(to=coroutine._frame)
+        try:
+            current._frame.switch(to=self._frame)
+        finally:
+            _tls.current_coroutine = current
 
     def kill(self):
         """coro.kill() : kill coroutine coro"""
-        _tls.current_coroutine = self
-        self._frame.throw(CoroutineExit)
+        current = _getcurrent()
+        try:
+            current._frame.throw(CoroutineExit, to=self._frame)
+        finally:
+            _tls.current_coroutine = current
 
     def _is_alive(self):
         if self._frame is None:
@@ -78,10 +71,7 @@
 
     def getcurrent():
         """coroutine.getcurrent() -> the currently running coroutine"""
-        try:
-            return _getcurrent()
-        except AttributeError:
-            return _maincoro
+        return _getcurrent()
     getcurrent = staticmethod(getcurrent)
 
     def __reduce__(self):
@@ -109,13 +99,10 @@
     # create the main coroutine for this thread
     _tls.current_coroutine = None
     main_coroutine = coroutine()
-    main_coroutine.bind(lambda x:x)
+    typ = _continuation.continulet
+    main_coroutine._frame = typ.__new__(typ)
     _tls.main_coroutine = main_coroutine
     _tls.current_coroutine = main_coroutine
-    return main_coroutine
-
-
-_maincoro = _coroutine_create_main()
 
 
 from collections import deque
@@ -161,10 +148,10 @@
     _last_task = next
     assert not next.blocked
     if next is not current:
-        try:
+        #try:
             next.switch()
-        except CoroutineExit:
-            raise TaskletExit
+        #except CoroutineExit:  --- they are the same anyway
+        #    raise TaskletExit
     return current
 
 def set_schedule_callback(callback):
@@ -459,6 +446,7 @@
         def _func():
             try:
                 try:
+                    coroutine.switch(back)
                     func(*argl, **argd)
                 except TaskletExit:
                     pass
@@ -468,6 +456,8 @@
 
         self.func = None
         coroutine.bind(self, _func)
+        back = _getcurrent()
+        coroutine.switch(self)
         self.alive = True
         _scheduler_append(self)
         return self
diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst
--- a/pypy/doc/stackless.rst
+++ b/pypy/doc/stackless.rst
@@ -66,7 +66,7 @@
 In practice, in PyPy, you cannot change the ``f_back`` of an abitrary
 frame, but only of frames stored in ``continulets``.
 
-Continulets are internally implemented using stacklets.  Stacklets are a
+Continulets are internally implemented using stacklets_.  Stacklets are a
 bit more primitive (they are really one-shot continuations), but that
 idea only works in C, not in Python.  The basic idea of continulets is
 to have at any point in time a complete valid stack; this is important
@@ -280,6 +280,24 @@
 to use other interfaces like genlets and greenlets.)
 
 
+Stacklets
++++++++++
+
+Continulets are internally implemented using stacklets, which is the
+generic RPython-level building block for "one-shot continuations".  For
+more information about them please see the documentation in the C source
+at `pypy/translator/c/src/stacklet/stacklet.h`_.
+
+The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above
+functions.  The key point is that new() and switch() always return a
+fresh stacklet handle (or an empty one), and switch() additionally
+consumes one.  It makes no sense to have code in which the returned
+handle is ignored, or used more than once.  Note that ``stacklet.c`` is
+written assuming that the user knows that, and so no additional checking
+occurs; this can easily lead to obscure crashes if you don't use a
+wrapper like PyPy's '_continuation' module.
+
+
 Theory of composability
 +++++++++++++++++++++++
 
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -48,6 +48,7 @@
         return frame
 
     @staticmethod
+    @jit.unroll_safe  # should usually loop 0 times, very rarely more than once
     def getnextframe_nohidden(frame):
         frame = frame.f_backref()
         while frame and frame.hide():
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -614,8 +614,8 @@
         return self.get_builtin().getdict(space)
 
     def fget_f_back(self, space):
-        f_backref = ExecutionContext.getnextframe_nohidden(self)
-        return self.space.wrap(f_backref)
+        f_back = ExecutionContext.getnextframe_nohidden(self)
+        return self.space.wrap(f_back)
 
     def fget_f_lasti(self, space):
         return self.space.wrap(self.last_instr)
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -3277,7 +3277,27 @@
             return n
 
         self.meta_interp(f, [10], repeat=3)
-        
+
+    def test_jit_merge_point_with_pbc(self):
+        driver = JitDriver(greens = [], reds = ['x'])
+
+        class A(object):
+            def __init__(self, x):
+                self.x = x
+            def _freeze_(self):
+                return True
+        pbc = A(1)
+
+        def main(x):
+            return f(x, pbc)
+
+        def f(x, pbc):
+            while x > 0:
+                driver.jit_merge_point(x = x)
+                x -= pbc.x
+            return x
+
+        self.meta_interp(main, [10])
 
     def test_look_inside_iff_const(self):
         @look_inside_iff(lambda arg: isconstant(arg))
diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py
--- a/pypy/module/_continuation/interp_continuation.py
+++ b/pypy/module/_continuation/interp_continuation.py
@@ -43,16 +43,29 @@
             raise getmemoryerror(self.space)
 
     def switch(self, w_to):
+        sthread = self.sthread
+        if sthread is not None and sthread.is_empty_handle(self.h):
+            start_state.clear()
+            raise geterror(self.space, "continulet already finished")
         to = self.space.interp_w(W_Continulet, w_to, can_be_None=True)
+        if to is not None and to.sthread is None:
+            to = None
+        if sthread is None:      # if self is non-initialized:
+            if to is not None:   #     if we are given a 'to'
+                self = to        #         then just use it and ignore 'self'
+                sthread = self.sthread
+                to = None
+            else:
+                return get_result()  # else: no-op
         if to is not None:
-            if to.sthread is None:
+            if to.sthread is not sthread:
                 start_state.clear()
-                raise geterror(self.space, "continulet not initialized yet")
+                raise geterror(self.space, "cross-thread double switch")
             if self is to:    # double-switch to myself: no-op
                 return get_result()
-        if self.sthread is None:
-            start_state.clear()
-            raise geterror(self.space, "continulet not initialized yet")
+            if sthread.is_empty_handle(to.h):
+                start_state.clear()
+                raise geterror(self.space, "continulet already finished")
         ec = self.check_sthread()
         #
         start_state.origin = self
@@ -63,14 +76,8 @@
             # double switch: the final destination is to.h
             start_state.destination = to
         #
-        h = start_state.destination.h
-        sthread = self.sthread
-        if sthread.is_empty_handle(h):
-            start_state.clear()
-            raise geterror(self.space, "continulet already finished")
-        #
         try:
-            do_switch(sthread, h)
+            do_switch(sthread, start_state.destination.h)
         except MemoryError:
             start_state.clear()
             raise getmemoryerror(self.space)
diff --git a/pypy/module/_continuation/test/test_stacklet.py b/pypy/module/_continuation/test/test_stacklet.py
--- a/pypy/module/_continuation/test/test_stacklet.py
+++ b/pypy/module/_continuation/test/test_stacklet.py
@@ -135,12 +135,6 @@
         e = raises(error, c.switch)
         assert str(e.value) == "continulet already finished"
 
-    def test_not_initialized_yet(self):
-        from _continuation import continulet, error
-        c = continulet.__new__(continulet)
-        e = raises(error, c.switch)
-        assert str(e.value) == "continulet not initialized yet"
-
     def test_go_depth2(self):
         from _continuation import continulet
         #
@@ -254,6 +248,15 @@
         res = c_upper.switch('D')
         assert res == 'E'
 
+    def test_switch_not_initialized(self):
+        from _continuation import continulet
+        c0 = continulet.__new__(continulet)
+        res = c0.switch()
+        assert res is None
+        res = c0.switch(123)
+        assert res == 123
+        raises(ValueError, c0.throw, ValueError)
+
     def test_exception_with_switch_depth2(self):
         from _continuation import continulet
         #
@@ -499,16 +502,31 @@
         assert res == 'z'
         raises(TypeError, c1.switch, to=c2)  # "can't send non-None value"
 
-    def test_switch2_not_initialized_yet(self):
-        from _continuation import continulet, error
+    def test_switch2_not_initialized(self):
+        from _continuation import continulet
+        c0 = continulet.__new__(continulet)
+        c0bis = continulet.__new__(continulet)
+        res = c0.switch(123, to=c0)
+        assert res == 123
+        res = c0.switch(123, to=c0bis)
+        assert res == 123
+        raises(ValueError, c0.throw, ValueError, to=c0)
+        raises(ValueError, c0.throw, ValueError, to=c0bis)
         #
         def f1(c1):
-            not_reachable
-        #
+            c1.switch('a')
+            raises(ValueError, c1.switch, 'b')
+            raises(KeyError, c1.switch, 'c')
+            return 'd'
         c1 = continulet(f1)
-        c2 = continulet.__new__(continulet)
-        e = raises(error, c1.switch, to=c2)
-        assert str(e.value) == "continulet not initialized yet"
+        res = c0.switch(to=c1)
+        assert res == 'a'
+        res = c1.switch(to=c0)
+        assert res == 'b'
+        res = c1.throw(ValueError, to=c0)
+        assert res == 'c'
+        res = c0.throw(KeyError, to=c1)
+        assert res == 'd'
 
     def test_switch2_already_finished(self):
         from _continuation import continulet, error
@@ -643,6 +661,16 @@
             assert res == "done"
         main()
 
+    def test_bug_finish_with_already_finished_stacklet(self):
+        from _continuation import continulet, error
+        # make an already-finished continulet
+        c1 = continulet(lambda x: x)
+        c1.switch()
+        # make another continulet
+        c2 = continulet(lambda x: x)
+        # this switch is forbidden, because it causes a crash when c2 finishes
+        raises(error, c1.switch, to=c2)
+
     def test_various_depths(self):
         skip("may fail on top of CPython")
         # run it from test_translated, but not while being actually translated
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -52,7 +52,8 @@
 constants["CERT_OPTIONAL"] = PY_SSL_CERT_OPTIONAL
 constants["CERT_REQUIRED"] = PY_SSL_CERT_REQUIRED
 
-constants["PROTOCOL_SSLv2"]  = PY_SSL_VERSION_SSL2
+if not OPENSSL_NO_SSL2:
+    constants["PROTOCOL_SSLv2"]  = PY_SSL_VERSION_SSL2
 constants["PROTOCOL_SSLv3"]  = PY_SSL_VERSION_SSL3
 constants["PROTOCOL_SSLv23"] = PY_SSL_VERSION_SSL23
 constants["PROTOCOL_TLSv1"]  = PY_SSL_VERSION_TLS1
@@ -673,7 +674,7 @@
         method = libssl_TLSv1_method()
     elif protocol == PY_SSL_VERSION_SSL3:
         method = libssl_SSLv3_method()
-    elif protocol == PY_SSL_VERSION_SSL2:
+    elif protocol == PY_SSL_VERSION_SSL2 and not OPENSSL_NO_SSL2:
         method = libssl_SSLv2_method()
     elif protocol == PY_SSL_VERSION_SSL23:
         method = libssl_SSLv23_method()
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -508,7 +508,7 @@
         return space._type_issubtype(w_sub, w_type)
 
     def isinstance(space, w_inst, w_type):
-        return space._type_isinstance(w_inst, w_type)
+        return space.wrap(space._type_isinstance(w_inst, w_type))
 
     def issubtype_allow_override(space, w_sub, w_type):
         w_check = space.lookup(w_type, "__subclasscheck__")
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -370,8 +370,8 @@
     newdata = []
     for i in range(len(list_w)):
         w_s = list_w[i]
-        if not (space.is_true(space.isinstance(w_s, space.w_str)) or
-                space.is_true(space.isinstance(w_s, space.w_bytearray))):
+        if not (space.isinstance_w(w_s, space.w_str) or
+                space.isinstance_w(w_s, space.w_bytearray)):
             raise operationerrfmt(
                 space.w_TypeError,
                 "sequence item %d: expected string, %s "
diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py
--- a/pypy/objspace/std/complextype.py
+++ b/pypy/objspace/std/complextype.py
@@ -127,8 +127,8 @@
                and space.is_w(space.type(w_real), space.w_complex)):
         return w_real
 
-    if space.is_true(space.isinstance(w_real, space.w_str)) or \
-            space.is_true(space.isinstance(w_real, space.w_unicode)):
+    if space.isinstance_w(w_real, space.w_str) or \
+            space.isinstance_w(w_real, space.w_unicode):
         # a string argument
         if not noarg2:
             raise OperationError(space.w_TypeError,
@@ -203,8 +203,8 @@
         return (w_complex.realval, w_complex.imagval)
     #
     # Check that it is not a string (on which space.float() would succeed).
-    if (space.is_true(space.isinstance(w_complex, space.w_str)) or
-        space.is_true(space.isinstance(w_complex, space.w_unicode))):
+    if (space.isinstance_w(w_complex, space.w_str) or
+        space.isinstance_w(w_complex, space.w_unicode)):
         raise operationerrfmt(space.w_TypeError,
                               "complex number expected, got '%s'",
                               space.type(w_complex).getname(space))
diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py
--- a/pypy/objspace/std/floattype.py
+++ b/pypy/objspace/std/floattype.py
@@ -32,14 +32,14 @@
         if space.is_w(w_floattype, space.w_float):
             return w_obj
         value = space.float_w(w_obj)
-    elif space.is_true(space.isinstance(w_value, space.w_str)):
+    elif space.isinstance_w(w_value, space.w_str):
         strvalue = space.str_w(w_value)
         try:
             value = string_to_float(strvalue)
         except ParseStringError, e:
             raise OperationError(space.w_ValueError,
                                  space.wrap(e.msg))
-    elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+    elif space.isinstance_w(w_value, space.w_unicode):
         if space.config.objspace.std.withropeunicode:
             from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
         else:
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -425,15 +425,15 @@
                                      space.wrap("operand does not support "
                                                 "unary str"))
             w_result = space.get_and_call_function(w_impl, w_value)
-            if space.is_true(space.isinstance(w_result,
-                                              space.w_unicode)):
+            if space.isinstance_w(w_result,
+                                              space.w_unicode):
                 raise NeedUnicodeFormattingError
             return space.str_w(w_result)
 
         def fmt_s(self, w_value):
             space = self.space
-            got_unicode = space.is_true(space.isinstance(w_value,
-                                                         space.w_unicode))
+            got_unicode = space.isinstance_w(w_value,
+                                                         space.w_unicode)
             if not do_unicode:
                 if got_unicode:
                     raise NeedUnicodeFormattingError
@@ -452,13 +452,13 @@
         def fmt_c(self, w_value):
             self.prec = -1     # just because
             space = self.space
-            if space.is_true(space.isinstance(w_value, space.w_str)):
+            if space.isinstance_w(w_value, space.w_str):
                 s = space.str_w(w_value)
                 if len(s) != 1:
                     raise OperationError(space.w_TypeError,
                                          space.wrap("%c requires int or char"))
                 self.std_wp(s)
-            elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+            elif space.isinstance_w(w_value, space.w_unicode):
                 if not do_unicode:
                     raise NeedUnicodeFormattingError
                 ustr = space.unicode_w(w_value)
@@ -520,15 +520,15 @@
     return space.wrap(result)
 
 def mod_format(space, w_format, w_values, do_unicode=False):
-    if space.is_true(space.isinstance(w_values, space.w_tuple)):
+    if space.isinstance_w(w_values, space.w_tuple):
         values_w = space.fixedview(w_values)
         return format(space, w_format, values_w, None, do_unicode)
     else:
         # we check directly for dict to avoid obscure checking
         # in simplest case
-        if space.is_true(space.isinstance(w_values, space.w_dict)) or \
+        if space.isinstance_w(w_values, space.w_dict) or \
            (space.lookup(w_values, '__getitem__') and
-           not space.is_true(space.isinstance(w_values, space.w_basestring))):
+           not space.isinstance_w(w_values, space.w_basestring)):
             return format(space, w_format, [w_values], w_values, do_unicode)
         else:
             return format(space, w_format, [w_values], None, do_unicode)
diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py
--- a/pypy/objspace/std/inttype.py
+++ b/pypy/objspace/std/inttype.py
@@ -99,10 +99,10 @@
         if type(w_value) is W_IntObject:
             value = w_value.intval
             ok = True
-        elif space.is_true(space.isinstance(w_value, space.w_str)):
+        elif space.isinstance_w(w_value, space.w_str):
             value, w_longval = string_to_int_or_long(space, space.str_w(w_value))
             ok = True
-        elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+        elif space.isinstance_w(w_value, space.w_unicode):
             if space.config.objspace.std.withropeunicode:
                 from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
             else:
@@ -145,7 +145,7 @@
     else:
         base = space.int_w(w_base)
 
-        if space.is_true(space.isinstance(w_value, space.w_unicode)):
+        if space.isinstance_w(w_value, space.w_unicode):
             if space.config.objspace.std.withropeunicode:
                 from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
             else:
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -72,6 +72,10 @@
     w_seqiter.index += 1 
     return w_item
 
+# XXX __length_hint__()
+##def len__SeqIter(space,  w_seqiter):
+##    return w_seqiter.getlength(space)
+
 
 def iter__FastTupleIter(space, w_seqiter):
     return w_seqiter
@@ -89,6 +93,10 @@
     w_seqiter.index = index + 1
     return w_item
 
+# XXX __length_hint__()
+##def len__FastTupleIter(space, w_seqiter):
+##    return w_seqiter.getlength(space)
+
 
 def iter__FastListIter(space, w_seqiter):
     return w_seqiter
@@ -106,6 +114,10 @@
     w_seqiter.index = index + 1
     return w_item
 
+# XXX __length_hint__()
+##def len__FastListIter(space, w_seqiter):
+##    return w_seqiter.getlength(space)
+
 
 def iter__ReverseSeqIter(space, w_seqiter):
     return w_seqiter
@@ -123,5 +135,20 @@
         raise OperationError(space.w_StopIteration, space.w_None) 
     return w_item
 
+# XXX __length_hint__()
+##def len__ReverseSeqIter(space, w_seqiter):
+##    if w_seqiter.w_seq is None:
+##        return space.wrap(0)
+##    index = w_seqiter.index+1
+##    w_length = space.len(w_seqiter.w_seq)
+##    # if length of sequence is less than index :exhaust iterator
+##    if space.is_true(space.gt(space.wrap(w_seqiter.index), w_length)):
+##        w_len = space.wrap(0)
+##        w_seqiter.w_seq = None
+##    else:
+##        w_len =space.wrap(index)
+##    if space.is_true(space.lt(w_len,space.wrap(0))):
+##        w_len = space.wrap(0)
+##    return w_len
 
 register_all(vars())
diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py
--- a/pypy/objspace/std/longtype.py
+++ b/pypy/objspace/std/longtype.py
@@ -24,9 +24,9 @@
             return w_value
         elif type(w_value) is W_LongObject:
             return newbigint(space, w_longtype, w_value.num)
-        elif space.is_true(space.isinstance(w_value, space.w_str)):
+        elif space.isinstance_w(w_value, space.w_str):
             return string_to_w_long(space, w_longtype, space.str_w(w_value))
-        elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+        elif space.isinstance_w(w_value, space.w_unicode):
             if space.config.objspace.std.withropeunicode:
                 from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
             else:
@@ -51,7 +51,7 @@
     else:
         base = space.int_w(w_base)
 
-        if space.is_true(space.isinstance(w_value, space.w_unicode)):
+        if space.isinstance_w(w_value, space.w_unicode):
             from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
             s = unicode_to_decimal_w(space, w_value)
         else:
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -350,7 +350,7 @@
 SLOTS_STARTING_FROM = 3
 
 
-class BaseMapdictObject: # slightly evil to make it inherit from W_Root
+class BaseMapdictObject:
     _mixin_ = True
 
     def _init_empty(self, map):
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -571,5 +571,8 @@
 
     def _type_isinstance(self, w_inst, w_type):
         if isinstance(w_type, W_TypeObject):
-            return self.wrap(self.type(w_inst).issubtype(w_type))
+            return self.type(w_inst).issubtype(w_type)
         raise OperationError(self.w_TypeError, self.wrap("need type object"))
+
+    def isinstance_w(space, w_inst, w_type):
+        return space._type_isinstance(w_inst, w_type)
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -292,8 +292,8 @@
     l = []
     for i in range(size):
         w_s = list_w[i]
-        if not space.is_true(space.isinstance(w_s, space.w_str)):
-            if space.is_true(space.isinstance(w_s, space.w_unicode)):
+        if not space.isinstance_w(w_s, space.w_str):
+            if space.isinstance_w(w_s, space.w_unicode):
                 w_u = space.call_function(space.w_unicode, w_self)
                 return space.call_method(w_u, "join", space.newlist(list_w))
             raise operationerrfmt(
@@ -556,7 +556,7 @@
                                                 W_RopeObject.EMPTY, w_start,
                                                 w_end, True)
     for w_suffix in space.fixedview(w_suffixes):
-        if space.is_true(space.isinstance(w_suffix, space.w_unicode)):
+        if space.isinstance_w(w_suffix, space.w_unicode):
             w_u = space.call_function(space.w_unicode, w_self)
             return space.call_method(w_u, "endswith", w_suffixes, w_start,
                                      w_end)
@@ -576,7 +576,7 @@
     (self, _, start, end) = _convert_idx_params(space, w_self, W_RopeObject.EMPTY,
                                                   w_start, w_end, True)
     for w_prefix in space.fixedview(w_prefixes):
-        if space.is_true(space.isinstance(w_prefix, space.w_unicode)):
+        if space.isinstance_w(w_prefix, space.w_unicode):
             w_u = space.call_function(space.w_unicode, w_self)
             return space.call_method(w_u, "startswith", w_prefixes, w_start,
                                      w_end)
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -29,7 +29,7 @@
     assert isinstance(w_str, W_RopeObject)
     encoding = getdefaultencoding(space)
     w_retval = decode_string(space, w_str, encoding, "strict")
-    if not space.is_true(space.isinstance(w_retval, space.w_unicode)):
+    if not space.isinstance_w(w_retval, space.w_unicode):
         raise operationerrfmt(
             space.w_TypeError,
             "decoder did not return an unicode object (type '%s')",
@@ -254,7 +254,7 @@
         if isinstance(w_item, W_RopeUnicodeObject):
             # shortcut for performane
             item = w_item._node
-        elif space.is_true(space.isinstance(w_item, space.w_str)):
+        elif space.isinstance_w(w_item, space.w_str):
             item = unicode_from_string(space, w_item)._node
         else:
             msg = 'sequence item %d: expected string or Unicode'
@@ -828,14 +828,14 @@
         else:
             if space.is_w(w_newval, space.w_None):
                 continue
-            elif space.is_true(space.isinstance(w_newval, space.w_int)):
+            elif space.isinstance_w(w_newval, space.w_int):
                 newval = space.int_w(w_newval)
                 if newval < 0 or newval > maxunicode:
                     raise OperationError(
                             space.w_TypeError,
                             space.wrap("character mapping must be in range(0x%x)" % (maxunicode + 1,)))
                 result.append(rope.rope_from_unichar(unichr(newval)))
-            elif space.is_true(space.isinstance(w_newval, space.w_unicode)):
+            elif space.isinstance_w(w_newval, space.w_unicode):
                 result.append(ropeunicode_w(space, w_newval))
             else:
                 raise OperationError(
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -132,7 +132,7 @@
         w_obj.setdata = make_setdata_from_w_iterable(space, w_iterable)
 
 def _convert_set_to_frozenset(space, w_obj):
-    if space.is_true(space.isinstance(w_obj, space.w_set)):
+    if space.isinstance_w(w_obj, space.w_set):
         return W_FrozensetObject(space,
                                  make_setdata_from_w_iterable(space, w_obj))
     else:
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -364,8 +364,8 @@
     reslen = len(self) * (size - 1)
     for i in range(size):
         w_s = list_w[i]
-        if not space.is_true(space.isinstance(w_s, space.w_str)):
-            if space.is_true(space.isinstance(w_s, space.w_unicode)):
+        if not space.isinstance_w(w_s, space.w_str):
+            if space.isinstance_w(w_s, space.w_unicode):
                 # we need to rebuild w_list here, because the original
                 # w_list might be an iterable which we already consumed
                 w_list = space.newlist(list_w)
@@ -646,7 +646,7 @@
                                                   space.wrap(''), w_start,
                                                   w_end, True)
     for w_suffix in space.fixedview(w_suffixes):
-        if space.is_true(space.isinstance(w_suffix, space.w_unicode)):
+        if space.isinstance_w(w_suffix, space.w_unicode):
             w_u = space.call_function(space.w_unicode, w_self)
             return space.call_method(w_u, "endswith", w_suffixes, w_start,
                                      w_end)
@@ -665,7 +665,7 @@
     (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''),
                                                   w_start, w_end, True)
     for w_prefix in space.fixedview(w_prefixes):
-        if space.is_true(space.isinstance(w_prefix, space.w_unicode)):
+        if space.isinstance_w(w_prefix, space.w_unicode):
             w_u = space.call_function(space.w_unicode, w_self)
             return space.call_method(w_u, "startswith", w_prefixes, w_start,
                                      w_end)
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -508,15 +508,15 @@
             # type name.  That's a hack, so we're allowed to use a different
             # hack...
             if ('__module__' in w_self.dict_w and
-                space.is_true(space.isinstance(w_self.getdictvalue(space, '__module__'),
-                                               space.w_str))):
+                space.isinstance_w(w_self.getdictvalue(space, '__module__'),
+                                               space.w_str)):
                 return w_self.getdictvalue(space, '__module__')
             return space.wrap('__builtin__')
 
     def get_module_type_name(w_self):
         space = w_self.space
         w_mod = w_self.get_module()
-        if not space.is_true(space.isinstance(w_mod, space.w_str)):
+        if not space.isinstance_w(w_mod, space.w_str):
             mod = '__builtin__'
         else:
             mod = space.str_w(w_mod)
@@ -850,7 +850,7 @@
             not space.is_w(w_newtype, space.w_type)):
             w_type.w_bltin_new = w_newfunc
         w_newobject = space.call_obj_args(w_newfunc, w_type, __args__)
-        call_init = space.is_true(space.isinstance(w_newobject, w_type))
+        call_init = space.isinstance_w(w_newobject, w_type)
 
     # maybe invoke the __init__ of the type
     if call_init:
@@ -876,7 +876,7 @@
 
 def repr__Type(space, w_obj):
     w_mod = w_obj.get_module()
-    if not space.is_true(space.isinstance(w_mod, space.w_str)):
+    if not space.isinstance_w(w_mod, space.w_str):
         mod = None
     else:
         mod = space.str_w(w_mod)
diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py
--- a/pypy/objspace/std/typetype.py
+++ b/pypy/objspace/std/typetype.py
@@ -110,7 +110,7 @@
     if not w_type.is_heaptype():
         raise operationerrfmt(space.w_TypeError,
                               "can't set %s.__bases__", w_type.name)
-    if not space.is_true(space.isinstance(w_value, space.w_tuple)):
+    if not space.isinstance_w(w_value, space.w_tuple):
         raise operationerrfmt(space.w_TypeError,
                               "can only assign tuple to %s.__bases__, not %s",
                               w_type.name,
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -900,14 +900,14 @@
         else:
             if space.is_w(w_newval, space.w_None):
                 continue
-            elif space.is_true(space.isinstance(w_newval, space.w_int)):
+            elif space.isinstance_w(w_newval, space.w_int):
                 newval = space.int_w(w_newval)
                 if newval < 0 or newval > maxunicode:
                     raise OperationError(
                             space.w_TypeError,
                             space.wrap("character mapping must be in range(0x%x)" % (maxunicode + 1,)))
                 result.append(unichr(newval))
-            elif space.is_true(space.isinstance(w_newval, space.w_unicode)):
+            elif space.isinstance_w(w_newval, space.w_unicode):
                 result.append(space.unicode_w(w_newval))
             else:
                 raise OperationError(
diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py
--- a/pypy/objspace/std/unicodetype.py
+++ b/pypy/objspace/std/unicodetype.py
@@ -251,7 +251,7 @@
         w_errors = space.wrap(errors)
     w_restuple = space.call_function(w_encoder, w_object, w_errors)
     w_retval = space.getitem(w_restuple, space.wrap(0))
-    if not space.is_true(space.isinstance(w_retval, space.w_str)):
+    if not space.isinstance_w(w_retval, space.w_str):
         raise operationerrfmt(space.w_TypeError,
             "encoder did not return an string object (type '%s')",
             space.type(w_retval).getname(space))
@@ -286,7 +286,7 @@
 
 def unicode_from_encoded_object(space, w_obj, encoding, errors):
     w_retval = decode_object(space, w_obj, encoding, errors)
-    if not space.is_true(space.isinstance(w_retval, space.w_unicode)):
+    if not space.isinstance_w(w_retval, space.w_unicode):
         raise operationerrfmt(space.w_TypeError,
             "decoder did not return an unicode object (type '%s')",
             space.type(w_retval).getname(space))
@@ -309,7 +309,7 @@
             w_res = space.get_and_call_function(w_unicode_method, w_obj)
         else:
             w_res = space.str(w_obj)
-        if space.is_true(space.isinstance(w_res, space.w_unicode)):
+        if space.isinstance_w(w_res, space.w_unicode):
             return w_res
     return unicode_from_encoded_object(space, w_res, None, "strict")
 
@@ -346,7 +346,7 @@
     # convoluted logic for the case when unicode subclass has a __unicode__
     # method, we need to call this method
     if (space.is_w(space.type(w_obj), space.w_unicode) or
-        (space.is_true(space.isinstance(w_obj, space.w_unicode)) and
+        (space.isinstance_w(w_obj, space.w_unicode) and
          space.findattr(w_obj, space.wrap('__unicode__')) is None)):
         if encoding is not None or errors is not None:
             raise OperationError(space.w_TypeError,
diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py
--- a/pypy/rlib/ropenssl.py
+++ b/pypy/rlib/ropenssl.py
@@ -62,6 +62,8 @@
         "OPENSSL_VERSION_NUMBER")
     SSLEAY_VERSION = rffi_platform.DefinedConstantString(
         "SSLEAY_VERSION", "SSLeay_version(SSLEAY_VERSION)")
+    OPENSSL_NO_SSL2 = rffi_platform.DefinedConstantInteger(
+        "OPENSSL_NO_SSL2")
     SSL_FILETYPE_PEM = rffi_platform.ConstantInteger("SSL_FILETYPE_PEM")
     SSL_OP_ALL = rffi_platform.ConstantInteger("SSL_OP_ALL")
     SSL_VERIFY_NONE = rffi_platform.ConstantInteger("SSL_VERIFY_NONE")
diff --git a/pypy/rlib/rstacklet.py b/pypy/rlib/rstacklet.py
--- a/pypy/rlib/rstacklet.py
+++ b/pypy/rlib/rstacklet.py
@@ -1,6 +1,8 @@
 from pypy.rlib import _rffi_stacklet as _c
 from pypy.rpython.lltypesystem import lltype, llmemory
 
+DEBUG = False
+
 
 class StackletThread(object):
 
@@ -10,15 +12,30 @@
         if not self._thrd:
             raise MemoryError
         self._thrd_deleter = StackletThreadDeleter(self._thrd)
+        if DEBUG:
+            assert debug.sthread is None, "multithread debug support missing"
+            debug.sthread = self
 
     def new(self, callback, arg=llmemory.NULL):
-        return self._gcrootfinder.new(self, callback, arg)
+        if DEBUG:
+            callback = _debug_wrapper(callback)
+        h = self._gcrootfinder.new(self, callback, arg)
+        if DEBUG:
+            debug.add(h)
+        return h
     new._annspecialcase_ = 'specialize:arg(1)'
 
     def switch(self, stacklet):
-        return self._gcrootfinder.switch(self, stacklet)
+        if DEBUG:
+            debug.remove(stacklet)
+        h = self._gcrootfinder.switch(self, stacklet)
+        if DEBUG:
+            debug.add(h)
+        return h
 
     def destroy(self, stacklet):
+        if DEBUG:
+            debug.remove(stacklet)
         self._gcrootfinder.destroy(self, stacklet)
 
     def is_empty_handle(self, stacklet):
@@ -56,3 +73,34 @@
                         None, None, ['__doc__'])
     return module.gcrootfinder
 _getgcrootfinder._annspecialcase_ = 'specialize:memo'
+
+
+class StackletDebugError(Exception):
+    pass
+
+class Debug(object):
+    def __init__(self):
+        self.sthread = None
+        self.active = []
+    def _freeze_(self):
+        self.__init__()
+        return False
+    def add(self, h):
+        if not self.sthread.is_empty_handle(h):
+            self.active.append(h)
+    def remove(self, h):
+        try:
+            i = self.active.index(h)
+        except ValueError:
+            raise StackletDebugError
+        del self.active[i]
+debug = Debug()
+
+def _debug_wrapper(callback):
+    def wrapper(h, arg):
+        debug.add(h)
+        h = callback(h, arg)
+        debug.remove(h)
+        return h
+    return wrapper
+_debug_wrapper._annspecialcase_ = 'specialize:memo'
diff --git a/pypy/rpython/memory/gctransform/asmgcroot.py b/pypy/rpython/memory/gctransform/asmgcroot.py
--- a/pypy/rpython/memory/gctransform/asmgcroot.py
+++ b/pypy/rpython/memory/gctransform/asmgcroot.py
@@ -636,7 +636,8 @@
                                       ASM_FRAMEDATA_HEAD_PTR],
                                      lltype.Signed,
                                      sandboxsafe=True,
-                                     _nowrapper=True)
+                                     _nowrapper=True,
+                                     random_effects_on_gcobjs=True)
 c_asm_stackwalk = Constant(pypy_asm_stackwalk,
                            lltype.typeOf(pypy_asm_stackwalk))
 
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -41,7 +41,7 @@
                                                               seen)
     def analyze_external_call(self, op, seen=None):
         funcobj = op.args[0].value._obj
-        if funcobj._name == 'pypy_asm_stackwalk':
+        if getattr(funcobj, 'random_effects_on_gcobjs', False):
             return True
         return graphanalyze.GraphAnalyzer.analyze_external_call(self, op,
                                                                 seen)
diff --git a/pypy/rpython/test/test_rbuilder.py b/pypy/rpython/test/test_rbuilder.py
--- a/pypy/rpython/test/test_rbuilder.py
+++ b/pypy/rpython/test/test_rbuilder.py
@@ -101,6 +101,23 @@
         res = self.interpret(func, [1])
         assert res
 
+    def test_unicode_builder_or_none(self):
+        def g(s):
+            if s:
+                s.append(u"3")
+            return bool(s)
+        
+        def func(i):
+            if i:
+                s = UnicodeBuilder()
+            else:
+                s = None
+            return g(s)
+        res = self.interpret(func, [0])
+        assert not res
+        res = self.interpret(func, [1])
+        assert res
+
 
 class TestLLtype(BaseTestStringBuilder, LLRtypeMixin):
     pass
diff --git a/pypy/translator/unsimplify.py b/pypy/translator/unsimplify.py
--- a/pypy/translator/unsimplify.py
+++ b/pypy/translator/unsimplify.py
@@ -97,6 +97,23 @@
     if _forcelink is not None:
         assert index == 0
         linkargs = list(_forcelink)
+        for v in varmap:
+            if v not in linkargs:
+                # 'v' was not specified by _forcelink, but we found out that
+                # we need it!  Hack: if it is 'concretetype is lltype.Void'
+                # then it's ok to recreate its value in the target block.
+                # If not, then we have a problem :-)
+                from pypy.rpython.lltypesystem import lltype
+                assert v.concretetype is lltype.Void
+                c = Constant(None, lltype.Void)
+                w = varmap[v]
+                newop = SpaceOperation('same_as', [c], w)
+                i = 0
+                while i < len(moved_operations):
+                    if w in moved_operations[i].args:
+                        break
+                    i += 1
+                moved_operations.insert(i, newop)
     else:
         linkargs = varmap.keys()
     newblock = Block([get_new_name(v) for v in linkargs])


More information about the pypy-commit mailing list