提交 8ca3cd31 编写于 作者: S Skylot

fix: don't use static vars of mutable LiteralArg class (#1005)

上级 2b7d7ce2
......@@ -843,7 +843,7 @@ public class InsnGen {
InsnArg first = insn.getArg(0);
InsnArg second = insn.getArg(1);
ConditionGen condGen = new ConditionGen(this);
if (first.equals(LiteralArg.TRUE) && second.equals(LiteralArg.FALSE)) {
if (first.isTrue() && second.isFalse()) {
condGen.add(code, insn.getCondition());
} else {
condGen.wrap(code, insn.getCondition());
......
package jadx.core.dex.instructions.args;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
......@@ -56,7 +58,7 @@ public abstract class InsnArg extends Typed {
}
public static LiteralArg lit(long literal, ArgType type) {
return new LiteralArg(literal, type);
return LiteralArg.makeWithFixedType(literal, type);
}
public static LiteralArg lit(InsnData insn, ArgType type) {
......@@ -210,6 +212,22 @@ public abstract class InsnArg extends Typed {
return isLiteral() && (((LiteralArg) this)).getLiteral() == 0;
}
public boolean isFalse() {
if (isLiteral()) {
LiteralArg litArg = (LiteralArg) this;
return litArg.getLiteral() == 0 && Objects.equals(litArg.getType(), ArgType.BOOLEAN);
}
return false;
}
public boolean isTrue() {
if (isLiteral()) {
LiteralArg litArg = (LiteralArg) this;
return litArg.getLiteral() == 1 && Objects.equals(litArg.getType(), ArgType.BOOLEAN);
}
return false;
}
public boolean isThis() {
return contains(AFlag.THIS);
}
......
......@@ -6,24 +6,37 @@ import jadx.core.utils.exceptions.JadxRuntimeException;
public final class LiteralArg extends InsnArg {
public static final LiteralArg TRUE = new LiteralArg(1, ArgType.BOOLEAN);
public static final LiteralArg FALSE = new LiteralArg(0, ArgType.BOOLEAN);
public static LiteralArg make(long value, ArgType type) {
return new LiteralArg(value, type);
}
public static LiteralArg makeWithFixedType(long value, ArgType type) {
return new LiteralArg(value, fixLiteralType(value, type));
}
private static ArgType fixLiteralType(long value, ArgType type) {
if (value == 0 || type.isTypeKnown() || type.contains(PrimitiveType.LONG) || type.contains(PrimitiveType.DOUBLE)) {
return type;
}
if (value == 1) {
return ArgType.NARROW_NUMBERS;
}
return ArgType.NARROW_NUMBERS_NO_BOOL;
}
public static LiteralArg litFalse() {
return new LiteralArg(0, ArgType.BOOLEAN);
}
public static LiteralArg litTrue() {
return new LiteralArg(1, ArgType.BOOLEAN);
}
private final long literal;
public LiteralArg(long value, ArgType type) {
if (value != 0) {
if (type.isObject()) {
throw new JadxRuntimeException("Wrong literal type: " + type + " for value: " + value);
} else if (!type.isTypeKnown()
&& !type.contains(PrimitiveType.LONG)
&& !type.contains(PrimitiveType.DOUBLE)) {
if (value != 1) {
type = ArgType.NARROW_NUMBERS_NO_BOOL;
} else {
type = ArgType.NARROW_NUMBERS;
}
}
private LiteralArg(long value, ArgType type) {
if (value != 0 && type.isObject()) {
throw new JadxRuntimeException("Wrong literal type: " + type + " for value: " + value);
}
this.literal = value;
this.type = type;
......@@ -33,6 +46,11 @@ public final class LiteralArg extends InsnArg {
return literal;
}
@Override
public void setType(ArgType type) {
super.setType(type);
}
@Override
public boolean isLiteral() {
return true;
......@@ -49,9 +67,7 @@ public final class LiteralArg extends InsnArg {
@Override
public InsnArg duplicate() {
LiteralArg copy = new LiteralArg(literal, getType());
copy.type = type;
return copyCommonParams(copy);
return copyCommonParams(new LiteralArg(literal, type));
}
@Override
......
......@@ -4,7 +4,6 @@ import java.util.Collection;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.LiteralArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.regions.conditions.IfCondition;
......@@ -18,7 +17,7 @@ public final class TernaryInsn extends InsnNode {
this();
setResult(result);
if (th.equals(LiteralArg.FALSE) && els.equals(LiteralArg.TRUE)) {
if (th.isFalse() && els.isTrue()) {
// inverted
this.condition = IfCondition.invert(condition);
addArg(els);
......
......@@ -39,8 +39,8 @@ public final class Compare {
* Change 'a != false' to 'a == true'
*/
public void normalize() {
if (getOp() == IfOp.NE && getB().isLiteral() && getB().equals(LiteralArg.FALSE)) {
insn.changeCondition(IfOp.EQ, getA(), LiteralArg.TRUE);
if (getOp() == IfOp.NE && getB().isFalse()) {
insn.changeCondition(IfOp.EQ, getA(), LiteralArg.litTrue());
}
}
......
......@@ -153,7 +153,7 @@ public final class IfCondition extends AttrNode {
if (i != null) {
return i;
}
if (c.getOp() == IfOp.EQ && c.getB().isLiteral() && c.getB().equals(LiteralArg.FALSE)) {
if (c.getOp() == IfOp.EQ && c.getB().isFalse()) {
cond = not(new IfCondition(c.invert()));
} else {
c.normalize();
......@@ -234,8 +234,8 @@ public final class IfCondition extends AttrNode {
Mode mode = isTrue && arithOp == ArithOp.OR
|| !isTrue && arithOp == ArithOp.AND ? Mode.OR : Mode.AND;
IfNode if1 = new IfNode(op, -1, wrapInsn.getArg(0), LiteralArg.FALSE);
IfNode if2 = new IfNode(op, -1, wrapInsn.getArg(1), LiteralArg.FALSE);
IfNode if1 = new IfNode(op, -1, wrapInsn.getArg(0), LiteralArg.litFalse());
IfNode if2 = new IfNode(op, -1, wrapInsn.getArg(1), LiteralArg.litFalse());
return new IfCondition(mode,
Arrays.asList(new IfCondition(new Compare(if1)),
new IfCondition(new Compare(if2))));
......
......@@ -253,16 +253,16 @@ public class ModVisitor extends AbstractVisitor {
}
public static TernaryInsn makeBooleanConvertInsn(RegisterArg result, InsnArg castArg, ArgType type) {
InsnArg zero = new LiteralArg(0, type);
InsnArg zero = LiteralArg.make(0, type);
long litVal = 1;
if (type == ArgType.DOUBLE) {
litVal = DOUBLE_TO_BITS;
} else if (type == ArgType.FLOAT) {
litVal = FLOAT_TO_BITS;
}
InsnArg one = new LiteralArg(litVal, type);
InsnArg one = LiteralArg.make(litVal, type);
IfNode ifNode = new IfNode(IfOp.EQ, -1, castArg, LiteralArg.TRUE);
IfNode ifNode = new IfNode(IfOp.EQ, -1, castArg, LiteralArg.litTrue());
IfCondition condition = IfCondition.fromIfNode(ifNode);
return new TernaryInsn(condition, result, one, zero);
}
......
......@@ -25,7 +25,7 @@ public class EncodedValueUtils {
case ENCODED_NULL:
return InsnArg.lit(0, ArgType.OBJECT);
case ENCODED_BOOLEAN:
return Boolean.TRUE.equals(value) ? LiteralArg.TRUE : LiteralArg.FALSE;
return Boolean.TRUE.equals(value) ? LiteralArg.litTrue() : LiteralArg.litFalse();
case ENCODED_BYTE:
return InsnArg.lit((Byte) value, ArgType.BYTE);
case ENCODED_SHORT:
......
......@@ -10,7 +10,6 @@ import jadx.core.dex.instructions.args.LiteralArg;
import jadx.core.dex.regions.conditions.Compare;
import jadx.core.dex.regions.conditions.IfCondition;
import static jadx.core.dex.instructions.args.LiteralArg.TRUE;
import static jadx.core.dex.regions.conditions.IfCondition.Mode;
import static jadx.core.dex.regions.conditions.IfCondition.Mode.AND;
import static jadx.core.dex.regions.conditions.IfCondition.Mode.COMPARE;
......@@ -29,11 +28,11 @@ public class TestIfCondition {
}
private static IfCondition makeSimpleCondition() {
return makeCondition(IfOp.EQ, mockArg(), LiteralArg.TRUE);
return makeCondition(IfOp.EQ, mockArg(), LiteralArg.litTrue());
}
private static IfCondition makeNegCondition() {
return makeCondition(IfOp.NE, mockArg(), LiteralArg.TRUE);
return makeCondition(IfOp.NE, mockArg(), LiteralArg.litTrue());
}
private static InsnArg mockArg() {
......@@ -44,13 +43,13 @@ public class TestIfCondition {
public void testNormalize() {
// 'a != false' => 'a == true'
InsnArg a = mockArg();
IfCondition c = makeCondition(IfOp.NE, a, LiteralArg.FALSE);
IfCondition c = makeCondition(IfOp.NE, a, LiteralArg.litFalse());
IfCondition simp = simplify(c);
assertThat(simp.getMode(), is(COMPARE));
Compare compare = simp.getCompare();
assertThat(compare.getA(), is(a));
assertThat(compare.getB(), is(TRUE));
assertThat(compare.getB(), is(LiteralArg.litTrue()));
}
@Test
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册