[pypy-commit] pypy stacklet: Because it's not much code, and for symmetry, implement
arigo
noreply at buildbot.pypy.org
Fri Aug 19 01:29:50 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46620:f3d97e54818d
Date: 2011-08-18 22:59 +0200
http://bitbucket.org/pypy/pypy/changeset/f3d97e54818d/
Log: Because it's not much code, and for symmetry, implement
c1.throw(exc, value, tb, to), giving an explicit "to", like in
c1.switch().
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
@@ -48,7 +48,14 @@
start_state.clear()
raise getmemoryerror(self.space)
- def switch(self, to=None):
+ def switch(self, w_to):
+ to = self.space.interp_w(W_Continulet, w_to, can_be_None=True)
+ if to is not None:
+ if self is to: # double-switch to myself: no-op
+ return get_result()
+ if to.sthread is None:
+ start_state.clear()
+ raise geterror(self.space, "continulet not initialized yet")
if self.sthread is None:
start_state.clear()
raise geterror(self.space, "continulet not initialized yet")
@@ -77,26 +84,13 @@
#
ec = sthread.ec
ec.topframeref = saved_topframeref
- 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
+ return get_result()
def descr_switch(self, w_value=None, w_to=None):
- to = self.space.interp_w(W_Continulet, w_to, can_be_None=True)
- if to is not None:
- if self is to: # double-switch to myself: no-op
- return w_value
- if to.sthread is None:
- start_state.clear()
- raise geterror(self.space, "continulet not initialized yet")
start_state.w_value = w_value
- return self.switch(to)
+ return self.switch(w_to)
- def descr_throw(self, w_type, w_val=None, w_tb=None):
+ def descr_throw(self, w_type, w_val=None, w_tb=None, w_to=None):
from pypy.interpreter.pytraceback import check_traceback
space = self.space
#
@@ -108,8 +102,9 @@
#
operr = OperationError(w_type, w_val, tb)
operr.normalize_exception(space)
+ start_state.w_value = None
start_state.propagate_exception = operr
- return self.switch()
+ return self.switch(w_to)
def descr_is_pending(self):
valid = (self.sthread is not None
@@ -218,3 +213,12 @@
start_state.origin = None
start_state.destination = None
self.h, origin.h = origin.h, h
+
+def get_result():
+ 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
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
@@ -576,6 +576,38 @@
c1 = continulet(f1)
raises(IndexError, c1.throw, IndexError)
+ def test_throw2_simple(self):
+ from _continuation import continulet
+ #
+ def f1(c1):
+ not_reached
+ def f2(c2):
+ try:
+ c2.switch("ready")
+ except IndexError:
+ raise ValueError
+ #
+ c1 = continulet(f1)
+ c2 = continulet(f2)
+ res = c2.switch()
+ assert res == "ready"
+ assert c1.is_pending()
+ assert c2.is_pending()
+ raises(ValueError, c1.throw, IndexError, to=c2)
+ assert not c1.is_pending()
+ assert not c2.is_pending()
+
+ def test_throw2_no_op(self):
+ from _continuation import continulet
+ #
+ def f1(c1):
+ raises(ValueError, c1.throw, ValueError, to=c1)
+ return "ok"
+ #
+ c1 = continulet(f1)
+ res = c1.switch()
+ assert res == "ok"
+
def test_various_depths(self):
skip("may fail on top of CPython")
# run it from test_translated, but not while being actually translated
More information about the pypy-commit
mailing list