use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class ConstInlineVisitor method checkInsn.
private static boolean checkInsn(MethodNode mth, InsnNode insn) {
if (insn.getType() != InsnType.CONST || insn.contains(AFlag.DONT_INLINE)) {
return false;
}
InsnArg arg = insn.getArg(0);
if (!arg.isLiteral()) {
return false;
}
long lit = ((LiteralArg) arg).getLiteral();
SSAVar sVar = insn.getResult().getSVar();
if (lit == 0 && checkObjectInline(sVar)) {
if (sVar.getUseCount() == 1) {
InsnNode assignInsn = insn.getResult().getAssignInsn();
if (assignInsn != null) {
assignInsn.add(AFlag.DONT_INLINE);
}
}
return false;
}
ArgType resType = insn.getResult().getType();
// make sure arg has correct type
if (!arg.getType().isTypeKnown()) {
arg.merge(mth.dex(), resType);
}
return replaceConst(mth, insn, lit);
}
use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class NameGen method guessName.
private String guessName(RegisterArg arg) {
SSAVar sVar = arg.getSVar();
if (sVar != null && sVar.getName() == null) {
RegisterArg assignArg = sVar.getAssign();
InsnNode assignInsn = assignArg.getParentInsn();
if (assignInsn != null) {
String name = makeNameFromInsn(assignInsn);
if (name != null && !NameMapper.isReserved(name)) {
assignArg.setName(name);
return name;
}
}
}
return makeNameForType(arg.getType());
}
use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class MethodGen method addMethodArguments.
private void addMethodArguments(CodeWriter argsCode, List<RegisterArg> args) {
MethodParameters paramsAnnotation = mth.get(AType.ANNOTATION_MTH_PARAMETERS);
int i = 0;
for (Iterator<RegisterArg> it = args.iterator(); it.hasNext(); ) {
RegisterArg arg = it.next();
// add argument annotation
if (paramsAnnotation != null) {
annotationGen.addForParameter(argsCode, paramsAnnotation, i);
}
SSAVar argSVar = arg.getSVar();
if (argSVar != null && argSVar.contains(AFlag.FINAL)) {
argsCode.add("final ");
}
if (!it.hasNext() && mth.getAccessFlags().isVarArgs()) {
// change last array argument to varargs
ArgType type = arg.getType();
if (type.isArray()) {
ArgType elType = type.getArrayElement();
classGen.useType(argsCode, elType);
argsCode.add("...");
} else {
LOG.warn(ErrorsCounter.formatErrorMsg(mth, "Last argument in varargs method not array"));
classGen.useType(argsCode, arg.getType());
}
} else {
classGen.useType(argsCode, arg.getType());
}
argsCode.add(' ');
argsCode.add(nameGen.assignArg(arg));
i++;
if (it.hasNext()) {
argsCode.add(", ");
}
}
}
use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class ClassModifier method removeSyntheticMethods.
private static void removeSyntheticMethods(ClassNode cls) {
for (MethodNode mth : cls.getMethods()) {
if (mth.isNoCode()) {
continue;
}
AccessInfo af = mth.getAccessFlags();
// remove bridge methods
if (af.isBridge() && af.isSynthetic() && !isMethodUniq(cls, mth)) {
// TODO add more checks before method deletion
mth.add(AFlag.DONT_GENERATE);
continue;
}
// remove synthetic constructor for inner classes
if (af.isSynthetic() && af.isConstructor() && mth.getBasicBlocks().size() == 2) {
List<InsnNode> insns = mth.getBasicBlocks().get(0).getInstructions();
if (insns.size() == 1 && insns.get(0).getType() == InsnType.CONSTRUCTOR) {
ConstructorInsn constr = (ConstructorInsn) insns.get(0);
List<RegisterArg> args = mth.getArguments(false);
if (constr.isThis() && !args.isEmpty()) {
// remove first arg for non-static class (references to outer class)
if (args.get(0).getType().equals(cls.getParentClass().getClassInfo().getType())) {
args.get(0).add(AFlag.SKIP_ARG);
}
// remove unused args
for (RegisterArg arg : args) {
SSAVar sVar = arg.getSVar();
if (sVar != null && sVar.getUseCount() == 0) {
arg.add(AFlag.SKIP_ARG);
}
}
mth.add(AFlag.DONT_GENERATE);
}
}
}
}
}
use of jadx.core.dex.instructions.args.SSAVar in project jadx by skylot.
the class CodeShrinker method shrinkBlock.
private static void shrinkBlock(MethodNode mth, BlockNode block) {
if (block.getInstructions().isEmpty()) {
return;
}
InsnList insnList = new InsnList(block.getInstructions());
int insnCount = insnList.size();
List<ArgsInfo> argsList = new ArrayList<ArgsInfo>(insnCount);
for (int i = 0; i < insnCount; i++) {
argsList.add(new ArgsInfo(insnList.get(i), argsList, i));
}
List<WrapInfo> wrapList = new ArrayList<WrapInfo>();
for (ArgsInfo argsInfo : argsList) {
List<RegisterArg> args = argsInfo.getArgs();
if (args.isEmpty()) {
continue;
}
ListIterator<RegisterArg> it = args.listIterator(args.size());
while (it.hasPrevious()) {
RegisterArg arg = it.previous();
// if (arg.getName() != null) {
// continue;
// }
SSAVar sVar = arg.getSVar();
// allow inline only one use arg or 'this'
if (sVar == null || sVar.getVariableUseCount() != 1 && !arg.isThis() || sVar.contains(AFlag.DONT_INLINE)) {
continue;
}
InsnNode assignInsn = sVar.getAssign().getParentInsn();
if (assignInsn == null || assignInsn.contains(AFlag.DONT_INLINE)) {
continue;
}
int assignPos = insnList.getIndex(assignInsn);
if (assignPos != -1) {
WrapInfo wrapInfo = argsInfo.checkInline(assignPos, arg);
if (wrapInfo != null) {
wrapList.add(wrapInfo);
}
} else {
// another block
BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignInsn);
if (assignBlock != null && assignInsn != arg.getParentInsn() && canMoveBetweenBlocks(assignInsn, assignBlock, block, argsInfo.getInsn())) {
inline(arg, assignInsn, assignBlock);
}
}
}
}
if (!wrapList.isEmpty()) {
for (WrapInfo wrapInfo : wrapList) {
inline(wrapInfo.getArg(), wrapInfo.getInsn(), block);
}
}
}
Aggregations