Commits

Ronan Lamy committed ecf2712 Draft

Refactor FlowExecutionContext.__init__

Push code down from FlowObjSpace.build_flow() to FlowExecutionContext.
This is safe as these objects are only ever instantiated from there,
and puts all flow graph initialisation code closer together.

Comments (0)

Files changed (2)

pypy/objspace/flow/flowcontext.py

 from pypy.interpreter.error import OperationError
 from pypy.interpreter import pyframe, nestedscope
 from pypy.interpreter.argument import ArgumentsForTranslation
+from pypy.interpreter.astcompiler.consts import CO_GENERATOR
+from pypy.interpreter.pycode import PyCode, cpython_code_signature
 from pypy.objspace.flow import operation
 from pypy.objspace.flow.model import *
 from pypy.objspace.flow.framestate import FrameState
 
 class FlowExecutionContext(ExecutionContext):
 
-    def __init__(self, space, code, globals, constargs={}, outer_func=None,
-                 name=None, is_generator=False):
+    def __init__(self, space, func, constargs={}):
         ExecutionContext.__init__(self, space)
+        code = PyCode._from_code(space, func.func_code)
+        self.is_generator = bool(code.co_flags & CO_GENERATOR)
         self.code = code
 
-        self.w_globals = w_globals = space.wrap(globals)
+        self.w_globals = space.wrap(func.func_globals)
 
         self.crnt_offset = -1
         self.crnt_frame = None
-        if outer_func and outer_func.closure:
-            self.closure = [nestedscope.Cell(Constant(value))
-                            for value in outer_func.closure]
+        if func.func_closure is not None:
+            cl = [c.cell_contents for c in func.func_closure]
+            self.closure = [nestedscope.Cell(Constant(value)) for value in cl]
         else:
             self.closure = None
         frame = self.create_frame()
         self.joinpoints = {}
         initialblock = SpamBlock(FrameState(frame).copy())
         self.pendingblocks = collections.deque([initialblock])
-        self.graph = FunctionGraph(name or code.co_name, initialblock)
-        self.is_generator = is_generator
+
+        # 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, '_')
+        self.graph = 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 = code.signature()
+        graph.defaults = func.func_defaults or ()
 
     make_link = Link # overridable for transition tracking
 

pypy/objspace/flow/objspace.py

 import types
 from pypy.tool import error
 from pypy.interpreter.baseobjspace import ObjSpace, Wrappable
-from pypy.interpreter.pycode import PyCode, cpython_code_signature
 from pypy.interpreter.module import Module
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.astcompiler.consts import CO_GENERATOR
 from pypy.interpreter import pyframe, argument
 from pypy.objspace.flow.model import *
 from pypy.objspace.flow import flowcontext, operation
         """
         if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'):
             raise Exception, "%r is tagged as NOT_RPYTHON" % (func,)
-        code = func.func_code
-        is_generator = bool(code.co_flags & CO_GENERATOR)
-        code = PyCode._from_code(self, code)
-        if func.func_closure is None:
-            cl = None
-        else:
-            cl = [c.cell_contents for c in func.func_closure]
-        # 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, '_')
-        class outerfunc: # hack
-            closure = cl
-        ec = flowcontext.FlowExecutionContext(self, code, func.func_globals,
-                                              constargs, outerfunc, name,
-                                              is_generator)
-        graph = ec.graph
-        graph.func = func
-        # attach a signature and defaults to the graph
-        # so that it becomes even more interchangeable with the function
-        # itself
-        graph.signature = cpython_code_signature(code)
-        graph.defaults = func.func_defaults or ()
+        ec = flowcontext.FlowExecutionContext(self, func, constargs)
         self.executioncontext = ec
 
         try:
                                                  str(a))
             e = error.FlowingError(formated)
             raise error.FlowingError, e, tb
+
+        graph = ec.graph
         checkgraph(graph)
-        #
-        if is_generator and tweak_for_generator:
+        if ec.is_generator and tweak_for_generator:
             from pypy.translator.generator import tweak_generator_graph
             tweak_generator_graph(graph)
-        #
         return graph
 
     def fixedview(self, w_tuple, expected_length=None):