void MethodBlock::new_instance(DexType* type, Location& dst) { auto insn = new IRInstruction(OPCODE_NEW_INSTANCE); insn->set_type(type); push_instruction(insn); push_instruction((new IRInstruction(IOPCODE_MOVE_RESULT_PSEUDO_OBJECT)) ->set_dest(dst.get_reg())); }
void MethodBlock::check_cast(Location& src_and_dst, DexType* type) { IRInstruction* check_cast = new IRInstruction(OPCODE_CHECK_CAST); auto reg = src_and_dst.get_reg(); check_cast->set_type(type)->set_src(0, reg); push_instruction(check_cast); push_instruction( (new IRInstruction(IOPCODE_MOVE_RESULT_PSEUDO_OBJECT))->set_dest(reg)); }
void MethodBlock::instance_of(Location& obj, Location& dst, DexType* type) { always_assert(obj.is_ref()); always_assert(dst.type == get_boolean_type()); IRInstruction* insn = new IRInstruction(OPCODE_INSTANCE_OF); insn->set_src(0, obj.get_reg()); insn->set_type(type); push_instruction(insn); push_instruction( (new IRInstruction(IOPCODE_MOVE_RESULT_PSEUDO))->set_dest(dst.get_reg())); }
void MethodBlock::load_const(Location& loc, DexType* value) { always_assert(!loc.is_wide()); IRInstruction* load = new IRInstruction(OPCODE_CONST_CLASS); load->set_type(value); push_instruction(load); IRInstruction* move_result_pseudo = new IRInstruction(IOPCODE_MOVE_RESULT_PSEUDO_OBJECT); loc.type = get_class_type(); move_result_pseudo->set_dest(loc.get_reg()); push_instruction(move_result_pseudo); }
void MethodBlock::new_array(DexType* type, const Location& size, const Location& dst) { auto insn = new IRInstruction(OPCODE_NEW_ARRAY); insn->set_type(type); insn->set_arg_word_count(1); insn->set_src(0, size.get_reg()); push_instruction(insn); push_instruction((new IRInstruction(IOPCODE_MOVE_RESULT_PSEUDO_OBJECT)) ->set_dest(dst.get_reg())); }
void MethodBlock::sfield_op(DexOpcode opcode, DexField* field, Location& src_or_dst) { always_assert(is_sfield_op(opcode)); if (is_sget(opcode)) { auto sget = new DexOpcodeField(opcode, field); sget->set_dest(reg_num(src_or_dst)); src_or_dst.type = field->get_class(); push_instruction(sget); } else { auto sput = new DexOpcodeField(opcode, field); sput->set_src(0, reg_num(src_or_dst)); push_instruction(sput); } }
void emitter::current_function(local_address destination) { push_instruction(instruction( instruction_type::current_function, destination )); }
int handle_client(t_selfd *fd, t_server *serv) { char *cmd; int r; ssize_t swr; if (ISREADABLE(fd)) { if (((r = read_from_client(fd)) < 0 && errno != EINTR) || (r == 0)) { log_connection(((t_client *)fd->data)->sock, "Client disconnected from:"); return (destroy_connection(serv, fd)); } } if (ISWRITEABLE(fd) && (r = write_to_client(fd)) < 0 && errno != EINTR) return (destroy_connection(serv, fd)); while ((cmd = get_command(fd))) handle_add_cmd(serv, fd, cmd); swr = ring_buffer_left_read(fd->wbuff); if (!swr && fd->to_close) return (destroy_connection(serv, fd)); if (swr) CHECKWRITE(fd); CHECKREAD(fd); push_instruction(serv, fd); return (0); }
void MethodBlock::load_const(Location& loc, DexString* value) { always_assert(!loc.is_wide()); DexInstruction* load = new DexOpcodeString(OPCODE_CONST_STRING, value); load->set_dest(reg_num(loc)); loc.type = get_string_type(); push_instruction(load); }
void MethodBlock::load_const(Location& loc, DexType* value) { always_assert(!loc.is_wide()); DexInstruction* load = new DexOpcodeType(OPCODE_CONST_CLASS, value); load->set_dest(reg_num(loc)); loc.type = get_class_type(); push_instruction(load); }
void MethodBlock::load_const(Location& loc, int32_t value) { always_assert(!loc.is_wide()); IRInstruction* load = new IRInstruction(OPCODE_CONST); load->set_dest(loc.get_reg()); load->set_literal(value); loc.type = get_int_type(); push_instruction(load); }
void MethodBlock::load_const(Location& loc, double value) { always_assert(loc.is_wide()); DexInstruction* load = new DexInstruction(OPCODE_CONST_WIDE); load->set_dest(reg_num(loc)); load->set_literal(value); loc.type = get_double_type(); push_instruction(load); }
void MethodBlock::load_null(Location& loc) { always_assert(!loc.is_wide()); DexInstruction* load = new DexInstruction(OPCODE_CONST_4); load->set_dest(reg_num(loc)); load->set_literal(0); loc.type = get_object_type(); push_instruction(load); }
void emitter::invert( local_address destination ) { push_instruction(instruction( instruction_type::invert, destination )); }
void emitter::not_( local_address destination ) { push_instruction(instruction( instruction_type::not_, destination )); }
void MethodBlock::sfield_op(IROpcode opcode, DexField* field, Location& src_or_dst) { always_assert(is_sfield_op(opcode)); if (is_sget(opcode)) { auto sget = new IRInstruction(opcode); sget->set_field(field); src_or_dst.type = field->get_class(); push_instruction(sget); push_instruction( (new IRInstruction(opcode::move_result_pseudo_for_sget(opcode))) ->set_dest(src_or_dst.get_reg())); } else { auto sput = new IRInstruction(opcode); sput->set_field(field)->set_src(0, src_or_dst.get_reg()); push_instruction(sput); } }
void emitter::set_null( local_address destination ) { push_instruction(instruction( instruction_type::set_null, destination )); }
void emitter::load_module( local_address name_and_result ) { push_instruction(instruction( instruction_type::load_module, name_and_result )); }
void emitter::new_table( local_address destination ) { push_instruction(instruction( instruction_type::new_table, destination )); }
void emitter::jump( jump_offset destination ) { push_instruction(instruction( instruction_type::jump, destination )); }
void emitter::not_equal( local_address left, local_address right) { push_instruction(instruction( instruction_type::not_equal, left, right )); }
void MethodBlock::binop_2addr(DexOpcode op, const Location& dest, const Location& src) { always_assert(OPCODE_ADD_INT_2ADDR <= op && op <= OPCODE_REM_DOUBLE_2ADDR); always_assert(dest.type == src.type); DexInstruction* insn = new DexInstruction(op); insn->set_src(0, reg_num(dest)); insn->set_src(1, reg_num(src)); push_instruction(insn); }
void emitter::less( local_address left, local_address right) { push_instruction(instruction( instruction_type::less, left, right )); }
void emitter::set_function( local_address destination, instruction_argument function_id ) { push_instruction(instruction( instruction_type::set_function, destination, function_id )); }
void emitter::jump_if_not( jump_offset destination, local_address condition_address ) { push_instruction(instruction( instruction_type::jump_if_not, destination, condition_address )); }
void emitter::add( local_address destination, local_address summand ) { push_instruction(instruction( instruction_type::add, destination, summand )); }
void emitter::set_string( local_address destination, instruction_argument string_id ) { push_instruction(instruction( instruction_type::set_string, destination, string_id )); }
void emitter::mod( local_address destination, local_address source ) { push_instruction(instruction( instruction_type::mod, destination, source )); }
void emitter::call( local_address arguments_address, instruction_argument argument_count ) { push_instruction(instruction( instruction_type::call, arguments_address, argument_count )); }
void emitter::set_constant( local_address destination, instruction_argument constant ) { push_instruction(instruction( instruction_type::set_from_constant, destination, constant )); }