def getframe(self, func): try: func = func.im_func except AttributeError: pass code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) frame = FlowSpaceFrame(FlowObjSpace(), graph, code) # hack the frame frame.setstate(graph.startblock.framestate) frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(None) return frame
def get_context(self, func): try: func = func.im_func except AttributeError: pass code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) ctx = FlowContext(graph, code) # hack the frame ctx.setstate(graph.startblock.framestate) ctx.locals_stack_w[ctx.pycode.co_nlocals - 1] = Constant(None) return ctx
def get_context(self, func): try: func = func.im_func except AttributeError: pass code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) ctx = FlowContext(graph, code) # hack the frame ctx.setstate(graph.startblock.framestate) ctx.locals_stack_w[ctx.pycode.co_nlocals-1] = Constant(None) return ctx
def build_flow(func): """ Create the flow graph (in SSA form) for the function. """ _assert_rpythonic(func) if (isgeneratorfunction(func) and not hasattr(func, '_generator_next_method_of_')): return make_generator_entry_graph(func) code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) ctx = FlowContext(graph, code) ctx.build_flow() fixeggblocks(graph) if code.is_generator: tweak_generator_graph(graph) return graph
def make_generator_entry_graph(func): # This is the first copy of the graph. We replace it with # a small bootstrap graph. code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) block = graph.startblock for name, w_value in zip(code.co_varnames, block.framestate.mergeable): if isinstance(w_value, Variable): w_value.rename(name) varnames = get_variable_names(graph.startblock.inputargs) GeneratorIterator = make_generatoriterator_class(varnames) replace_graph_with_bootstrap(GeneratorIterator, graph) # We attach a 'next' method to the GeneratorIterator class # that will invoke the real function, based on a second # copy of the graph. attach_next_method(GeneratorIterator, graph) return graph
def build_flow(func, space=FlowObjSpace()): """ Create the flow graph for the function. """ _assert_rpythonic(func) code = HostCode._from_code(func.func_code) if (code.is_generator and not hasattr(func, '_generator_next_method_of_')): graph = PyGraph(func, code) block = graph.startblock for name, w_value in zip(code.co_varnames, block.framestate.mergeable): if isinstance(w_value, Variable): w_value.rename(name) return bootstrap_generator(graph) graph = PyGraph(func, code) frame = space.frame = FlowSpaceFrame(space, graph, code) frame.build_flow() fixeggblocks(graph) checkgraph(graph) if code.is_generator: tweak_generator_graph(graph) return graph