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 }