[pypy-commit] pypy translation-cleanup: Remove FlowExecutionContext: merge it with FlowSpaceFrame.

rlamy noreply at buildbot.pypy.org
Thu Sep 20 19:39:06 CEST 2012


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: translation-cleanup
Changeset: r57422:0298c7f450b5
Date: 2012-09-14 19:42 +0100
http://bitbucket.org/pypy/pypy/changeset/0298c7f450b5/

Log:	Remove FlowExecutionContext: merge it with FlowSpaceFrame.

diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py
--- a/pypy/objspace/flow/flowcontext.py
+++ b/pypy/objspace/flow/flowcontext.py
@@ -83,7 +83,7 @@
     def bytecode_trace(self, frame):
         pass
 
-    def guessbool(self, ec, w_condition, **kwds):
+    def guessbool(self, frame, w_condition, **kwds):
         raise AssertionError, "cannot guessbool(%s)" % (w_condition,)
 
 
@@ -120,13 +120,13 @@
             # before.
             self.last_join_point = frame.getstate()
 
-    def guessbool(self, ec, w_condition):
+    def guessbool(self, frame, w_condition):
         block = self.crnt_block
         vars = block.getvariables()
         links = []
         for case in [False, True]:
             egg = EggBlock(vars, block, case)
-            ec.pendingblocks.append(egg)
+            frame.pendingblocks.append(egg)
             link = Link(vars, egg, case)
             links.append(link)
 
@@ -138,7 +138,7 @@
         # block.exits[True] = ifLink.
         raise StopFlowing
 
-    def guessexception(self, ec, *cases):
+    def guessexception(self, frame, *cases):
         block = self.crnt_block
         bvars = vars = vars2 = block.getvariables()
         links = []
@@ -155,7 +155,7 @@
                 vars.extend([last_exc, last_exc_value])
                 vars2.extend([Variable(), Variable()])
             egg = EggBlock(vars2, block, case)
-            ec.pendingblocks.append(egg)
+            frame.pendingblocks.append(egg)
             link = Link(vars, egg, case)
             if case is not None:
                 link.extravars(last_exception=last_exc, last_exc_value=last_exc_value)
@@ -186,14 +186,14 @@
                       [str(s) for s in self.listtoreplay[self.index:]]))
         self.index += 1
 
-    def guessbool(self, ec, w_condition, **kwds):
+    def guessbool(self, frame, w_condition, **kwds):
         assert self.index == len(self.listtoreplay)
-        ec.recorder = self.nextreplayer
+        frame.recorder = self.nextreplayer
         return self.booloutcome
 
-    def guessexception(self, ec, *classes):
+    def guessexception(self, frame, *classes):
         assert self.index == len(self.listtoreplay)
-        ec.recorder = self.nextreplayer
+        frame.recorder = self.nextreplayer
         outcome = self.booloutcome
         if outcome is None:
             w_exc_cls, w_exc_value = None, None
@@ -206,10 +206,116 @@
 
 # ____________________________________________________________
 
+class FlowSpaceFrame(pyframe.CPythonFrame):
 
-class FlowExecutionContext(object):
-    def __init__(self, space):
+    def __init__(self, space, func, constargs=None):
+        code = HostCode._from_code(space, func.func_code)
+        self.pycode = code
         self.space = space
