66import org .objectweb .asm .tree .*;
77
88
9- public class FlowTransformer implements ITransformer {
10- private String prefix ;
9+ public class ExpressionTransformer implements ITransformer {
1110
12- @ Override
13- public void setPrefix (String prefix ) {
14- this .prefix = prefix ;
15- }
1611 private static final int LARGE_METHOD_LIMIT = 4000 ;
1712
1813 private static boolean isMethodTooLarge (MethodNode method ) {
@@ -51,6 +46,34 @@ public void modify(ClassNode classNode) {
5146 }
5247
5348 if (isIfComparisonInsn (insnNode )) {
49+ if (!isClinit ) {
50+ AbstractInsnNode prev = previousMeaningful (insnNode );
51+ if (prev != null && isIntConstant (prev )) {
52+ int constantValue = getIntValue (prev );
53+ InsnList replacement = createComplexIntExpression (constantValue );
54+ AbstractInsnNode prevPrev = previousMeaningful (prev );
55+ method .instructions .insertBefore (prev , replacement );
56+ method .instructions .remove (prev );
57+
58+ if (prevPrev != null && isIntConstant (prevPrev )) {
59+ int constantValue2 = getIntValue (prevPrev );
60+ InsnList replacement2 = createComplexIntExpression (constantValue2 );
61+ method .instructions .insertBefore (prevPrev , replacement2 );
62+ method .instructions .remove (prevPrev );
63+ }
64+ } else if (prev != null ) {
65+ AbstractInsnNode prevPrev = previousMeaningful (prev );
66+ if (prevPrev != null && isIntConstant (prevPrev )) {
67+ int constantValue2 = getIntValue (prevPrev );
68+ InsnList replacement2 = createComplexIntExpression (constantValue2 );
69+ method .instructions .insertBefore (prevPrev , replacement2 );
70+ method .instructions .remove (prevPrev );
71+ }
72+ }
73+ }
74+ }
75+
76+ if (isIfZeroComparisonInsn (insnNode )) {
5477 if (!isClinit ) {
5578 AbstractInsnNode prev = previousMeaningful (insnNode );
5679 if (prev != null && isIntConstant (prev )) {
@@ -73,7 +96,7 @@ public void modify(ClassNode classNode) {
7396 AbstractInsnNode prev = previousMeaningful (insnNode );
7497 if (prev != null && isIntConstant (prev )) {
7598 int constantValue = getIntValue (prev );
76- if (constantValue > 0 && constantValue <= 30000 ) {
99+ if (constantValue > 0 ) {
77100 InsnList replacement = createComplexIntExpression (constantValue );
78101 method .instructions .insertBefore (prev , replacement );
79102 method .instructions .remove (prev );
@@ -159,110 +182,22 @@ private boolean isMethodInvocation(AbstractInsnNode node) {
159182 || op == INVOKESTATIC || op == INVOKEINTERFACE ;
160183 }
161184
162- private boolean isNullCheckInsn (AbstractInsnNode node ) {
163- if (node == null ) {
164- return false ;
165- }
166- int op = node .getOpcode ();
167- return op == IFNULL || op == IFNONNULL ;
168- }
169-
170- private boolean isObjectComparisonInsn (AbstractInsnNode node ) {
185+ private boolean isIfComparisonInsn (AbstractInsnNode node ) {
171186 if (node == null ) {
172187 return false ;
173188 }
174189 int op = node .getOpcode ();
175- return op == IF_ACMPEQ || op == IF_ACMPNE ;
176- }
177-
178- private void invertCondition (MethodNode method , AbstractInsnNode jumpInsn ) {
179- JumpInsnNode jump = (JumpInsnNode ) jumpInsn ;
180- LabelNode originalTarget = jump .label ;
181-
182- if (!hasCodeBetween (jumpInsn , originalTarget )) {
183- return ;
184- }
185-
186- LabelNode newElseLabel = new LabelNode ();
187- int invertedOp = getInvertedIntComparison (jump .getOpcode ());
188- JumpInsnNode newJump = new JumpInsnNode (invertedOp , newElseLabel );
189-
190- method .instructions .set (jump , newJump );
191- method .instructions .insert (newJump , newElseLabel );
192- method .instructions .insert (newElseLabel , new JumpInsnNode (GOTO , originalTarget ));
193- }
194-
195- private void invertNullCheck (MethodNode method , AbstractInsnNode jumpInsn ) {
196- JumpInsnNode jump = (JumpInsnNode ) jumpInsn ;
197- LabelNode originalTarget = jump .label ;
198-
199- if (!hasCodeBetween (jumpInsn , originalTarget )) {
200- return ;
201- }
202-
203- LabelNode newElseLabel = new LabelNode ();
204- int invertedOp = jump .getOpcode () == IFNULL ? IFNONNULL : IFNULL ;
205- JumpInsnNode newJump = new JumpInsnNode (invertedOp , newElseLabel );
206-
207- method .instructions .set (jump , newJump );
208- method .instructions .insert (newJump , newElseLabel );
209- method .instructions .insert (newElseLabel , new JumpInsnNode (GOTO , originalTarget ));
210- }
211-
212- private void invertObjectComparison (MethodNode method , AbstractInsnNode jumpInsn ) {
213- JumpInsnNode jump = (JumpInsnNode ) jumpInsn ;
214- LabelNode originalTarget = jump .label ;
215-
216- if (!hasCodeBetween (jumpInsn , originalTarget )) {
217- return ;
218- }
219-
220- LabelNode newElseLabel = new LabelNode ();
221- int invertedOp = jump .getOpcode () == IF_ACMPEQ ? IF_ACMPNE : IF_ACMPEQ ;
222- JumpInsnNode newJump = new JumpInsnNode (invertedOp , newElseLabel );
223-
224- method .instructions .set (jump , newJump );
225- method .instructions .insert (newJump , newElseLabel );
226- method .instructions .insert (newElseLabel , new JumpInsnNode (GOTO , originalTarget ));
227- }
228-
229- private boolean hasCodeBetween (AbstractInsnNode start , LabelNode target ) {
230- AbstractInsnNode current = start .getNext ();
231- while (current != null && current != target ) {
232- if (current .getOpcode () >= 0 && !(current instanceof LabelNode )
233- && !(current instanceof LineNumberNode ) && !(current instanceof FrameNode )) {
234- return true ;
235- }
236- current = current .getNext ();
237- }
238- return false ;
239- }
240-
241- private int getInvertedIntComparison (int opcode ) {
242- switch (opcode ) {
243- case IF_ICMPEQ : return IF_ICMPNE ;
244- case IF_ICMPNE : return IF_ICMPEQ ;
245- case IF_ICMPLT : return IF_ICMPGE ;
246- case IF_ICMPGE : return IF_ICMPLT ;
247- case IF_ICMPGT : return IF_ICMPLE ;
248- case IF_ICMPLE : return IF_ICMPGT ;
249- case IFEQ : return IFNE ;
250- case IFNE : return IFEQ ;
251- case IFLT : return IFGE ;
252- case IFGE : return IFLT ;
253- case IFGT : return IFLE ;
254- case IFLE : return IFGT ;
255- default : return opcode ;
256- }
190+ return op == IF_ICMPEQ || op == IF_ICMPNE || op == IF_ICMPLT
191+ || op == IF_ICMPGE || op == IF_ICMPGT || op == IF_ICMPLE ;
257192 }
258193
259- private boolean isIfComparisonInsn (AbstractInsnNode node ) {
194+ private boolean isIfZeroComparisonInsn (AbstractInsnNode node ) {
260195 if (node == null ) {
261196 return false ;
262197 }
263198 int op = node .getOpcode ();
264- return op == IF_ICMPEQ || op == IF_ICMPNE || op == IF_ICMPLT
265- || op == IF_ICMPGE || op == IF_ICMPGT || op == IF_ICMPLE ;
199+ return op == IFEQ || op == IFNE || op == IFLT
200+ || op == IFLE || op == IFGT || op == IFGE ;
266201 }
267202
268203 private boolean isIntConstant (AbstractInsnNode node ) {
0 commit comments