libredex/CFGInliner.cpp
/*
 * Callees that were not in a try region when their CFGs were created, need to
 * have some blocks split because the callsite is in a try region. We do this
 * because we need to add edges from the throwing opcodes to the catch handler
 * of the caller's try region.
 *
 * Assumption: callsite is in a try region
 */
Callees that were not in a try region when their CFGs were created, need to
have some blocks split because the callsite is in a try region. We do this
because we need to add edges from the throwing opcodes to the catch handler
of the caller's try region.

callsite is in a try region
Callees that were not in a try region when their CFGs were created need to have some blocks split because the callsite is in a try region . We do this because we need to add edges from the throwing opcodes to the catch handler of the caller ' s try region . callsite is in a try region
void CFGInliner::split_on_callee_throws(ControlFlowGraph* callee) {
  std::vector<Block*> work_list = callee->blocks();
  for (uint32_t i = 0; i < work_list.size(); ++i) {
    Block* b = work_list[i];
    IRList::iterator last = b->get_last_insn();
    const auto& iterable = ir_list::InstructionIterable(*b);
    for (auto it = iterable.begin(); it != iterable.end(); ++it) {
      const auto& mie = *it;
      const auto insn = mie.insn;
      const auto op = insn->opcode();
      if (opcode::can_throw(op) && it.unwrap() != last) {
        const auto& cfg_it = b->to_cfg_instruction_iterator(it);
        Block* new_block = callee->split_block(cfg_it);
        work_list.push_back(new_block);
      }
    }
  }
}
void CFGInliner :: split_on_callee_throws ( ControlFlowGraph * callee ) { std :: vector < Block * > work_list = callee -> blocks ( ) ; for ( uint32_t i = 0 ; i < work_list . size ( ) ; ++ i ) { Block * b = work_list [ i ] ; IRList :: iterator last = b -> get_last_insn ( ) ; const auto & iterable = ir_list :: InstructionIterable ( * b ) ; for ( auto it = iterable . begin ( ) ; it != iterable . end ( ) ; ++ it ) { const auto & mie = * it ; const auto insn = mie . insn ; const auto op = insn -> opcode ( ) ; if ( opcode :: can_throw ( op ) && it . unwrap ( ) != last ) { const auto & cfg_it = b -> to_cfg_instruction_iterator ( it ) ; Block * new_block = callee -> split_block ( cfg_it ) ; work_list . push_back ( new_block ) ; } } } }
Callees that were not in a try region when their CFGs were created, need to
 have some blocks split because the callsite is in a try region.
Callees that were not in a try region when their CFGs were created need to have some blocks split because the callsite is in a try region .
// iterate with an index instead of an iterator because we're adding to the // end while we iterate // look for blocks we need to split