提交 940de240 编写于 作者: S Skylot

core: split const-string and const-class instructions

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