From 5dc3a8d75a12cd6bab6744f670bc940314a3677c Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Thu, 4 Jun 2009 06:44:10 +0000 Subject: [PATCH] - Added a new "p0" style register reference, where p0 indicates the first parameter register, p1 the 2nd parameter register and so forth. This makes it less annoying when you are writing a method and have to add more registers, which would push the parameter registers back. - Updated the the tests and examples with the new register format, where appropriate git-svn-id: https://smali.googlecode.com/svn/trunk@89 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- examples/AnnotationValues/Enum.smali | 4 +- examples/Enums/Enum.smali | 4 +- .../antlr3/org/JesusFreke/smali/smaliLexer.g | 2 +- .../org/JesusFreke/smali/smaliTreeWalker.g | 165 ++++++++++-------- .../junit-tests/FieldTest/FieldTest.smali | 20 +-- .../SpecialInstructionPaddingTest.smali | 2 +- 6 files changed, 108 insertions(+), 89 deletions(-) diff --git a/examples/AnnotationValues/Enum.smali b/examples/AnnotationValues/Enum.smali index f965d6e8..cbc60a44 100644 --- a/examples/AnnotationValues/Enum.smali +++ b/examples/AnnotationValues/Enum.smali @@ -27,7 +27,7 @@ .method private constructor (Ljava/lang/String;I)V .registers 3 - invoke-direct {v0, v1, v2}, Ljava/lang/Enum;->(Ljava/lang/String;I)V + invoke-direct {p0, p1, p2}, Ljava/lang/Enum;->(Ljava/lang/String;I)V return-void .end method @@ -35,7 +35,7 @@ .registers 2 const-class v0, LEnum; - invoke-static {v0, v1}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; + invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; move-result-object v1 check-cast v1, LEnum; return-object v1 diff --git a/examples/Enums/Enum.smali b/examples/Enums/Enum.smali index 82d93686..1bae8c5b 100644 --- a/examples/Enums/Enum.smali +++ b/examples/Enums/Enum.smali @@ -50,14 +50,14 @@ .method private constructor (Ljava/lang/String;I)V .registers 3 - invoke-direct {v0, v1, v2}, Ljava/lang/Enum;->(Ljava/lang/String;I)V + invoke-direct {p0, p1, p2}, Ljava/lang/Enum;->(Ljava/lang/String;I)V return-void .end method .method public static valueof(Ljava/lang/String;)LEnum; .registers 2 const-class v0, LEnum; - invoke-static {v0, v1}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; + invoke-static {v0, p0}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; move-result-object v1 check-cast v1, LEnum; return-object v1 diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g index e4df537e..1ba2731d 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g @@ -641,7 +641,7 @@ fragment EPILOGUE_DIRECTIVE fragment REGISTER_EMIT : REGISTER {emit($REGISTER, REGISTER);}; fragment REGISTER - : 'v' ('0'..'9')+; + : ('v' | 'p') ('0'..'9')+; fragment REGISTER_LIST_EMITCHILDREN : OPEN_BRACKET_EMIT diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g index 495ca5cd..09634251 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g @@ -50,32 +50,41 @@ import org.JesusFreke.dexlib.code.Format.*; public ClassDefItem classDefItem; public ClassDataItem classDataItem; - private static byte parseRegister_nibble(String register) { + private static byte parseRegister_nibble(String register, int totalMethodRegisters, int methodParameterRegisters) { //register should be in the format "v12" - byte val = Byte.parseByte(register.substring(1)); + int val = Byte.parseByte(register.substring(1)); + if (register.charAt(0) == 'p') { + val = totalMethodRegisters - methodParameterRegisters + val; + } if (val >= 2<<4) { //TODO: throw correct exception type throw new RuntimeException("The maximum allowed register in this context is list of registers is v15"); } //the parser wouldn't accept a negative register, i.e. v-1, so we don't have to check for val<0; - return val; + return (byte)val; } //return a short, because java's byte is signed - private static short parseRegister_byte(String register) { + private static short parseRegister_byte(String register, int totalMethodRegisters, int methodParameterRegisters) { //register should be in the format "v123" - short val = Short.parseShort(register.substring(1)); + int val = Short.parseShort(register.substring(1)); + if (register.charAt(0) == 'p') { + val = totalMethodRegisters - methodParameterRegisters + val; + } if (val >= 2<<8) { //TODO: throw correct exception type throw new RuntimeException("The maximum allowed register in this context is v255"); } - return val; + return (short)val; } //return an int because java's short is signed - private static int parseRegister_short(String register) { + private static int parseRegister_short(String register, int totalMethodRegisters, int methodParameterRegisters) { //register should be in the format "v12345" int val = Integer.parseInt(register.substring(1)); + if (register.charAt(0) == 'p') { + val = totalMethodRegisters - methodParameterRegisters + val; + } if (val >= 2<<16) { //TODO: throw correct exception type throw new RuntimeException("The maximum allowed register in this context is v65535"); @@ -342,6 +351,14 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod, int currentAddress; DebugInfoBuilder debugInfo; } + @init + { + MethodIdItem methodIdItem = null; + int totalMethodRegisters = 0; + int methodParameterRegisters = 0; + int accessFlags = 0; + boolean isStatic = false; + } : { $method::labels = new HashMap(); $method::tryList = new TryListBuilder(); @@ -351,20 +368,24 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod, ^( I_METHOD method_name_and_prototype access_list + { + methodIdItem = $method_name_and_prototype.methodIdItem; + accessFlags = $access_list.value; + isStatic = (accessFlags & AccessFlags.STATIC) != 0; + methodParameterRegisters = methodIdItem.getParameterRegisterCount(isStatic); + } registers_directive + { + totalMethodRegisters = $registers_directive.registers; + } labels - statements + statements[totalMethodRegisters, methodParameterRegisters] catches parameters - ordered_debug_directives + ordered_debug_directives[totalMethodRegisters, methodParameterRegisters] annotations ) - { - MethodIdItem methodIdItem = $method_name_and_prototype.methodIdItem; - int access = $access_list.value; - boolean isStatic = (access & AccessFlags.STATIC) != 0; - - int registers = $registers_directive.registers; + { ArrayList instructions = $statements.instructions; Pair, List> temp = $method::tryList.encodeTries(dexFile); @@ -376,7 +397,7 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod, CodeItem codeItem; - if (registers == 0 && + if (totalMethodRegisters == 0 && instructions.size() == 0 && $method::labels.size()== 0 && (tries == null || tries.size() == 0) && @@ -386,12 +407,10 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod, codeItem = null; } else { - int minRegisters = methodIdItem.getParameterRegisterCount((access & AccessFlags.STATIC) != 0); - - if (registers < minRegisters) { + if (totalMethodRegisters < methodParameterRegisters) { //TODO: throw the correct exception type throw new RuntimeException( "This method requires at least " + - Integer.toString(minRegisters) + + Integer.toString(methodParameterRegisters) + " registers, for the method parameters"); } @@ -404,7 +423,7 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod, } codeItem = new CodeItem(dexFile, - registers, + totalMethodRegisters, methodIdItem.getParameterRegisterCount(isStatic), instructions, debugInfoItem, @@ -412,7 +431,7 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod, handlers); } - $encodedMethod = new ClassDataItem.EncodedMethod(dexFile, methodIdItem, access, codeItem); + $encodedMethod = new ClassDataItem.EncodedMethod(dexFile, methodIdItem, accessFlags, codeItem); if ($annotations.annotationSetItem != null) { $methodAnnotationSet = new AnnotationDirectoryItem.MethodAnnotation(dexFile, methodIdItem, $annotations.annotationSetItem); @@ -547,11 +566,11 @@ parameter returns[AnnotationSetItem parameterAnnotationSet] annotations {$parameterAnnotationSet = $annotations.annotationSetItem;} ); -ordered_debug_directives +ordered_debug_directives[int totalMethodRegisters, int methodParameterRegisters] : ^(I_ORDERED_DEBUG_DIRECTIVES ( line - | local - | end_local - | restart_local + | local[$totalMethodRegisters, $methodParameterRegisters] + | end_local[$totalMethodRegisters, $methodParameterRegisters] + | restart_local[$totalMethodRegisters, $methodParameterRegisters] | prologue | epilogue | source @@ -563,10 +582,10 @@ line $method::debugInfo.addLine($address.address, $integral_literal.value); }; -local +local[int totalMethodRegisters, int methodParameterRegisters] : ^(I_LOCAL REGISTER SIMPLE_NAME nonvoid_type_descriptor string_literal? address) { - int registerNumber = parseRegister_short($REGISTER.text); + int registerNumber = parseRegister_short($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); if ($string_literal.value != null) { $method::debugInfo.addLocalExtended($address.address, registerNumber, $SIMPLE_NAME.text, $nonvoid_type_descriptor.type.getTypeDescriptor(), $string_literal.value); @@ -575,18 +594,18 @@ local } }; -end_local +end_local[int totalMethodRegisters, int methodParameterRegisters] : ^(I_END_LOCAL REGISTER address) { - int registerNumber = parseRegister_short($REGISTER.text); + int registerNumber = parseRegister_short($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); $method::debugInfo.addEndLocal($address.address, registerNumber); }; -restart_local +restart_local[int totalMethodRegisters, int methodParameterRegisters] : ^(I_RESTART_LOCAL REGISTER address) { - int registerNumber = parseRegister_short($REGISTER.text); + int registerNumber = parseRegister_short($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); $method::debugInfo.addRestartLocal($address.address, registerNumber); }; @@ -609,12 +628,12 @@ source $method::debugInfo.addSetFile($address.address, $string_literal.value); }; -statements returns[ArrayList instructions] +statements[int totalMethodRegisters, int methodParameterRegisters] returns[ArrayList instructions] @init { $instructions = new ArrayList(); } - : ^(I_STATEMENTS (instruction + : ^(I_STATEMENTS (instruction[$totalMethodRegisters, $methodParameterRegisters] { $instructions.add($instruction.instruction); $method::currentAddress += $instruction.instruction.getBytes().length/2; @@ -658,7 +677,7 @@ offset_or_label returns[int offsetValue] : offset {$offsetValue = $offset.offsetValue;} | label_ref {$offsetValue = $label_ref.labelAddress-$method::currentAddress;}; -instruction returns[Instruction instruction] +instruction[int totalMethodRegisters, int methodParameterRegisters] returns[Instruction instruction] : //e.g. goto endloop: ^(I_STATEMENT_FORMAT10t INSTRUCTION_FORMAT10t offset_or_label) { @@ -683,7 +702,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT11n INSTRUCTION_FORMAT11n REGISTER short_integral_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT11n.text); - byte regA = parseRegister_nibble($REGISTER.text); + byte regA = parseRegister_nibble($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); short litB = $short_integral_literal.value; literalTools.checkNibble(litB); @@ -694,7 +713,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT11x INSTRUCTION_FORMAT11x REGISTER) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT11x.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); $instruction = Format11x.Format.make(dexFile, opcode.value, regA); } @@ -702,8 +721,8 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT12x INSTRUCTION_FORMAT12x registerA=REGISTER registerB=REGISTER) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT12x.text); - byte regA = parseRegister_nibble($registerA.text); - byte regB = parseRegister_nibble($registerB.text); + byte regA = parseRegister_nibble($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + byte regB = parseRegister_nibble($registerB.text, $totalMethodRegisters, $methodParameterRegisters); $instruction = Format12x.Format.make(dexFile, opcode.value, regA, regB); } @@ -725,7 +744,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT21c_FIELD INSTRUCTION_FORMAT21c_FIELD REGISTER fully_qualified_field) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21c_FIELD.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem; @@ -735,7 +754,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT21c_STRING INSTRUCTION_FORMAT21c_STRING REGISTER string_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21c_STRING.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value); @@ -745,7 +764,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT21c_TYPE INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21c_TYPE.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); TypeIdItem typeIdItem = $reference_type_descriptor.type; @@ -755,7 +774,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT21h INSTRUCTION_FORMAT21h REGISTER short_integral_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21h.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); short litB = $short_integral_literal.value; @@ -765,7 +784,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT21s INSTRUCTION_FORMAT21s REGISTER short_integral_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21s.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); short litB = $short_integral_literal.value; @@ -775,7 +794,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT21t INSTRUCTION_FORMAT21t REGISTER offset_or_label) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21t.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); int addressOffset = $offset_or_label.offsetValue; @@ -790,8 +809,8 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT22b INSTRUCTION_FORMAT22b registerA=REGISTER registerB=REGISTER short_integral_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22b.text); - short regA = parseRegister_byte($registerA.text); - short regB = parseRegister_byte($registerB.text); + short regA = parseRegister_byte($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + short regB = parseRegister_byte($registerB.text, $totalMethodRegisters, $methodParameterRegisters); short litC = $short_integral_literal.value; literalTools.checkByte(litC); @@ -802,8 +821,8 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT22c_FIELD INSTRUCTION_FORMAT22c_FIELD registerA=REGISTER registerB=REGISTER fully_qualified_field) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22c_FIELD.text); - byte regA = parseRegister_nibble($registerA.text); - byte regB = parseRegister_nibble($registerB.text); + byte regA = parseRegister_nibble($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + byte regB = parseRegister_nibble($registerB.text, $totalMethodRegisters, $methodParameterRegisters); FieldIdItem fieldIdItem = $fully_qualified_field.fieldIdItem; @@ -813,8 +832,8 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT22c_TYPE INSTRUCTION_FORMAT22c_TYPE registerA=REGISTER registerB=REGISTER nonvoid_type_descriptor) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22c_TYPE.text); - byte regA = parseRegister_nibble($registerA.text); - byte regB = parseRegister_nibble($registerB.text); + byte regA = parseRegister_nibble($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + byte regB = parseRegister_nibble($registerB.text, $totalMethodRegisters, $methodParameterRegisters); TypeIdItem typeIdItem = $nonvoid_type_descriptor.type; @@ -824,8 +843,8 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT22s INSTRUCTION_FORMAT22s registerA=REGISTER registerB=REGISTER short_integral_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22s.text); - byte regA = parseRegister_nibble($registerA.text); - byte regB = parseRegister_nibble($registerB.text); + byte regA = parseRegister_nibble($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + byte regB = parseRegister_nibble($registerB.text, $totalMethodRegisters, $methodParameterRegisters); short litC = $short_integral_literal.value; @@ -835,8 +854,8 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT22t INSTRUCTION_FORMAT22t registerA=REGISTER registerB=REGISTER offset_or_label) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22t.text); - byte regA = parseRegister_nibble($registerA.text); - byte regB = parseRegister_nibble($registerB.text); + byte regA = parseRegister_nibble($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + byte regB = parseRegister_nibble($registerB.text, $totalMethodRegisters, $methodParameterRegisters); int addressOffset = $offset_or_label.offsetValue; @@ -851,8 +870,8 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT22x INSTRUCTION_FORMAT22x registerA=REGISTER registerB=REGISTER) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22x.text); - short regA = parseRegister_byte($registerA.text); - int regB = parseRegister_short($registerB.text); + short regA = parseRegister_byte($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters); $instruction = Format22x.Format.make(dexFile, opcode.value, regA, regB); } @@ -860,9 +879,9 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT23x INSTRUCTION_FORMAT23x registerA=REGISTER registerB=REGISTER registerC=REGISTER) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT23x.text); - short regA = parseRegister_byte($registerA.text); - short regB = parseRegister_byte($registerB.text); - short regC = parseRegister_byte($registerC.text); + short regA = parseRegister_byte($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + short regB = parseRegister_byte($registerB.text, $totalMethodRegisters, $methodParameterRegisters); + short regC = parseRegister_byte($registerC.text, $totalMethodRegisters, $methodParameterRegisters); $instruction = Format23x.Format.make(dexFile, opcode.value, regA, regB, regC); } @@ -879,7 +898,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT31c INSTRUCTION_FORMAT31c REGISTER string_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT31c.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value); @@ -889,7 +908,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT31i INSTRUCTION_FORMAT31i REGISTER fixed_32bit_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT31i.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); int litB = $fixed_32bit_literal.value; @@ -900,7 +919,7 @@ instruction returns[Instruction instruction] { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT31t.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); int addressOffset = $offset_or_label.offsetValue; if (($method::currentAddress + addressOffset) \% 2 != 0) { @@ -913,13 +932,13 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT32x INSTRUCTION_FORMAT32x registerA=REGISTER registerB=REGISTER) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT32x.text); - int regA = parseRegister_short($registerA.text); - int regB = parseRegister_short($registerB.text); + int regA = parseRegister_short($registerA.text, $totalMethodRegisters, $methodParameterRegisters); + int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters); $instruction = Format32x.Format.make(dexFile, opcode.value, regA, regB); } | //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V - ^(I_STATEMENT_FORMAT35c_METHOD INSTRUCTION_FORMAT35c_METHOD register_list fully_qualified_method) + ^(I_STATEMENT_FORMAT35c_METHOD INSTRUCTION_FORMAT35c_METHOD register_list[$totalMethodRegisters, $methodParameterRegisters] fully_qualified_method) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT35c_METHOD.text); @@ -932,7 +951,7 @@ instruction returns[Instruction instruction] $instruction = Format35c.Format.make(dexFile, opcode.value, registerCount, registers[0], registers[1], registers[2], registers[3], registers[4], methodIdItem); } | //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder; - ^(I_STATEMENT_FORMAT3rc_METHOD INSTRUCTION_FORMAT3rc_METHOD register_range fully_qualified_method) + ^(I_STATEMENT_FORMAT3rc_METHOD INSTRUCTION_FORMAT3rc_METHOD register_range[$totalMethodRegisters, $methodParameterRegisters] fully_qualified_method) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT3rc_METHOD.text); int startRegister = $register_range.startRegister; @@ -957,7 +976,7 @@ instruction returns[Instruction instruction] ^(I_STATEMENT_FORMAT51l INSTRUCTION_FORMAT51l REGISTER fixed_64bit_literal) { Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT51l.text); - short regA = parseRegister_byte($REGISTER.text); + short regA = parseRegister_byte($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); long litB = $fixed_64bit_literal.value; @@ -991,7 +1010,7 @@ instruction returns[Instruction instruction] ; -register_list returns[byte[\] registers, byte registerCount] +register_list[int totalMethodRegisters, int methodParameterRegisters] returns[byte[\] registers, byte registerCount] @init { $registers = new byte[5]; @@ -1004,17 +1023,17 @@ register_list returns[byte[\] registers, byte registerCount] //TODO: throw the correct type of exception throw new RuntimeException("A list of registers can only have a maximum of 5 registers. Use the /range alternate opcode instead."); } - $registers[$registerCount++] = parseRegister_nibble($REGISTER.text); + $registers[$registerCount++] = parseRegister_nibble($REGISTER.text, $totalMethodRegisters, $methodParameterRegisters); })*); -register_range returns[int startRegister, int endRegister] +register_range[int totalMethodRegisters, int methodParameterRegisters] returns[int startRegister, int endRegister] : ^(I_REGISTER_RANGE startReg=REGISTER endReg=REGISTER?) { - $startRegister = parseRegister_short($startReg.text); + $startRegister = parseRegister_short($startReg.text, $totalMethodRegisters, $methodParameterRegisters); if ($endReg == null) { $endRegister = $startRegister; } else { - $endRegister = parseRegister_short($endReg.text); + $endRegister = parseRegister_short($endReg.text, $totalMethodRegisters, $methodParameterRegisters); } } ; diff --git a/src/test/smali/junit-tests/FieldTest/FieldTest.smali b/src/test/smali/junit-tests/FieldTest/FieldTest.smali index b02bc5e8..aebb9635 100644 --- a/src/test/smali/junit-tests/FieldTest/FieldTest.smali +++ b/src/test/smali/junit-tests/FieldTest/FieldTest.smali @@ -6,16 +6,16 @@ .method public constructor ()V .registers 4 - invoke-direct {v3}, Ljava/lang/Object;->()V + invoke-direct {p0}, Ljava/lang/Object;->()V const-string v0, "publicStringFieldValue" - iput-object v0, v3, LFieldTest;->publicStringField:Ljava/lang/String; + iput-object v0, p0, LFieldTest;->publicStringField:Ljava/lang/String; const v0, 23 - iput v0, v3, LFieldTest;->publicIntegerField:I + iput v0, p0, LFieldTest;->publicIntegerField:I const-string v0, "publicObjectFieldValue" - iput-object v0, v3, LFieldTest;->publicObjectField:Ljava/lang/Object; + iput-object v0, p0, LFieldTest;->publicObjectField:Ljava/lang/Object; const/4 v0, 3 new-array v0, v0, [Ljava/lang/String; @@ -32,10 +32,10 @@ const/4 v2, 2 aput-object v1, v0, v2 - iput-object v0, v3, LFieldTest;->publicStringArrayField:[Ljava/lang/String; + iput-object v0, p0, LFieldTest;->publicStringArrayField:[Ljava/lang/String; const-string v0, "privateStringFieldValue" - iput-object v0, v3, LFieldTest;->privateStringField:Ljava/lang/String; + iput-object v0, p0, LFieldTest;->privateStringField:Ljava/lang/String; const-string v0, "publicStaticStringFieldValue" sput-object v0, LFieldTest;->publicStaticStringField:Ljava/lang/String; @@ -61,7 +61,7 @@ .end annotation .line 1 - iget-object v0, v4, LFieldTest;->publicStringField:Ljava/lang/String; + iget-object v0, p0, LFieldTest;->publicStringField:Ljava/lang/String; const-string v1, "publicStringFieldValue" invoke-static {v0, v1}, Lorg/junit/Assert;->assertEquals(Ljava/lang/Object;Ljava/lang/Object;)V @@ -72,7 +72,7 @@ invoke-static {v0, v1, v2, v3}, Lorg/junit/Assert;->assertEquals(JJ)V .line 3 - iget-object v0, v4, LFieldTest;->publicObjectField:Ljava/lang/Object; + iget-object v0, p0, LFieldTest;->publicObjectField:Ljava/lang/Object; const-string v1, "publicObjectFieldValue" invoke-static {v0, v1}, Lorg/junit/Assert;->assertEquals(Ljava/lang/Object;Ljava/lang/Object;)V @@ -92,11 +92,11 @@ const/4 v2, 2 aput-object v1, v0, v2 - iget-object v1, v4, LFieldTest;->publicStringArrayField:[Ljava/lang/String; + iget-object v1, p0, LFieldTest;->publicStringArrayField:[Ljava/lang/String; invoke-static {v0, v1}, Lorg/junit/Assert;->assertEquals([Ljava/lang/Object;[Ljava/lang/Object;)V .line 5 - iget-object v0, v4, LFieldTest;->privateStringField:Ljava/lang/String; + iget-object v0, p0, LFieldTest;->privateStringField:Ljava/lang/String; const-string v1, "privateStringFieldValue" invoke-static {v0, v1}, Lorg/junit/Assert;->assertEquals(Ljava/lang/Object;Ljava/lang/Object;)V diff --git a/src/test/smali/junit-tests/SpecialInstructionPaddingTest/SpecialInstructionPaddingTest.smali b/src/test/smali/junit-tests/SpecialInstructionPaddingTest/SpecialInstructionPaddingTest.smali index 28ebd04e..6a860076 100644 --- a/src/test/smali/junit-tests/SpecialInstructionPaddingTest/SpecialInstructionPaddingTest.smali +++ b/src/test/smali/junit-tests/SpecialInstructionPaddingTest/SpecialInstructionPaddingTest.smali @@ -4,7 +4,7 @@ .method public constructor ()V .registers 1 - invoke-direct {v0}, Ljava/lang/Object;->()V + invoke-direct {p0}, Ljava/lang/Object;->()V return-void .end method