// line 1 "SyntheticAccessorFSM.rl" /* * Copyright 2012, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.jf.dexlib2.util; import org.jf.dexlib2.Opcodes; import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.OneRegisterInstruction; import org.jf.dexlib2.iface.instruction.WideLiteralInstruction; import javax.annotation.Nonnull; import java.util.List; public class SyntheticAccessorFSM { // line 43 "SyntheticAccessorFSM.rl" // line 48 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" private static byte[] init__SyntheticAccessorFSM_actions_0() { return new byte [] { 0, 1, 0, 1, 1, 1, 2, 1, 13, 1, 14, 1, 15, 1, 16, 1, 17, 1, 18, 1, 19, 1, 20, 1, 21, 1, 25, 2, 3, 7, 2, 4, 7, 2, 5, 7, 2, 6, 7, 2, 8, 12, 2, 9, 12, 2, 10, 12, 2, 11, 12, 2, 22, 23, 2, 22, 24, 2, 22, 25, 2, 22, 26, 2, 22, 27, 2, 22, 28 }; } private static final byte _SyntheticAccessorFSM_actions[] = init__SyntheticAccessorFSM_actions_0(); private static short[] init__SyntheticAccessorFSM_key_offsets_0() { return new short [] { 0, 0, 12, 82, 98, 102, 104, 166, 172, 174, 180, 184, 190, 192, 196, 198, 201, 203 }; } private static final short _SyntheticAccessorFSM_key_offsets[] = init__SyntheticAccessorFSM_key_offsets_0(); private static short[] init__SyntheticAccessorFSM_trans_keys_0() { return new short [] { 82, 88, 89, 95, 96, 102, 103, 109, 110, 114, 116, 120, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 201, 202, 203, 204, 206, 207, 208, 216, 15, 17, 18, 25, 129, 143, 144, 176, 178, 205, 144, 145, 155, 156, 166, 167, 171, 172, 176, 177, 187, 188, 198, 199, 203, 204, 89, 95, 103, 109, 15, 17, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 201, 202, 203, 204, 206, 207, 144, 176, 178, 205, 89, 95, 103, 109, 129, 143, 15, 17, 89, 95, 103, 109, 129, 143, 89, 95, 103, 109, 89, 95, 103, 109, 129, 143, 15, 17, 89, 95, 103, 109, 15, 17, 14, 10, 12, 15, 17, 0 }; } private static final short _SyntheticAccessorFSM_trans_keys[] = init__SyntheticAccessorFSM_trans_keys_0(); private static byte[] init__SyntheticAccessorFSM_single_lengths_0() { return new byte [] { 0, 0, 60, 16, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }; } private static final byte _SyntheticAccessorFSM_single_lengths[] = init__SyntheticAccessorFSM_single_lengths_0(); private static byte[] init__SyntheticAccessorFSM_range_lengths_0() { return new byte [] { 0, 6, 5, 0, 2, 1, 2, 3, 1, 3, 2, 3, 1, 2, 1, 1, 1, 0 }; } private static final byte _SyntheticAccessorFSM_range_lengths[] = init__SyntheticAccessorFSM_range_lengths_0(); private static short[] init__SyntheticAccessorFSM_index_offsets_0() { return new short [] { 0, 0, 7, 73, 90, 93, 95, 156, 160, 162, 166, 169, 173, 175, 178, 180, 183, 185 }; } private static final short _SyntheticAccessorFSM_index_offsets[] = init__SyntheticAccessorFSM_index_offsets_0(); private static byte[] init__SyntheticAccessorFSM_indicies_0() { return new byte [] { 0, 2, 0, 2, 3, 3, 1, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 9, 10, 11, 22, 23, 9, 10, 11, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 10, 11, 22, 23, 10, 11, 24, 24, 4, 5, 6, 7, 9, 1, 25, 26, 27, 28, 29, 30, 31, 32, 25, 26, 27, 28, 29, 30, 31, 32, 1, 33, 33, 1, 34, 1, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 9, 10, 11, 22, 23, 9, 10, 11, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 10, 11, 22, 23, 10, 11, 7, 9, 1, 35, 35, 36, 1, 37, 1, 35, 35, 38, 1, 35, 35, 1, 39, 39, 40, 1, 41, 1, 39, 39, 1, 42, 1, 44, 43, 1, 45, 1, 1, 0 }; } private static final byte _SyntheticAccessorFSM_indicies[] = init__SyntheticAccessorFSM_indicies_0(); private static byte[] init__SyntheticAccessorFSM_trans_targs_0() { return new byte [] { 2, 0, 14, 15, 17, 3, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 11, 4, 4, 4, 4, 4, 4, 4, 4, 5, 17, 8, 9, 17, 10, 12, 13, 17, 17, 16, 17, 17 }; } private static final byte _SyntheticAccessorFSM_trans_targs[] = init__SyntheticAccessorFSM_trans_targs_0(); private static byte[] init__SyntheticAccessorFSM_trans_actions_0() { return new byte [] { 0, 0, 1, 0, 51, 3, 0, 27, 39, 7, 9, 11, 13, 15, 17, 19, 21, 23, 30, 42, 33, 45, 36, 48, 5, 27, 39, 30, 42, 33, 45, 36, 48, 1, 63, 1, 0, 66, 0, 1, 0, 60, 54, 0, 25, 57 }; } private static final byte _SyntheticAccessorFSM_trans_actions[] = init__SyntheticAccessorFSM_trans_actions_0(); static final int SyntheticAccessorFSM_start = 1; static final int SyntheticAccessorFSM_first_final = 17; static final int SyntheticAccessorFSM_error = 0; static final int SyntheticAccessorFSM_en_main = 1; // line 44 "SyntheticAccessorFSM.rl" // math type constants public static final int ADD = SyntheticAccessorResolver.ADD_ASSIGNMENT; public static final int SUB = SyntheticAccessorResolver.SUB_ASSIGNMENT; public static final int MUL = SyntheticAccessorResolver.MUL_ASSIGNMENT; public static final int DIV = SyntheticAccessorResolver.DIV_ASSIGNMENT; public static final int REM = SyntheticAccessorResolver.REM_ASSIGNMENT; public static final int AND = SyntheticAccessorResolver.AND_ASSIGNMENT; public static final int OR = SyntheticAccessorResolver.OR_ASSIGNMENT; public static final int XOR = SyntheticAccessorResolver.XOR_ASSIGNMENT; public static final int SHL = SyntheticAccessorResolver.SHL_ASSIGNMENT; public static final int SHR = SyntheticAccessorResolver.SHR_ASSIGNMENT; public static final int USHR = SyntheticAccessorResolver.USHR_ASSIGNMENT; public static final int INT = 0; public static final int LONG = 1; public static final int FLOAT = 2; public static final int DOUBLE = 3; public static final int POSITIVE_ONE = 1; public static final int NEGATIVE_ONE = -1; public static final int OTHER = 0; @Nonnull private final Opcodes opcodes; public SyntheticAccessorFSM(@Nonnull Opcodes opcodes) { this.opcodes = opcodes; } public int test(List<? extends Instruction> instructions) { int accessorType = -1; int cs, p = 0; int pe = instructions.size(); // one of the math type constants representing the type of math operation being performed int mathOp = -1; // for increments an decrements, the type of value the math operation is on int mathType = -1; // for increments and decrements, the value of the constant that is used long constantValue = 0; // The source register for the put instruction int putRegister = -1; // The return register; int returnRegister = -1; // line 242 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" { cs = SyntheticAccessorFSM_start; } // line 247 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" { int _klen; int _trans = 0; int _acts; int _nacts; int _keys; int _goto_targ = 0; _goto: while (true) { switch ( _goto_targ ) { case 0: if ( p == pe ) { _goto_targ = 4; continue _goto; } if ( cs == 0 ) { _goto_targ = 5; continue _goto; } case 1: _match: do { _keys = _SyntheticAccessorFSM_key_offsets[cs]; _trans = _SyntheticAccessorFSM_index_offsets[cs]; _klen = _SyntheticAccessorFSM_single_lengths[cs]; if ( _klen > 0 ) { int _lower = _keys; int _mid; int _upper = _keys + _klen - 1; while (true) { if ( _upper < _lower ) break; _mid = _lower + ((_upper-_lower) >> 1); if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] ) _upper = _mid - 1; else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid] ) _lower = _mid + 1; else { _trans += (_mid - _keys); break _match; } } _keys += _klen; _trans += _klen; } _klen = _SyntheticAccessorFSM_range_lengths[cs]; if ( _klen > 0 ) { int _lower = _keys; int _mid; int _upper = _keys + (_klen<<1) - 2; while (true) { if ( _upper < _lower ) break; _mid = _lower + (((_upper-_lower) >> 1) & ~1); if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] ) _upper = _mid - 2; else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid+1] ) _lower = _mid + 2; else { _trans += ((_mid - _keys)>>1); break _match; } } _trans += _klen; } } while (false); _trans = _SyntheticAccessorFSM_indicies[_trans]; cs = _SyntheticAccessorFSM_trans_targs[_trans]; if ( _SyntheticAccessorFSM_trans_actions[_trans] != 0 ) { _acts = _SyntheticAccessorFSM_trans_actions[_trans]; _nacts = (int) _SyntheticAccessorFSM_actions[_acts++]; while ( _nacts-- > 0 ) { switch ( _SyntheticAccessorFSM_actions[_acts++] ) { case 0: // line 100 "SyntheticAccessorFSM.rl" { putRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA(); } break; case 1: // line 107 "SyntheticAccessorFSM.rl" { constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral(); } break; case 2: // line 111 "SyntheticAccessorFSM.rl" { mathType = INT; mathOp = ADD; constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral(); } break; case 3: // line 117 "SyntheticAccessorFSM.rl" { mathType = INT; } break; case 4: // line 118 "SyntheticAccessorFSM.rl" { mathType = LONG; } break; case 5: // line 119 "SyntheticAccessorFSM.rl" { mathType = FLOAT; } break; case 6: // line 120 "SyntheticAccessorFSM.rl" {mathType = DOUBLE; } break; case 7: // line 120 "SyntheticAccessorFSM.rl" { mathOp = ADD; } break; case 8: // line 123 "SyntheticAccessorFSM.rl" { mathType = INT; } break; case 9: // line 124 "SyntheticAccessorFSM.rl" { mathType = LONG; } break; case 10: // line 125 "SyntheticAccessorFSM.rl" { mathType = FLOAT; } break; case 11: // line 126 "SyntheticAccessorFSM.rl" {mathType = DOUBLE; } break; case 12: // line 126 "SyntheticAccessorFSM.rl" { mathOp = SUB; } break; case 13: // line 130 "SyntheticAccessorFSM.rl" { mathOp = MUL; } break; case 14: // line 134 "SyntheticAccessorFSM.rl" { mathOp = DIV; } break; case 15: // line 138 "SyntheticAccessorFSM.rl" { mathOp = REM; } break; case 16: // line 141 "SyntheticAccessorFSM.rl" { mathOp = AND; } break; case 17: // line 144 "SyntheticAccessorFSM.rl" { mathOp = OR; } break; case 18: // line 147 "SyntheticAccessorFSM.rl" { mathOp = XOR; } break; case 19: // line 150 "SyntheticAccessorFSM.rl" { mathOp = SHL; } break; case 20: // line 153 "SyntheticAccessorFSM.rl" { mathOp = SHR; } break; case 21: // line 156 "SyntheticAccessorFSM.rl" { mathOp = USHR; } break; case 22: // line 162 "SyntheticAccessorFSM.rl" { returnRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA(); } break; case 23: // line 168 "SyntheticAccessorFSM.rl" { accessorType = SyntheticAccessorResolver.GETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; case 24: // line 172 "SyntheticAccessorFSM.rl" { accessorType = SyntheticAccessorResolver.SETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; case 25: // line 176 "SyntheticAccessorFSM.rl" { accessorType = SyntheticAccessorResolver.METHOD; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; case 26: // line 180 "SyntheticAccessorFSM.rl" { accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister); } break; case 27: // line 184 "SyntheticAccessorFSM.rl" { accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister); } break; case 28: // line 192 "SyntheticAccessorFSM.rl" { accessorType = mathOp; { p += 1; _goto_targ = 5; if (true) continue _goto;} } break; // line 487 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java" } } } case 2: if ( cs == 0 ) { _goto_targ = 5; continue _goto; } if ( ++p != pe ) { _goto_targ = 1; continue _goto; } case 4: case 5: } break; } } // line 205 "SyntheticAccessorFSM.rl" return accessorType; } private static int getIncrementType(int mathOp, int mathType, long constantValue, int putRegister, int returnRegister) { boolean isPrefix = putRegister == returnRegister; boolean negativeConstant = false; switch (mathType) { case INT: case LONG: { if (constantValue == 1) { negativeConstant = false; } else if (constantValue == -1) { negativeConstant = true; } else { return -1; } break; } case FLOAT: { float val = Float.intBitsToFloat((int)constantValue); if (val == 1) { negativeConstant = false; } else if (val == -1) { negativeConstant = true; } else { return -1; } break; } case DOUBLE: { double val = Double.longBitsToDouble(constantValue); if (val == 1) { negativeConstant = false; } else if (val == -1) { negativeConstant = true; } else { return -1; } break; } } boolean isAdd = ((mathOp == ADD) && !negativeConstant) || ((mathOp == SUB) && negativeConstant); if (isPrefix) { if (isAdd) { return SyntheticAccessorResolver.PREFIX_INCREMENT; } else { return SyntheticAccessorResolver.PREFIX_DECREMENT; } } else { if (isAdd) { return SyntheticAccessorResolver.POSTFIX_INCREMENT; } else { return SyntheticAccessorResolver.POSTFIX_DECREMENT; } } } }