[pypy-commit] lang-smalltalk storage-context-state-v3: Added LocalReturn. this is where it breaks.
anton_gulenko
noreply at buildbot.pypy.org
Mon Jul 28 10:11:31 CEST 2014
Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage-context-state-v3
Changeset: r994:3bd27f741c83
Date: 2014-07-27 00:25 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/3bd27f741c83/
Log: Added LocalReturn. this is where it breaks.
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -12,10 +12,15 @@
class Return(Exception):
_attrs_ = ["value", "s_target_context", "is_local"]
- def __init__(self, s_target_context, w_result):
+ def __init__(self, s_target_context, w_result, is_local):
self.value = w_result
self.s_target_context = s_target_context
- self.is_local = False
+ self.is_local = is_local
+
+class LocalReturn(Exception):
+ _attrs_ = ["value"]
+ def __init__(self, value):
+ self.value = value
class ContextSwitchException(Exception):
"""General Exception that causes the interpreter to leave
@@ -104,14 +109,16 @@
if self.is_tracing() or self.trace_important:
e.print_trace(s_new_context)
s_new_context = e.s_new_context
+ except LocalReturn, nlr:
+ s_new_context = s_sender
+ s_new_context.push(nlr.value)
except Return, nlr:
- assert nlr.s_target_context or nlr.is_local
+ assert nlr.s_target_context and not nlr.is_local
s_new_context = s_sender
- if not nlr.is_local:
- while s_new_context is not nlr.s_target_context:
- s_sender = s_new_context.s_sender()
- s_new_context._activate_unwind_context(self)
- s_new_context = s_sender
+ while s_new_context is not nlr.s_target_context:
+ s_sender = s_new_context.s_sender()
+ s_new_context._activate_unwind_context(self)
+ s_new_context = s_sender
s_new_context.push(nlr.value)
# This is a wrapper around loop_bytecodes that cleanly enters/leaves the frame
@@ -124,6 +131,12 @@
s_frame.store_s_sender(s_sender, raise_error=False)
# Now (continue to) execute the context bytecodes
self.loop_bytecodes(s_frame, may_context_switch)
+ except Return, ret:
+ s_frame._activate_unwind_context(self)
+ if ret.s_target_context is s_sender or ret.is_local:
+ raise LocalReturn(ret.value)
+ else:
+ raise ret
except rstackovf.StackOverflow:
rstackovf.check_stack_overflow()
raise StackOverflow(s_frame)
@@ -151,16 +164,8 @@
s_context=s_context)
try:
self.step(s_context)
- except Return, nlr:
- if nlr.s_target_context is s_context or nlr.is_local:
- s_context.push(nlr.value)
- else:
- if nlr.s_target_context is None:
- # This is the case where we are returning to our sender.
- # Mark the return as local, so our sender will take it
- nlr.is_local = True
- s_context._activate_unwind_context(self)
- raise nlr
+ except LocalReturn, ret:
+ s_context.push(ret.value)
def step(self, context):
bytecode = context.fetch_next_bytecode()
diff --git a/spyvm/interpreter_bytecodes.py b/spyvm/interpreter_bytecodes.py
--- a/spyvm/interpreter_bytecodes.py
+++ b/spyvm/interpreter_bytecodes.py
@@ -394,8 +394,10 @@
# it will find the sender as a local, and we don't have to
# force the reference
s_return_to = None
+ is_local = True
return_from_top = self.s_sender() is None
else:
+ is_local = False
s_return_to = self.s_home().s_sender()
return_from_top = s_return_to is None
@@ -405,7 +407,7 @@
raise ReturnFromTopLevel(return_value)
else:
from spyvm.interpreter import Return
- raise Return(s_return_to, return_value)
+ raise Return(s_return_to, return_value, is_local)
# ====== Send/Return bytecodes ======
@@ -508,13 +510,11 @@
if self.gettemp(1).is_nil(self.space):
self.settemp(1, self.space.w_true) # mark unwound
self.push(self.gettemp(0)) # push the first argument
- from spyvm.interpreter import Return
+ from spyvm.interpreter import LocalReturn
try:
self.bytecodePrimValue(interp, 0)
- except Return, nlr:
- assert nlr.s_target_context or nlr.is_local
- if self is not nlr.s_target_context and not nlr.is_local:
- raise nlr
+ except LocalReturn:
+ pass # Ignore local return value of ensure block.
finally:
self.mark_returned()
More information about the pypy-commit
mailing list