+        self.w_globals = Constant(func.func_globals)
+        self.locals_stack_w = [None] * (code.co_nlocals + code.co_stacksize)
+        self.valuestackdepth = code.co_nlocals
+        self.lastblock = None
+
+        if func.func_closure is not None:
+            cl = [c.cell_contents for c in func.func_closure]
+            closure = [Cell(Constant(value)) for value in cl]
+        else:
+            closure = []
+        self.initialize_frame_scopes(closure, code)
+        self.f_lineno = code.co_firstlineno
+        self.last_instr = 0
+
+        if constargs is None:
+            constargs = {}
+        formalargcount = code.getformalargcount()
+        arg_list = [Variable() for i in range(formalargcount)]
+        for position, value in constargs.items():
+            arg_list[position] = Constant(value)
+        self.setfastscope(arg_list)
+
+        self.w_locals = None # XXX: only for compatibility with PyFrame
+
+        self.joinpoints = {}
+        self._init_graph(func)
+        self.pendingblocks = collections.deque([self.graph.startblock])
+
+    def initialize_frame_scopes(self, closure, code):
+        if not (code.co_flags & CO_NEWLOCALS):
+            raise ValueError("The code object for a function should have "
+                    "the flag CO_NEWLOCALS set.")
+        if len(closure) != len(code.co_freevars):
+            raise ValueError("code object received a closure with "
+                                 "an unexpected number of free variables")
+        self.cells = [Cell() for _ in code.co_cellvars] + closure
+
+    def _init_graph(self, func):
+        # CallableFactory.pycall may add class_ to functions that are methods
+        name = func.func_name
+        class_ = getattr(func, 'class_', None)
+        if class_ is not None:
+            name = '%s.%s' % (class_.__name__, name)
+        for c in "<>&!":
+            name = name.replace(c, '_')
+
+        initialblock = SpamBlock(self.getstate())
+        if self.pycode.is_generator:
+            initialblock.operations.append(
+                SpaceOperation('generator_mark', [], Variable()))
+        graph = FunctionGraph(name, initialblock)
+        graph.func = func
+        # attach a signature and defaults to the graph
+        # so that it becomes even more interchangeable with the function
+        # itself
+        graph.signature = self.pycode.signature()
+        graph.defaults = func.func_defaults or ()
+        graph.is_generator = self.pycode.is_generator
+        self.graph = graph
+
+    def getstate(self):
+        # getfastscope() can return real None, for undefined locals
+        data = self.save_locals_stack()
+        if self.last_exception is None:
+            data.append(Constant(None))
+            data.append(Constant(None))
+        else:
+            data.append(self.last_exception.w_type)
+            data.append(self.last_exception.get_w_value(self.space))
+        recursively_flatten(self.space, data)
+        nonmergeable = (self.get_blocklist(),
+            self.last_instr)   # == next_instr when between bytecodes
+        return FrameState(data, nonmergeable)
+
+    def setstate(self, state):
+        """ Reset the frame to the given state. """
+        data = state.mergeable[:]
+        recursively_unflatten(self.space, data)
+        self.restore_locals_stack(data[:-2])  # Nones == undefined locals
+        if data[-2] == Constant(None):
+            assert data[-1] == Constant(None)
+            self.last_exception = None
+        else:
+            self.last_exception = OperationError(data[-2], data[-1])
+        blocklist, self.last_instr = state.nonmergeable
+        self.set_blocklist(blocklist)
+
+    def recording(self, block):
+        """ Setup recording of the block and return the recorder. """
+        parentblocks = []
+        parent = block
+        while isinstance(parent, EggBlock):
+            parent = parent.prevblock
+            parentblocks.append(parent)
+        # parentblocks = [Egg, Egg, ..., Egg, Spam] not including block
+        if parent.dead:
+            raise StopFlowing
+        self.setstate(parent.framestate)
+        recorder = BlockRecorder(block)
+        prevblock = block
+        for parent in parentblocks:
+            recorder = Replayer(parent, prevblock.booloutcome, recorder)
+            prevblock = parent
+        return recorder
 
     def guessbool(self, w_condition, **kwds):
         return self.recorder.guessbool(self, w_condition, **kwds)
@@ -217,21 +323,15 @@
     def guessexception(self, *classes):
         return self.recorder.guessexception(self, *classes)
 
-    def build_flow(self, func, constargs={}):
-        space = self.space
-        space.frame = frame = FlowSpaceFrame(self.space, func, constargs)
-        self.joinpoints = {}
-        self.graph = frame._init_graph(func)
-        self.pendingblocks = collections.deque([self.graph.startblock])
-
+    def build_flow(self):
         while self.pendingblocks:
             block = self.pendingblocks.popleft()
             try:
-                self.recorder = frame.recording(block)
-                frame.frame_finished_execution = False
-                next_instr = frame.last_instr
+                self.recorder = self.recording(block)
+                self.frame_finished_execution = False
+                next_instr = self.last_instr
                 while True:
-                    next_instr = frame.handle_bytecode(next_instr)
+                    next_instr = self.handle_bytecode(next_instr)
 
             except ImplicitOperationError, e:
                 if isinstance(e.w_type, Constant):
@@ -259,7 +359,7 @@
                 self.mergeblock(e.block, e.currentstate)
 
             except Return:
-                w_result = frame.popvalue()
+                w_result = self.popvalue()
                 assert w_result is not None
                 link = Link([w_result], self.graph.returnblock)
                 self.recorder.crnt_block.closeblock(link)
@@ -311,114 +411,6 @@
             operr = OperationError(operr.w_type, w_value)
         return operr
 
