[pypy-commit] pypy framestate: Split RETURN_VALUE into 2 intructions and store the active return value on the flow context
rlamy
noreply at buildbot.pypy.org
Sat Feb 14 19:48:15 CET 2015
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: framestate
Changeset: r75873:e4db2b64834f
Date: 2015-02-14 18:41 +0000
http://bitbucket.org/pypy/pypy/changeset/e4db2b64834f/
Log: Split RETURN_VALUE into 2 intructions and store the active return
value on the flow context
diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -253,7 +253,7 @@
if not b._exits:
instr = b.operations[-1]
assert instr.name in (
- 'RETURN_VALUE', 'RAISE_VARARGS', 'EXEC_STMT')
+ 'RETURN', 'RAISE_VARARGS', 'EXEC_STMT')
for x in b._exits:
assert x in self.blocks
@@ -630,13 +630,24 @@
@bc_reader.register_opcode
class RETURN_VALUE(NullaryOpcode):
def bc_flow(self, reader):
- reader.curr_block.operations.append(self)
+ block = reader.curr_block
+ block.operations.append(SET_RETURN_VALUE(offset=self.offset))
+ block.operations.append(RETURN(offset=self.offset))
reader.end_block()
+class SET_RETURN_VALUE(NullaryOpcode):
+ num = name = 'SET_RETURN_VALUE'
+ arg = NO_ARG
+ def eval(self, ctx):
+ w_value = ctx.popvalue()
+ ctx.w_return_value = w_value
+
+class RETURN(NullaryOpcode):
+ num = name = 'RETURN'
+ arg = NO_ARG
def eval(self, ctx):
from rpython.flowspace.flowcontext import Return
- w_returnvalue = ctx.popvalue()
- raise Return(w_returnvalue)
+ raise Return()
@bc_reader.register_opcode
class END_FINALLY(NullaryOpcode):
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -291,13 +291,15 @@
def getstate(self, position):
return FrameState(self.locals_w[:], self.stack[:],
- self.last_exception, self.blockstack[:], position)
+ self.last_exception, self.w_return_value,
+ self.blockstack[:], position)
def setstate(self, state):
""" Reset the context to the given frame state. """
self.locals_w = state.locals_w[:]
self.stack = state.stack[:]
self.last_exception = state.last_exception
+ self.w_return_value = state.w_return_value
self.blockstack = state.blocklist[:]
self._normalize_raise_signals()
@@ -606,7 +608,8 @@
w_module = self.peekvalue()
self.pushvalue(self.import_from(w_module, w_name))
- def return_value(self, w_result):
+ def do_return(self):
+ w_result = self.w_return_value
link = Link([w_result], self.graph.returnblock)
self.recorder.crnt_block.closeblock(link)
raise StopFlowing
@@ -1008,22 +1011,18 @@
class Return(FlowSignal):
- """Signals a 'return' statement.
- Argument is the wrapped object to return.
- """
- def __init__(self, w_value):
- self.w_value = w_value
-
+ """Signals a 'return' statement. """
def nomoreblocks(self, ctx):
- ctx.return_value(self.w_value)
+ ctx.do_return()
@property
def args(self):
- return [self.w_value]
+ return []
@staticmethod
- def rebuild(w_value):
- return Return(w_value)
+ def rebuild():
+ return Return()
+
class Raise(FlowSignal):
"""Signals an application-level exception
diff --git a/rpython/flowspace/framestate.py b/rpython/flowspace/framestate.py
--- a/rpython/flowspace/framestate.py
+++ b/rpython/flowspace/framestate.py
@@ -16,10 +16,12 @@
class FrameState(object):
- def __init__(self, locals_w, stack, last_exception, blocklist, position):
+ def __init__(self, locals_w, stack, last_exception, w_return_value,
+ blocklist, position):
self.locals_w = locals_w
self.stack = stack
self.last_exception = last_exception
+ self.w_return_value = w_return_value
self.blocklist = blocklist
self.position = position
self._mergeable = None
@@ -35,6 +37,7 @@
else:
data.append(self.last_exception.w_type)
data.append(self.last_exception.w_value)
+ data.append(self.w_return_value)
recursively_flatten(data)
return data
@@ -44,7 +47,7 @@
if exc is not None:
exc = FSException(_copy(exc.w_type), _copy(exc.w_value))
return FrameState(map(_copy, self.locals_w), map(_copy, self.stack),
- exc, self.blocklist, self.position)
+ exc, _copy(self.w_return_value), self.blocklist, self.position)
def getvariables(self):
return [w for w in self.mergeable if isinstance(w, Variable)]
@@ -84,9 +87,10 @@
args2 = other._exc_args()
exc = FSException(union(args1[0], args2[0]),
union(args1[1], args2[1]))
+ w_rv = union(self.w_return_value, other.w_return_value)
except UnionError:
return None
- return FrameState(locals, stack, exc, self.blocklist, self.position)
+ return FrameState(locals, stack, exc, w_rv, self.blocklist, self.position)
def getoutputargs(self, targetstate):
"Return the output arguments needed to link self to targetstate."
diff --git a/rpython/flowspace/pygraph.py b/rpython/flowspace/pygraph.py
--- a/rpython/flowspace/pygraph.py
+++ b/rpython/flowspace/pygraph.py
@@ -16,7 +16,7 @@
locals[i] = Variable(code.co_varnames[i])
bc_graph = code.graph
start_pos = bc_graph.entry._exits[0], 0
- state = FrameState(locals, [], None, [], start_pos)
+ state = FrameState(locals, [], None, None, [], start_pos)
initialblock = SpamBlock(state)
super(PyGraph, self).__init__(self._sanitize_funcname(func), initialblock)
self.func = func
diff --git a/rpython/flowspace/test/test_flowcontext.py b/rpython/flowspace/test/test_flowcontext.py
--- a/rpython/flowspace/test/test_flowcontext.py
+++ b/rpython/flowspace/test/test_flowcontext.py
@@ -5,7 +5,7 @@
Return, Raise, RaiseImplicit, Continue, Break)
@pytest.mark.parametrize('signal', [
- Return(Variable()),
+ Return(),
Raise(FSException(Variable(), Variable())),
RaiseImplicit(FSException(Variable(), Variable())),
Break(),
More information about the pypy-commit
mailing list