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