[pypy-commit] pypy stacklet: Exception support.

arigo noreply at buildbot.pypy.org
Wed Aug 17 17:49:32 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46563:9f78054283f7
Date: 2011-08-17 17:51 +0200
http://bitbucket.org/pypy/pypy/changeset/9f78054283f7/

Log:	Exception support.

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
@@ -35,17 +35,27 @@
 
     def descr_init(self, w_callable):
         if self.h:
-            raise geterror(self.space, "continuation already filled")
+            raise geterror(self.space, "continuation already __init__ialized")
         sthread = self.build_sthread()
         start_state.origin = self
         start_state.w_callable = w_callable
-        self.h = self.sthread.new(new_stacklet_callback)
-        if not self.h:
+        try:
+            self.h = sthread.new(new_stacklet_callback)
+            if sthread.is_empty_handle(self.h):    # early return
+                raise MemoryError
+        except MemoryError:
             raise getmemoryerror(self.space)
 
     def descr_switch(self, w_value=None):
         start_state.w_value = w_value
-        self.h = self.sthread.switch(self.h)
+        try:
+            self.h = self.sthread.switch(self.h)
+        except MemoryError:
+            raise getmemoryerror(self.space)
+        if start_state.propagate_exception:
+            e = start_state.propagate_exception
+            start_state.propagate_exception = None
+            raise e
         w_value = start_state.w_value
         start_state.w_value = None
         return w_value
@@ -118,6 +128,7 @@
         self.w_callable = None
         self.args = None
         self.w_value = None
+        self.propagate_exception = None
 start_state = StartState()
 start_state.clear()
 
@@ -126,10 +137,17 @@
     self = start_state.origin
     w_callable = start_state.w_callable
     start_state.clear()
-    self.h = self.sthread.switch(h)
+    try:
+        self.h = self.sthread.switch(h)
+    except MemoryError:
+        return h       # oups!  do an early return in this case
     #
     space = self.space
-    w_result = space.call_function(w_callable, space.wrap(self))
-    #
-    start_state.w_value = w_result
-    return self.h
+    try:
+        w_result = space.call_function(w_callable, space.wrap(self))
+    except Exception, e:
+        start_state.propagate_exception = e
+        return self.h
+    else:
+        start_state.w_value = w_result
+        return self.h
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
@@ -54,31 +54,18 @@
         assert res == 42
         raises(error, c.__init__, empty_callback)
 
-    def test_bogus_return_value(self):
-        from _continuation import new
+    def test_propagate_exception(self):
+        from _continuation import continuation
         #
-        def empty_callback(h):
-            assert h.is_pending()
-            seen.append(h)
-            return 42
-        #
-        seen = []
-        raises(TypeError, new, empty_callback)
-        assert len(seen) == 1
-        assert not seen[0].is_pending()
-
-    def test_propagate_exception(self):
-        from _continuation import new
-        #
-        def empty_callback(h):
-            assert h.is_pending()
-            seen.append(h)
+        def empty_callback(c1):
+            assert c1 is c
+            seen.append(42)
             raise ValueError
         #
         seen = []
-        raises(ValueError, new, empty_callback)
-        assert len(seen) == 1
-        assert not seen[0].is_pending()
+        c = continuation(empty_callback)
+        raises(ValueError, c.switch)
+        assert seen == [42]
 
     def test_callback_with_arguments(self):
         from _continuation import new


More information about the pypy-commit mailing list