-
-class FlowSpaceFrame(pyframe.CPythonFrame):
-
-    def __init__(self, space, func, constargs=None):
-        code = HostCode._from_code(space, func.func_code)
-        self.pycode = code
-        self.space = space
-        self.w_globals = Constant(func.func_globals)
-        self.locals_stack_w = [None] * (code.co_nlocals + code.co_stacksize)
-        self.valuestackdepth = code.co_nlocals
-        self.lastblock = None
-
-        if func.func_closure is not None:
-            cl = [c.cell_contents for c in func.func_closure]
-            closure = [Cell(Constant(value)) for value in cl]
-        else:
-            closure = []
-        self.initialize_frame_scopes(closure, code)
-        self.f_lineno = code.co_firstlineno
-        self.last_instr = 0
-
-        if constargs is None:
-            constargs = {}
-        formalargcount = code.getformalargcount()
-        arg_list = [Variable() for i in range(formalargcount)]
-        for position, value in constargs.items():
-            arg_list[position] = Constant(value)
-        self.setfastscope(arg_list)
-
-        self.w_locals = None # XXX: only for compatibility with PyFrame
-
-    def initialize_frame_scopes(self, closure, code):
-        if not (code.co_flags & CO_NEWLOCALS):
-            raise ValueError("The code object for a function should have "
-                    "the flag CO_NEWLOCALS set.")
-        if len(closure) != len(code.co_freevars):
-            raise ValueError("code object received a closure with "
-                                 "an unexpected number of free variables")
-        self.cells = [Cell() for _ in code.co_cellvars] + closure
-
-    def _init_graph(self, func):
-        # CallableFactory.pycall may add class_ to functions that are methods
-        name = func.func_name
-        class_ = getattr(func, 'class_', None)
-        if class_ is not None:
-            name = '%s.%s' % (class_.__name__, name)
-        for c in "<>&!":
-            name = name.replace(c, '_')
-
-        initialblock = SpamBlock(self.getstate())
-        if self.pycode.is_generator:
-            initialblock.operations.append(
-                SpaceOperation('generator_mark', [], Variable()))
-        graph = FunctionGraph(name, initialblock)
-        graph.func = func
-        # attach a signature and defaults to the graph
-        # so that it becomes even more interchangeable with the function
-        # itself
-        graph.signature = self.pycode.signature()
-        graph.defaults = func.func_defaults or ()
-        graph.is_generator = self.pycode.is_generator
-        return graph
-
-    def getstate(self):
-        # getfastscope() can return real None, for undefined locals
-        data = self.save_locals_stack()
-        if self.last_exception is None:
-            data.append(Constant(None))
-            data.append(Constant(None))
-        else:
-            data.append(self.last_exception.w_type)
-            data.append(self.last_exception.get_w_value(self.space))
-        recursively_flatten(self.space, data)
-        nonmergeable = (self.get_blocklist(),
-            self.last_instr)   # == next_instr when between bytecodes
-        return FrameState(data, nonmergeable)
-
-    def setstate(self, state):
-        """ Reset the frame to the given state. """
-        data = state.mergeable[:]
-        recursively_unflatten(self.space, data)
-        self.restore_locals_stack(data[:-2])  # Nones == undefined locals
-        if data[-2] == Constant(None):
-            assert data[-1] == Constant(None)
-            self.last_exception = None
-        else:
-            self.last_exception = OperationError(data[-2], data[-1])
-        blocklist, self.last_instr = state.nonmergeable
-        self.set_blocklist(blocklist)
-
-    def recording(self, block):
-        """ Setup recording of the block and return the recorder. """
-        parentblocks = []
-        parent = block
-        while isinstance(parent, EggBlock):
-            parent = parent.prevblock
-            parentblocks.append(parent)
-        # parentblocks = [Egg, Egg, ..., Egg, Spam] not including block
-        if parent.dead:
-            raise StopFlowing
-        self.setstate(parent.framestate)
-        recorder = BlockRecorder(block)
-        prevblock = block
-        for parent in parentblocks:
-            recorder = Replayer(parent, prevblock.booloutcome, recorder)
-            prevblock = parent
-        return recorder
-
     # hack for unrolling iterables, don't use this
     def replace_in_stack(self, oldvalue, newvalue):
         w_new = Constant(newvalue)
@@ -472,7 +464,7 @@
 
     def enter_bytecode(self, next_instr):
         self.last_instr = next_instr
-        self.space.executioncontext.recorder.bytecode_trace(self)
+        self.recorder.bytecode_trace(self)
 
     def dispatch_bytecode(self, next_instr):
         while True:
diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py
--- a/pypy/objspace/flow/objspace.py
+++ b/pypy/objspace/flow/objspace.py
@@ -8,7 +8,8 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter import pyframe, argument
 from pypy.objspace.flow.model import *
-from pypy.objspace.flow import flowcontext, operation
+from pypy.objspace.flow import operation
+from pypy.objspace.flow.flowcontext import FlowSpaceFrame, fixeggblocks
 from pypy.objspace.flow.specialcase import SPECIAL_CASES
 from pypy.rlib.unroll import unrolling_iterable, _unroller
 from pypy.rlib import rstackovf, rarithmetic
@@ -46,7 +47,7 @@
     """
 
     full_exceptions = False
-    FrameClass = flowcontext.FlowSpaceFrame
+    FrameClass = FlowSpaceFrame
 
     def initialize(self):
         self.w_None     = Constant(None)
@@ -182,7 +183,7 @@
                                         isinstance(w_obj.value, RequiredClass))
 
     def getexecutioncontext(self):
-        return getattr(self, 'executioncontext', None)
+        return self.frame
 
     def exception_match(self, w_exc_type, w_check_class):
         try:
@@ -220,21 +221,20 @@
         """
         if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
             raise Exception, "%r is tagged as NOT_RPYTHON" % (func,)
-        ec = flowcontext.FlowExecutionContext(self)
-        self.executioncontext = ec
+        frame = self.frame = FlowSpaceFrame(self, func, constargs)
 
         try:
-            ec.build_flow(func, constargs)
+            frame.build_flow()
         except error.FlowingError, a:
             # attach additional source info to AnnotatorError
             _, _, tb = sys.exc_info()
-            formated = error.format_global_error(ec.graph, self.frame.last_instr,
+            formated = error.format_global_error(frame.graph, self.frame.last_instr,
                                                  str(a))
             e = error.FlowingError(formated)
             raise error.FlowingError, e, tb
 
-        graph = ec.graph
-        flowcontext.fixeggblocks(graph)
+        graph = frame.graph
+        fixeggblocks(graph)
         checkgraph(graph)
         if graph.is_generator and tweak_for_generator:
             from pypy.translator.generator import tweak_generator_graph
@@ -269,7 +269,7 @@
     def do_operation(self, name, *args_w):
         spaceop = SpaceOperation(name, args_w, Variable())
         spaceop.offset = self.frame.last_instr
-        self.executioncontext.recorder.append(spaceop)
+        self.frame.recorder.append(spaceop)
         return spaceop.result
 
     def do_operation_with_implicit_exceptions(self, name, *args_w):
@@ -285,8 +285,7 @@
         else:
             return bool(obj)
         w_truthvalue = self.do_operation('is_true', w_obj)
-        context = self.getexecutioncontext()
-        return context.guessbool(w_truthvalue)
+        return self.frame.guessbool(w_truthvalue)
 
     def iter(self, w_iterable):
         try:
@@ -300,7 +299,7 @@
         return w_iter
 
     def next(self, w_iter):
-        context = self.getexecutioncontext()
+        frame = self.frame
         try:
             it = self.unwrap(w_iter)
         except UnwrapException:
@@ -312,10 +311,10 @@
                 except IndexError:
                     raise OperationError(self.w_StopIteration, self.w_None)
                 else:
-                    self.frame.replace_in_stack(it, next_unroller)
+                    frame.replace_in_stack(it, next_unroller)
                     return self.wrap(v)
         w_item = self.do_operation("next", w_iter)
-        outcome, w_exc_cls, w_exc_value = context.guessexception(StopIteration,
+        outcome, w_exc_cls, w_exc_value = frame.guessexception(StopIteration,
                                                                  RuntimeError)
         if outcome is StopIteration:
             raise OperationError(self.w_StopIteration, w_exc_value)
@@ -438,8 +437,7 @@
         # exception-raising return block in the flow graph.  Note that
         # even if the interpreter re-raises the exception, it will not
         # be the same ImplicitOperationError instance internally.
-        context = self.getexecutioncontext()
-        outcome, w_exc_cls, w_exc_value = context.guessexception(*exceptions)
+        outcome, w_exc_cls, w_exc_value = self.frame.guessexception(*exceptions)
         if outcome is not None:
             # we assume that the caught exc_cls will be exactly the
             # one specified by 'outcome', and not a subclass of it,


More information about the pypy-commit mailing list