use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class InsnGen method generateMethodArguments.
void generateMethodArguments(CodeWriter code, InsnNode insn, int startArgNum, @Nullable MethodNode callMth) throws CodegenException {
int k = startArgNum;
if (callMth != null && callMth.contains(AFlag.SKIP_FIRST_ARG)) {
k++;
}
int argsCount = insn.getArgsCount();
code.add('(');
boolean firstArg = true;
if (k < argsCount) {
boolean overloaded = callMth != null && callMth.isArgsOverload();
for (int i = k; i < argsCount; i++) {
InsnArg arg = insn.getArg(i);
if (arg.contains(AFlag.SKIP_ARG)) {
continue;
}
RegisterArg callArg = getCallMthArg(callMth, i - startArgNum);
if (callArg != null && callArg.contains(AFlag.SKIP_ARG)) {
continue;
}
if (!firstArg) {
code.add(", ");
}
boolean cast = overloaded && processOverloadedArg(code, callMth, arg, i - startArgNum);
if (!cast && i == argsCount - 1 && processVarArg(code, callMth, arg)) {
continue;
}
addArg(code, arg, false);
firstArg = false;
}
}
code.add(')');
}
use of jadx.core.dex.instructions.args.RegisterArg 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.RegisterArg in project jadx by skylot.
the class ModVisitor method processInvoke.
private static void processInvoke(MethodNode mth, BlockNode block, int insnNumber, InstructionRemover remover) {
ClassNode parentClass = mth.getParentClass();
InsnNode insn = block.getInstructions().get(insnNumber);
InvokeNode inv = (InvokeNode) insn;
MethodInfo callMth = inv.getCallMth();
if (!callMth.isConstructor()) {
return;
}
InsnNode instArgAssignInsn = ((RegisterArg) inv.getArg(0)).getAssignInsn();
ConstructorInsn co = new ConstructorInsn(mth, inv);
boolean remove = false;
if (co.isSuper() && (co.getArgsCount() == 0 || parentClass.isEnum())) {
remove = true;
} else if (co.isThis() && co.getArgsCount() == 0) {
MethodNode defCo = parentClass.searchMethodByName(callMth.getShortId());
if (defCo == null || defCo.isNoCode()) {
// default constructor not implemented
remove = true;
}
}
// remove super() call in instance initializer
if (parentClass.isAnonymous() && mth.isDefaultConstructor() && co.isSuper()) {
remove = true;
}
if (remove) {
remover.add(insn);
return;
}
if (co.isNewInstance()) {
InsnNode newInstInsn = removeAssignChain(instArgAssignInsn, remover, InsnType.NEW_INSTANCE);
if (newInstInsn != null) {
RegisterArg instArg = newInstInsn.getResult();
RegisterArg resultArg = co.getResult();
if (!resultArg.equals(instArg)) {
// replace all usages of 'instArg' with result of this constructor instruction
for (RegisterArg useArg : new ArrayList<RegisterArg>(instArg.getSVar().getUseList())) {
RegisterArg dup = resultArg.duplicate();
InsnNode parentInsn = useArg.getParentInsn();
parentInsn.replaceArg(useArg, dup);
dup.setParentInsn(parentInsn);
resultArg.getSVar().use(dup);
}
}
}
}
ConstructorInsn replace = processConstructor(mth, co);
if (replace != null) {
co = replace;
}
replaceInsn(block, insnNumber, co);
processAnonymousConstructor(mth, co);
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class ExtractFieldInit method checkInsn.
private static boolean checkInsn(InsnNode insn) {
InsnArg arg = insn.getArg(0);
if (arg.isInsnWrap()) {
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
if (!wrapInsn.canReorderRecursive() && insn.contains(AType.CATCH_BLOCK)) {
return false;
}
} else {
return arg.isLiteral() || arg.isThis();
}
Set<RegisterArg> regs = new HashSet<RegisterArg>();
insn.getRegisterArgs(regs);
if (!regs.isEmpty()) {
for (RegisterArg reg : regs) {
if (!reg.isThis()) {
return false;
}
}
}
return true;
}
use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.
the class MethodInlineVisitor method inlineMth.
private static void inlineMth(MethodNode mth, BlockNode firstBlock, BlockNode returnBlock) {
List<InsnNode> insnList = firstBlock.getInstructions();
if (insnList.isEmpty()) {
// synthetic field getter
BlockNode block = mth.getBasicBlocks().get(1);
InsnNode insn = block.getInstructions().get(0);
// set arg from 'return' instruction
addInlineAttr(mth, InsnNode.wrapArg(insn.getArg(0)));
return;
}
// synthetic field setter or method invoke
if (insnList.size() == 1) {
addInlineAttr(mth, insnList.get(0));
return;
}
// other field operations
if (insnList.size() == 2 && returnBlock.getInstructions().size() == 1 && !mth.getReturnType().equals(ArgType.VOID)) {
InsnNode get = insnList.get(0);
InsnNode put = insnList.get(1);
InsnArg retArg = returnBlock.getInstructions().get(0).getArg(0);
if (get.getType() == InsnType.IGET && put.getType() == InsnType.IPUT && retArg.isRegister() && get.getResult().equalRegisterAndType((RegisterArg) retArg)) {
RegisterArg retReg = (RegisterArg) retArg;
retReg.getSVar().removeUse(retReg);
CodeShrinker.shrinkMethod(mth);
insnList = firstBlock.getInstructions();
if (insnList.size() == 1) {
addInlineAttr(mth, insnList.get(0));
}
}
}
}
Aggregations