blob: f9ce4dec210cb1e5dd8bc2e7972658cb48f65c22 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andy McFadden3a1aedb2009-05-07 13:30:23 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Dalvik instruction utility functions.
19 */
20#include "InstrUtils.h"
21
22#include <stdlib.h>
23
24
25/*
26 * Generate a table that holds the width of all instructions.
27 *
28 * Standard instructions have positive values, optimizer instructions
29 * have negative values, unimplemented instructions have a width of zero.
30 *
31 * I'm doing it with a giant switch statement because it's easier to
32 * maintain and update than a static table with 256 unadorned integers,
33 * and if we're missing a case gcc emits a "warning: enumeration value not
34 * handled" message.
35 *
36 * (To save space in the binary we could generate a static table with a
37 * command-line utility.)
38 */
39InstructionWidth* dexCreateInstrWidthTable(void)
40{
41 InstructionWidth* instrWidth;
42 int i;
43
44 instrWidth = malloc(sizeof(InstructionWidth) * kNumDalvikInstructions);
45 if (instrWidth == NULL)
46 return NULL;
47
48 for (i = 0; i < kNumDalvikInstructions; i++) {
49 OpCode opc = (OpCode) i;
50 int width = 0;
51
52 switch (opc) {
Andy McFadden3a1aedb2009-05-07 13:30:23 -070053 case OP_NOP: /* note data for e.g. switch-* encoded "inside" a NOP */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080054 case OP_MOVE:
55 case OP_MOVE_WIDE:
56 case OP_MOVE_OBJECT:
57 case OP_MOVE_RESULT:
58 case OP_MOVE_RESULT_WIDE:
59 case OP_MOVE_RESULT_OBJECT:
60 case OP_MOVE_EXCEPTION:
61 case OP_RETURN_VOID:
62 case OP_RETURN:
63 case OP_RETURN_WIDE:
64 case OP_RETURN_OBJECT:
65 case OP_CONST_4:
66 case OP_MONITOR_ENTER:
67 case OP_MONITOR_EXIT:
68 case OP_ARRAY_LENGTH:
69 case OP_THROW:
70 case OP_GOTO:
71 case OP_NEG_INT:
72 case OP_NOT_INT:
73 case OP_NEG_LONG:
74 case OP_NOT_LONG:
75 case OP_NEG_FLOAT:
76 case OP_NEG_DOUBLE:
77 case OP_INT_TO_LONG:
78 case OP_INT_TO_FLOAT:
79 case OP_INT_TO_DOUBLE:
80 case OP_LONG_TO_INT:
81 case OP_LONG_TO_FLOAT:
82 case OP_LONG_TO_DOUBLE:
83 case OP_FLOAT_TO_INT:
84 case OP_FLOAT_TO_LONG:
85 case OP_FLOAT_TO_DOUBLE:
86 case OP_DOUBLE_TO_INT:
87 case OP_DOUBLE_TO_LONG:
88 case OP_DOUBLE_TO_FLOAT:
89 case OP_INT_TO_BYTE:
90 case OP_INT_TO_CHAR:
91 case OP_INT_TO_SHORT:
92 case OP_ADD_INT_2ADDR:
93 case OP_SUB_INT_2ADDR:
94 case OP_MUL_INT_2ADDR:
95 case OP_DIV_INT_2ADDR:
96 case OP_REM_INT_2ADDR:
97 case OP_AND_INT_2ADDR:
98 case OP_OR_INT_2ADDR:
99 case OP_XOR_INT_2ADDR:
100 case OP_SHL_INT_2ADDR:
101 case OP_SHR_INT_2ADDR:
102 case OP_USHR_INT_2ADDR:
103 case OP_ADD_LONG_2ADDR:
104 case OP_SUB_LONG_2ADDR:
105 case OP_MUL_LONG_2ADDR:
106 case OP_DIV_LONG_2ADDR:
107 case OP_REM_LONG_2ADDR:
108 case OP_AND_LONG_2ADDR:
109 case OP_OR_LONG_2ADDR:
110 case OP_XOR_LONG_2ADDR:
111 case OP_SHL_LONG_2ADDR:
112 case OP_SHR_LONG_2ADDR:
113 case OP_USHR_LONG_2ADDR:
114 case OP_ADD_FLOAT_2ADDR:
115 case OP_SUB_FLOAT_2ADDR:
116 case OP_MUL_FLOAT_2ADDR:
117 case OP_DIV_FLOAT_2ADDR:
118 case OP_REM_FLOAT_2ADDR:
119 case OP_ADD_DOUBLE_2ADDR:
120 case OP_SUB_DOUBLE_2ADDR:
121 case OP_MUL_DOUBLE_2ADDR:
122 case OP_DIV_DOUBLE_2ADDR:
123 case OP_REM_DOUBLE_2ADDR:
124 width = 1;
125 break;
126
127 case OP_MOVE_FROM16:
128 case OP_MOVE_WIDE_FROM16:
129 case OP_MOVE_OBJECT_FROM16:
130 case OP_CONST_16:
131 case OP_CONST_HIGH16:
132 case OP_CONST_WIDE_16:
133 case OP_CONST_WIDE_HIGH16:
134 case OP_CONST_STRING:
135 case OP_CONST_CLASS:
136 case OP_CHECK_CAST:
137 case OP_INSTANCE_OF:
138 case OP_NEW_INSTANCE:
139 case OP_NEW_ARRAY:
140 case OP_CMPL_FLOAT:
141 case OP_CMPG_FLOAT:
142 case OP_CMPL_DOUBLE:
143 case OP_CMPG_DOUBLE:
144 case OP_CMP_LONG:
145 case OP_GOTO_16:
146 case OP_IF_EQ:
147 case OP_IF_NE:
148 case OP_IF_LT:
149 case OP_IF_GE:
150 case OP_IF_GT:
151 case OP_IF_LE:
152 case OP_IF_EQZ:
153 case OP_IF_NEZ:
154 case OP_IF_LTZ:
155 case OP_IF_GEZ:
156 case OP_IF_GTZ:
157 case OP_IF_LEZ:
158 case OP_AGET:
159 case OP_AGET_WIDE:
160 case OP_AGET_OBJECT:
161 case OP_AGET_BOOLEAN:
162 case OP_AGET_BYTE:
163 case OP_AGET_CHAR:
164 case OP_AGET_SHORT:
165 case OP_APUT:
166 case OP_APUT_WIDE:
167 case OP_APUT_OBJECT:
168 case OP_APUT_BOOLEAN:
169 case OP_APUT_BYTE:
170 case OP_APUT_CHAR:
171 case OP_APUT_SHORT:
172 case OP_IGET:
173 case OP_IGET_WIDE:
174 case OP_IGET_OBJECT:
175 case OP_IGET_BOOLEAN:
176 case OP_IGET_BYTE:
177 case OP_IGET_CHAR:
178 case OP_IGET_SHORT:
179 case OP_IPUT:
180 case OP_IPUT_WIDE:
181 case OP_IPUT_OBJECT:
182 case OP_IPUT_BOOLEAN:
183 case OP_IPUT_BYTE:
184 case OP_IPUT_CHAR:
185 case OP_IPUT_SHORT:
186 case OP_SGET:
187 case OP_SGET_WIDE:
188 case OP_SGET_OBJECT:
189 case OP_SGET_BOOLEAN:
190 case OP_SGET_BYTE:
191 case OP_SGET_CHAR:
192 case OP_SGET_SHORT:
193 case OP_SPUT:
194 case OP_SPUT_WIDE:
195 case OP_SPUT_OBJECT:
196 case OP_SPUT_BOOLEAN:
197 case OP_SPUT_BYTE:
198 case OP_SPUT_CHAR:
199 case OP_SPUT_SHORT:
200 case OP_ADD_INT:
201 case OP_SUB_INT:
202 case OP_MUL_INT:
203 case OP_DIV_INT:
204 case OP_REM_INT:
205 case OP_AND_INT:
206 case OP_OR_INT:
207 case OP_XOR_INT:
208 case OP_SHL_INT:
209 case OP_SHR_INT:
210 case OP_USHR_INT:
211 case OP_ADD_LONG:
212 case OP_SUB_LONG:
213 case OP_MUL_LONG:
214 case OP_DIV_LONG:
215 case OP_REM_LONG:
216 case OP_AND_LONG:
217 case OP_OR_LONG:
218 case OP_XOR_LONG:
219 case OP_SHL_LONG:
220 case OP_SHR_LONG:
221 case OP_USHR_LONG:
222 case OP_ADD_FLOAT:
223 case OP_SUB_FLOAT:
224 case OP_MUL_FLOAT:
225 case OP_DIV_FLOAT:
226 case OP_REM_FLOAT:
227 case OP_ADD_DOUBLE:
228 case OP_SUB_DOUBLE:
229 case OP_MUL_DOUBLE:
230 case OP_DIV_DOUBLE:
231 case OP_REM_DOUBLE:
232 case OP_ADD_INT_LIT16:
233 case OP_RSUB_INT:
234 case OP_MUL_INT_LIT16:
235 case OP_DIV_INT_LIT16:
236 case OP_REM_INT_LIT16:
237 case OP_AND_INT_LIT16:
238 case OP_OR_INT_LIT16:
239 case OP_XOR_INT_LIT16:
240 case OP_ADD_INT_LIT8:
241 case OP_RSUB_INT_LIT8:
242 case OP_MUL_INT_LIT8:
243 case OP_DIV_INT_LIT8:
244 case OP_REM_INT_LIT8:
245 case OP_AND_INT_LIT8:
246 case OP_OR_INT_LIT8:
247 case OP_XOR_INT_LIT8:
248 case OP_SHL_INT_LIT8:
249 case OP_SHR_INT_LIT8:
250 case OP_USHR_INT_LIT8:
251 width = 2;
252 break;
253
254 case OP_MOVE_16:
255 case OP_MOVE_WIDE_16:
256 case OP_MOVE_OBJECT_16:
257 case OP_CONST:
258 case OP_CONST_WIDE_32:
259 case OP_CONST_STRING_JUMBO:
260 case OP_GOTO_32:
261 case OP_FILLED_NEW_ARRAY:
262 case OP_FILLED_NEW_ARRAY_RANGE:
263 case OP_FILL_ARRAY_DATA:
264 case OP_PACKED_SWITCH:
265 case OP_SPARSE_SWITCH:
266 case OP_INVOKE_VIRTUAL:
267 case OP_INVOKE_SUPER:
268 case OP_INVOKE_DIRECT:
269 case OP_INVOKE_STATIC:
270 case OP_INVOKE_INTERFACE:
271 case OP_INVOKE_VIRTUAL_RANGE:
272 case OP_INVOKE_SUPER_RANGE:
273 case OP_INVOKE_DIRECT_RANGE:
274 case OP_INVOKE_STATIC_RANGE:
275 case OP_INVOKE_INTERFACE_RANGE:
276 width = 3;
277 break;
278
279 case OP_CONST_WIDE:
280 width = 5;
281 break;
282
283 /*
284 * Optimized instructions. We return negative size values for these
285 * to distinguish them.
286 */
287 case OP_IGET_QUICK:
288 case OP_IGET_WIDE_QUICK:
289 case OP_IGET_OBJECT_QUICK:
290 case OP_IPUT_QUICK:
291 case OP_IPUT_WIDE_QUICK:
292 case OP_IPUT_OBJECT_QUICK:
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700293 case OP_THROW_VERIFICATION_ERROR:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800294 width = -2;
295 break;
296 case OP_INVOKE_VIRTUAL_QUICK:
297 case OP_INVOKE_VIRTUAL_QUICK_RANGE:
298 case OP_INVOKE_SUPER_QUICK:
299 case OP_INVOKE_SUPER_QUICK_RANGE:
300 case OP_EXECUTE_INLINE:
301 case OP_INVOKE_DIRECT_EMPTY:
302 width = -3;
303 break;
304
305 /* these should never appear */
306 case OP_UNUSED_3E:
307 case OP_UNUSED_3F:
308 case OP_UNUSED_40:
309 case OP_UNUSED_41:
310 case OP_UNUSED_42:
311 case OP_UNUSED_43:
312 case OP_UNUSED_73:
313 case OP_UNUSED_79:
314 case OP_UNUSED_7A:
315 case OP_UNUSED_E3:
316 case OP_UNUSED_E4:
317 case OP_UNUSED_E5:
318 case OP_UNUSED_E6:
319 case OP_UNUSED_E7:
320 case OP_UNUSED_E8:
321 case OP_UNUSED_E9:
322 case OP_UNUSED_EA:
323 case OP_UNUSED_EB:
324 case OP_UNUSED_EC:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800325 case OP_UNUSED_EF:
326 case OP_UNUSED_F1:
327 case OP_UNUSED_FC:
328 case OP_UNUSED_FD:
329 case OP_UNUSED_FE:
330 case OP_UNUSED_FF:
331 assert(width == 0);
332 break;
333
334 /*
335 * DO NOT add a "default" clause here. Without it the compiler will
336 * complain if an instruction is missing (which is desirable).
337 */
338 }
339
340 instrWidth[opc] = width;
341 }
342
343 return instrWidth;
344}
345
346/*
347 * Generate a table that holds instruction flags.
348 */
349InstructionFlags* dexCreateInstrFlagsTable(void)
350{
351 InstructionFlags* instrFlags;
352 int i;
353
354 instrFlags = malloc(sizeof(InstructionFlags) * kNumDalvikInstructions);
355 if (instrFlags == NULL)
356 return NULL;
357
358 for (i = 0; i < kNumDalvikInstructions; i++) {
359 OpCode opc = (OpCode) i;
360 InstructionFlags flags = 0;
361
362 switch (opc) {
363 /* these don't affect the PC and can't cause an exception */
364 case OP_NOP:
365 case OP_MOVE:
366 case OP_MOVE_FROM16:
367 case OP_MOVE_16:
368 case OP_MOVE_WIDE:
369 case OP_MOVE_WIDE_FROM16:
370 case OP_MOVE_WIDE_16:
371 case OP_MOVE_OBJECT:
372 case OP_MOVE_OBJECT_FROM16:
373 case OP_MOVE_OBJECT_16:
374 case OP_MOVE_RESULT:
375 case OP_MOVE_RESULT_WIDE:
376 case OP_MOVE_RESULT_OBJECT:
377 case OP_MOVE_EXCEPTION:
378 case OP_CONST_4:
379 case OP_CONST_16:
380 case OP_CONST:
381 case OP_CONST_HIGH16:
382 case OP_CONST_WIDE_16:
383 case OP_CONST_WIDE_32:
384 case OP_CONST_WIDE:
385 case OP_CONST_WIDE_HIGH16:
386 case OP_FILL_ARRAY_DATA:
387 case OP_CMPL_FLOAT:
388 case OP_CMPG_FLOAT:
389 case OP_CMPL_DOUBLE:
390 case OP_CMPG_DOUBLE:
391 case OP_CMP_LONG:
392 case OP_NEG_INT:
393 case OP_NOT_INT:
394 case OP_NEG_LONG:
395 case OP_NOT_LONG:
396 case OP_NEG_FLOAT:
397 case OP_NEG_DOUBLE:
398 case OP_INT_TO_LONG:
399 case OP_INT_TO_FLOAT:
400 case OP_INT_TO_DOUBLE:
401 case OP_LONG_TO_INT:
402 case OP_LONG_TO_FLOAT:
403 case OP_LONG_TO_DOUBLE:
404 case OP_FLOAT_TO_INT:
405 case OP_FLOAT_TO_LONG:
406 case OP_FLOAT_TO_DOUBLE:
407 case OP_DOUBLE_TO_INT:
408 case OP_DOUBLE_TO_LONG:
409 case OP_DOUBLE_TO_FLOAT:
410 case OP_INT_TO_BYTE:
411 case OP_INT_TO_CHAR:
412 case OP_INT_TO_SHORT:
413 case OP_ADD_INT:
414 case OP_SUB_INT:
415 case OP_MUL_INT:
416 case OP_AND_INT:
417 case OP_OR_INT:
418 case OP_XOR_INT:
419 case OP_SHL_INT:
420 case OP_SHR_INT:
421 case OP_USHR_INT:
422 case OP_ADD_LONG:
423 case OP_SUB_LONG:
424 case OP_MUL_LONG:
425 case OP_AND_LONG:
426 case OP_OR_LONG:
427 case OP_XOR_LONG:
428 case OP_SHL_LONG:
429 case OP_SHR_LONG:
430 case OP_USHR_LONG:
431 case OP_ADD_FLOAT:
432 case OP_SUB_FLOAT:
433 case OP_MUL_FLOAT:
434 case OP_DIV_FLOAT:
435 case OP_REM_FLOAT:
436 case OP_ADD_DOUBLE:
437 case OP_SUB_DOUBLE:
438 case OP_MUL_DOUBLE:
439 case OP_DIV_DOUBLE: // div by zero just returns NaN
440 case OP_REM_DOUBLE:
441 case OP_ADD_INT_2ADDR:
442 case OP_SUB_INT_2ADDR:
443 case OP_MUL_INT_2ADDR:
444 case OP_AND_INT_2ADDR:
445 case OP_OR_INT_2ADDR:
446 case OP_XOR_INT_2ADDR:
447 case OP_SHL_INT_2ADDR:
448 case OP_SHR_INT_2ADDR:
449 case OP_USHR_INT_2ADDR:
450 case OP_ADD_LONG_2ADDR:
451 case OP_SUB_LONG_2ADDR:
452 case OP_MUL_LONG_2ADDR:
453 case OP_AND_LONG_2ADDR:
454 case OP_OR_LONG_2ADDR:
455 case OP_XOR_LONG_2ADDR:
456 case OP_SHL_LONG_2ADDR:
457 case OP_SHR_LONG_2ADDR:
458 case OP_USHR_LONG_2ADDR:
459 case OP_ADD_FLOAT_2ADDR:
460 case OP_SUB_FLOAT_2ADDR:
461 case OP_MUL_FLOAT_2ADDR:
462 case OP_DIV_FLOAT_2ADDR:
463 case OP_REM_FLOAT_2ADDR:
464 case OP_ADD_DOUBLE_2ADDR:
465 case OP_SUB_DOUBLE_2ADDR:
466 case OP_MUL_DOUBLE_2ADDR:
467 case OP_DIV_DOUBLE_2ADDR:
468 case OP_REM_DOUBLE_2ADDR:
469 case OP_ADD_INT_LIT16:
470 case OP_RSUB_INT:
471 case OP_MUL_INT_LIT16:
472 case OP_AND_INT_LIT16:
473 case OP_OR_INT_LIT16:
474 case OP_XOR_INT_LIT16:
475 case OP_ADD_INT_LIT8:
476 case OP_RSUB_INT_LIT8:
477 case OP_MUL_INT_LIT8:
478 case OP_AND_INT_LIT8:
479 case OP_OR_INT_LIT8:
480 case OP_XOR_INT_LIT8:
481 case OP_SHL_INT_LIT8:
482 case OP_SHR_INT_LIT8:
483 case OP_USHR_INT_LIT8:
484 flags = kInstrCanContinue;
485 break;
486
487 /* these don't affect the PC, but can cause exceptions */
488 case OP_CONST_STRING:
489 case OP_CONST_STRING_JUMBO:
490 case OP_CONST_CLASS:
491 case OP_MONITOR_ENTER:
492 case OP_MONITOR_EXIT:
493 case OP_CHECK_CAST:
494 case OP_INSTANCE_OF:
495 case OP_ARRAY_LENGTH:
496 case OP_NEW_INSTANCE:
497 case OP_NEW_ARRAY:
498 case OP_FILLED_NEW_ARRAY:
499 case OP_FILLED_NEW_ARRAY_RANGE:
500 case OP_AGET:
501 case OP_AGET_BOOLEAN:
502 case OP_AGET_BYTE:
503 case OP_AGET_CHAR:
504 case OP_AGET_SHORT:
505 case OP_AGET_WIDE:
506 case OP_AGET_OBJECT:
507 case OP_APUT:
508 case OP_APUT_BOOLEAN:
509 case OP_APUT_BYTE:
510 case OP_APUT_CHAR:
511 case OP_APUT_SHORT:
512 case OP_APUT_WIDE:
513 case OP_APUT_OBJECT:
514 case OP_IGET:
515 case OP_IGET_BOOLEAN:
516 case OP_IGET_BYTE:
517 case OP_IGET_CHAR:
518 case OP_IGET_SHORT:
519 case OP_IGET_WIDE:
520 case OP_IGET_OBJECT:
521 case OP_IPUT:
522 case OP_IPUT_BOOLEAN:
523 case OP_IPUT_BYTE:
524 case OP_IPUT_CHAR:
525 case OP_IPUT_SHORT:
526 case OP_IPUT_WIDE:
527 case OP_IPUT_OBJECT:
528 case OP_SGET:
529 case OP_SGET_BOOLEAN:
530 case OP_SGET_BYTE:
531 case OP_SGET_CHAR:
532 case OP_SGET_SHORT:
533 case OP_SGET_WIDE:
534 case OP_SGET_OBJECT:
535 case OP_SPUT:
536 case OP_SPUT_BOOLEAN:
537 case OP_SPUT_BYTE:
538 case OP_SPUT_CHAR:
539 case OP_SPUT_SHORT:
540 case OP_SPUT_WIDE:
541 case OP_SPUT_OBJECT:
542 case OP_INVOKE_VIRTUAL:
543 case OP_INVOKE_VIRTUAL_RANGE:
544 case OP_INVOKE_SUPER:
545 case OP_INVOKE_SUPER_RANGE:
546 case OP_INVOKE_DIRECT:
547 case OP_INVOKE_DIRECT_RANGE:
548 case OP_INVOKE_STATIC:
549 case OP_INVOKE_STATIC_RANGE:
550 case OP_INVOKE_INTERFACE:
551 case OP_INVOKE_INTERFACE_RANGE:
552 case OP_DIV_INT:
553 case OP_REM_INT:
554 case OP_DIV_LONG:
555 case OP_REM_LONG:
556 case OP_DIV_INT_2ADDR:
557 case OP_REM_INT_2ADDR:
558 case OP_DIV_LONG_2ADDR:
559 case OP_REM_LONG_2ADDR:
560 case OP_DIV_INT_LIT16:
561 case OP_REM_INT_LIT16:
562 case OP_DIV_INT_LIT8:
563 case OP_REM_INT_LIT8:
564 flags = kInstrCanContinue | kInstrCanThrow;
565 break;
566
567 case OP_RETURN_VOID:
568 case OP_RETURN:
569 case OP_RETURN_WIDE:
570 case OP_RETURN_OBJECT:
571 flags = kInstrCanReturn;
572 break;
573
574 case OP_THROW:
575 flags = kInstrCanThrow;
576 break;
577
578 /* unconditional branches */
579 case OP_GOTO:
580 case OP_GOTO_16:
581 case OP_GOTO_32:
582 flags = kInstrCanBranch;
583 break;
584
585 /* conditional branches */
586 case OP_IF_EQ:
587 case OP_IF_NE:
588 case OP_IF_LT:
589 case OP_IF_GE:
590 case OP_IF_GT:
591 case OP_IF_LE:
592 case OP_IF_EQZ:
593 case OP_IF_NEZ:
594 case OP_IF_LTZ:
595 case OP_IF_GEZ:
596 case OP_IF_GTZ:
597 case OP_IF_LEZ:
598 flags = kInstrCanBranch | kInstrCanContinue;
599 break;
600
601 /* switch statements; if value not in switch, it continues */
602 case OP_PACKED_SWITCH:
603 case OP_SPARSE_SWITCH:
604 flags = kInstrCanSwitch | kInstrCanContinue;
605 break;
606
607 /* optimizer-generated instructions */
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700608 case OP_THROW_VERIFICATION_ERROR:
609 flags = kInstrCanThrow;
610 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800611 case OP_EXECUTE_INLINE:
612 flags = kInstrCanContinue;
613 break;
614 case OP_IGET_QUICK:
615 case OP_IGET_WIDE_QUICK:
616 case OP_IGET_OBJECT_QUICK:
617 case OP_IPUT_QUICK:
618 case OP_IPUT_WIDE_QUICK:
619 case OP_IPUT_OBJECT_QUICK:
620 case OP_INVOKE_VIRTUAL_QUICK:
621 case OP_INVOKE_VIRTUAL_QUICK_RANGE:
622 case OP_INVOKE_SUPER_QUICK:
623 case OP_INVOKE_SUPER_QUICK_RANGE:
624 case OP_INVOKE_DIRECT_EMPTY:
625 flags = kInstrCanContinue | kInstrCanThrow;
626 break;
627
628 /* these should never appear */
629 case OP_UNUSED_3E:
630 case OP_UNUSED_3F:
631 case OP_UNUSED_40:
632 case OP_UNUSED_41:
633 case OP_UNUSED_42:
634 case OP_UNUSED_43:
635 case OP_UNUSED_73:
636 case OP_UNUSED_79:
637 case OP_UNUSED_7A:
638 case OP_UNUSED_E3:
639 case OP_UNUSED_E4:
640 case OP_UNUSED_E5:
641 case OP_UNUSED_E6:
642 case OP_UNUSED_E7:
643 case OP_UNUSED_E8:
644 case OP_UNUSED_E9:
645 case OP_UNUSED_EA:
646 case OP_UNUSED_EB:
647 case OP_UNUSED_EC:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800648 case OP_UNUSED_EF:
649 case OP_UNUSED_F1:
650 case OP_UNUSED_FC:
651 case OP_UNUSED_FD:
652 case OP_UNUSED_FE:
653 case OP_UNUSED_FF:
654 break;
655
656 /*
657 * DO NOT add a "default" clause here. Without it the compiler will
658 * complain if an instruction is missing (which is desirable).
659 */
660 }
661
662 instrFlags[opc] = flags;
663 }
664
665 return instrFlags;
666}
667
668/*
669 * Allocate and populate a 256-element array with instruction formats.
670 * Used in conjunction with dexDecodeInstruction.
671 */
672InstructionFormat* dexCreateInstrFormatTable(void)
673{
674 InstructionFormat* instFmt;
675 int i;
676
677 instFmt = malloc(sizeof(InstructionFormat) * kNumDalvikInstructions);
678 if (instFmt == NULL)
679 return NULL;
680
681 for (i = 0; i < kNumDalvikInstructions; i++) {
682 OpCode opc = (OpCode) i;
683 InstructionFormat fmt = kFmtUnknown;
684
685 switch (opc) {
686 case OP_GOTO:
687 fmt = kFmt10t;
688 break;
689 case OP_NOP:
690 case OP_RETURN_VOID:
691 fmt = kFmt10x;
692 break;
693 case OP_CONST_4:
694 fmt = kFmt11n;
695 break;
696 case OP_CONST_HIGH16:
697 case OP_CONST_WIDE_HIGH16:
698 fmt = kFmt21h;
699 break;
700 case OP_MOVE_RESULT:
701 case OP_MOVE_RESULT_WIDE:
702 case OP_MOVE_RESULT_OBJECT:
703 case OP_MOVE_EXCEPTION:
704 case OP_RETURN:
705 case OP_RETURN_WIDE:
706 case OP_RETURN_OBJECT:
707 case OP_MONITOR_ENTER:
708 case OP_MONITOR_EXIT:
709 case OP_THROW:
710 fmt = kFmt11x;
711 break;
712 case OP_MOVE:
713 case OP_MOVE_WIDE:
714 case OP_MOVE_OBJECT:
715 case OP_ARRAY_LENGTH:
716 case OP_NEG_INT:
717 case OP_NOT_INT:
718 case OP_NEG_LONG:
719 case OP_NOT_LONG:
720 case OP_NEG_FLOAT:
721 case OP_NEG_DOUBLE:
722 case OP_INT_TO_LONG:
723 case OP_INT_TO_FLOAT:
724 case OP_INT_TO_DOUBLE:
725 case OP_LONG_TO_INT:
726 case OP_LONG_TO_FLOAT:
727 case OP_LONG_TO_DOUBLE:
728 case OP_FLOAT_TO_INT:
729 case OP_FLOAT_TO_LONG:
730 case OP_FLOAT_TO_DOUBLE:
731 case OP_DOUBLE_TO_INT:
732 case OP_DOUBLE_TO_LONG:
733 case OP_DOUBLE_TO_FLOAT:
734 case OP_INT_TO_BYTE:
735 case OP_INT_TO_CHAR:
736 case OP_INT_TO_SHORT:
737 case OP_ADD_INT_2ADDR:
738 case OP_SUB_INT_2ADDR:
739 case OP_MUL_INT_2ADDR:
740 case OP_DIV_INT_2ADDR:
741 case OP_REM_INT_2ADDR:
742 case OP_AND_INT_2ADDR:
743 case OP_OR_INT_2ADDR:
744 case OP_XOR_INT_2ADDR:
745 case OP_SHL_INT_2ADDR:
746 case OP_SHR_INT_2ADDR:
747 case OP_USHR_INT_2ADDR:
748 case OP_ADD_LONG_2ADDR:
749 case OP_SUB_LONG_2ADDR:
750 case OP_MUL_LONG_2ADDR:
751 case OP_DIV_LONG_2ADDR:
752 case OP_REM_LONG_2ADDR:
753 case OP_AND_LONG_2ADDR:
754 case OP_OR_LONG_2ADDR:
755 case OP_XOR_LONG_2ADDR:
756 case OP_SHL_LONG_2ADDR:
757 case OP_SHR_LONG_2ADDR:
758 case OP_USHR_LONG_2ADDR:
759 case OP_ADD_FLOAT_2ADDR:
760 case OP_SUB_FLOAT_2ADDR:
761 case OP_MUL_FLOAT_2ADDR:
762 case OP_DIV_FLOAT_2ADDR:
763 case OP_REM_FLOAT_2ADDR:
764 case OP_ADD_DOUBLE_2ADDR:
765 case OP_SUB_DOUBLE_2ADDR:
766 case OP_MUL_DOUBLE_2ADDR:
767 case OP_DIV_DOUBLE_2ADDR:
768 case OP_REM_DOUBLE_2ADDR:
769 fmt = kFmt12x;
770 break;
771 case OP_GOTO_16:
772 fmt = kFmt20t;
773 break;
774 case OP_GOTO_32:
775 fmt = kFmt30t;
776 break;
777 case OP_CONST_STRING:
778 case OP_CONST_CLASS:
779 case OP_CHECK_CAST:
780 case OP_NEW_INSTANCE:
781 case OP_SGET:
782 case OP_SGET_WIDE:
783 case OP_SGET_OBJECT:
784 case OP_SGET_BOOLEAN:
785 case OP_SGET_BYTE:
786 case OP_SGET_CHAR:
787 case OP_SGET_SHORT:
788 case OP_SPUT:
789 case OP_SPUT_WIDE:
790 case OP_SPUT_OBJECT:
791 case OP_SPUT_BOOLEAN:
792 case OP_SPUT_BYTE:
793 case OP_SPUT_CHAR:
794 case OP_SPUT_SHORT:
795 fmt = kFmt21c;
796 break;
797 case OP_CONST_16:
798 case OP_CONST_WIDE_16:
799 fmt = kFmt21s;
800 break;
801 case OP_IF_EQZ:
802 case OP_IF_NEZ:
803 case OP_IF_LTZ:
804 case OP_IF_GEZ:
805 case OP_IF_GTZ:
806 case OP_IF_LEZ:
807 fmt = kFmt21t;
808 break;
809 case OP_FILL_ARRAY_DATA:
810 case OP_PACKED_SWITCH:
811 case OP_SPARSE_SWITCH:
812 fmt = kFmt31t;
813 break;
814 case OP_ADD_INT_LIT8:
815 case OP_RSUB_INT_LIT8:
816 case OP_MUL_INT_LIT8:
817 case OP_DIV_INT_LIT8:
818 case OP_REM_INT_LIT8:
819 case OP_AND_INT_LIT8:
820 case OP_OR_INT_LIT8:
821 case OP_XOR_INT_LIT8:
822 case OP_SHL_INT_LIT8:
823 case OP_SHR_INT_LIT8:
824 case OP_USHR_INT_LIT8:
825 fmt = kFmt22b;
826 break;
827 case OP_INSTANCE_OF:
828 case OP_NEW_ARRAY:
829 case OP_IGET:
830 case OP_IGET_WIDE:
831 case OP_IGET_OBJECT:
832 case OP_IGET_BOOLEAN:
833 case OP_IGET_BYTE:
834 case OP_IGET_CHAR:
835 case OP_IGET_SHORT:
836 case OP_IPUT:
837 case OP_IPUT_WIDE:
838 case OP_IPUT_OBJECT:
839 case OP_IPUT_BOOLEAN:
840 case OP_IPUT_BYTE:
841 case OP_IPUT_CHAR:
842 case OP_IPUT_SHORT:
843 fmt = kFmt22c;
844 break;
845 case OP_ADD_INT_LIT16:
846 case OP_RSUB_INT:
847 case OP_MUL_INT_LIT16:
848 case OP_DIV_INT_LIT16:
849 case OP_REM_INT_LIT16:
850 case OP_AND_INT_LIT16:
851 case OP_OR_INT_LIT16:
852 case OP_XOR_INT_LIT16:
853 fmt = kFmt22s;
854 break;
855 case OP_IF_EQ:
856 case OP_IF_NE:
857 case OP_IF_LT:
858 case OP_IF_GE:
859 case OP_IF_GT:
860 case OP_IF_LE:
861 fmt = kFmt22t;
862 break;
863 case OP_MOVE_FROM16:
864 case OP_MOVE_WIDE_FROM16:
865 case OP_MOVE_OBJECT_FROM16:
866 fmt = kFmt22x;
867 break;
868 case OP_CMPL_FLOAT:
869 case OP_CMPG_FLOAT:
870 case OP_CMPL_DOUBLE:
871 case OP_CMPG_DOUBLE:
872 case OP_CMP_LONG:
873 case OP_AGET:
874 case OP_AGET_WIDE:
875 case OP_AGET_OBJECT:
876 case OP_AGET_BOOLEAN:
877 case OP_AGET_BYTE:
878 case OP_AGET_CHAR:
879 case OP_AGET_SHORT:
880 case OP_APUT:
881 case OP_APUT_WIDE:
882 case OP_APUT_OBJECT:
883 case OP_APUT_BOOLEAN:
884 case OP_APUT_BYTE:
885 case OP_APUT_CHAR:
886 case OP_APUT_SHORT:
887 case OP_ADD_INT:
888 case OP_SUB_INT:
889 case OP_MUL_INT:
890 case OP_DIV_INT:
891 case OP_REM_INT:
892 case OP_AND_INT:
893 case OP_OR_INT:
894 case OP_XOR_INT:
895 case OP_SHL_INT:
896 case OP_SHR_INT:
897 case OP_USHR_INT:
898 case OP_ADD_LONG:
899 case OP_SUB_LONG:
900 case OP_MUL_LONG:
901 case OP_DIV_LONG:
902 case OP_REM_LONG:
903 case OP_AND_LONG:
904 case OP_OR_LONG:
905 case OP_XOR_LONG:
906 case OP_SHL_LONG:
907 case OP_SHR_LONG:
908 case OP_USHR_LONG:
909 case OP_ADD_FLOAT:
910 case OP_SUB_FLOAT:
911 case OP_MUL_FLOAT:
912 case OP_DIV_FLOAT:
913 case OP_REM_FLOAT:
914 case OP_ADD_DOUBLE:
915 case OP_SUB_DOUBLE:
916 case OP_MUL_DOUBLE:
917 case OP_DIV_DOUBLE:
918 case OP_REM_DOUBLE:
919 fmt = kFmt23x;
920 break;
921 case OP_CONST:
922 case OP_CONST_WIDE_32:
923 fmt = kFmt31i;
924 break;
925 case OP_CONST_STRING_JUMBO:
926 fmt = kFmt31c;
927 break;
928 case OP_MOVE_16:
929 case OP_MOVE_WIDE_16:
930 case OP_MOVE_OBJECT_16:
931 fmt = kFmt32x;
932 break;
933 case OP_FILLED_NEW_ARRAY:
934 case OP_INVOKE_VIRTUAL:
935 case OP_INVOKE_SUPER:
936 case OP_INVOKE_DIRECT:
937 case OP_INVOKE_STATIC:
938 case OP_INVOKE_INTERFACE:
939 fmt = kFmt35c;
940 break;
941 case OP_FILLED_NEW_ARRAY_RANGE:
942 case OP_INVOKE_VIRTUAL_RANGE:
943 case OP_INVOKE_SUPER_RANGE:
944 case OP_INVOKE_DIRECT_RANGE:
945 case OP_INVOKE_STATIC_RANGE:
946 case OP_INVOKE_INTERFACE_RANGE:
947 fmt = kFmt3rc;
948 break;
949 case OP_CONST_WIDE:
950 fmt = kFmt51l;
951 break;
952
953 /*
954 * Optimized instructions.
955 */
Andy McFadden3a1aedb2009-05-07 13:30:23 -0700956 case OP_THROW_VERIFICATION_ERROR:
957 fmt = kFmt20bc;
958 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800959 case OP_IGET_QUICK:
960 case OP_IGET_WIDE_QUICK:
961 case OP_IGET_OBJECT_QUICK:
962 case OP_IPUT_QUICK:
963 case OP_IPUT_WIDE_QUICK:
964 case OP_IPUT_OBJECT_QUICK:
965 fmt = kFmt22cs;
966 break;
967 case OP_INVOKE_VIRTUAL_QUICK:
968 case OP_INVOKE_SUPER_QUICK:
969 fmt = kFmt35ms;
970 break;
971 case OP_INVOKE_VIRTUAL_QUICK_RANGE:
972 case OP_INVOKE_SUPER_QUICK_RANGE:
973 fmt = kFmt3rms;
974 break;
975 case OP_EXECUTE_INLINE:
976 fmt = kFmt3inline;
977 break;
978 case OP_INVOKE_DIRECT_EMPTY:
979 fmt = kFmt35c;
980 break;
981
982 /* these should never appear */
983 case OP_UNUSED_3E:
984 case OP_UNUSED_3F:
985 case OP_UNUSED_40:
986 case OP_UNUSED_41:
987 case OP_UNUSED_42:
988 case OP_UNUSED_43:
989 case OP_UNUSED_73:
990 case OP_UNUSED_79:
991 case OP_UNUSED_7A:
992 case OP_UNUSED_E3:
993 case OP_UNUSED_E4:
994 case OP_UNUSED_E5:
995 case OP_UNUSED_E6:
996 case OP_UNUSED_E7:
997 case OP_UNUSED_E8:
998 case OP_UNUSED_E9:
999 case OP_UNUSED_EA:
1000 case OP_UNUSED_EB:
1001 case OP_UNUSED_EC:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001002 case OP_UNUSED_EF:
1003 case OP_UNUSED_F1:
1004 case OP_UNUSED_FC:
1005 case OP_UNUSED_FD:
1006 case OP_UNUSED_FE:
1007 case OP_UNUSED_FF:
1008 fmt = kFmtUnknown;
1009 break;
1010
1011 /*
1012 * DO NOT add a "default" clause here. Without it the compiler will
1013 * complain if an instruction is missing (which is desirable).
1014 */
1015 }
1016
1017 instFmt[opc] = fmt;
1018 }
1019
1020 return instFmt;
1021}
1022
1023/*
1024 * Copied from InterpCore.h. Used for instruction decoding.
1025 */
1026#define FETCH(_offset) (insns[(_offset)])
1027#define INST_INST(_inst) ((_inst) & 0xff)
1028#define INST_A(_inst) (((u2)(_inst) >> 8) & 0x0f)
1029#define INST_B(_inst) ((u2)(_inst) >> 12)
1030#define INST_AA(_inst) ((_inst) >> 8)
1031
1032/*
1033 * Decode the instruction pointed to by "insns".
1034 *
1035 * Fills out the pieces of "pDec" that are affected by the current
1036 * instruction. Does not touch anything else.
1037 */
1038void dexDecodeInstruction(const InstructionFormat* fmts, const u2* insns,
1039 DecodedInstruction* pDec)
1040{
1041 u2 inst = *insns;
1042
1043 pDec->opCode = (OpCode) INST_INST(inst);
1044
1045 switch (dexGetInstrFormat(fmts, pDec->opCode)) {
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001046 case kFmt10x: // op
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001047 /* nothing to do; copy the AA bits out for the verifier */
1048 pDec->vA = INST_AA(inst);
1049 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001050 case kFmt12x: // op vA, vB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001051 pDec->vA = INST_A(inst);
1052 pDec->vB = INST_B(inst);
1053 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001054 case kFmt11n: // op vA, #+B
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001055 pDec->vA = INST_A(inst);
1056 pDec->vB = (s4) (INST_B(inst) << 28) >> 28; // sign extend 4-bit value
1057 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001058 case kFmt11x: // op vAA
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001059 pDec->vA = INST_AA(inst);
1060 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001061 case kFmt10t: // op +AA
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001062 pDec->vA = (s1) INST_AA(inst); // sign-extend 8-bit value
1063 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001064 case kFmt20t: // op +AAAA
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001065 pDec->vA = (s2) FETCH(1); // sign-extend 16-bit value
1066 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001067 case kFmt20bc: // op AA, thing@BBBB
1068 case kFmt21c: // op vAA, thing@BBBB
1069 case kFmt22x: // op vAA, vBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001070 pDec->vA = INST_AA(inst);
1071 pDec->vB = FETCH(1);
1072 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001073 case kFmt21s: // op vAA, #+BBBB
1074 case kFmt21t: // op vAA, +BBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001075 pDec->vA = INST_AA(inst);
1076 pDec->vB = (s2) FETCH(1); // sign-extend 16-bit value
1077 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001078 case kFmt21h: // op vAA, #+BBBB0000[00000000]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001079 pDec->vA = INST_AA(inst);
1080 /*
1081 * The value should be treated as right-zero-extended, but we don't
1082 * actually do that here. Among other things, we don't know if it's
1083 * the top bits of a 32- or 64-bit value.
1084 */
1085 pDec->vB = FETCH(1);
1086 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001087 case kFmt23x: // op vAA, vBB, vCC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001088 pDec->vA = INST_AA(inst);
1089 pDec->vB = FETCH(1) & 0xff;
1090 pDec->vC = FETCH(1) >> 8;
1091 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001092 case kFmt22b: // op vAA, vBB, #+CC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001093 pDec->vA = INST_AA(inst);
1094 pDec->vB = FETCH(1) & 0xff;
1095 pDec->vC = (s1) (FETCH(1) >> 8); // sign-extend 8-bit value
1096 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001097 case kFmt22s: // op vA, vB, #+CCCC
1098 case kFmt22t: // op vA, vB, +CCCC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001099 pDec->vA = INST_A(inst);
1100 pDec->vB = INST_B(inst);
1101 pDec->vC = (s2) FETCH(1); // sign-extend 16-bit value
1102 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001103 case kFmt22c: // op vA, vB, thing@CCCC
1104 case kFmt22cs: // [opt] op vA, vB, field offset CCCC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001105 pDec->vA = INST_A(inst);
1106 pDec->vB = INST_B(inst);
1107 pDec->vC = FETCH(1);
1108 break;
1109 case kFmt30t: // op +AAAAAAAA
1110 pDec->vA = FETCH(1) | ((u4) FETCH(2) << 16); // signed 32-bit value
1111 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001112 case kFmt31t: // op vAA, +BBBBBBBB
1113 case kFmt31c: // op vAA, thing@BBBBBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001114 pDec->vA = INST_AA(inst);
1115 pDec->vB = FETCH(1) | ((u4) FETCH(2) << 16); // 32-bit value
1116 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001117 case kFmt32x: // op vAAAA, vBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001118 pDec->vA = FETCH(1);
1119 pDec->vB = FETCH(2);
1120 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001121 case kFmt31i: // op vAA, #+BBBBBBBB
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001122 pDec->vA = INST_AA(inst);
1123 pDec->vB = FETCH(1) | ((u4) FETCH(2) << 16);
1124 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001125 case kFmt35c: // op vB, {vD..vG,vA}, thing@CCCC
1126 case kFmt35ms: // [opt] invoke-virtual+super
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001127 {
1128 /*
1129 * The lettering changes that came about when we went from 4 args
1130 * to 5 made the "range" versions of the calls different from
1131 * the non-range versions. We have the choice between decoding
1132 * them the way the spec shows and having lots of conditionals
1133 * in the verifier, or mapping the values onto their original
1134 * registers and leaving the verifier intact.
1135 *
1136 * Current plan is to leave the verifier alone. We can fix it
1137 * later if it's architecturally unbearable.
1138 *
1139 * Bottom line: method constant is always in vB.
1140 */
1141 u2 regList;
1142 int i, count;
1143
1144 pDec->vA = INST_B(inst);
1145 pDec->vB = FETCH(1);
1146 regList = FETCH(2);
1147
1148 if (pDec->vA > 5) {
1149 LOGW("Invalid arg count in 35c/35ms (%d)\n", pDec->vA);
1150 goto bail;
1151 }
1152 count = pDec->vA;
1153 if (count == 5) {
1154 /* 5th arg comes from A field in instruction */
1155 pDec->arg[4] = INST_A(inst);
1156 count--;
1157 }
1158 for (i = 0; i < count; i++) {
1159 pDec->arg[i] = regList & 0x0f;
1160 regList >>= 4;
1161 }
1162 /* copy arg[0] to vC; we don't have vD/vE/vF, so ignore those */
1163 if (pDec->vA > 0)
1164 pDec->vC = pDec->arg[0];
1165 }
1166 break;
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001167 case kFmt3inline: // [opt] inline invoke
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001168 {
1169 u2 regList;
1170 int i;
1171
1172 pDec->vA = INST_B(inst);
1173 pDec->vB = FETCH(1);
1174 regList = FETCH(2);
1175
1176 if (pDec->vA > 4) {
1177 LOGW("Invalid arg count in 3inline (%d)\n", pDec->vA);
1178 goto bail;
1179 }
1180 for (i = 0; i < (int) pDec->vA; i++) {
1181 pDec->arg[i] = regList & 0x0f;
1182 regList >>= 4;
1183 }
1184 /* copy arg[0] to vC; we don't have vD/vE/vF, so ignore those */
1185 if (pDec->vA > 0)
1186 pDec->vC = pDec->arg[0];
1187 }
1188 break;
1189 case kFmt35fs: // [opt] invoke-interface
1190 assert(false); // TODO
1191 break;
1192 case kFmt3rc: // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
1193 case kFmt3rms: // [opt] invoke-virtual+super/range
1194 pDec->vA = INST_AA(inst);
1195 pDec->vB = FETCH(1);
1196 pDec->vC = FETCH(2);
1197 break;
1198 case kFmt3rfs: // [opt] invoke-interface/range
1199 assert(false); // TODO
1200 break;
1201 case kFmt51l: // op vAA, #+BBBBBBBBBBBBBBBB
1202 pDec->vA = INST_AA(inst);
1203 pDec->vB_wide = FETCH(1);
1204 pDec->vB_wide |= (u8)FETCH(2) << 16;
1205 pDec->vB_wide |= (u8)FETCH(3) << 32;
1206 pDec->vB_wide |= (u8)FETCH(4) << 48;
1207 break;
1208 default:
1209 LOGW("Can't decode unexpected format %d (op=%d)\n",
1210 dexGetInstrFormat(fmts, pDec->opCode), pDec->opCode);
1211 assert(false);
1212 break;
1213 }
1214
1215bail:
1216 ;
1217}
1218
1219/*
1220 * Return the width of the specified instruction, or 0 if not defined. Also
1221 * works for special OP_NOP entries, including switch statement data tables
1222 * and array data.
1223 */
1224int dexGetInstrOrTableWidthAbs(const InstructionWidth* widths, const u2* insns)
1225{
1226 int width;
1227
1228 if (*insns == kPackedSwitchSignature) {
1229 width = 4 + insns[1] * 2;
1230 } else if (*insns == kSparseSwitchSignature) {
1231 width = 2 + insns[1] * 4;
1232 } else if (*insns == kArrayDataSignature) {
1233 u2 elemWidth = insns[1];
1234 u4 len = insns[2] | (((u4)insns[3]) << 16);
1235 width = 4 + (elemWidth * len + 1) / 2;
1236 } else {
1237 width = dexGetInstrWidthAbs(widths, INST_INST(insns[0]));
1238 }
1239 return width;
1240}
Andy McFadden3a1aedb2009-05-07 13:30:23 -07001241