void patch_iget(DexMethod* meth, IRList::iterator it, DexType* original_field_type) { auto insn = it->insn; const auto op = insn->opcode(); always_assert(is_iget(op)); switch (op) { case OPCODE_IGET_OBJECT: { auto dest = std::next(it)->insn->dest(); auto cast = ModelMethodMerger::make_check_cast(original_field_type, dest); meth->get_code()->insert_after(insn, cast); break; } case OPCODE_IGET_BYTE: { always_assert(original_field_type == get_byte_type()); auto int_to_byte = new IRInstruction(OPCODE_INT_TO_BYTE); patch_iget_for_int_like_types(meth, it, int_to_byte); break; } case OPCODE_IGET_CHAR: { always_assert(original_field_type == get_char_type()); auto int_to_char = new IRInstruction(OPCODE_INT_TO_CHAR); patch_iget_for_int_like_types(meth, it, int_to_char); break; } case OPCODE_IGET_SHORT: { always_assert(original_field_type == get_short_type()); auto int_to_short = new IRInstruction(OPCODE_INT_TO_SHORT); patch_iget_for_int_like_types(meth, it, int_to_short); break; } default: break; } };
int count_igets(cfg::ControlFlowGraph& cfg, std::string field_name) { size_t num_igets = 0; for (const auto& mie : InstructionIterable(cfg)) { if (is_iget(mie.insn->opcode()) && mie.insn->get_field()->get_name()->str() == field_name) { num_igets++; } } return num_igets; }
void MethodBlock::ifield_op(DexOpcode opcode, DexField* field, Location obj, Location& src_or_dst) { always_assert(is_ifield_op(opcode)); if (is_iget(opcode)) { auto iget = new DexOpcodeField(opcode, field); iget->set_dest(reg_num(src_or_dst)); src_or_dst.type = field->get_class(); iget->set_src(0, reg_num(obj)); push_instruction(iget); } else { auto iput = new DexOpcodeField(opcode, field); iput->set_src(0, reg_num(src_or_dst)); iput->set_src(1, reg_num(obj)); push_instruction(iput); } }
void MethodBlock::ifield_op(IROpcode opcode, DexField* field, Location obj, Location& src_or_dst) { always_assert(is_ifield_op(opcode)); if (is_iget(opcode)) { auto iget = new IRInstruction(opcode); iget->set_field(field); src_or_dst.type = field->get_class(); iget->set_src(0, obj.get_reg()); push_instruction(iget); push_instruction( (new IRInstruction(opcode::move_result_pseudo_for_iget(opcode))) ->set_dest(src_or_dst.get_reg())); } else { auto iput = new IRInstruction(opcode); iput->set_field(field); iput->set_src(0, src_or_dst.get_reg()); iput->set_src(1, obj.get_reg()); push_instruction(iput); } }