1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2010 Ben Gruver 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28parser grammar smaliParser; 29 30options { 31 output=AST; 32 ASTLabelType=CommonTree; 33} 34 35tokens { 36 //Lexer tokens 37 ACCESS_SPEC; 38 ANNOTATION_DIRECTIVE; 39 ANNOTATION_VISIBILITY; 40 ARRAY_DATA_DIRECTIVE; 41 ARRAY_TYPE_PREFIX; 42 ARROW; 43 AT; 44 BOOL_LITERAL; 45 BYTE_LITERAL; 46 CATCH_DIRECTIVE; 47 CATCHALL_DIRECTIVE; 48 CHAR_LITERAL; 49 CLASS_DESCRIPTOR; 50 CLASS_DIRECTIVE; 51 CLOSE_BRACE; 52 CLOSE_PAREN; 53 COLON; 54 COMMA; 55 DOTDOT; 56 DOUBLE_LITERAL; 57 DOUBLE_LITERAL_OR_ID; 58 END_ANNOTATION_DIRECTIVE; 59 END_ARRAY_DATA_DIRECTIVE; 60 END_FIELD_DIRECTIVE; 61 END_LOCAL_DIRECTIVE; 62 END_METHOD_DIRECTIVE; 63 END_PACKED_SWITCH_DIRECTIVE; 64 END_PARAMETER_DIRECTIVE; 65 END_SPARSE_SWITCH_DIRECTIVE; 66 END_SUBANNOTATION_DIRECTIVE; 67 ENUM_DIRECTIVE; 68 EPILOGUE_DIRECTIVE; 69 EQUAL; 70 FIELD_DIRECTIVE; 71 FIELD_OFFSET; 72 FLOAT_LITERAL; 73 FLOAT_LITERAL_OR_ID; 74 HIDDENAPI_RESTRICTION; 75 IMPLEMENTS_DIRECTIVE; 76 INLINE_INDEX; 77 INSTRUCTION_FORMAT10t; 78 INSTRUCTION_FORMAT10x; 79 INSTRUCTION_FORMAT10x_ODEX; 80 INSTRUCTION_FORMAT11n; 81 INSTRUCTION_FORMAT11x; 82 INSTRUCTION_FORMAT12x; 83 INSTRUCTION_FORMAT12x_OR_ID; 84 INSTRUCTION_FORMAT20bc; 85 INSTRUCTION_FORMAT20t; 86 INSTRUCTION_FORMAT21c_FIELD; 87 INSTRUCTION_FORMAT21c_FIELD_ODEX; 88 INSTRUCTION_FORMAT21c_STRING; 89 INSTRUCTION_FORMAT21c_TYPE; 90 INSTRUCTION_FORMAT21ih; 91 INSTRUCTION_FORMAT21lh; 92 INSTRUCTION_FORMAT21s; 93 INSTRUCTION_FORMAT21t; 94 INSTRUCTION_FORMAT22b; 95 INSTRUCTION_FORMAT22c_FIELD; 96 INSTRUCTION_FORMAT22c_FIELD_ODEX; 97 INSTRUCTION_FORMAT22c_TYPE; 98 INSTRUCTION_FORMAT22cs_FIELD; 99 INSTRUCTION_FORMAT22s; 100 INSTRUCTION_FORMAT22s_OR_ID; 101 INSTRUCTION_FORMAT22t; 102 INSTRUCTION_FORMAT22x; 103 INSTRUCTION_FORMAT23x; 104 INSTRUCTION_FORMAT30t; 105 INSTRUCTION_FORMAT31c; 106 INSTRUCTION_FORMAT31i; 107 INSTRUCTION_FORMAT31i_OR_ID; 108 INSTRUCTION_FORMAT31t; 109 INSTRUCTION_FORMAT32x; 110 INSTRUCTION_FORMAT35c_CALL_SITE; 111 INSTRUCTION_FORMAT35c_METHOD; 112 INSTRUCTION_FORMAT35c_METHOD_ODEX; 113 INSTRUCTION_FORMAT35c_METHOD_OR_METHOD_HANDLE_TYPE; 114 INSTRUCTION_FORMAT35c_TYPE; 115 INSTRUCTION_FORMAT35mi_METHOD; 116 INSTRUCTION_FORMAT35ms_METHOD; 117 INSTRUCTION_FORMAT3rc_CALL_SITE; 118 INSTRUCTION_FORMAT3rc_METHOD; 119 INSTRUCTION_FORMAT3rc_METHOD_ODEX; 120 INSTRUCTION_FORMAT3rc_TYPE; 121 INSTRUCTION_FORMAT3rmi_METHOD; 122 INSTRUCTION_FORMAT3rms_METHOD; 123 INSTRUCTION_FORMAT45cc_METHOD; 124 INSTRUCTION_FORMAT4rcc_METHOD; 125 INSTRUCTION_FORMAT51l; 126 LINE_COMMENT; 127 LINE_DIRECTIVE; 128 LOCAL_DIRECTIVE; 129 LOCALS_DIRECTIVE; 130 LONG_LITERAL; 131 METHOD_DIRECTIVE; 132 METHOD_HANDLE_TYPE_FIELD; 133 METHOD_HANDLE_TYPE_METHOD; 134 MEMBER_NAME; 135 NEGATIVE_INTEGER_LITERAL; 136 NULL_LITERAL; 137 OPEN_BRACE; 138 OPEN_PAREN; 139 PACKED_SWITCH_DIRECTIVE; 140 PARAM_LIST_OR_ID_PRIMITIVE_TYPE; 141 PARAMETER_DIRECTIVE; 142 POSITIVE_INTEGER_LITERAL; 143 PRIMITIVE_TYPE; 144 PROLOGUE_DIRECTIVE; 145 REGISTER; 146 REGISTERS_DIRECTIVE; 147 RESTART_LOCAL_DIRECTIVE; 148 SHORT_LITERAL; 149 SIMPLE_NAME; 150 SOURCE_DIRECTIVE; 151 SPARSE_SWITCH_DIRECTIVE; 152 STRING_LITERAL; 153 SUBANNOTATION_DIRECTIVE; 154 SUPER_DIRECTIVE; 155 VERIFICATION_ERROR_TYPE; 156 VOID_TYPE; 157 VTABLE_INDEX; 158 WHITE_SPACE; 159 160 // misc non-lexer tokens 161 INTEGER_LITERAL; 162 INVALID_TOKEN; 163 164 //I_* tokens are imaginary tokens used as parent AST nodes 165 I_CLASS_DEF; 166 I_SUPER; 167 I_IMPLEMENTS; 168 I_SOURCE; 169 I_ACCESS_LIST; 170 I_ACCESS_OR_RESTRICTION_LIST; 171 I_METHODS; 172 I_FIELDS; 173 I_FIELD; 174 I_FIELD_TYPE; 175 I_FIELD_INITIAL_VALUE; 176 I_METHOD; 177 I_METHOD_PROTOTYPE; 178 I_METHOD_RETURN_TYPE; 179 I_REGISTERS; 180 I_LOCALS; 181 I_LABEL; 182 I_ANNOTATIONS; 183 I_ANNOTATION; 184 I_ANNOTATION_ELEMENT; 185 I_SUBANNOTATION; 186 I_ENCODED_METHOD_HANDLE; 187 I_ENCODED_FIELD; 188 I_ENCODED_METHOD; 189 I_ENCODED_ENUM; 190 I_ENCODED_ARRAY; 191 I_ARRAY_ELEMENT_SIZE; 192 I_ARRAY_ELEMENTS; 193 I_PACKED_SWITCH_START_KEY; 194 I_PACKED_SWITCH_ELEMENTS; 195 I_SPARSE_SWITCH_ELEMENTS; 196 I_CATCH; 197 I_CATCHALL; 198 I_CATCHES; 199 I_PARAMETER; 200 I_PARAMETERS; 201 I_PARAMETER_NOT_SPECIFIED; 202 I_LINE; 203 I_LOCAL; 204 I_END_LOCAL; 205 I_RESTART_LOCAL; 206 I_PROLOGUE; 207 I_EPILOGUE; 208 I_ORDERED_METHOD_ITEMS; 209 I_STATEMENT_FORMAT10t; 210 I_STATEMENT_FORMAT10x; 211 I_STATEMENT_FORMAT11n; 212 I_STATEMENT_FORMAT11x; 213 I_STATEMENT_FORMAT12x; 214 I_STATEMENT_FORMAT20bc; 215 I_STATEMENT_FORMAT20t; 216 I_STATEMENT_FORMAT21c_TYPE; 217 I_STATEMENT_FORMAT21c_FIELD; 218 I_STATEMENT_FORMAT21c_STRING; 219 I_STATEMENT_FORMAT21c_METHOD_HANDLE; 220 I_STATEMENT_FORMAT21c_METHOD_TYPE; 221 I_STATEMENT_FORMAT21ih; 222 I_STATEMENT_FORMAT21lh; 223 I_STATEMENT_FORMAT21s; 224 I_STATEMENT_FORMAT21t; 225 I_STATEMENT_FORMAT22b; 226 I_STATEMENT_FORMAT22c_FIELD; 227 I_STATEMENT_FORMAT22c_TYPE; 228 I_STATEMENT_FORMAT22s; 229 I_STATEMENT_FORMAT22t; 230 I_STATEMENT_FORMAT22x; 231 I_STATEMENT_FORMAT23x; 232 I_STATEMENT_FORMAT30t; 233 I_STATEMENT_FORMAT31c; 234 I_STATEMENT_FORMAT31i; 235 I_STATEMENT_FORMAT31t; 236 I_STATEMENT_FORMAT32x; 237 I_STATEMENT_FORMAT35c_CALL_SITE; 238 I_STATEMENT_FORMAT35c_METHOD; 239 I_STATEMENT_FORMAT35c_TYPE; 240 I_STATEMENT_FORMAT3rc_CALL_SITE; 241 I_STATEMENT_FORMAT3rc_METHOD; 242 I_STATEMENT_FORMAT3rc_TYPE; 243 I_STATEMENT_FORMAT45cc_METHOD; 244 I_STATEMENT_FORMAT4rcc_METHOD; 245 I_STATEMENT_FORMAT51l; 246 I_STATEMENT_ARRAY_DATA; 247 I_STATEMENT_PACKED_SWITCH; 248 I_STATEMENT_SPARSE_SWITCH; 249 I_REGISTER_RANGE; 250 I_REGISTER_LIST; 251 I_CALL_SITE_EXTRA_ARGUMENTS; 252 I_CALL_SITE_REFERENCE; 253} 254 255@header { 256package com.android.tools.smali.smali; 257 258import com.android.tools.smali.dexlib2.Opcode; 259import com.android.tools.smali.dexlib2.Opcodes; 260} 261 262 263@members { 264 public static final int ERROR_CHANNEL = 100; 265 266 private boolean verboseErrors = false; 267 private boolean allowOdex = false; 268 private int apiLevel = 15; 269 private Opcodes opcodes = Opcodes.forApi(apiLevel); 270 271 public void setVerboseErrors(boolean verboseErrors) { 272 this.verboseErrors = verboseErrors; 273 } 274 275 public void setAllowOdex(boolean allowOdex) { 276 this.allowOdex = allowOdex; 277 } 278 279 public void setApiLevel(int apiLevel) { 280 this.opcodes = Opcodes.forApi(apiLevel); 281 this.apiLevel = apiLevel; 282 } 283 284 public String getErrorMessage(RecognitionException e, 285 String[] tokenNames) { 286 287 if (verboseErrors) { 288 List stack = getRuleInvocationStack(e, this.getClass().getName()); 289 String msg = null; 290 291 if (e instanceof NoViableAltException) { 292 NoViableAltException nvae = (NoViableAltException)e; 293 msg = " no viable alt; token="+getTokenErrorDisplay(e.token)+ 294 " (decision="+nvae.decisionNumber+ 295 " state "+nvae.stateNumber+")"+ 296 " decision=<<"+nvae.grammarDecisionDescription+">>"; 297 } else { 298 msg = super.getErrorMessage(e, tokenNames); 299 } 300 301 return stack + " " + msg; 302 } else { 303 return super.getErrorMessage(e, tokenNames); 304 } 305 } 306 307 public String getTokenErrorDisplay(Token t) { 308 if (!verboseErrors) { 309 String s = t.getText(); 310 if ( s==null ) { 311 if ( t.getType()==Token.EOF ) { 312 s = "<EOF>"; 313 } 314 else { 315 s = "<"+tokenNames[t.getType()]+">"; 316 } 317 } 318 s = s.replaceAll("\n","\\\\n"); 319 s = s.replaceAll("\r","\\\\r"); 320 s = s.replaceAll("\t","\\\\t"); 321 return "'"+s+"'"; 322 } 323 324 CommonToken ct = (CommonToken)t; 325 326 String channelStr = ""; 327 if (t.getChannel()>0) { 328 channelStr=",channel="+t.getChannel(); 329 } 330 String txt = t.getText(); 331 if ( txt!=null ) { 332 txt = txt.replaceAll("\n","\\\\n"); 333 txt = txt.replaceAll("\r","\\\\r"); 334 txt = txt.replaceAll("\t","\\\\t"); 335 } 336 else { 337 txt = "<no text>"; 338 } 339 return "[@"+t.getTokenIndex()+","+ct.getStartIndex()+":"+ct.getStopIndex()+"='"+txt+"',<"+tokenNames[t.getType()]+">"+channelStr+","+t.getLine()+":"+t.getCharPositionInLine()+"]"; 340 } 341 342 public String getErrorHeader(RecognitionException e) { 343 return getSourceName()+"["+ e.line+","+e.charPositionInLine+"]"; 344 } 345 346 private CommonTree buildTree(int type, String text, List<CommonTree> children) { 347 CommonTree root = new CommonTree(new CommonToken(type, text)); 348 for (CommonTree child: children) { 349 root.addChild(child); 350 } 351 return root; 352 } 353 354 private CommonToken getParamListSubToken(CommonToken baseToken, String str, int typeStartIndex) { 355 CommonToken token = new CommonToken(baseToken); 356 token.setStartIndex(baseToken.getStartIndex() + typeStartIndex); 357 358 switch (str.charAt(typeStartIndex)) { 359 case 'Z': 360 case 'B': 361 case 'S': 362 case 'C': 363 case 'I': 364 case 'J': 365 case 'F': 366 case 'D': 367 { 368 token.setType(PRIMITIVE_TYPE); 369 token.setText(str.substring(typeStartIndex, typeStartIndex+1)); 370 token.setStopIndex(baseToken.getStartIndex() + typeStartIndex); 371 break; 372 } 373 case 'L': 374 { 375 int i = typeStartIndex; 376 while (str.charAt(++i) != ';'); 377 378 token.setType(CLASS_DESCRIPTOR); 379 token.setText(str.substring(typeStartIndex, i + 1)); 380 token.setStopIndex(baseToken.getStartIndex() + i); 381 break; 382 } 383 case '[': 384 { 385 int i = typeStartIndex; 386 while (str.charAt(++i) == '['); 387 388 token.setType(ARRAY_TYPE_PREFIX); 389 token.setText(str.substring(typeStartIndex, i)); 390 token.setStopIndex(baseToken.getStartIndex() + i - 1); 391 break; 392 } 393 default: 394 throw new RuntimeException(String.format("Invalid character '\%c' in param list \"\%s\" at position \%d", str.charAt(typeStartIndex), str, typeStartIndex)); 395 } 396 397 return token; 398 } 399 400 private CommonTree parseParamList(CommonToken paramListToken) { 401 String paramList = paramListToken.getText(); 402 CommonTree root = new CommonTree(); 403 404 int startIndex = paramListToken.getStartIndex(); 405 406 int i=0; 407 while (i<paramList.length()) { 408 CommonToken token = getParamListSubToken(paramListToken, paramList, i); 409 root.addChild(new CommonTree(token)); 410 i += token.getText().length(); 411 } 412 413 if (root.getChildCount() == 0) { 414 return null; 415 } 416 return root; 417 } 418 419 private void throwOdexedInstructionException(IntStream input, String odexedInstruction) 420 throws OdexedInstructionException { 421 /*this has to be done in a separate method, otherwise java will complain about the 422 auto-generated code in the rule after the throw not being reachable*/ 423 throw new OdexedInstructionException(input, odexedInstruction); 424 } 425} 426 427 428smali_file 429 scope 430 { 431 boolean hasClassSpec; 432 boolean hasSuperSpec; 433 boolean hasSourceSpec; 434 List<CommonTree> classAnnotations; 435 } 436 @init 437 { $smali_file::hasClassSpec = $smali_file::hasSuperSpec = $smali_file::hasSourceSpec = false; 438 $smali_file::classAnnotations = new ArrayList<CommonTree>(); 439 } 440 : 441 ( {!$smali_file::hasClassSpec}?=> class_spec {$smali_file::hasClassSpec = true;} 442 | {!$smali_file::hasSuperSpec}?=> super_spec {$smali_file::hasSuperSpec = true;} 443 | implements_spec 444 | {!$smali_file::hasSourceSpec}?=> source_spec {$smali_file::hasSourceSpec = true;} 445 | method 446 | field 447 | annotation {$smali_file::classAnnotations.add($annotation.tree);} 448 )+ 449 EOF 450 { 451 if (!$smali_file::hasClassSpec) { 452 throw new SemanticException(input, "The file must contain a .class directive"); 453 } 454 455 if (!$smali_file::hasSuperSpec) { 456 if (!$class_spec.className.equals("Ljava/lang/Object;")) { 457 throw new SemanticException(input, "The file must contain a .super directive"); 458 } 459 } 460 } 461 -> ^(I_CLASS_DEF 462 class_spec 463 super_spec? 464 implements_spec* 465 source_spec? 466 ^(I_METHODS method*) ^(I_FIELDS field*) {buildTree(I_ANNOTATIONS, "I_ANNOTATIONS", $smali_file::classAnnotations)}); 467 468class_spec returns[String className] 469 : CLASS_DIRECTIVE access_list CLASS_DESCRIPTOR {$className = $CLASS_DESCRIPTOR.text;} -> CLASS_DESCRIPTOR access_list; 470 471super_spec 472 : SUPER_DIRECTIVE CLASS_DESCRIPTOR -> ^(I_SUPER[$start, "I_SUPER"] CLASS_DESCRIPTOR); 473 474implements_spec 475 : IMPLEMENTS_DIRECTIVE CLASS_DESCRIPTOR -> ^(I_IMPLEMENTS[$start, "I_IMPLEMENTS"] CLASS_DESCRIPTOR); 476 477source_spec 478 : SOURCE_DIRECTIVE STRING_LITERAL -> ^(I_SOURCE[$start, "I_SOURCE"] STRING_LITERAL); 479 480access_list 481 : ACCESS_SPEC* -> ^(I_ACCESS_LIST[$start,"I_ACCESS_LIST"] ACCESS_SPEC*); 482 483access_or_restriction 484 : ACCESS_SPEC | HIDDENAPI_RESTRICTION; 485 486access_or_restriction_list 487 : access_or_restriction* 488 -> ^(I_ACCESS_OR_RESTRICTION_LIST[$start,"I_ACCESS_AND_RESTRICTION_LIST"] access_or_restriction*); 489 490 491/*When there are annotations immediately after a field definition, we don't know whether they are field annotations 492or class annotations until we determine if there is an .end field directive. In either case, we still "consume" and parse 493the annotations. If it turns out that they are field annotations, we include them in the I_FIELD AST. Otherwise, we 494add them to the $smali_file::classAnnotations list*/ 495field 496 @init {List<CommonTree> annotations = new ArrayList<CommonTree>();} 497 : FIELD_DIRECTIVE access_or_restriction_list member_name COLON nonvoid_type_descriptor (EQUAL literal)? 498 ( ({input.LA(1) == ANNOTATION_DIRECTIVE}? annotation {annotations.add($annotation.tree);})* 499 ( END_FIELD_DIRECTIVE 500 -> ^(I_FIELD[$start, "I_FIELD"] member_name access_or_restriction_list ^(I_FIELD_TYPE nonvoid_type_descriptor) ^(I_FIELD_INITIAL_VALUE literal)? ^(I_ANNOTATIONS annotation*)) 501 | /*epsilon*/ {$smali_file::classAnnotations.addAll(annotations);} 502 -> ^(I_FIELD[$start, "I_FIELD"] member_name access_or_restriction_list ^(I_FIELD_TYPE nonvoid_type_descriptor) ^(I_FIELD_INITIAL_VALUE literal)? ^(I_ANNOTATIONS)) 503 ) 504 ); 505 506method 507 : METHOD_DIRECTIVE access_or_restriction_list member_name method_prototype statements_and_directives 508 END_METHOD_DIRECTIVE 509 -> ^(I_METHOD[$start, "I_METHOD"] member_name method_prototype access_or_restriction_list statements_and_directives); 510 511statements_and_directives 512 scope 513 { 514 boolean hasRegistersDirective; 515 List<CommonTree> methodAnnotations; 516 } 517 : { 518 $statements_and_directives::hasRegistersDirective = false; 519 $statements_and_directives::methodAnnotations = new ArrayList<CommonTree>(); 520 } 521 ( ordered_method_item 522 | registers_directive 523 | catch_directive 524 | catchall_directive 525 | parameter_directive 526 | annotation {$statements_and_directives::methodAnnotations.add($annotation.tree);} 527 )* 528 -> registers_directive? 529 ^(I_ORDERED_METHOD_ITEMS ordered_method_item*) 530 ^(I_CATCHES catch_directive* catchall_directive*) 531 ^(I_PARAMETERS parameter_directive*) 532 {buildTree(I_ANNOTATIONS, "I_ANNOTATIONS", $statements_and_directives::methodAnnotations)}; 533 534/* Method items whose order/location is important */ 535ordered_method_item 536 : label 537 | instruction 538 | debug_directive; 539 540registers_directive 541 : ( 542 directive=REGISTERS_DIRECTIVE regCount=integral_literal -> ^(I_REGISTERS[$REGISTERS_DIRECTIVE, "I_REGISTERS"] $regCount) 543 | directive=LOCALS_DIRECTIVE regCount2=integral_literal -> ^(I_LOCALS[$LOCALS_DIRECTIVE, "I_LOCALS"] $regCount2) 544 ) 545 { 546 if ($statements_and_directives::hasRegistersDirective) { 547 throw new SemanticException(input, $directive, "There can only be a single .registers or .locals directive in a method"); 548 } 549 $statements_and_directives::hasRegistersDirective=true; 550 }; 551 552param_list_or_id 553 : PARAM_LIST_OR_ID_PRIMITIVE_TYPE+; 554 555/*identifiers are much more general than most languages. Any of the below can either be 556the indicated type OR an identifier, depending on the context*/ 557simple_name 558 : SIMPLE_NAME 559 | ACCESS_SPEC -> SIMPLE_NAME[$ACCESS_SPEC] 560 | HIDDENAPI_RESTRICTION -> SIMPLE_NAME[$HIDDENAPI_RESTRICTION] 561 | VERIFICATION_ERROR_TYPE -> SIMPLE_NAME[$VERIFICATION_ERROR_TYPE] 562 | POSITIVE_INTEGER_LITERAL -> SIMPLE_NAME[$POSITIVE_INTEGER_LITERAL] 563 | NEGATIVE_INTEGER_LITERAL -> SIMPLE_NAME[$NEGATIVE_INTEGER_LITERAL] 564 | FLOAT_LITERAL_OR_ID -> SIMPLE_NAME[$FLOAT_LITERAL_OR_ID] 565 | DOUBLE_LITERAL_OR_ID -> SIMPLE_NAME[$DOUBLE_LITERAL_OR_ID] 566 | BOOL_LITERAL -> SIMPLE_NAME[$BOOL_LITERAL] 567 | NULL_LITERAL -> SIMPLE_NAME[$NULL_LITERAL] 568 | REGISTER -> SIMPLE_NAME[$REGISTER] 569 | param_list_or_id -> { adaptor.create(SIMPLE_NAME, $param_list_or_id.text) } 570 | PRIMITIVE_TYPE -> SIMPLE_NAME[$PRIMITIVE_TYPE] 571 | VOID_TYPE -> SIMPLE_NAME[$VOID_TYPE] 572 | ANNOTATION_VISIBILITY -> SIMPLE_NAME[$ANNOTATION_VISIBILITY] 573 | METHOD_HANDLE_TYPE_FIELD 574 | METHOD_HANDLE_TYPE_METHOD 575 | INSTRUCTION_FORMAT10t -> SIMPLE_NAME[$INSTRUCTION_FORMAT10t] 576 | INSTRUCTION_FORMAT10x -> SIMPLE_NAME[$INSTRUCTION_FORMAT10x] 577 | INSTRUCTION_FORMAT10x_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT10x_ODEX] 578 | INSTRUCTION_FORMAT11x -> SIMPLE_NAME[$INSTRUCTION_FORMAT11x] 579 | INSTRUCTION_FORMAT12x_OR_ID -> SIMPLE_NAME[$INSTRUCTION_FORMAT12x_OR_ID] 580 | INSTRUCTION_FORMAT21c_FIELD -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_FIELD] 581 | INSTRUCTION_FORMAT21c_FIELD_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_FIELD_ODEX] 582 | INSTRUCTION_FORMAT21c_METHOD_HANDLE -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_METHOD_HANDLE] 583 | INSTRUCTION_FORMAT21c_METHOD_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_METHOD_TYPE] 584 | INSTRUCTION_FORMAT21c_STRING -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_STRING] 585 | INSTRUCTION_FORMAT21c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_TYPE] 586 | INSTRUCTION_FORMAT21t -> SIMPLE_NAME[$INSTRUCTION_FORMAT21t] 587 | INSTRUCTION_FORMAT22c_FIELD -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_FIELD] 588 | INSTRUCTION_FORMAT22c_FIELD_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_FIELD_ODEX] 589 | INSTRUCTION_FORMAT22c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_TYPE] 590 | INSTRUCTION_FORMAT22cs_FIELD -> SIMPLE_NAME[$INSTRUCTION_FORMAT22cs_FIELD] 591 | INSTRUCTION_FORMAT22s_OR_ID -> SIMPLE_NAME[$INSTRUCTION_FORMAT22s_OR_ID] 592 | INSTRUCTION_FORMAT22t -> SIMPLE_NAME[$INSTRUCTION_FORMAT22t] 593 | INSTRUCTION_FORMAT23x -> SIMPLE_NAME[$INSTRUCTION_FORMAT23x] 594 | INSTRUCTION_FORMAT31i_OR_ID -> SIMPLE_NAME[$INSTRUCTION_FORMAT31i_OR_ID] 595 | INSTRUCTION_FORMAT31t -> SIMPLE_NAME[$INSTRUCTION_FORMAT31t] 596 | INSTRUCTION_FORMAT35c_CALL_SITE -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_CALL_SITE] 597 | INSTRUCTION_FORMAT35c_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_METHOD] 598 | INSTRUCTION_FORMAT35c_METHOD_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_METHOD_ODEX] 599 | INSTRUCTION_FORMAT35c_METHOD_OR_METHOD_HANDLE_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_METHOD_OR_METHOD_HANDLE_TYPE] 600 | INSTRUCTION_FORMAT35c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_TYPE] 601 | INSTRUCTION_FORMAT35mi_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35mi_METHOD] 602 | INSTRUCTION_FORMAT35ms_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35ms_METHOD] 603 | INSTRUCTION_FORMAT45cc_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT45cc_METHOD] 604 | INSTRUCTION_FORMAT4rcc_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT4rcc_METHOD] 605 | INSTRUCTION_FORMAT51l -> SIMPLE_NAME[$INSTRUCTION_FORMAT51l]; 606 607member_name 608 : simple_name 609 | MEMBER_NAME -> SIMPLE_NAME[$MEMBER_NAME]; 610 611method_prototype 612 : OPEN_PAREN param_list CLOSE_PAREN type_descriptor 613 -> ^(I_METHOD_PROTOTYPE[$start, "I_METHOD_PROTOTYPE"] ^(I_METHOD_RETURN_TYPE type_descriptor) param_list?); 614 615param_list_or_id_primitive_type 616 : PARAM_LIST_OR_ID_PRIMITIVE_TYPE -> PRIMITIVE_TYPE[$PARAM_LIST_OR_ID_PRIMITIVE_TYPE]; 617 618param_list 619 : param_list_or_id_primitive_type+ 620 | nonvoid_type_descriptor*; 621 622array_descriptor 623 : ARRAY_TYPE_PREFIX (PRIMITIVE_TYPE | CLASS_DESCRIPTOR); 624 625type_descriptor 626 : VOID_TYPE 627 | PRIMITIVE_TYPE 628 | CLASS_DESCRIPTOR 629 | array_descriptor; 630 631nonvoid_type_descriptor 632 : PRIMITIVE_TYPE 633 | CLASS_DESCRIPTOR 634 | array_descriptor; 635 636reference_type_descriptor 637 : CLASS_DESCRIPTOR 638 | array_descriptor; 639 640integer_literal 641 : POSITIVE_INTEGER_LITERAL -> INTEGER_LITERAL[$POSITIVE_INTEGER_LITERAL] 642 | NEGATIVE_INTEGER_LITERAL -> INTEGER_LITERAL[$NEGATIVE_INTEGER_LITERAL]; 643 644float_literal 645 : FLOAT_LITERAL_OR_ID -> FLOAT_LITERAL[$FLOAT_LITERAL_OR_ID] 646 | FLOAT_LITERAL; 647 648double_literal 649 : DOUBLE_LITERAL_OR_ID -> DOUBLE_LITERAL[$DOUBLE_LITERAL_OR_ID] 650 | DOUBLE_LITERAL; 651 652literal 653 : LONG_LITERAL 654 | integer_literal 655 | SHORT_LITERAL 656 | BYTE_LITERAL 657 | float_literal 658 | double_literal 659 | CHAR_LITERAL 660 | STRING_LITERAL 661 | BOOL_LITERAL 662 | NULL_LITERAL 663 | array_literal 664 | subannotation 665 | type_field_method_literal 666 | enum_literal 667 | method_handle_literal 668 | method_prototype; 669 670parsed_integer_literal returns[int value] 671 : integer_literal { $value = LiteralTools.parseInt($integer_literal.text); }; 672 673integral_literal 674 : LONG_LITERAL 675 | integer_literal 676 | SHORT_LITERAL 677 | CHAR_LITERAL 678 | BYTE_LITERAL; 679 680fixed_32bit_literal 681 : LONG_LITERAL 682 | integer_literal 683 | SHORT_LITERAL 684 | BYTE_LITERAL 685 | float_literal 686 | CHAR_LITERAL 687 | BOOL_LITERAL; 688 689fixed_literal 690 : integer_literal 691 | LONG_LITERAL 692 | SHORT_LITERAL 693 | BYTE_LITERAL 694 | float_literal 695 | double_literal 696 | CHAR_LITERAL 697 | BOOL_LITERAL; 698 699array_literal 700 : OPEN_BRACE (literal (COMMA literal)* | ) CLOSE_BRACE 701 -> ^(I_ENCODED_ARRAY[$start, "I_ENCODED_ARRAY"] literal*); 702 703annotation_element 704 : simple_name EQUAL literal 705 -> ^(I_ANNOTATION_ELEMENT[$start, "I_ANNOTATION_ELEMENT"] simple_name literal); 706 707annotation 708 : ANNOTATION_DIRECTIVE ANNOTATION_VISIBILITY CLASS_DESCRIPTOR 709 annotation_element* END_ANNOTATION_DIRECTIVE 710 -> ^(I_ANNOTATION[$start, "I_ANNOTATION"] ANNOTATION_VISIBILITY ^(I_SUBANNOTATION[$start, "I_SUBANNOTATION"] CLASS_DESCRIPTOR annotation_element*)); 711 712subannotation 713 : SUBANNOTATION_DIRECTIVE CLASS_DESCRIPTOR annotation_element* END_SUBANNOTATION_DIRECTIVE 714 -> ^(I_SUBANNOTATION[$start, "I_SUBANNOTATION"] CLASS_DESCRIPTOR annotation_element*); 715 716// TODO: how does dalvik handle a primitive or array type, or a non-enum type? 717enum_literal 718 : ENUM_DIRECTIVE field_reference 719 -> ^(I_ENCODED_ENUM field_reference); 720 721type_field_method_literal 722 : reference_type_descriptor 723 | ( (reference_type_descriptor ARROW)? 724 ( member_name COLON nonvoid_type_descriptor -> ^(I_ENCODED_FIELD reference_type_descriptor? member_name nonvoid_type_descriptor) 725 | member_name method_prototype -> ^(I_ENCODED_METHOD reference_type_descriptor? member_name method_prototype) 726 ) 727 ) 728 | PRIMITIVE_TYPE 729 | VOID_TYPE; 730 731call_site_reference 732 : simple_name OPEN_PAREN STRING_LITERAL COMMA method_prototype (COMMA literal)* CLOSE_PAREN AT method_reference 733 -> ^(I_CALL_SITE_REFERENCE simple_name STRING_LITERAL method_prototype ^(I_CALL_SITE_EXTRA_ARGUMENTS literal*) 734 method_reference); 735 736method_handle_reference 737 : METHOD_HANDLE_TYPE_FIELD AT field_reference -> METHOD_HANDLE_TYPE_FIELD field_reference 738 | METHOD_HANDLE_TYPE_METHOD AT method_reference -> METHOD_HANDLE_TYPE_METHOD method_reference 739 | INSTRUCTION_FORMAT35c_METHOD_OR_METHOD_HANDLE_TYPE AT method_reference -> INSTRUCTION_FORMAT35c_METHOD_OR_METHOD_HANDLE_TYPE method_reference; 740 741method_handle_literal 742 : method_handle_reference 743 -> ^(I_ENCODED_METHOD_HANDLE method_handle_reference); 744 745method_reference 746 : (reference_type_descriptor ARROW)? member_name method_prototype 747 -> reference_type_descriptor? member_name method_prototype; 748 749field_reference 750 : (reference_type_descriptor ARROW)? member_name COLON nonvoid_type_descriptor 751 -> reference_type_descriptor? member_name nonvoid_type_descriptor; 752 753label 754 : COLON simple_name -> ^(I_LABEL[$COLON, "I_LABEL"] simple_name); 755 756label_ref 757 : COLON simple_name -> simple_name; 758 759register_list 760 : REGISTER (COMMA REGISTER)* -> ^(I_REGISTER_LIST[$start, "I_REGISTER_LIST"] REGISTER*) 761 | ->^(I_REGISTER_LIST[$start, "I_REGISTER_LIST"]); 762 763register_range 764 : (startreg=REGISTER (DOTDOT endreg=REGISTER)?)? -> ^(I_REGISTER_RANGE[$start, "I_REGISTER_RANGE"] $startreg? $endreg?); 765 766verification_error_reference 767 : CLASS_DESCRIPTOR | field_reference | method_reference; 768 769catch_directive 770 : CATCH_DIRECTIVE nonvoid_type_descriptor OPEN_BRACE from=label_ref DOTDOT to=label_ref CLOSE_BRACE using=label_ref 771 -> ^(I_CATCH[$start, "I_CATCH"] nonvoid_type_descriptor $from $to $using); 772 773catchall_directive 774 : CATCHALL_DIRECTIVE OPEN_BRACE from=label_ref DOTDOT to=label_ref CLOSE_BRACE using=label_ref 775 -> ^(I_CATCHALL[$start, "I_CATCHALL"] $from $to $using); 776 777/*When there are annotations immediately after a parameter definition, we don't know whether they are parameter annotations 778or method annotations until we determine if there is an .end parameter directive. In either case, we still "consume" and parse 779the annotations. If it turns out that they are parameter annotations, we include them in the I_PARAMETER AST. Otherwise, we 780add them to the $statements_and_directives::methodAnnotations list*/ 781parameter_directive 782 @init {List<CommonTree> annotations = new ArrayList<CommonTree>();} 783 : PARAMETER_DIRECTIVE REGISTER (COMMA STRING_LITERAL)? 784 ({input.LA(1) == ANNOTATION_DIRECTIVE}? annotation {annotations.add($annotation.tree);})* 785 786 ( END_PARAMETER_DIRECTIVE 787 -> ^(I_PARAMETER[$start, "I_PARAMETER"] REGISTER STRING_LITERAL? ^(I_ANNOTATIONS annotation*)) 788 | /*epsilon*/ {$statements_and_directives::methodAnnotations.addAll(annotations);} 789 -> ^(I_PARAMETER[$start, "I_PARAMETER"] REGISTER STRING_LITERAL? ^(I_ANNOTATIONS)) 790 ); 791 792debug_directive 793 : line_directive 794 | local_directive 795 | end_local_directive 796 | restart_local_directive 797 | prologue_directive 798 | epilogue_directive 799 | source_directive; 800 801line_directive 802 : LINE_DIRECTIVE integral_literal 803 -> ^(I_LINE[$start, "I_LINE"] integral_literal); 804 805local_directive 806 : LOCAL_DIRECTIVE REGISTER (COMMA (NULL_LITERAL | name=STRING_LITERAL) COLON (VOID_TYPE | nonvoid_type_descriptor) 807 (COMMA signature=STRING_LITERAL)? )? 808 -> ^(I_LOCAL[$start, "I_LOCAL"] REGISTER NULL_LITERAL? $name? nonvoid_type_descriptor? $signature?); 809 810end_local_directive 811 : END_LOCAL_DIRECTIVE REGISTER 812 -> ^(I_END_LOCAL[$start, "I_END_LOCAL"] REGISTER); 813 814restart_local_directive 815 : RESTART_LOCAL_DIRECTIVE REGISTER 816 -> ^(I_RESTART_LOCAL[$start, "I_RESTART_LOCAL"] REGISTER); 817 818prologue_directive 819 : PROLOGUE_DIRECTIVE 820 -> ^(I_PROLOGUE[$start, "I_PROLOGUE"]); 821 822epilogue_directive 823 : EPILOGUE_DIRECTIVE 824 -> ^(I_EPILOGUE[$start, "I_EPILOGUE"]); 825 826source_directive 827 : SOURCE_DIRECTIVE STRING_LITERAL? 828 -> ^(I_SOURCE[$start, "I_SOURCE"] STRING_LITERAL?); 829 830instruction_format12x 831 : INSTRUCTION_FORMAT12x 832 | INSTRUCTION_FORMAT12x_OR_ID -> INSTRUCTION_FORMAT12x[$INSTRUCTION_FORMAT12x_OR_ID]; 833 834instruction_format22s 835 : INSTRUCTION_FORMAT22s 836 | INSTRUCTION_FORMAT22s_OR_ID -> INSTRUCTION_FORMAT22s[$INSTRUCTION_FORMAT22s_OR_ID]; 837 838instruction_format31i 839 : INSTRUCTION_FORMAT31i 840 | INSTRUCTION_FORMAT31i_OR_ID -> INSTRUCTION_FORMAT31i[$INSTRUCTION_FORMAT31i_OR_ID]; 841 842instruction_format35c_method 843 : INSTRUCTION_FORMAT35c_METHOD 844 | INSTRUCTION_FORMAT35c_METHOD_OR_METHOD_HANDLE_TYPE -> INSTRUCTION_FORMAT35c_METHOD[$INSTRUCTION_FORMAT35c_METHOD_OR_METHOD_HANDLE_TYPE]; 845 846instruction 847 : insn_format10t 848 | insn_format10x 849 | insn_format10x_odex 850 | insn_format11n 851 | insn_format11x 852 | insn_format12x 853 | insn_format20bc 854 | insn_format20t 855 | insn_format21c_field 856 | insn_format21c_field_odex 857 | insn_format21c_method_handle 858 | insn_format21c_method_type 859 | insn_format21c_string 860 | insn_format21c_type 861 | insn_format21ih 862 | insn_format21lh 863 | insn_format21s 864 | insn_format21t 865 | insn_format22b 866 | insn_format22c_field 867 | insn_format22c_field_odex 868 | insn_format22c_type 869 | insn_format22cs_field 870 | insn_format22s 871 | insn_format22t 872 | insn_format22x 873 | insn_format23x 874 | insn_format30t 875 | insn_format31c 876 | insn_format31i 877 | insn_format31t 878 | insn_format32x 879 | insn_format35c_call_site 880 | insn_format35c_method 881 | insn_format35c_type 882 | insn_format35c_method_odex 883 | insn_format35mi_method 884 | insn_format35ms_method 885 | insn_format3rc_call_site 886 | insn_format3rc_method 887 | insn_format3rc_method_odex 888 | insn_format3rc_type 889 | insn_format3rmi_method 890 | insn_format3rms_method 891 | insn_format45cc_method 892 | insn_format4rcc_method 893 | insn_format51l 894 | insn_array_data_directive 895 | insn_packed_switch_directive 896 | insn_sparse_switch_directive; 897 898insn_format10t 899 : //e.g. goto endloop: 900 //e.g. goto +3 901 INSTRUCTION_FORMAT10t label_ref 902 -> ^(I_STATEMENT_FORMAT10t[$start, "I_STATEMENT_FORMAT10t"] INSTRUCTION_FORMAT10t label_ref); 903 904insn_format10x 905 : //e.g. return-void 906 INSTRUCTION_FORMAT10x 907 -> ^(I_STATEMENT_FORMAT10x[$start, "I_STATEMENT_FORMAT10x"] INSTRUCTION_FORMAT10x); 908 909insn_format10x_odex 910 : //e.g. return-void-barrier 911 INSTRUCTION_FORMAT10x_ODEX 912 { 913 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT10x_ODEX.text); 914 }; 915 916insn_format11n 917 : //e.g. const/4 v0, 5 918 INSTRUCTION_FORMAT11n REGISTER COMMA integral_literal 919 -> ^(I_STATEMENT_FORMAT11n[$start, "I_STATEMENT_FORMAT11n"] INSTRUCTION_FORMAT11n REGISTER integral_literal); 920 921insn_format11x 922 : //e.g. move-result-object v1 923 INSTRUCTION_FORMAT11x REGISTER 924 -> ^(I_STATEMENT_FORMAT11x[$start, "I_STATEMENT_FORMAT11x"] INSTRUCTION_FORMAT11x REGISTER); 925 926insn_format12x 927 : //e.g. move v1 v2 928 instruction_format12x REGISTER COMMA REGISTER 929 -> ^(I_STATEMENT_FORMAT12x[$start, "I_STATEMENT_FORMAT12x"] instruction_format12x REGISTER REGISTER); 930 931insn_format20bc 932 : //e.g. throw-verification-error generic-error, Lsome/class; 933 INSTRUCTION_FORMAT20bc VERIFICATION_ERROR_TYPE COMMA verification_error_reference 934 { 935 if (!allowOdex || opcodes.getOpcodeByName($INSTRUCTION_FORMAT20bc.text) == null || apiLevel >= 14) { 936 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT20bc.text); 937 } 938 } 939 -> ^(I_STATEMENT_FORMAT20bc INSTRUCTION_FORMAT20bc VERIFICATION_ERROR_TYPE verification_error_reference); 940 941insn_format20t 942 : //e.g. goto/16 endloop: 943 INSTRUCTION_FORMAT20t label_ref 944 -> ^(I_STATEMENT_FORMAT20t[$start, "I_STATEMENT_FORMAT20t"] INSTRUCTION_FORMAT20t label_ref); 945 946insn_format21c_field 947 : //e.g. sget-object v0, java/lang/System/out LJava/io/PrintStream; 948 INSTRUCTION_FORMAT21c_FIELD REGISTER COMMA field_reference 949 -> ^(I_STATEMENT_FORMAT21c_FIELD[$start, "I_STATEMENT_FORMAT21c_FIELD"] INSTRUCTION_FORMAT21c_FIELD REGISTER field_reference); 950 951insn_format21c_field_odex 952 : //e.g. sget-object-volatile v0, java/lang/System/out LJava/io/PrintStream; 953 INSTRUCTION_FORMAT21c_FIELD_ODEX REGISTER COMMA field_reference 954 { 955 if (!allowOdex || opcodes.getOpcodeByName($INSTRUCTION_FORMAT21c_FIELD_ODEX.text) == null || apiLevel >= 14) { 956 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT21c_FIELD_ODEX.text); 957 } 958 } 959 -> ^(I_STATEMENT_FORMAT21c_FIELD[$start, "I_STATEMENT_FORMAT21c_FIELD"] INSTRUCTION_FORMAT21c_FIELD_ODEX REGISTER field_reference); 960 961insn_format21c_method_handle 962 : //e.g. const-method-handle v0, invoke-static@Ljava/lang/Integer;->toString(I)Ljava/lang/String; 963 INSTRUCTION_FORMAT21c_METHOD_HANDLE REGISTER COMMA method_handle_reference 964 -> ^(I_STATEMENT_FORMAT21c_METHOD_HANDLE[$start, "I_STATEMENT_FORMAT21c_METHOD_HANDLE"] 965 INSTRUCTION_FORMAT21c_METHOD_HANDLE REGISTER method_handle_reference); 966 967insn_format21c_method_type 968 : //e.g. const-method-type v0, (ILjava/lang/String;)Ljava/lang/String; 969 INSTRUCTION_FORMAT21c_METHOD_TYPE REGISTER COMMA method_prototype 970 -> ^(I_STATEMENT_FORMAT21c_METHOD_TYPE[$start, "I_STATEMENT_FORMAT21c_METHOD_TYPE"] 971 INSTRUCTION_FORMAT21c_METHOD_TYPE REGISTER method_prototype); 972 973insn_format21c_string 974 : //e.g. const-string v1, "Hello World!" 975 INSTRUCTION_FORMAT21c_STRING REGISTER COMMA STRING_LITERAL 976 -> ^(I_STATEMENT_FORMAT21c_STRING[$start, "I_STATEMENT_FORMAT21c_STRING"] INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL); 977 978insn_format21c_type 979 : //e.g. const-class v2, Lcom/android/tools/smali/HelloWorld2/HelloWorld2; 980 INSTRUCTION_FORMAT21c_TYPE REGISTER COMMA nonvoid_type_descriptor 981 -> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER nonvoid_type_descriptor); 982 983insn_format21ih 984 : //e.g. const/high16 v1, 1234 985 INSTRUCTION_FORMAT21ih REGISTER COMMA fixed_32bit_literal 986 -> ^(I_STATEMENT_FORMAT21ih[$start, "I_STATEMENT_FORMAT21ih"] INSTRUCTION_FORMAT21ih REGISTER fixed_32bit_literal); 987 988insn_format21lh 989 : //e.g. const-wide/high16 v1, 1234 990 INSTRUCTION_FORMAT21lh REGISTER COMMA fixed_32bit_literal 991 -> ^(I_STATEMENT_FORMAT21lh[$start, "I_STATEMENT_FORMAT21lh"] INSTRUCTION_FORMAT21lh REGISTER fixed_32bit_literal); 992 993insn_format21s 994 : //e.g. const/16 v1, 1234 995 INSTRUCTION_FORMAT21s REGISTER COMMA integral_literal 996 -> ^(I_STATEMENT_FORMAT21s[$start, "I_STATEMENT_FORMAT21s"] INSTRUCTION_FORMAT21s REGISTER integral_literal); 997 998insn_format21t 999 : //e.g. if-eqz v0, endloop: 1000 INSTRUCTION_FORMAT21t REGISTER COMMA label_ref 1001 -> ^(I_STATEMENT_FORMAT21t[$start, "I_STATEMENT_FORMAT21t"] INSTRUCTION_FORMAT21t REGISTER label_ref); 1002 1003insn_format22b 1004 : //e.g. add-int v0, v1, 123 1005 INSTRUCTION_FORMAT22b REGISTER COMMA REGISTER COMMA integral_literal 1006 -> ^(I_STATEMENT_FORMAT22b[$start, "I_STATEMENT_FORMAT22b"] INSTRUCTION_FORMAT22b REGISTER REGISTER integral_literal); 1007 1008insn_format22c_field 1009 : //e.g. iput-object v1, v0 com/android/tools/smali/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; 1010 INSTRUCTION_FORMAT22c_FIELD REGISTER COMMA REGISTER COMMA field_reference 1011 -> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_STATEMENT_FORMAT22c_FIELD"] INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER field_reference); 1012 1013insn_format22c_field_odex 1014 : //e.g. iput-object-volatile v1, v0 com/android/tools/smali/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; 1015 INSTRUCTION_FORMAT22c_FIELD_ODEX REGISTER COMMA REGISTER COMMA field_reference 1016 { 1017 if (!allowOdex || opcodes.getOpcodeByName($INSTRUCTION_FORMAT22c_FIELD_ODEX.text) == null || apiLevel >= 14) { 1018 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT22c_FIELD_ODEX.text); 1019 } 1020 } 1021 -> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_STATEMENT_FORMAT22c_FIELD"] INSTRUCTION_FORMAT22c_FIELD_ODEX REGISTER REGISTER field_reference); 1022 1023insn_format22c_type 1024 : //e.g. instance-of v0, v1, Ljava/lang/String; 1025 INSTRUCTION_FORMAT22c_TYPE REGISTER COMMA REGISTER COMMA nonvoid_type_descriptor 1026 -> ^(I_STATEMENT_FORMAT22c_TYPE[$start, "I_STATEMENT_FORMAT22c_TYPE"] INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor); 1027 1028insn_format22cs_field 1029 : //e.g. iget-quick v0, v1, field@0xc 1030 INSTRUCTION_FORMAT22cs_FIELD REGISTER COMMA REGISTER COMMA FIELD_OFFSET 1031 { 1032 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT22cs_FIELD.text); 1033 }; 1034 1035insn_format22s 1036 : //e.g. add-int/lit16 v0, v1, 12345 1037 instruction_format22s REGISTER COMMA REGISTER COMMA integral_literal 1038 -> ^(I_STATEMENT_FORMAT22s[$start, "I_STATEMENT_FORMAT22s"] instruction_format22s REGISTER REGISTER integral_literal); 1039 1040insn_format22t 1041 : //e.g. if-eq v0, v1, endloop: 1042 INSTRUCTION_FORMAT22t REGISTER COMMA REGISTER COMMA label_ref 1043 -> ^(I_STATEMENT_FORMAT22t[$start, "I_STATEMENT_FFORMAT22t"] INSTRUCTION_FORMAT22t REGISTER REGISTER label_ref); 1044 1045insn_format22x 1046 : //e.g. move/from16 v1, v1234 1047 INSTRUCTION_FORMAT22x REGISTER COMMA REGISTER 1048 -> ^(I_STATEMENT_FORMAT22x[$start, "I_STATEMENT_FORMAT22x"] INSTRUCTION_FORMAT22x REGISTER REGISTER); 1049 1050insn_format23x 1051 : //e.g. add-int v1, v2, v3 1052 INSTRUCTION_FORMAT23x REGISTER COMMA REGISTER COMMA REGISTER 1053 -> ^(I_STATEMENT_FORMAT23x[$start, "I_STATEMENT_FORMAT23x"] INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER); 1054 1055insn_format30t 1056 : //e.g. goto/32 endloop: 1057 INSTRUCTION_FORMAT30t label_ref 1058 -> ^(I_STATEMENT_FORMAT30t[$start, "I_STATEMENT_FORMAT30t"] INSTRUCTION_FORMAT30t label_ref); 1059 1060insn_format31c 1061 : //e.g. const-string/jumbo v1 "Hello World!" 1062 INSTRUCTION_FORMAT31c REGISTER COMMA STRING_LITERAL 1063 ->^(I_STATEMENT_FORMAT31c[$start, "I_STATEMENT_FORMAT31c"] INSTRUCTION_FORMAT31c REGISTER STRING_LITERAL); 1064 1065insn_format31i 1066 : //e.g. const v0, 123456 1067 instruction_format31i REGISTER COMMA fixed_32bit_literal 1068 -> ^(I_STATEMENT_FORMAT31i[$start, "I_STATEMENT_FORMAT31i"] instruction_format31i REGISTER fixed_32bit_literal); 1069 1070insn_format31t 1071 : //e.g. fill-array-data v0, ArrayData: 1072 INSTRUCTION_FORMAT31t REGISTER COMMA label_ref 1073 -> ^(I_STATEMENT_FORMAT31t[$start, "I_STATEMENT_FORMAT31t"] INSTRUCTION_FORMAT31t REGISTER label_ref); 1074 1075insn_format32x 1076 : //e.g. move/16 v4567, v1234 1077 INSTRUCTION_FORMAT32x REGISTER COMMA REGISTER 1078 -> ^(I_STATEMENT_FORMAT32x[$start, "I_STATEMENT_FORMAT32x"] INSTRUCTION_FORMAT32x REGISTER REGISTER); 1079 1080insn_format35c_call_site 1081 : //e.g. invoke-custom {v0, v1}, call_site_name 1082 // OR invoke-custom {v0, v1}, {"doSomething", (LCustom;Ljava/lang/String;)Ljava/lang/String;, "just testing"}, BootstrapLinker;->normalLink(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;)Ljava/lang/invoke/CallSite; 1083 INSTRUCTION_FORMAT35c_CALL_SITE OPEN_BRACE register_list CLOSE_BRACE COMMA call_site_reference 1084 -> ^(I_STATEMENT_FORMAT35c_CALL_SITE[$start, "I_STATEMENT_FORMAT35c_CALL_SITE"] INSTRUCTION_FORMAT35c_CALL_SITE register_list call_site_reference); 1085 1086insn_format35c_method 1087 : //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V 1088 instruction_format35c_method OPEN_BRACE register_list CLOSE_BRACE COMMA method_reference 1089 -> ^(I_STATEMENT_FORMAT35c_METHOD[$start, "I_STATEMENT_FORMAT35c_METHOD"] instruction_format35c_method register_list method_reference); 1090 1091insn_format35c_type 1092 : //e.g. filled-new-array {v0,v1}, I 1093 INSTRUCTION_FORMAT35c_TYPE OPEN_BRACE register_list CLOSE_BRACE COMMA nonvoid_type_descriptor 1094 -> ^(I_STATEMENT_FORMAT35c_TYPE[$start, "I_STATEMENT_FORMAT35c_TYPE"] INSTRUCTION_FORMAT35c_TYPE register_list nonvoid_type_descriptor); 1095 1096insn_format35c_method_odex 1097 : //e.g. invoke-direct {p0}, Ljava/lang/Object;-><init>()V 1098 INSTRUCTION_FORMAT35c_METHOD_ODEX OPEN_BRACE register_list CLOSE_BRACE COMMA method_reference 1099 { 1100 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT35c_METHOD_ODEX.text); 1101 }; 1102 1103insn_format35mi_method 1104 : //e.g. execute-inline {v0, v1}, inline@0x4 1105 INSTRUCTION_FORMAT35mi_METHOD OPEN_BRACE register_list CLOSE_BRACE COMMA INLINE_INDEX 1106 { 1107 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT35mi_METHOD.text); 1108 }; 1109 1110insn_format35ms_method 1111 : //e.g. invoke-virtual-quick {v0, v1}, vtable@0x4 1112 INSTRUCTION_FORMAT35ms_METHOD OPEN_BRACE register_list CLOSE_BRACE COMMA VTABLE_INDEX 1113 { 1114 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT35ms_METHOD.text); 1115 }; 1116 1117insn_format3rc_call_site 1118 : //e.g. invoke-custom/range {v0 .. v1}, call_site_name 1119 // OR invoke-custom/range {v0 .. v1}, {"doSomething", (LCustom;Ljava/lang/String;)Ljava/lang/String;, "just testing"}, BootstrapLinker;->normalLink(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;)Ljava/lang/invoke/CallSite; 1120 INSTRUCTION_FORMAT3rc_CALL_SITE OPEN_BRACE register_range CLOSE_BRACE COMMA call_site_reference 1121 -> ^(I_STATEMENT_FORMAT3rc_CALL_SITE[$start, "I_STATEMENT_FORMAT3rc_CALL_SITE"] INSTRUCTION_FORMAT3rc_CALL_SITE register_range call_site_reference); 1122 1123insn_format3rc_method 1124 : //e.g. invoke-virtual/range {v25..v26}, java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder; 1125 INSTRUCTION_FORMAT3rc_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA method_reference 1126 -> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_FORMAT3rc_METHOD register_range method_reference); 1127 1128insn_format3rc_method_odex 1129 : //e.g. invoke-object-init/range {p0}, Ljava/lang/Object;-><init>()V 1130 INSTRUCTION_FORMAT3rc_METHOD_ODEX OPEN_BRACE register_list CLOSE_BRACE COMMA method_reference 1131 { 1132 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rc_METHOD_ODEX.text); 1133 }; 1134 1135insn_format3rc_type 1136 : //e.g. filled-new-array/range {v0..v6}, I 1137 INSTRUCTION_FORMAT3rc_TYPE OPEN_BRACE register_range CLOSE_BRACE COMMA nonvoid_type_descriptor 1138 -> ^(I_STATEMENT_FORMAT3rc_TYPE[$start, "I_STATEMENT_FORMAT3rc_TYPE"] INSTRUCTION_FORMAT3rc_TYPE register_range nonvoid_type_descriptor); 1139 1140insn_format3rmi_method 1141 : //e.g. execute-inline/range {v0 .. v10}, inline@0x14 1142 INSTRUCTION_FORMAT3rmi_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA INLINE_INDEX 1143 { 1144 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rmi_METHOD.text); 1145 }; 1146 1147insn_format3rms_method 1148 : //e.g. invoke-virtual-quick/range {v0 .. v10}, vtable@0x14 1149 INSTRUCTION_FORMAT3rms_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA VTABLE_INDEX 1150 { 1151 throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rms_METHOD.text); 1152 }; 1153 1154insn_format45cc_method 1155 : //e.g. invoke-polymorphic {v0..v1}, java/lang/invoke/MethodHandle;->invoke([Ljava/lang/Object;)Ljava/lang/Object;, (I)J 1156 INSTRUCTION_FORMAT45cc_METHOD OPEN_BRACE register_list CLOSE_BRACE COMMA method_reference COMMA method_prototype 1157 -> ^(I_STATEMENT_FORMAT45cc_METHOD[$start, "I_STATEMENT_FORMAT45cc_METHOD"] INSTRUCTION_FORMAT45cc_METHOD register_list method_reference method_prototype); 1158 1159insn_format4rcc_method 1160 : //e.g. invoke-polymorphic/range {v0,v1}, java/lang/invoke/MethodHandle;->invoke([Ljava/lang/Object;)Ljava/lang/Object;, (I)J 1161 INSTRUCTION_FORMAT4rcc_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA method_reference COMMA method_prototype 1162 -> ^(I_STATEMENT_FORMAT4rcc_METHOD[$start, "I_STATEMENT_FORMAT4rcc_METHOD"] INSTRUCTION_FORMAT4rcc_METHOD register_range method_reference method_prototype); 1163 1164insn_format51l 1165 : //e.g. const-wide v0, 5000000000L 1166 INSTRUCTION_FORMAT51l REGISTER COMMA fixed_literal 1167 -> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal); 1168 1169insn_array_data_directive 1170 : ARRAY_DATA_DIRECTIVE 1171 parsed_integer_literal 1172 { 1173 int elementWidth = $parsed_integer_literal.value; 1174 if (elementWidth != 4 && elementWidth != 8 && elementWidth != 1 && elementWidth != 2) { 1175 throw new SemanticException(input, $start, "Invalid element width: \%d. Must be 1, 2, 4 or 8", elementWidth); 1176 } 1177 } 1178 fixed_literal* END_ARRAY_DATA_DIRECTIVE 1179 1180 -> ^(I_STATEMENT_ARRAY_DATA[$start, "I_STATEMENT_ARRAY_DATA"] ^(I_ARRAY_ELEMENT_SIZE parsed_integer_literal) 1181 ^(I_ARRAY_ELEMENTS fixed_literal*)); 1182 1183insn_packed_switch_directive 1184 : PACKED_SWITCH_DIRECTIVE 1185 fixed_32bit_literal 1186 label_ref* 1187 END_PACKED_SWITCH_DIRECTIVE 1188 -> ^(I_STATEMENT_PACKED_SWITCH[$start, "I_STATEMENT_PACKED_SWITCH"] 1189 ^(I_PACKED_SWITCH_START_KEY[$start, "I_PACKED_SWITCH_START_KEY"] fixed_32bit_literal) 1190 ^(I_PACKED_SWITCH_ELEMENTS[$start, "I_PACKED_SWITCH_ELEMENTS"] 1191 label_ref*) 1192 ); 1193 1194insn_sparse_switch_directive 1195 : SPARSE_SWITCH_DIRECTIVE 1196 (fixed_32bit_literal ARROW label_ref)* 1197 END_SPARSE_SWITCH_DIRECTIVE 1198 -> ^(I_STATEMENT_SPARSE_SWITCH[$start, "I_STATEMENT_SPARSE_SWITCH"] 1199 ^(I_SPARSE_SWITCH_ELEMENTS[$start, "I_SPARSE_SWITCH_ELEMENTS"] (fixed_32bit_literal label_ref)*)); 1200