def replace_graph_with_bootstrap(GeneratorIterator, graph): Entry = GeneratorIterator.Entry newblock = Block(graph.startblock.inputargs) op_entry = op.simple_call(const(Entry)) v_entry = op_entry.result newblock.operations.append(op_entry) assert len(graph.startblock.inputargs) == len(Entry.varnames) for v, name in zip(graph.startblock.inputargs, Entry.varnames): newblock.operations.append(op.setattr(v_entry, Constant(name), v)) op_generator = op.simple_call(const(GeneratorIterator), v_entry) newblock.operations.append(op_generator) newblock.closeblock(Link([op_generator.result], graph.returnblock)) graph.startblock = newblock
def replace_graph_with_bootstrap(GeneratorIterator, graph): Entry = GeneratorIterator.Entry newblock = Block(graph.startblock.inputargs) op_entry = op.simple_call(const(Entry)) v_entry = op_entry.result newblock.operations.append(op_entry) assert len(graph.startblock.inputargs) == len(Entry.varnames) for v, name in zip(graph.startblock.inputargs, Entry.varnames): newblock.operations.append(op.setattr(v_entry, Constant(name), v)) op_generator = op.simple_call(const(GeneratorIterator), v_entry) newblock.operations.append(op_generator) newblock.closeblock(Link([op_generator.result], graph.returnblock)) graph.startblock = newblock
def tweak_generator_body_graph(Entry, graph): # First, always run simplify_graph in order to reduce the number of # variables passed around simplify_graph(graph) insert_empty_startblock(graph) _insert_reads(graph.startblock, Entry.varnames) Entry.block = graph.startblock # mappings = [Entry] # stopblock = Block([]) op0 = op.simple_call(const(StopIteration)) op1 = op.type(op0.result) stopblock.operations = [op0, op1] stopblock.closeblock(Link([op1.result, op0.result], graph.exceptblock)) # for block in list(graph.iterblocks()): for exit in block.exits: if exit.target is graph.returnblock: exit.args = [] exit.target = stopblock assert block is not stopblock for index in range(len(block.operations) - 1, -1, -1): hlop = block.operations[index] if hlop.opname == 'yield_': [v_yielded_value] = hlop.args del block.operations[index] newlink = split_block(block, index) newblock = newlink.target # class Resume(AbstractPosition): _immutable_ = True block = newblock Resume.__name__ = 'Resume%d' % len(mappings) mappings.append(Resume) varnames = get_variable_names(newlink.args) # _insert_reads(newblock, varnames) # op_resume = op.simple_call(const(Resume)) block.operations.append(op_resume) v_resume = op_resume.result for i, name in enumerate(varnames): block.operations.append( op.setattr(v_resume, const(name), newlink.args[i])) op_pair = op.newtuple(v_resume, v_yielded_value) block.operations.append(op_pair) newlink.args = [op_pair.result] newlink.target = graph.returnblock # regular_entry_block = Block([Variable('entry')]) block = regular_entry_block for Resume in mappings: op_check = op.isinstance(block.inputargs[0], const(Resume)) block.operations.append(op_check) block.exitswitch = op_check.result link1 = Link([block.inputargs[0]], Resume.block) link1.exitcase = True nextblock = Block([Variable('entry')]) link2 = Link([block.inputargs[0]], nextblock) link2.exitcase = False block.closeblock(link1, link2) block = nextblock block.closeblock( Link([ Constant(AssertionError), Constant(AssertionError("bad generator class")) ], graph.exceptblock)) graph.startblock = regular_entry_block graph.signature = Signature(['entry']) graph.defaults = () checkgraph(graph) eliminate_empty_blocks(graph)
def STORE_ATTR(self, nameindex): "obj.attributename = newvalue" w_attributename = self.getname_w(nameindex) w_obj = self.popvalue() w_newvalue = self.popvalue() op.setattr(w_obj, w_attributename, w_newvalue).eval(self)
def STORE_ATTR(self, nameindex): "obj.attributename = newvalue" w_attributename = self.getname_w(nameindex) w_obj = self.popvalue() w_newvalue = self.popvalue() op.setattr(w_obj, w_attributename, w_newvalue).eval(self)
def tweak_generator_body_graph(Entry, graph): # First, always run simplify_graph in order to reduce the number of # variables passed around simplify_graph(graph) insert_empty_startblock(None, graph) _insert_reads(graph.startblock, Entry.varnames) Entry.block = graph.startblock # mappings = [Entry] # stopblock = Block([]) op0 = op.simple_call(const(StopIteration)) op1 = op.type(op0.result) stopblock.operations = [op0, op1] stopblock.closeblock(Link([op1.result, op0.result], graph.exceptblock)) # for block in list(graph.iterblocks()): for exit in block.exits: if exit.target is graph.returnblock: exit.args = [] exit.target = stopblock assert block is not stopblock for index in range(len(block.operations)-1, -1, -1): hlop = block.operations[index] if hlop.opname == 'yield_': [v_yielded_value] = hlop.args del block.operations[index] newlink = split_block(None, block, index) newblock = newlink.target # class Resume(AbstractPosition): _immutable_ = True block = newblock Resume.__name__ = 'Resume%d' % len(mappings) mappings.append(Resume) varnames = get_variable_names(newlink.args) # _insert_reads(newblock, varnames) # op_resume = op.simple_call(const(Resume)) block.operations.append(op_resume) v_resume = op_resume.result for i, name in enumerate(varnames): block.operations.append( op.setattr(v_resume, const(name), newlink.args[i])) op_pair = op.newtuple(v_resume, v_yielded_value) block.operations.append(op_pair) newlink.args = [op_pair.result] newlink.target = graph.returnblock # regular_entry_block = Block([Variable('entry')]) block = regular_entry_block for Resume in mappings: op_check = op.simple_call( const(isinstance), block.inputargs[0], const(Resume)) block.operations.append(op_check) block.exitswitch = op_check.result link1 = Link([block.inputargs[0]], Resume.block) link1.exitcase = True nextblock = Block([Variable('entry')]) link2 = Link([block.inputargs[0]], nextblock) link2.exitcase = False block.closeblock(link1, link2) block = nextblock block.closeblock(Link([Constant(AssertionError), Constant(AssertionError("bad generator class"))], graph.exceptblock)) graph.startblock = regular_entry_block graph.signature = Signature(['entry']) graph.defaults = () checkgraph(graph) eliminate_empty_blocks(graph)