Example #1
0
DexClass* create_merger_class(const DexType* type,
                              const DexType* super_type,
                              const std::vector<DexField*>& merger_fields,
                              const TypeSet& interfaces,
                              bool add_type_tag_field,
                              bool with_default_ctor /* false */) {
  always_assert(type && super_type);
  std::vector<DexField*> fields;

  if (add_type_tag_field) {
    auto type_tag_field = static_cast<DexField*>(DexField::make_field(
        type, DexString::make_string(INTERNAL_TYPE_TAG_FIELD_NAME),
        get_int_type()));
    type_tag_field->make_concrete(ACC_PUBLIC | ACC_FINAL);
    fields.push_back(type_tag_field);
  }

  for (auto f : merger_fields) {
    fields.push_back(f);
  }
  // Put merger class in the same package as super_type.
  auto pkg_name = get_merger_package_name(super_type);
  auto cls = create_class(type, super_type, pkg_name, fields, interfaces,
                          with_default_ctor);
  TRACE(TERA, 3, "  created merger class w/ fields %s \n", SHOW(cls));
  return cls;
}
Example #2
0
DexField* make_field_def(DexType* cls, const char* name, DexType* type,
    DexAccessFlags access = ACC_PUBLIC, bool external = false) {
  auto field = DexField::make_field(cls, DexString::make_string(name), type);
  if (external) {
    field->set_access(access);
    field->set_external();
  } else {
    field->make_concrete(access);
  }
  return field;
}
Example #3
0
DexMethod* MethodCreator::make_static_from(DexString* name,
                                           DexProto* proto,
                                           DexMethod* meth,
                                           DexClass* target_cls) {
  assert(!(meth->get_access() & ACC_STATIC));
  assert(!is_init(meth) && !is_clinit(meth));
  auto smeth = DexMethod::make_method(target_cls->get_type(), name, proto);
  smeth->make_concrete(
      meth->get_access() | ACC_STATIC, std::move(meth->get_code()), false);
  target_cls->add_method(smeth);
  return smeth;
}
Example #4
0
DexMethod* MethodCreator::make_static_from(DexString* name,
                                           DexProto* proto,
                                           DexMethod* meth,
                                           DexClass* target_cls) {
  assert(!(meth->get_access() & ACC_STATIC));
  assert(!is_init(meth) && !is_clinit(meth));
  auto smeth = DexMethod::make_method(target_cls->get_type(), name, proto);
  smeth->make_concrete(
      meth->get_access() | ACC_STATIC, meth->get_code(), false);
  insert_sorted(target_cls->get_dmethods(), smeth, compare_dexmethods);
  meth->set_code(nullptr);
  return smeth;
}
Example #5
0
std::vector<DexField*> create_merger_fields(
    const DexType* owner, const std::vector<DexField*>& mergeable_fields) {
  std::vector<DexField*> res;
  size_t cnt = 0;
  for (const auto f : mergeable_fields) {
    auto type = f->get_type();
    std::string name;
    if (type == get_byte_type() || type == get_char_type() ||
        type == get_short_type() || type == get_int_type()) {
      type = get_int_type();
      name = "i";
    } else if (type == get_boolean_type()) {
      type = get_boolean_type();
      name = "z";
    } else if (type == get_long_type()) {
      type = get_long_type();
      name = "j";
    } else if (type == get_float_type()) {
      type = get_float_type();
      name = "f";
    } else if (type == get_double_type()) {
      type = get_double_type();
      name = "d";
    } else {
      static DexType* string_type = DexType::make_type("Ljava/lang/String;");
      if (type == string_type) {
        type = string_type;
        name = "s";
      } else {
        char t = type_shorty(type);
        always_assert(t == 'L' || t == '[');
        type = get_object_type();
        name = "l";
      }
    }

    name = name + std::to_string(cnt);
    auto field = static_cast<DexField*>(
        DexField::make_field(owner, DexString::make_string(name), type));
    field->make_concrete(ACC_PUBLIC);
    res.push_back(field);
    cnt++;
  }

  TRACE(TERA, 8, "  created merger fields %d \n", res.size());
  return res;
}