void MethodBlock::ret(DexType* rtype, Location loc) { if (rtype != get_void_type()) { ret(loc); } else { ret_void(); } }
DexClass* create_class(const DexType* type, const DexType* super_type, const std::string& pkg_name, std::vector<DexField*> fields, const TypeSet& interfaces, bool with_default_ctor, DexAccessFlags access) { DexType* t = const_cast<DexType*>(type); always_assert(!pkg_name.empty()); auto name = std::string(type->get_name()->c_str()); name = pkg_name + "/" + name.substr(1); t->set_name(DexString::make_string(name)); // Create class. ClassCreator creator(t); creator.set_access(access); always_assert(super_type != nullptr); creator.set_super(const_cast<DexType*>(super_type)); for (const auto& itf : interfaces) { creator.add_interface(const_cast<DexType*>(itf)); } for (const auto& field : fields) { creator.add_field(field); } auto cls = creator.create(); // Keeping type-erasure generated classes from being renamed. cls->rstate.set_keep_name(); if (!with_default_ctor) { return cls; } // Create ctor. auto super_ctors = type_class(super_type)->get_ctors(); for (auto super_ctor : super_ctors) { auto mc = new MethodCreator(t, DexString::make_string("<init>"), super_ctor->get_proto(), ACC_PUBLIC | ACC_CONSTRUCTOR); // Call to super.<init> std::vector<Location> args; size_t args_size = super_ctor->get_proto()->get_args()->size(); for (size_t arg_loc = 0; arg_loc < args_size + 1; ++arg_loc) { args.push_back(mc->get_local(arg_loc)); } auto mb = mc->get_main_block(); mb->invoke(OPCODE_INVOKE_DIRECT, super_ctor, args); mb->ret_void(); auto ctor = mc->create(); TRACE(TERA, 4, " default ctor created %s\n", SHOW(ctor)); cls->add_method(ctor); } return cls; }