Commit 940de240 authored by Skylot's avatar Skylot

core: split const-string and const-class instructions

parent 6ddb71e2
...@@ -355,6 +355,10 @@ public class ClassGen { ...@@ -355,6 +355,10 @@ public class ClassGen {
if (isInner(classInfo, cls.getClassInfo())) if (isInner(classInfo, cls.getClassInfo()))
return shortName; return shortName;
// don't add import if this class from same package
if(classInfo.getPackage().equals(cls.getPackage()))
return shortName;
for (ClassInfo cls : imports) { for (ClassInfo cls : imports) {
if (!cls.equals(classInfo)) { if (!cls.equals(classInfo)) {
if (cls.getShortName().equals(shortName)) if (cls.getShortName().equals(shortName))
......
...@@ -5,16 +5,12 @@ import jadx.core.dex.nodes.ClassNode; ...@@ -5,16 +5,12 @@ import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.visitors.AbstractVisitor; import jadx.core.dex.visitors.AbstractVisitor;
import jadx.core.utils.exceptions.CodegenException; import jadx.core.utils.exceptions.CodegenException;
import java.io.File;
public class CodeGen extends AbstractVisitor { public class CodeGen extends AbstractVisitor {
private final File dir;
private final IJadxArgs args; private final IJadxArgs args;
public CodeGen(IJadxArgs args) { public CodeGen(IJadxArgs args) {
this.args = args; this.args = args;
this.dir = args.getOutDir();
} }
@Override @Override
......
...@@ -8,6 +8,8 @@ import jadx.core.dex.info.FieldInfo; ...@@ -8,6 +8,8 @@ import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.info.MethodInfo; import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.ArithNode; import jadx.core.dex.instructions.ArithNode;
import jadx.core.dex.instructions.ArithOp; import jadx.core.dex.instructions.ArithOp;
import jadx.core.dex.instructions.ConstClassInsn;
import jadx.core.dex.instructions.ConstStringInsn;
import jadx.core.dex.instructions.FillArrayOp; import jadx.core.dex.instructions.FillArrayOp;
import jadx.core.dex.instructions.GotoNode; import jadx.core.dex.instructions.GotoNode;
import jadx.core.dex.instructions.IfNode; import jadx.core.dex.instructions.IfNode;
...@@ -181,18 +183,19 @@ public class InsnGen { ...@@ -181,18 +183,19 @@ public class InsnGen {
private void makeInsnBody(CodeWriter code, InsnNode insn, EnumSet<InsnGenState> state) throws CodegenException { private void makeInsnBody(CodeWriter code, InsnNode insn, EnumSet<InsnGenState> state) throws CodegenException {
switch (insn.getType()) { switch (insn.getType()) {
case CONST_STR:
String str = ((ConstStringInsn) insn).getString();
code.add(StringUtils.unescapeString(str));
break;
case CONST_CLASS:
ArgType clsType = ((ConstClassInsn) insn).getClsType();
code.add(useType(clsType)).add(".class");
break;
case CONST: case CONST:
if (insn.getArgsCount() == 0) {
// const in 'index' - string or class
Object ind = ((IndexInsnNode) insn).getIndex();
if (ind instanceof String)
code.add(StringUtils.unescapeString(ind.toString()));
else if (ind instanceof ArgType)
code.add(useType((ArgType) ind)).add(".class");
} else {
LiteralArg arg = (LiteralArg) insn.getArg(0); LiteralArg arg = (LiteralArg) insn.getArg(0);
code.add(lit(arg)); code.add(lit(arg));
}
break; break;
case MOVE: case MOVE:
......
package jadx.core.dex.instructions;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.InsnNode;
public class ConstClassInsn extends InsnNode {
private final ArgType clsType;
public ConstClassInsn(ArgType clsType) {
super(InsnType.CONST_CLASS, 0);
this.clsType = clsType;
}
public ArgType getClsType() {
return clsType;
}
@Override
public String toString() {
return super.toString() + " " + clsType;
}
}
package jadx.core.dex.instructions;
import jadx.core.dex.nodes.InsnNode;
public class ConstStringInsn extends InsnNode {
private final String str;
public ConstStringInsn(String str) {
super(InsnType.CONST_STR, 0);
this.str = str;
}
public String getString() {
return str;
}
@Override
public String toString() {
return super.toString() + " \"" + str + "\"";
}
}
...@@ -96,13 +96,13 @@ public class InsnDecoder { ...@@ -96,13 +96,13 @@ public class InsnDecoder {
case Opcodes.CONST_STRING: case Opcodes.CONST_STRING:
case Opcodes.CONST_STRING_JUMBO: { case Opcodes.CONST_STRING_JUMBO: {
InsnNode node = new IndexInsnNode(InsnType.CONST, dex.getString(insn.getIndex()), 0); InsnNode node = new ConstStringInsn(dex.getString(insn.getIndex()));
node.setResult(InsnArg.reg(insn, 0, ArgType.STRING)); node.setResult(InsnArg.reg(insn, 0, ArgType.STRING));
return node; return node;
} }
case Opcodes.CONST_CLASS: { case Opcodes.CONST_CLASS: {
InsnNode node = new IndexInsnNode(InsnType.CONST, dex.getType(insn.getIndex()), 0); InsnNode node = new ConstClassInsn(dex.getType(insn.getIndex()));
node.setResult(InsnArg.reg(insn, 0, ArgType.CLASS)); node.setResult(InsnArg.reg(insn, 0, ArgType.CLASS));
return node; return node;
} }
......
...@@ -4,6 +4,8 @@ public enum InsnType { ...@@ -4,6 +4,8 @@ public enum InsnType {
NOP, // replacement for removed instructions NOP, // replacement for removed instructions
CONST, CONST,
CONST_STR,
CONST_CLASS,
ARITH, ARITH,
NEG, NEG,
......
...@@ -64,10 +64,27 @@ public abstract class InsnArg extends Typed { ...@@ -64,10 +64,27 @@ public abstract class InsnArg extends Typed {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (parentInsn.getArg(i) == this) { if (parentInsn.getArg(i) == this) {
InsnArg arg; InsnArg arg;
if (insn.getType() == InsnType.MOVE) { InsnType insnType = insn.getType();
switch (insnType) {
case MOVE:
case CONST:
arg = insn.getArg(0); arg = insn.getArg(0);
} else { String name = insn.getResult().getTypedVar().getName();
if (name != null) {
arg.getTypedVar().setName(name);
}
break;
case CONST_STR:
arg = wrap(insn);
arg.getTypedVar().forceSetType(ArgType.STRING);
break;
case CONST_CLASS:
arg = wrap(insn);
arg.getTypedVar().forceSetType(ArgType.CLASS);
break;
default:
arg = wrap(insn); arg = wrap(insn);
break;
} }
parentInsn.setArg(i, arg); parentInsn.setArg(i, arg);
return arg; return arg;
...@@ -80,8 +97,4 @@ public abstract class InsnArg extends Typed { ...@@ -80,8 +97,4 @@ public abstract class InsnArg extends Typed {
// must be implemented in RegisterArg // must be implemented in RegisterArg
return false; return false;
} }
public int getRegNum() {
throw new UnsupportedOperationException("Must be called from RegisterArg");
}
} }
package jadx.core.dex.instructions.args; package jadx.core.dex.instructions.args;
import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.ConstClassInsn;
import jadx.core.dex.instructions.ConstStringInsn;
import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.visitors.InstructionRemover; import jadx.core.dex.visitors.InstructionRemover;
...@@ -17,7 +18,6 @@ public class RegisterArg extends InsnArg { ...@@ -17,7 +18,6 @@ public class RegisterArg extends InsnArg {
this.regNum = rn; this.regNum = rn;
} }
@Override
public int getRegNum() { public int getRegNum() {
return regNum; return regNum;
} }
...@@ -47,12 +47,15 @@ public class RegisterArg extends InsnArg { ...@@ -47,12 +47,15 @@ public class RegisterArg extends InsnArg {
*/ */
public Object getConstValue() { public Object getConstValue() {
InsnNode parInsn = getAssignInsn(); InsnNode parInsn = getAssignInsn();
if (parInsn != null && parInsn.getType() == InsnType.CONST) { if (parInsn != null) {
if (parInsn.getArgsCount() == 0) { InsnType insnType = parInsn.getType();
// const in 'index' - string or class switch (insnType) {
return ((IndexInsnNode) parInsn).getIndex(); case CONST:
} else {
return parInsn.getArg(0); return parInsn.getArg(0);
case CONST_STR:
return ((ConstStringInsn) parInsn).getString();
case CONST_CLASS:
return ((ConstClassInsn) parInsn).getClsType();
} }
} }
return null; return null;
......
...@@ -21,7 +21,7 @@ public class TypedVar { ...@@ -21,7 +21,7 @@ public class TypedVar {
* This method must be used very carefully * This method must be used very carefully
*/ */
public boolean forceSetType(ArgType newType) { public boolean forceSetType(ArgType newType) {
if (newType != null && !type.equals(newType)) { if (!newType.equals(type)) {
type = newType; type = newType;
return true; return true;
} else { } else {
......
...@@ -4,6 +4,7 @@ import jadx.core.dex.info.ClassInfo; ...@@ -4,6 +4,7 @@ import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.info.MethodInfo; import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.InvokeNode; import jadx.core.dex.instructions.InvokeNode;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
......
...@@ -71,7 +71,7 @@ public class InsnNode extends LineAttrNode { ...@@ -71,7 +71,7 @@ public class InsnNode extends LineAttrNode {
public boolean containsArg(RegisterArg arg) { public boolean containsArg(RegisterArg arg) {
for (InsnArg a : arguments) { for (InsnArg a : arguments) {
if (a == arg || (a.isRegister() && a.getRegNum() == arg.getRegNum())) if (a == arg || (a.isRegister() && ((RegisterArg)a).getRegNum() == arg.getRegNum()))
return true; return true;
} }
return false; return false;
......
...@@ -168,7 +168,7 @@ public class DebugInfoParser { ...@@ -168,7 +168,7 @@ public class DebugInfoParser {
insn.setSourceLine(line); insn.setSourceLine(line);
for (InsnArg arg : insn.getArguments()) for (InsnArg arg : insn.getArguments())
if (arg.isRegister()) { if (arg.isRegister()) {
activeRegisters[arg.getRegNum()] = arg; activeRegisters[((RegisterArg) arg).getRegNum()] = arg;
} }
RegisterArg res = insn.getResult(); RegisterArg res = insn.getResult();
...@@ -211,7 +211,7 @@ public class DebugInfoParser { ...@@ -211,7 +211,7 @@ public class DebugInfoParser {
private static void merge(InsnArg arg, LocalVar var) { private static void merge(InsnArg arg, LocalVar var) {
if (arg != null && arg.isRegister()) { if (arg != null && arg.isRegister()) {
if (var.getRegNum() == arg.getRegNum()) if (var.getRegNum() == ((RegisterArg) arg).getRegNum())
arg.setTypedVar(var.getTypedVar()); arg.setTypedVar(var.getTypedVar());
} }
} }
......
...@@ -36,13 +36,12 @@ public class ConstInlinerVisitor extends AbstractVisitor { ...@@ -36,13 +36,12 @@ public class ConstInlinerVisitor extends AbstractVisitor {
private static boolean checkInsn(MethodNode mth, BlockNode block, InsnNode insn) { private static boolean checkInsn(MethodNode mth, BlockNode block, InsnNode insn) {
if (insn.getType() == InsnType.CONST) { if (insn.getType() == InsnType.CONST) {
if (insn.getArgsCount() == 1 if (insn.getArg(0).isLiteral()
&& insn.getArg(0).isLiteral()
&& insn.getResult().getType().getRegCount() == 1 /* process only narrow types */) { && insn.getResult().getType().getRegCount() == 1 /* process only narrow types */) {
long lit = ((LiteralArg) insn.getArg(0)).getLiteral(); long lit = ((LiteralArg) insn.getArg(0)).getLiteral();
return replaceConst(mth, block, insn, lit); return replaceConst(mth, block, insn, lit);
} }
// TODO process string const // TODO process string and class const
} }
return false; return false;
} }
...@@ -106,9 +105,7 @@ public class ConstInlinerVisitor extends AbstractVisitor { ...@@ -106,9 +105,7 @@ public class ConstInlinerVisitor extends AbstractVisitor {
private static void fixTypes(MethodNode mth, InsnNode insn) { private static void fixTypes(MethodNode mth, InsnNode insn) {
switch (insn.getType()) { switch (insn.getType()) {
case CONST: case CONST:
if (insn.getArgsCount() > 0) {
insn.getArg(0).merge(insn.getResult()); insn.getArg(0).merge(insn.getResult());
}
break; break;
case MOVE: case MOVE:
......
...@@ -26,6 +26,8 @@ public class FallbackModeVisitor extends AbstractVisitor { ...@@ -26,6 +26,8 @@ public class FallbackModeVisitor extends AbstractVisitor {
case ARITH: // ?? case ARITH: // ??
case NEG: case NEG:
case CONST: case CONST:
case CONST_STR:
case CONST_CLASS:
case CMP_L: case CMP_L:
case CMP_G: case CMP_G:
catchAttr.getTryBlock().removeInsn(insn); catchAttr.getTryBlock().removeInsn(insn);
......
...@@ -4,6 +4,8 @@ import jadx.core.Consts; ...@@ -4,6 +4,8 @@ import jadx.core.Consts;
import jadx.core.deobf.NameMapper; import jadx.core.deobf.NameMapper;
import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.info.MethodInfo; import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.ConstClassInsn;
import jadx.core.dex.instructions.ConstStringInsn;
import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.InvokeNode; import jadx.core.dex.instructions.InvokeNode;
...@@ -98,12 +100,16 @@ public class ModVisitor extends AbstractVisitor { ...@@ -98,12 +100,16 @@ public class ModVisitor extends AbstractVisitor {
break; break;
case CONST: case CONST:
case CONST_STR:
case CONST_CLASS:
ClassNode parentClass = mth.getParentClass(); ClassNode parentClass = mth.getParentClass();
FieldNode f = null; FieldNode f = null;
if (insn.getArgsCount() == 0) { if (insn.getType() == InsnType.CONST_STR) {
// const-string String s = ((ConstStringInsn) insn).getString();
IndexInsnNode node = (IndexInsnNode) insn; f = parentClass.getConstField(s);
f = parentClass.getConstField(node.getIndex()); } else if (insn.getType() == InsnType.CONST_CLASS) {
ArgType t = ((ConstClassInsn) insn).getClsType();
f = parentClass.getConstField(t);
} else { } else {
LiteralArg arg = (LiteralArg) insn.getArg(0); LiteralArg arg = (LiteralArg) insn.getArg(0);
ArgType type = arg.getType(); ArgType type = arg.getType();
......
package jadx.core.dex.visitors.regions; package jadx.core.dex.visitors.regions;
import jadx.core.Consts;
import jadx.core.dex.attributes.AttributeFlag; import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.attributes.AttributeType;
import jadx.core.dex.attributes.AttributesList; import jadx.core.dex.attributes.AttributesList;
...@@ -42,19 +43,23 @@ public class RegionMaker { ...@@ -42,19 +43,23 @@ public class RegionMaker {
private static final Logger LOG = LoggerFactory.getLogger(RegionMaker.class); private static final Logger LOG = LoggerFactory.getLogger(RegionMaker.class);
private final MethodNode mth; private final MethodNode mth;
private final BitSet processedBlocks; private BitSet processedBlocks;
public RegionMaker(MethodNode mth) { public RegionMaker(MethodNode mth) {
this.mth = mth; this.mth = mth;
if (Consts.DEBUG) {
this.processedBlocks = new BitSet(mth.getBasicBlocks().size()); this.processedBlocks = new BitSet(mth.getBasicBlocks().size());
} }
}
public Region makeRegion(BlockNode startBlock, RegionStack stack) { public Region makeRegion(BlockNode startBlock, RegionStack stack) {
if (Consts.DEBUG) {
int id = startBlock.getId(); int id = startBlock.getId();
if (processedBlocks.get(id)) if (processedBlocks.get(id))
LOG.debug(" Block already processed: " + startBlock + ", mth: " + mth); LOG.debug(" Block already processed: " + startBlock + ", mth: " + mth);
else else
processedBlocks.set(id); processedBlocks.set(id);
}
Region r = new Region(stack.peekRegion()); Region r = new Region(stack.peekRegion());
BlockNode next = startBlock; BlockNode next = startBlock;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment