Ejemplo n.º 1
0
void MethodCreator::forward_method_to(DexMethod* meth, DexMethod* smeth) {
  auto code = meth->get_code();
  if (code != nullptr) {
    meth->set_code(nullptr);
    delete code;
  }
  MethodCreator mc(meth);
  MethodBlock* block = mc.get_main_block();
  std::vector<Location> args;
  auto proto = smeth->get_proto();
  auto rtype = proto->get_rtype();
  auto meth_args = proto->get_args();
  if (meth_args != nullptr) {
    uint16_t arg_count =
        static_cast<uint16_t>(meth_args->get_type_list().size());
    for (auto i = 0; i < arg_count; ++i) {
      args.push_back(mc.get_local(i));
    }
  }
  block->invoke(smeth, args);
  if (rtype == get_void_type()) {
    block->ret_void();
  } else {
    auto ret = mc.make_local(rtype);
    block->move_result(ret, rtype);
    block->ret(ret);
  }
  mc.create();
}
Ejemplo n.º 2
0
DexProto* DexIdx::get_protoidx_fromdex(uint32_t pidx) {
  redex_assert(pidx < m_proto_ids_size);
  DexType* rtype = get_typeidx(m_proto_ids[pidx].rtypeidx);
  DexString* shorty = get_stringidx(m_proto_ids[pidx].shortyidx);
  DexTypeList* args = get_type_list(m_proto_ids[pidx].param_off);
  return DexProto::make_proto(rtype, args, shorty);
}
Ejemplo n.º 3
0
uint16_t MethodCreator::ins_count() const {
  auto proto = method->get_proto();
  auto args = proto->get_args();
  uint16_t ins =
      args == nullptr ? 0 : static_cast<uint16_t>(args->get_type_list().size());
  if (!(access & ACC_STATIC)) ins++;
  return ins;
}
Ejemplo n.º 4
0
        TypeListComboBox::TypeListComboBox(const uint16_t gen, QWidget* parent):
            QComboBox(parent)
        {
            std::vector<pkstring> types_vec;
            get_type_list(types_vec, gen);

            for(uint16_t i = 0; i < types_vec.size(); i++)
                addItem(QString::fromUtf16(types_vec[i]), QVariant(i));
        }
Ejemplo n.º 5
0
bool check_cast(const DexType* type, const DexType* base_type) {
  if (type == base_type) return true;
  const auto cls = type_class(type);
  if (cls == nullptr) return false;
  if (check_cast(cls->get_super_class(), base_type)) return true;
  auto intfs = cls->get_interfaces();
  for (auto intf : intfs->get_type_list()) {
    if (check_cast(intf, base_type)) return true;
  }
  return false;
}
Ejemplo n.º 6
0
void MethodCreator::load_locals(DexMethod* meth) {
  if (!(access & ACC_STATIC)) {
    make_local(meth->get_class());
  }
  auto proto = meth->get_proto();
  auto args = proto->get_args();
  if (args) {
    for (auto arg : args->get_type_list()) {
      make_local(arg);
    }
  }
}
Ejemplo n.º 7
0
void MethodCreator::load_locals(DexMethod* meth) {
  auto ii = InstructionIterable(
      meth->get_code()->get_param_instructions());
  auto it = ii.begin();
  if (!is_static(meth)) {
    make_local_at(meth->get_class(), it->insn->dest());
    ++it;
  }
  auto proto = meth->get_proto();
  auto args = proto->get_args();
  if (args) {
    for (auto arg : args->get_type_list()) {
      make_local_at(arg, it->insn->dest());
      ++it;
    }
  }
  always_assert(it == ii.end());
}
Ejemplo n.º 8
0
/**
 * If the caller is in the primary DEX we want to make sure there are no
 * references in other DEXes that may cause a verification error.
 * Don't inline if so.
 */
bool MultiMethodInliner::refs_not_in_primary(DexMethod* callee) {

  const auto ok_from_primary = [&](DexType* type) {
    if (primary.count(type) == 0 && type_class_internal(type) != nullptr) {
      info.not_in_primary++;
      return false;
    }
    return true;
  };

  for (auto insn : callee->get_code()->get_instructions()) {
    if (insn->has_types()) {
      auto top = static_cast<DexOpcodeType*>(insn);
      if (!ok_from_primary(top->get_type())) {
        return true;
      }
    } else if (insn->has_methods()) {
      auto mop = static_cast<DexOpcodeMethod*>(insn);
      auto meth = mop->get_method();
      if (!ok_from_primary(meth->get_class())) {
        return true;
      }
      auto proto = meth->get_proto();
      if (!ok_from_primary(proto->get_rtype())) {
        return true;
      }
      auto args = proto->get_args();
      if (args == nullptr) continue;
      for (const auto& arg : args->get_type_list()) {
        if (!ok_from_primary(arg)) {
          return true;
        }
      }
    } else if (insn->has_fields()) {
      auto fop = static_cast<DexOpcodeField*>(insn);
      auto field = fop->field();
      if (!ok_from_primary(field->get_class()) ||
          !ok_from_primary(field->get_type())) {
        return true;
      }
    }
  }
  return false;
}
Ejemplo n.º 9
0
/**
 * Move all single impl in a single impl method signature to next pass.
 * We make a single optimization per pass over any given single impl so
 * I1, I2 and void I1.m(I2)
 * the first optimization (I1 or I2) moves the other interface to next pass.
 * That is not the case for methods on non optimizable classes, so for
 * I1, I2 and void C.m(I1, I2)
 * then m is changed in a single pass for both I1 and I2.
 */
void OptimizationImpl::drop_single_impl_collision(DexType* intf,
                                                  SingleImplData& data,
                                                  DexMethod* method) {
  auto check_type = [&](DexType* type) {
    if (type != intf && single_impls->is_single_impl(type) &&
        !single_impls->is_escaped(type)) {
      single_impls->escape_interface(type, NEXT_PASS);
      assert(optimized.find(type) == optimized.end());
    }
  };

  auto owner = method->get_class();
  if (!single_impls->is_single_impl(owner)) return;
  check_type(owner);
  auto proto = method->get_proto();
  check_type(proto->get_rtype());
  auto args_list = proto->get_args();
  for (auto arg : args_list->get_type_list()) {
    check_type(arg);
  }
}