[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