[pypy-commit] lang-smalltalk default: moved the returning-context identification from the copy of returnTopFromMethod to s_home, because simply overwriting returnTopFromMethod in MethodContextShadow is not sufficient for implementing Non-local-return. E.g. ReturnNil also needs that changed behavior.
lwassermann
noreply at buildbot.pypy.org
Tue May 28 18:27:18 CEST 2013
Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch:
Changeset: r418:0c6b78a77dca
Date: 2013-05-28 18:24 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/0c6b78a77dca/
Log: moved the returning-context identification from the copy of
returnTopFromMethod to s_home, because simply overwriting
returnTopFromMethod in MethodContextShadow is not sufficient for
implementing Non-local-return. E.g. ReturnNil also needs that
changed behavior.
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -447,7 +447,6 @@
return self._return(interp.space.w_nil, interp, self.s_home().s_sender())
def returnTopFromMethod(self, interp, current_bytecode):
- # overwritten in MethodContextShadow
return self._return(self.pop(), interp, self.s_home().s_sender())
def returnTopFromBlock(self, interp, current_bytecode):
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -947,7 +947,18 @@
return self.w_self()
def s_home(self):
- return self
+ if self.is_closure_context():
+ # this is a context for a blockClosure
+ w_outerContext = self.w_closure_or_nil.fetch(self.space,
+ constants.BLKCLSR_OUTER_CONTEXT)
+ assert isinstance(w_outerContext, model.W_PointersObject)
+ s_outerContext = w_outerContext.as_context_get_shadow(self.space)
+ # XXX check whether we can actually return from that context
+ if s_outerContext.pc() == -1:
+ raise error.BlockCannotReturnError()
+ return s_outerContext.s_home()
+ else:
+ return self
def stackpointer_offset(self):
return constants.MTHDCTX_TEMP_FRAME_START
@@ -958,21 +969,6 @@
def myblocksize(self):
return self.size() - self.tempsize()
- def returnTopFromMethod(self, interp, current_bytecode):
- if self.is_closure_context():
- # this is a context for a blockClosure
- w_outerContext = self.w_closure_or_nil.fetch(self.space,
- constants.BLKCLSR_OUTER_CONTEXT)
- assert isinstance(w_outerContext, model.W_PointersObject)
- s_outerContext = w_outerContext.as_context_get_shadow(self.space)
- # XXX check whether we can actually return from that context
- if s_outerContext.pc() == -1:
- raise error.BlockCannotReturnError()
- return_to_context = s_outerContext.s_home().s_sender()
- else:
- return_to_context = self.s_home().s_sender()
- return self._return(self.pop(), interp, return_to_context)
-
def is_closure_context(self):
return self.w_closure_or_nil is not self.space.w_nil
diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py
--- a/spyvm/test/test_shadow.py
+++ b/spyvm/test/test_shadow.py
@@ -282,3 +282,14 @@
assert w_context.fetch(space, constants.CTXPART_PC_INDEX) is not space.w_nil
s_context.mark_returned()
assert w_context.fetch(space, constants.CTXPART_PC_INDEX) is space.w_nil
+
+def test_methodcontext_s_home():
+ from spyvm.wrapper import BlockClosureWrapper
+ w_context = methodcontext()
+ s_context = w_context.as_methodcontext_get_shadow(space)
+ w_middle_context = methodcontext(w_sender=w_context)
+ s_middle_context = w_middle_context.as_methodcontext_get_shadow(space)
+
+ w_closure = space.newClosure(w_context, 3, 0, [])
+ s_closure_context = BlockClosureWrapper(space, w_closure).asContextWithSender(w_middle_context, [])
+ assert s_closure_context.s_home() is s_context
More information about the pypy-commit
mailing list