• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // line 1 "SyntheticAccessorFSM.rl"
3 /*
4  * Copyright 2012, Google LLC
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  *     * Neither the name of Google LLC nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package com.android.tools.smali.dexlib2.util;
34 
35 import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
36 import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction;
37 import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction;
38 import com.android.tools.smali.dexlib2.Opcodes;
39 
40 import java.util.List;
41 import javax.annotation.Nonnull;
42 
43 public class SyntheticAccessorFSM {
44 
45 // line 42 "SyntheticAccessorFSM.rl"
46 
47 // line 47 "/usr/local/google/home/sgjesse/prj/smali/smali/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorFSM.java"
init__SyntheticAccessorFSM_actions_0()48 private static byte[] init__SyntheticAccessorFSM_actions_0()
49 {
50 	return new byte [] {
51 	    0,    1,    0,    1,    1,    1,    2,    1,   13,    1,   14,    1,
52 	   15,    1,   16,    1,   17,    1,   18,    1,   19,    1,   20,    1,
53 	   21,    1,   25,    2,    3,    7,    2,    4,    7,    2,    5,    7,
54 	    2,    6,    7,    2,    8,   12,    2,    9,   12,    2,   10,   12,
55 	    2,   11,   12,    2,   22,   23,    2,   22,   24,    2,   22,   25,
56 	    2,   22,   26,    2,   22,   27,    2,   22,   28
57 	};
58 }
59 
60 private static final byte _SyntheticAccessorFSM_actions[] = init__SyntheticAccessorFSM_actions_0();
61 
62 
init__SyntheticAccessorFSM_key_offsets_0()63 private static short[] init__SyntheticAccessorFSM_key_offsets_0()
64 {
65 	return new short [] {
66 	    0,    0,   12,   82,   98,  102,  104,  166,  172,  174,  180,  184,
67 	  190,  192,  196,  198,  201,  203
68 	};
69 }
70 
71 private static final short _SyntheticAccessorFSM_key_offsets[] = init__SyntheticAccessorFSM_key_offsets_0();
72 
73 
init__SyntheticAccessorFSM_trans_keys_0()74 private static short[] init__SyntheticAccessorFSM_trans_keys_0()
75 {
76 	return new short [] {
77 	   82,   88,   89,   95,   96,  102,  103,  109,  110,  114,  116,  120,
78 	  145,  146,  147,  148,  149,  150,  151,  152,  153,  154,  155,  156,
79 	  157,  158,  159,  160,  161,  162,  163,  164,  165,  166,  167,  168,
80 	  169,  170,  171,  172,  173,  174,  175,  177,  179,  180,  181,  182,
81 	  183,  184,  185,  186,  187,  188,  190,  191,  192,  193,  194,  195,
82 	  196,  197,  198,  199,  201,  202,  203,  204,  206,  207,  208,  216,
83 	   15,   17,   18,   25,  129,  143,  144,  176,  178,  205,  144,  145,
84 	  155,  156,  166,  167,  171,  172,  176,  177,  187,  188,  198,  199,
85 	  203,  204,   89,   95,  103,  109,   15,   17,  145,  146,  147,  148,
86 	  149,  150,  151,  152,  153,  154,  155,  156,  157,  158,  159,  160,
87 	  161,  162,  163,  164,  165,  166,  167,  168,  169,  170,  171,  172,
88 	  173,  174,  175,  177,  179,  180,  181,  182,  183,  184,  185,  186,
89 	  187,  188,  190,  191,  192,  193,  194,  195,  196,  197,  198,  199,
90 	  201,  202,  203,  204,  206,  207,  144,  176,  178,  205,   89,   95,
91 	  103,  109,  129,  143,   15,   17,   89,   95,  103,  109,  129,  143,
92 	   89,   95,  103,  109,   89,   95,  103,  109,  129,  143,   15,   17,
93 	   89,   95,  103,  109,   15,   17,   14,   10,   12,   15,   17,    0
94 	};
95 }
96 
97 private static final short _SyntheticAccessorFSM_trans_keys[] = init__SyntheticAccessorFSM_trans_keys_0();
98 
99 
init__SyntheticAccessorFSM_single_lengths_0()100 private static byte[] init__SyntheticAccessorFSM_single_lengths_0()
101 {
102 	return new byte [] {
103 	    0,    0,   60,   16,    0,    0,   58,    0,    0,    0,    0,    0,
104 	    0,    0,    0,    1,    0,    0
105 	};
106 }
107 
108 private static final byte _SyntheticAccessorFSM_single_lengths[] = init__SyntheticAccessorFSM_single_lengths_0();
109 
110 
init__SyntheticAccessorFSM_range_lengths_0()111 private static byte[] init__SyntheticAccessorFSM_range_lengths_0()
112 {
113 	return new byte [] {
114 	    0,    6,    5,    0,    2,    1,    2,    3,    1,    3,    2,    3,
115 	    1,    2,    1,    1,    1,    0
116 	};
117 }
118 
119 private static final byte _SyntheticAccessorFSM_range_lengths[] = init__SyntheticAccessorFSM_range_lengths_0();
120 
121 
init__SyntheticAccessorFSM_index_offsets_0()122 private static short[] init__SyntheticAccessorFSM_index_offsets_0()
123 {
124 	return new short [] {
125 	    0,    0,    7,   73,   90,   93,   95,  156,  160,  162,  166,  169,
126 	  173,  175,  178,  180,  183,  185
127 	};
128 }
129 
130 private static final short _SyntheticAccessorFSM_index_offsets[] = init__SyntheticAccessorFSM_index_offsets_0();
131 
132 
init__SyntheticAccessorFSM_indicies_0()133 private static byte[] init__SyntheticAccessorFSM_indicies_0()
134 {
135 	return new byte [] {
136 	    0,    2,    0,    2,    3,    3,    1,    8,    9,   10,   11,   12,
137 	   13,   14,   15,   16,   17,   18,   19,    9,   10,   11,   12,   13,
138 	   14,   15,   16,   17,   20,   21,    9,   10,   11,   22,   23,    9,
139 	   10,   11,    8,   10,   11,   12,   13,   14,   15,   16,   17,   18,
140 	   19,   10,   11,   12,   13,   14,   15,   16,   17,   20,   21,   10,
141 	   11,   22,   23,   10,   11,   24,   24,    4,    5,    6,    7,    9,
142 	    1,   25,   26,   27,   28,   29,   30,   31,   32,   25,   26,   27,
143 	   28,   29,   30,   31,   32,    1,   33,   33,    1,   34,    1,    8,
144 	    9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,    9,
145 	   10,   11,   12,   13,   14,   15,   16,   17,   20,   21,    9,   10,
146 	   11,   22,   23,    9,   10,   11,    8,   10,   11,   12,   13,   14,
147 	   15,   16,   17,   18,   19,   10,   11,   12,   13,   14,   15,   16,
148 	   17,   20,   21,   10,   11,   22,   23,   10,   11,    7,    9,    1,
149 	   35,   35,   36,    1,   37,    1,   35,   35,   38,    1,   35,   35,
150 	    1,   39,   39,   40,    1,   41,    1,   39,   39,    1,   42,    1,
151 	   44,   43,    1,   45,    1,    1,    0
152 	};
153 }
154 
155 private static final byte _SyntheticAccessorFSM_indicies[] = init__SyntheticAccessorFSM_indicies_0();
156 
157 
init__SyntheticAccessorFSM_trans_targs_0()158 private static byte[] init__SyntheticAccessorFSM_trans_targs_0()
159 {
160 	return new byte [] {
161 	    2,    0,   14,   15,   17,    3,    6,    7,    7,    7,    7,    7,
162 	    7,    7,    7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
163 	   11,    4,    4,    4,    4,    4,    4,    4,    4,    5,   17,    8,
164 	    9,   17,   10,   12,   13,   17,   17,   16,   17,   17
165 	};
166 }
167 
168 private static final byte _SyntheticAccessorFSM_trans_targs[] = init__SyntheticAccessorFSM_trans_targs_0();
169 
170 
init__SyntheticAccessorFSM_trans_actions_0()171 private static byte[] init__SyntheticAccessorFSM_trans_actions_0()
172 {
173 	return new byte [] {
174 	    0,    0,    1,    0,   51,    3,    0,   27,   39,    7,    9,   11,
175 	   13,   15,   17,   19,   21,   23,   30,   42,   33,   45,   36,   48,
176 	    5,   27,   39,   30,   42,   33,   45,   36,   48,    1,   63,    1,
177 	    0,   66,    0,    1,    0,   60,   54,    0,   25,   57
178 	};
179 }
180 
181 private static final byte _SyntheticAccessorFSM_trans_actions[] = init__SyntheticAccessorFSM_trans_actions_0();
182 
183 
184 static final int SyntheticAccessorFSM_start = 1;
185 static final int SyntheticAccessorFSM_first_final = 17;
186 static final int SyntheticAccessorFSM_error = 0;
187 
188 static final int SyntheticAccessorFSM_en_main = 1;
189 
190 
191 // line 43 "SyntheticAccessorFSM.rl"
192 
193     // math type constants
194     public static final int ADD = SyntheticAccessorResolver.ADD_ASSIGNMENT;
195     public static final int SUB = SyntheticAccessorResolver.SUB_ASSIGNMENT;
196     public static final int MUL = SyntheticAccessorResolver.MUL_ASSIGNMENT;
197     public static final int DIV = SyntheticAccessorResolver.DIV_ASSIGNMENT;
198     public static final int REM = SyntheticAccessorResolver.REM_ASSIGNMENT;
199     public static final int AND = SyntheticAccessorResolver.AND_ASSIGNMENT;
200     public static final int OR = SyntheticAccessorResolver.OR_ASSIGNMENT;
201     public static final int XOR = SyntheticAccessorResolver.XOR_ASSIGNMENT;
202     public static final int SHL = SyntheticAccessorResolver.SHL_ASSIGNMENT;
203     public static final int SHR = SyntheticAccessorResolver.SHR_ASSIGNMENT;
204     public static final int USHR = SyntheticAccessorResolver.USHR_ASSIGNMENT;
205 
206     public static final int INT = 0;
207     public static final int LONG = 1;
208     public static final int FLOAT = 2;
209     public static final int DOUBLE = 3;
210 
211     public static final int POSITIVE_ONE = 1;
212     public static final int NEGATIVE_ONE = -1;
213     public static final int OTHER = 0;
214 
215     @Nonnull
216 		private final Opcodes opcodes;
217 
SyntheticAccessorFSM(@onnull Opcodes opcodes)218     public SyntheticAccessorFSM(@Nonnull Opcodes opcodes) {
219         this.opcodes = opcodes;
220     }
221 
test(List<? extends Instruction> instructions)222     public int test(List<? extends Instruction> instructions) {
223         int accessorType = -1;
224         int cs, p = 0;
225         int pe = instructions.size();
226 
227         // one of the math type constants representing the type of math operation being performed
228         int mathOp = -1;
229 
230         // for increments an decrements, the type of value the math operation is on
231         int mathType = -1;
232 
233         // for increments and decrements, the value of the constant that is used
234         long constantValue = 0;
235 
236         // The source register for the put instruction
237         int putRegister = -1;
238         // The return register;
239         int returnRegister = -1;
240 
241 
242 // line 241 "/usr/local/google/home/sgjesse/prj/smali/smali/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorFSM.java"
243 	{
244 	cs = SyntheticAccessorFSM_start;
245 	}
246 
247 // line 246 "/usr/local/google/home/sgjesse/prj/smali/smali/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorFSM.java"
248 	{
249 	int _klen;
250 	int _trans = 0;
251 	int _acts;
252 	int _nacts;
253 	int _keys;
254 	int _goto_targ = 0;
255 
256 	_goto: while (true) {
257 	switch ( _goto_targ ) {
258 	case 0:
259 	if ( p == pe ) {
260 		_goto_targ = 4;
261 		continue _goto;
262 	}
263 	if ( cs == 0 ) {
264 		_goto_targ = 5;
265 		continue _goto;
266 	}
267 case 1:
268 	_match: do {
269 	_keys = _SyntheticAccessorFSM_key_offsets[cs];
270 	_trans = _SyntheticAccessorFSM_index_offsets[cs];
271 	_klen = _SyntheticAccessorFSM_single_lengths[cs];
272 	if ( _klen > 0 ) {
273 		int _lower = _keys;
274 		int _mid;
275 		int _upper = _keys + _klen - 1;
276 		while (true) {
277 			if ( _upper < _lower )
278 				break;
279 
280 			_mid = _lower + ((_upper-_lower) >> 1);
281 			if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] )
282 				_upper = _mid - 1;
283 			else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid] )
284 				_lower = _mid + 1;
285 			else {
286 				_trans += (_mid - _keys);
287 				break _match;
288 			}
289 		}
290 		_keys += _klen;
291 		_trans += _klen;
292 	}
293 
294 	_klen = _SyntheticAccessorFSM_range_lengths[cs];
295 	if ( _klen > 0 ) {
296 		int _lower = _keys;
297 		int _mid;
298 		int _upper = _keys + (_klen<<1) - 2;
299 		while (true) {
300 			if ( _upper < _lower )
301 				break;
302 
303 			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
304 			if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] )
305 				_upper = _mid - 2;
306 			else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid+1] )
307 				_lower = _mid + 2;
308 			else {
309 				_trans += ((_mid - _keys)>>1);
310 				break _match;
311 			}
312 		}
313 		_trans += _klen;
314 	}
315 	} while (false);
316 
317 	_trans = _SyntheticAccessorFSM_indicies[_trans];
318 	cs = _SyntheticAccessorFSM_trans_targs[_trans];
319 
320 	if ( _SyntheticAccessorFSM_trans_actions[_trans] != 0 ) {
321 		_acts = _SyntheticAccessorFSM_trans_actions[_trans];
322 		_nacts = (int) _SyntheticAccessorFSM_actions[_acts++];
323 		while ( _nacts-- > 0 )
324 	{
325 			switch ( _SyntheticAccessorFSM_actions[_acts++] )
326 			{
327 	case 0:
328 // line 99 "SyntheticAccessorFSM.rl"
329 	{
330                 putRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA();
331             }
332 	break;
333 	case 1:
334 // line 106 "SyntheticAccessorFSM.rl"
335 	{
336                 constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral();
337             }
338 	break;
339 	case 2:
340 // line 110 "SyntheticAccessorFSM.rl"
341 	{
342                 mathType = INT;
343                 mathOp = ADD;
344                 constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral();
345             }
346 	break;
347 	case 3:
348 // line 116 "SyntheticAccessorFSM.rl"
349 	{ mathType = INT; }
350 	break;
351 	case 4:
352 // line 117 "SyntheticAccessorFSM.rl"
353 	{ mathType = LONG; }
354 	break;
355 	case 5:
356 // line 118 "SyntheticAccessorFSM.rl"
357 	{ mathType = FLOAT; }
358 	break;
359 	case 6:
360 // line 119 "SyntheticAccessorFSM.rl"
361 	{mathType = DOUBLE; }
362 	break;
363 	case 7:
364 // line 119 "SyntheticAccessorFSM.rl"
365 	{
366                 mathOp = ADD;
367             }
368 	break;
369 	case 8:
370 // line 122 "SyntheticAccessorFSM.rl"
371 	{ mathType = INT; }
372 	break;
373 	case 9:
374 // line 123 "SyntheticAccessorFSM.rl"
375 	{ mathType = LONG; }
376 	break;
377 	case 10:
378 // line 124 "SyntheticAccessorFSM.rl"
379 	{ mathType = FLOAT; }
380 	break;
381 	case 11:
382 // line 125 "SyntheticAccessorFSM.rl"
383 	{mathType = DOUBLE; }
384 	break;
385 	case 12:
386 // line 125 "SyntheticAccessorFSM.rl"
387 	{
388                 mathOp = SUB;
389             }
390 	break;
391 	case 13:
392 // line 129 "SyntheticAccessorFSM.rl"
393 	{
394                 mathOp = MUL;
395             }
396 	break;
397 	case 14:
398 // line 133 "SyntheticAccessorFSM.rl"
399 	{
400                 mathOp = DIV;
401             }
402 	break;
403 	case 15:
404 // line 137 "SyntheticAccessorFSM.rl"
405 	{
406                 mathOp = REM;
407             }
408 	break;
409 	case 16:
410 // line 140 "SyntheticAccessorFSM.rl"
411 	{
412                 mathOp = AND;
413             }
414 	break;
415 	case 17:
416 // line 143 "SyntheticAccessorFSM.rl"
417 	{
418                 mathOp = OR;
419             }
420 	break;
421 	case 18:
422 // line 146 "SyntheticAccessorFSM.rl"
423 	{
424                 mathOp = XOR;
425             }
426 	break;
427 	case 19:
428 // line 149 "SyntheticAccessorFSM.rl"
429 	{
430                 mathOp = SHL;
431             }
432 	break;
433 	case 20:
434 // line 152 "SyntheticAccessorFSM.rl"
435 	{
436                 mathOp = SHR;
437             }
438 	break;
439 	case 21:
440 // line 155 "SyntheticAccessorFSM.rl"
441 	{
442                 mathOp = USHR;
443             }
444 	break;
445 	case 22:
446 // line 161 "SyntheticAccessorFSM.rl"
447 	{
448                 returnRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA();
449             }
450 	break;
451 	case 23:
452 // line 167 "SyntheticAccessorFSM.rl"
453 	{
454                 accessorType = SyntheticAccessorResolver.GETTER; { p += 1; _goto_targ = 5; if (true)  continue _goto;}
455             }
456 	break;
457 	case 24:
458 // line 171 "SyntheticAccessorFSM.rl"
459 	{
460                 accessorType = SyntheticAccessorResolver.SETTER; { p += 1; _goto_targ = 5; if (true)  continue _goto;}
461             }
462 	break;
463 	case 25:
464 // line 175 "SyntheticAccessorFSM.rl"
465 	{
466                 accessorType = SyntheticAccessorResolver.METHOD; { p += 1; _goto_targ = 5; if (true)  continue _goto;}
467             }
468 	break;
469 	case 26:
470 // line 179 "SyntheticAccessorFSM.rl"
471 	{
472                 accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister);
473             }
474 	break;
475 	case 27:
476 // line 183 "SyntheticAccessorFSM.rl"
477 	{
478                 accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister);
479             }
480 	break;
481 	case 28:
482 // line 191 "SyntheticAccessorFSM.rl"
483 	{
484                 accessorType = mathOp; { p += 1; _goto_targ = 5; if (true)  continue _goto;}
485             }
486 	break;
487 // line 486 "/usr/local/google/home/sgjesse/prj/smali/smali/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/SyntheticAccessorFSM.java"
488 			}
489 		}
490 	}
491 
492 case 2:
493 	if ( cs == 0 ) {
494 		_goto_targ = 5;
495 		continue _goto;
496 	}
497 	if ( ++p != pe ) {
498 		_goto_targ = 1;
499 		continue _goto;
500 	}
501 case 4:
502 case 5:
503 	}
504 	break; }
505 	}
506 
507 // line 204 "SyntheticAccessorFSM.rl"
508 
509 
510         return accessorType;
511     }
512 
getIncrementType(int mathOp, int mathType, long constantValue, int putRegister, int returnRegister)513     private static int getIncrementType(int mathOp, int mathType, long constantValue, int putRegister,
514             int returnRegister) {
515         boolean isPrefix = putRegister == returnRegister;
516 
517         boolean negativeConstant = false;
518 
519         switch (mathType) {
520             case INT:
521             case LONG: {
522                 if (constantValue == 1) {
523                     negativeConstant = false;
524                 } else if (constantValue == -1) {
525                     negativeConstant = true;
526                 } else {
527                     return -1;
528                 }
529                 break;
530             }
531             case FLOAT: {
532                 float val = Float.intBitsToFloat((int)constantValue);
533                 if (val == 1) {
534                     negativeConstant = false;
535                 } else if (val == -1) {
536                     negativeConstant = true;
537                 } else {
538                     return -1;
539                 }
540                 break;
541             }
542             case DOUBLE: {
543                 double val = Double.longBitsToDouble(constantValue);
544                 if (val == 1) {
545                     negativeConstant = false;
546                 } else if (val == -1) {
547                     negativeConstant = true;
548                 } else {
549                     return -1;
550                 }
551                 break;
552             }
553         }
554 
555         boolean isAdd = ((mathOp == ADD) && !negativeConstant) ||
556                         ((mathOp == SUB) && negativeConstant);
557 
558         if (isPrefix) {
559             if (isAdd) {
560                 return SyntheticAccessorResolver.PREFIX_INCREMENT;
561             } else {
562                 return SyntheticAccessorResolver.PREFIX_DECREMENT;
563             }
564         } else {
565             if (isAdd) {
566                 return SyntheticAccessorResolver.POSTFIX_INCREMENT;
567             } else {
568                 return SyntheticAccessorResolver.POSTFIX_DECREMENT;
569             }
570         }
571     }
572 }