From 54f4c6d2cb65c1cbe920fa283e01c752d1bc356d Mon Sep 17 00:00:00 2001 From: Skylot Date: Mon, 29 Jul 2013 18:44:01 +0400 Subject: [PATCH] build samples without debug info, fix try/catch processing --- .../main/java/jadx/core/codegen/InsnGen.java | 17 +++---- .../java/jadx/core/codegen/MethodGen.java | 21 ++++++--- .../java/jadx/core/codegen/RegionGen.java | 2 +- .../core/dex/attributes/BlockRegState.java | 3 +- .../core/dex/instructions/InsnDecoder.java | 28 +++++++++--- .../core/dex/instructions/args/ArgType.java | 5 +++ .../instructions/args/ImmutableTypedVar.java | 23 ++++++++++ .../core/dex/instructions/args/InsnArg.java | 6 ++- .../dex/instructions/args/InsnWrapArg.java | 2 +- .../dex/instructions/args/LiteralArg.java | 2 +- .../core/dex/instructions/args/NamedArg.java | 29 ++++++++++++ .../core/dex/instructions/args/Typed.java | 1 - .../core/dex/instructions/args/TypedVar.java | 5 +++ .../java/jadx/core/dex/nodes/DexNode.java | 3 +- .../java/jadx/core/dex/nodes/MethodNode.java | 19 +++++--- .../core/dex/trycatch/ExceptionHandler.java | 8 ++-- .../dex/visitors/BlockProcessingHelper.java | 22 +++++++--- .../jadx/core/dex/visitors/CodeShrinker.java | 16 ++++--- .../jadx/core/dex/visitors/ModVisitor.java | 44 ++++++++++--------- 19 files changed, 180 insertions(+), 76 deletions(-) create mode 100644 jadx-core/src/main/java/jadx/core/dex/instructions/args/ImmutableTypedVar.java create mode 100644 jadx-core/src/main/java/jadx/core/dex/instructions/args/NamedArg.java diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 5786d94c5..f25b37336 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -19,6 +19,7 @@ import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.LiteralArg; +import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.mods.ConstructorInsn; import jadx.core.dex.nodes.ClassNode; @@ -77,10 +78,14 @@ public class InsnGen { return arg((RegisterArg) arg); } else if (arg.isLiteral()) { return lit((LiteralArg) arg); - } else { + } else if (arg.isInsnWrap()) { CodeWriter code = new CodeWriter(); makeInsn(((InsnWrapArg) arg).getWrapInsn(), code, true); return code.toString(); + } else if (arg.isNamed()) { + return ((NamedArg) arg).getName(); + } else { + throw new CodegenException("Unknown arg type " + arg); } } @@ -318,7 +323,7 @@ public class InsnGen { case MONITOR_EXIT: if (isFallback()) { - code.add("monitor-exit(").add(arg(insn.getArg(0))).add(')'); + code.add("monitor-exit(").add(arg(insn, 0)).add(')'); } else { state.add(InsnGenState.SKIP); } @@ -328,11 +333,7 @@ public class InsnGen { if (isFallback()) { code.add("move-exception"); } else { - // don't have body - if (state.contains(InsnGenState.BODY_ONLY)) - code.add(arg(insn.getResult())); - else - state.add(InsnGenState.SKIP); + code.add(arg(insn, 0)); } break; @@ -340,7 +341,7 @@ public class InsnGen { break; case ARGS: - code.add(arg(insn.getArg(0))); + code.add(arg(insn, 0)); break; case NOP: diff --git a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java index f0d48f11a..c459e77de 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java @@ -8,6 +8,7 @@ import jadx.core.dex.attributes.JadxErrorAttr; import jadx.core.dex.attributes.annotations.MethodParameters; import jadx.core.dex.info.AccessInfo; import jadx.core.dex.instructions.args.ArgType; +import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; @@ -118,7 +119,7 @@ public class MethodGen { (MethodParameters) mth.getAttributes().get(AttributeType.ANNOTATION_MTH_PARAMETERS); int i = 0; - for (Iterator it = args.iterator(); it.hasNext();) { + for (Iterator it = args.iterator(); it.hasNext(); ) { RegisterArg arg = it.next(); // add argument annotation @@ -179,16 +180,12 @@ public class MethodGen { /** * Put variable declaration and return variable name (used for assignments) * - * @param arg - * register variable + * @param arg register variable * @return variable name */ public String assignArg(RegisterArg arg) { String name = makeArgName(arg); - if (varNames.add(name)) - return name; - - if (fallback) + if (varNames.add(name) || fallback) return name; name = getUniqVarName(name); @@ -196,6 +193,16 @@ public class MethodGen { return name; } + public String assignNamedArg(NamedArg arg) { + String name = arg.getName(); + if (varNames.add(name) || fallback) + return name; + + name = getUniqVarName(name); + arg.setName(name); + return name; + } + private String getUniqVarName(String name) { String r; int i = 2; diff --git a/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java b/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java index 4b802aa93..d5c0004e0 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java @@ -270,7 +270,7 @@ public class RegionGen extends InsnGen { code.startLine("} catch ("); code.add(handler.isCatchAll() ? "Throwable" : useClass(handler.getCatchType())); code.add(' '); - code.add(mgen.assignArg(handler.getArg())); + code.add(mgen.assignNamedArg(handler.getArg())); code.add(") {"); makeRegionIndent(code, region); } diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/BlockRegState.java b/jadx-core/src/main/java/jadx/core/dex/attributes/BlockRegState.java index 8b01f0643..eac16cd6f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/BlockRegState.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/BlockRegState.java @@ -32,8 +32,7 @@ public final class BlockRegState { regType = new TypedVar(arg.getType()); regs[arg.getRegNum()].setTypedVar(regType); } - arg.replace(regType); - regType.getUseList().add(arg); + regType.use(arg); } public RegisterArg getRegister(int r) { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java index 5afabc4b8..eefd683cc 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java @@ -4,6 +4,7 @@ import jadx.core.dex.info.FieldInfo; import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; +import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.instructions.args.PrimitiveType; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.nodes.DexNode; @@ -387,7 +388,8 @@ public class InsnDecoder { case Opcodes.MOVE_EXCEPTION: return insn(InsnType.MOVE_EXCEPTION, - InsnArg.reg(insn, 0, ArgType.unknown(PrimitiveType.OBJECT))); + InsnArg.reg(insn, 0, ArgType.unknown(PrimitiveType.OBJECT)), + new NamedArg("e", ArgType.unknown(PrimitiveType.OBJECT))); case Opcodes.RETURN_VOID: return new InsnNode(InsnType.RETURN, 0); @@ -668,13 +670,27 @@ public class InsnDecoder { return inode; } + private InsnNode insn(InsnType type, RegisterArg res) { + InsnNode node = new InsnNode(type, 0); + node.setResult(res); + return node; + } + + private InsnNode insn(InsnType type, RegisterArg res, InsnArg arg) { + InsnNode node = new InsnNode(type, 1); + node.setResult(res); + node.addArg(arg); + return node; + } + private InsnNode insn(InsnType type, RegisterArg res, InsnArg... args) { - InsnNode inode = new InsnNode(type, args == null ? 0 : args.length); - inode.setResult(res); - if (args != null) + InsnNode node = new InsnNode(type, args == null ? 0 : args.length); + node.setResult(res); + if (args != null) { for (InsnArg arg : args) - inode.addArg(arg); - return inode; + node.addArg(arg); + } + return node; } private int getMoveResultRegister(DecodedInstruction[] insnArr, int offset) { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java index 795b87138..f0c077e20 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java @@ -344,6 +344,11 @@ public abstract class ArgType { } } } else { + if(a.isGenericType()) + return a; + if(b.isGenericType()) + return b; + if (a.isObject() && b.isObject()) { if (a.getObject().equals(b.getObject())) { if (a.getGenericTypes() != null) diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/ImmutableTypedVar.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/ImmutableTypedVar.java new file mode 100644 index 000000000..6702a4862 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/ImmutableTypedVar.java @@ -0,0 +1,23 @@ +package jadx.core.dex.instructions.args; + +public class ImmutableTypedVar extends TypedVar { + + public ImmutableTypedVar(ArgType initType) { + super(initType); + } + + @Override + public boolean forceSetType(ArgType newType) { + return false; + } + + @Override + public boolean merge(TypedVar typedVar) { + return false; + } + + @Override + public boolean merge(ArgType mtype) { + return false; + } +} diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java index f47eb74f1..ebb228deb 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java @@ -14,7 +14,6 @@ public abstract class InsnArg extends Typed { protected InsnNode parentInsn; public static RegisterArg reg(int regNum, ArgType type) { - assert regNum >= 0 : "Register number must be positive"; return new RegisterArg(regNum, type); } @@ -46,6 +45,10 @@ public abstract class InsnArg extends Typed { return false; } + public boolean isNamed() { + return false; + } + public InsnNode getParentInsn() { return parentInsn; } @@ -75,5 +78,4 @@ public abstract class InsnArg extends Typed { public int getRegNum() { throw new UnsupportedOperationException("Must be called from RegisterArg"); } - } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnWrapArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnWrapArg.java index d1a615644..2ae4d39cb 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnWrapArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnWrapArg.java @@ -2,7 +2,7 @@ package jadx.core.dex.instructions.args; import jadx.core.dex.nodes.InsnNode; -public class InsnWrapArg extends InsnArg { +public final class InsnWrapArg extends InsnArg { private final InsnNode wrappedInsn; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java index 5ef70ffbe..3a78ee354 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java @@ -3,7 +3,7 @@ package jadx.core.dex.instructions.args; import jadx.core.codegen.TypeGen; import jadx.core.utils.exceptions.JadxRuntimeException; -public class LiteralArg extends InsnArg { +public final class LiteralArg extends InsnArg { private final long literal; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/NamedArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/NamedArg.java new file mode 100644 index 000000000..ecb87d0c2 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/NamedArg.java @@ -0,0 +1,29 @@ +package jadx.core.dex.instructions.args; + +public final class NamedArg extends InsnArg { + + private String name; + + public NamedArg(String name, ArgType type) { + this.name = name; + this.typedVar = new TypedVar(type); + } + + public String getName() { + return name; + } + + @Override + public boolean isNamed() { + return true; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "(" + name + " " + typedVar + ")"; + } +} diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java index bc6815fcd..5da151a75 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java @@ -29,7 +29,6 @@ public abstract class Typed { } public void replace(TypedVar newVar) { - assert newVar != null; if (typedVar == newVar) return; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java index fb44d42a9..3a1495831 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java @@ -43,6 +43,11 @@ public class TypedVar { } } + public void use(InsnArg arg) { + arg.replace(this); + useList.add(arg); + } + public List getUseList() { return useList; } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java index 8ba804764..d33ca73d9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java @@ -7,6 +7,7 @@ import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.files.InputFile; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -99,7 +100,7 @@ public class DexNode { for (short t : paramList.getTypes()) { args.add(getType(t)); } - return args; + return Collections.unmodifiableList(args); } public Code readCode(Method mth) { diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java index b5122b76c..74f87b992 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java @@ -169,23 +169,24 @@ public class MethodNode extends LineAttrNode implements ILoadable { if (argsTypes == null) return false; - if (argsTypes.size() != mthInfo.getArgumentsTypes().size()) { + List mthArgs = mthInfo.getArgumentsTypes(); + if (argsTypes.size() != mthArgs.size()) { if (argsTypes.isEmpty()) { return false; } if (!mthInfo.isConstructor()) { LOG.warn("Wrong signature parse result: " + sign + " -> " + argsTypes - + ", not generic version: " + mthInfo.getArgumentsTypes()); + + ", not generic version: " + mthArgs); return false; } else if (getParentClass().getAccessFlags().isEnum()) { // TODO: - argsTypes.add(0, mthInfo.getArgumentsTypes().get(0)); - argsTypes.add(1, mthInfo.getArgumentsTypes().get(1)); + argsTypes.add(0, mthArgs.get(0)); + argsTypes.add(1, mthArgs.get(1)); } else { // add synthetic arg for outer class - argsTypes.add(0, mthInfo.getArgumentsTypes().get(0)); + argsTypes.add(0, mthArgs.get(0)); } - if (argsTypes.size() != mthInfo.getArgumentsTypes().size()) { + if (argsTypes.size() != mthArgs.size()) { return false; } } @@ -454,6 +455,11 @@ public class MethodNode extends LineAttrNode implements ILoadable { return exceptionHandlers; } + public boolean isMethodOverloaded() { + // TODO + return false; + } + public int getRegsCount() { return regsCount; } @@ -505,5 +511,4 @@ public class MethodNode extends LineAttrNode implements ILoadable { + " " + parentClass.getFullName() + "." + mthInfo.getName() + "(" + Utils.listToString(mthInfo.getArgumentsTypes()) + ")"; } - } diff --git a/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java b/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java index a26054073..83f76685f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java +++ b/jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java @@ -2,7 +2,7 @@ package jadx.core.dex.trycatch; import jadx.core.Consts; import jadx.core.dex.info.ClassInfo; -import jadx.core.dex.instructions.args.RegisterArg; +import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.IContainer; import jadx.core.utils.InsnUtils; @@ -18,7 +18,7 @@ public class ExceptionHandler { private BlockNode handleBlock; private final List blocks = new ArrayList(); private IContainer handlerRegion; - private RegisterArg arg; + private NamedArg arg; private TryCatchBlock tryBlock; @@ -63,11 +63,11 @@ public class ExceptionHandler { this.handlerRegion = handlerRegion; } - public RegisterArg getArg() { + public NamedArg getArg() { return arg; } - public void setArg(RegisterArg arg) { + public void setArg(NamedArg arg) { this.arg = arg; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/BlockProcessingHelper.java b/jadx-core/src/main/java/jadx/core/dex/visitors/BlockProcessingHelper.java index 75a528a94..95762732e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/BlockProcessingHelper.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/BlockProcessingHelper.java @@ -3,6 +3,7 @@ package jadx.core.dex.visitors; import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.args.ArgType; +import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.InsnNode; @@ -40,15 +41,22 @@ public class BlockProcessingHelper { if (!block.getInstructions().isEmpty()) { InsnNode me = block.getInstructions().get(0); ExcHandlerAttr handlerAttr = (ExcHandlerAttr) me.getAttributes().get(AttributeType.EXC_HANDLER); - if (handlerAttr != null) { + if (handlerAttr != null && me.getType() == InsnType.MOVE_EXCEPTION) { ExceptionHandler excHandler = handlerAttr.getHandler(); - assert me.getType() == InsnType.MOVE_EXCEPTION && me.getOffset() == excHandler.getHandleOffset(); + assert me.getOffset() == excHandler.getHandleOffset(); // set correct type for 'move-exception' operation - RegisterArg excArg = me.getResult(); - if (excHandler.isCatchAll()) - excArg.getTypedVar().forceSetType(ArgType.THROWABLE); - else - excArg.getTypedVar().forceSetType(excHandler.getCatchType().getType()); + RegisterArg resArg = me.getResult(); + NamedArg excArg = (NamedArg) me.getArg(0); + ArgType type; + if (excHandler.isCatchAll()) { + type = ArgType.THROWABLE; + excArg.setName("th"); + } else { + type = excHandler.getCatchType().getType(); + excArg.setName("e"); + } + resArg.getTypedVar().forceSetType(type); + excArg.getTypedVar().forceSetType(type); excHandler.setArg(excArg); block.getAttributes().add(handlerAttr); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/CodeShrinker.java b/jadx-core/src/main/java/jadx/core/dex/visitors/CodeShrinker.java index 3a1afcb84..f19e152de 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/CodeShrinker.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/CodeShrinker.java @@ -70,18 +70,20 @@ public class CodeShrinker extends AbstractVisitor { } else { // TODO implement rules for shrink insn from different blocks BlockNode useBlock = BlockUtils.getBlockByInsn(mth, useInsn); - if (useBlock != null && useBlock.getPredecessors().contains(block)) { + if (useBlock != null + && (useBlock.getPredecessors().contains(block) + || insn.getType() == InsnType.MOVE_EXCEPTION)) { wrap = true; } } if (wrap) { - if (useInsn.getType() == InsnType.MOVE) { - // TODO - // remover.add(useInsn); - } else { +// if (useInsn.getType() == InsnType.MOVE) { +// // TODO +// // remover.add(useInsn); +// } else { useInsnArg.wrapInstruction(insn); remover.add(insn); - } +// } } } } @@ -193,7 +195,7 @@ public class CodeShrinker extends AbstractVisitor { while (i.isInsnWrap()) { InsnNode wrapInsn = ((InsnWrapArg) i).getWrapInsn(); chain.add(wrapInsn); - if(wrapInsn.getArgsCount() == 0) + if (wrapInsn.getArgsCount() == 0) break; i = wrapInsn.getArg(0); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java index fcd3433dd..4ebf35e8c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java @@ -19,7 +19,6 @@ import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.trycatch.ExcHandlerAttr; import jadx.core.dex.trycatch.ExceptionHandler; -import jadx.core.dex.trycatch.TryCatchBlock; import jadx.core.utils.BlockUtils; import jadx.core.utils.exceptions.JadxRuntimeException; @@ -188,45 +187,48 @@ public class ModVisitor extends AbstractVisitor { if (handlerAttr == null) return; - TryCatchBlock tryBlock = handlerAttr.getTryBlock(); ExceptionHandler excHandler = handlerAttr.getHandler(); - List blockInsns = block.getInstructions(); - int size = blockInsns.size(); - if (size > 0 && blockInsns.get(0).getType() == InsnType.MOVE_EXCEPTION) { - InstructionRemover.remove(block, 0); - } - - int totalSize = 0; boolean noExitNode = true; // check if handler has exit edge to block not from this handler for (BlockNode excBlock : excHandler.getBlocks()) { - List insns = excBlock.getInstructions(); - size = insns.size(); - if (noExitNode) + if (noExitNode) { noExitNode = excHandler.getBlocks().containsAll(excBlock.getCleanSuccessors()); + } + List insns = excBlock.getInstructions(); + int size = insns.size(); if (excHandler.isCatchAll() && size > 0 && insns.get(size - 1).getType() == InsnType.THROW) { InstructionRemover.remove(excBlock, size - 1); - size = insns.size(); // move not removed instructions to 'finally' block - if (size != 0) { + if (insns.size() != 0) { // TODO: support instructions from several blocks // tryBlock.setFinalBlockFromInsns(mth, insns); - - // TODO; because of incomplete realization don't extract final block, + // TODO: because of incomplete realization don't extract final block, // just remove unnecessary instructions insns.clear(); - - size = insns.size(); } } - totalSize += size; } - if (totalSize == 0 && noExitNode) - tryBlock.removeHandler(mth, excHandler); + + List blockInsns = block.getInstructions(); + if (blockInsns.size() > 0) { + InsnNode insn = blockInsns.get(0); + if (insn.getType() == InsnType.MOVE_EXCEPTION + && insn.getResult().getTypedVar().getUseList().size() <= 1) { + InstructionRemover.remove(block, 0); + } + } + + int totalSize = 0; + for (BlockNode excBlock : excHandler.getBlocks()) { + totalSize += excBlock.getInstructions().size(); + } + if (totalSize == 0 && noExitNode) { + handlerAttr.getTryBlock().removeHandler(mth, excHandler); + } } /**