提交 b29223c5 编写于 作者: S Skylot

core: fix enum processing order, remove synchronization (#257)

上级 d5cfdfb5
package jadx.core.dex.attributes.nodes;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.Nullable;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.IAttribute;
import jadx.core.dex.nodes.FieldNode;
import java.util.HashMap;
import java.util.Map;
public class EnumMapAttr implements IAttribute {
public static class KeyValueMap {
......@@ -21,9 +23,14 @@ public class EnumMapAttr implements IAttribute {
}
}
private final Map<FieldNode, KeyValueMap> fieldsMap = new HashMap<>();
@Nullable
private Map<FieldNode, KeyValueMap> fieldsMap;
@Nullable
public KeyValueMap getMap(FieldNode field) {
if (fieldsMap == null) {
return null;
}
return fieldsMap.get(field);
}
......@@ -31,11 +38,18 @@ public class EnumMapAttr implements IAttribute {
KeyValueMap map = getMap(field);
if (map == null) {
map = new KeyValueMap();
if (fieldsMap == null) {
fieldsMap = new HashMap<>();
}
fieldsMap.put(field, map);
}
map.put(key, value);
}
public boolean isEmpty() {
return fieldsMap == null || fieldsMap.isEmpty();
}
@Override
public AType<EnumMapAttr> getType() {
return AType.ENUM_MAP;
......@@ -45,5 +59,4 @@ public class EnumMapAttr implements IAttribute {
public String toString() {
return "Enum fields map: " + fieldsMap;
}
}
package jadx.core.dex.visitors;
import jadx.core.ProcessClass;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.EnumMapAttr;
......@@ -18,18 +23,13 @@ import jadx.core.dex.instructions.args.InsnWrapArg;
import jadx.core.dex.instructions.args.LiteralArg;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.DexNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.InstructionRemover;
import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@JadxVisitor(
name = "ReSugarCode",
desc = "Simplify synthetic or verbose code",
......@@ -39,6 +39,12 @@ public class ReSugarCode extends AbstractVisitor {
private static final Logger LOG = LoggerFactory.getLogger(ReSugarCode.class);
@Override
public boolean visit(ClassNode cls) throws JadxException {
initClsEnumMap(cls);
return true;
}
@Override
public void visit(MethodNode mth) throws JadxException {
if (mth.isNoCode()) {
......@@ -78,7 +84,7 @@ public class ReSugarCode extends AbstractVisitor {
* Replace new array and sequence of array-put to new filled-array instruction.
*/
private static InsnNode processNewArray(MethodNode mth, List<InsnNode> instructions, int i,
InstructionRemover remover) {
InstructionRemover remover) {
NewArrayNode newArrayInsn = (NewArrayNode) instructions.get(i);
InsnArg arg = newArrayInsn.getArg(0);
if (!arg.isLiteral()) {
......@@ -115,7 +121,7 @@ public class ReSugarCode extends AbstractVisitor {
if (wrapInsn.getType() != InsnType.AGET) {
return;
}
EnumMapInfo enumMapInfo = checkEnumMapAccess(mth, wrapInsn);
EnumMapInfo enumMapInfo = checkEnumMapAccess(mth.dex(), wrapInsn);
if (enumMapInfo == null) {
return;
}
......@@ -144,49 +150,40 @@ public class ReSugarCode extends AbstractVisitor {
checkAndHideClass(enumMapField.getParentClass());
}
private static EnumMapAttr.KeyValueMap getEnumMap(MethodNode mth, FieldNode field) {
ClassNode syntheticClass = field.getParentClass();
EnumMapAttr mapAttr = syntheticClass.get(AType.ENUM_MAP);
if (mapAttr != null) {
return mapAttr.getMap(field);
private static void initClsEnumMap(ClassNode enumCls) {
MethodNode clsInitMth = enumCls.getClassInitMth();
if (clsInitMth == null || clsInitMth.isNoCode()) {
return;
}
synchronized (ProcessClass.getSyncObj(syntheticClass)) {
mapAttr = new EnumMapAttr();
syntheticClass.addAttr(mapAttr);
MethodNode clsInitMth = syntheticClass.searchMethodByName("<clinit>()V");
if (clsInitMth == null || clsInitMth.isNoCode()) {
return null;
}
if (clsInitMth.getBasicBlocks() == null) {
try {
clsInitMth.load();
} catch (DecodeException e) {
LOG.error("Load failed", e);
return null;
}
if (clsInitMth.getBasicBlocks() == null) {
// TODO:
return null;
}
}
for (BlockNode block : clsInitMth.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == InsnType.APUT) {
addToEnumMap(mth, mapAttr, insn);
}
EnumMapAttr mapAttr = new EnumMapAttr();
for (BlockNode block : clsInitMth.getBasicBlocks()) {
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == InsnType.APUT) {
addToEnumMap(enumCls.dex(), mapAttr, insn);
}
}
return mapAttr.getMap(field);
}
if (!mapAttr.isEmpty()) {
enumCls.addAttr(mapAttr);
}
}
@Nullable
private static EnumMapAttr.KeyValueMap getEnumMap(MethodNode mth, FieldNode field) {
ClassNode syntheticClass = field.getParentClass();
EnumMapAttr mapAttr = syntheticClass.get(AType.ENUM_MAP);
if (mapAttr == null) {
return null;
}
return mapAttr.getMap(field);
}
private static void addToEnumMap(MethodNode mth, EnumMapAttr mapAttr, InsnNode aputInsn) {
private static void addToEnumMap(DexNode dex, EnumMapAttr mapAttr, InsnNode aputInsn) {
InsnArg litArg = aputInsn.getArg(2);
if (!litArg.isLiteral()) {
return;
}
EnumMapInfo mapInfo = checkEnumMapAccess(mth, aputInsn);
EnumMapInfo mapInfo = checkEnumMapAccess(dex, aputInsn);
if (mapInfo == null) {
return;
}
......@@ -203,7 +200,7 @@ public class ReSugarCode extends AbstractVisitor {
if (!(index instanceof FieldInfo)) {
return;
}
FieldNode fieldNode = mth.dex().resolveField((FieldInfo) index);
FieldNode fieldNode = dex.resolveField((FieldInfo) index);
if (fieldNode == null) {
return;
}
......@@ -211,7 +208,7 @@ public class ReSugarCode extends AbstractVisitor {
mapAttr.add(field, literal, fieldNode);
}
public static EnumMapInfo checkEnumMapAccess(MethodNode mth, InsnNode checkInsn) {
public static EnumMapInfo checkEnumMapAccess(DexNode dex, InsnNode checkInsn) {
InsnArg sgetArg = checkInsn.getArg(0);
InsnArg invArg = checkInsn.getArg(1);
if (!sgetArg.isInsnWrap() || !invArg.isInsnWrap()) {
......@@ -226,7 +223,7 @@ public class ReSugarCode extends AbstractVisitor {
if (!inv.getCallMth().getShortId().equals("ordinal()I")) {
return null;
}
ClassNode enumCls = mth.dex().resolveClass(inv.getCallMth().getDeclClass());
ClassNode enumCls = dex.resolveClass(inv.getCallMth().getDeclClass());
if (enumCls == null || !enumCls.isEnum()) {
return null;
}
......@@ -234,7 +231,7 @@ public class ReSugarCode extends AbstractVisitor {
if (!(index instanceof FieldInfo)) {
return null;
}
FieldNode enumMapField = mth.dex().resolveField((FieldInfo) index);
FieldNode enumMapField = dex.resolveField((FieldInfo) index);
if (enumMapField == null || !enumMapField.getAccessFlags().isSynthetic()) {
return null;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册