| |
| // 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; |
| } |
| } |
| } |
| } |