Refactored the statement rules so that the names reflect the format of the opcode being used

git-svn-id: https://smali.googlecode.com/svn/trunk@5 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-04-17 06:00:38 +00:00
parent 487deca11c
commit 82884f441f
3 changed files with 128 additions and 160 deletions

View File

@ -93,16 +93,14 @@ tokens {
I_METHOD_RETURN_TYPE; I_METHOD_RETURN_TYPE;
I_REGISTERS; I_REGISTERS;
I_STATEMENTS; I_STATEMENTS;
I_INVOKE_STATEMENT; I_STATEMENT_FORMAT35c_METHOD;
I_INVOKE_RANGE_STATEMENT; I_STATEMENT_FORMAT3rc_METHOD;
I_BARE_STATEMENT; I_STATEMENT_FORMAT10x;
I_STATIC_FIELD_STATEMENT; I_STATEMENT_FORMAT11x;
I_INSTANCE_FIELD_STATEMENT; I_STATEMENT_FORMAT21c_TYPE;
I_CONST_STRING_STATEMENT; I_STATEMENT_FORMAT21c_FIELD;
I_CONST_CLASS_STATEMENT; I_STATEMENT_FORMAT22c_FIELD;
I_CHECK_CAST_STATEMENT; I_STATEMENT_FORMAT21c_STRING;
I_NEW_INSTANCE_STATEMENT;
I_SINGLE_REGISTER_STATEMENT;
I_REGISTER_RANGE; I_REGISTER_RANGE;
I_REGISTER_LIST; I_REGISTER_LIST;
} }
@ -228,35 +226,29 @@ statement
instruction instruction
//e.g. return //e.g. return
: BARE_INSTRUCTION_NAME : INSTRUCTION_NAME_FORMAT10x
-> ^(I_BARE_STATEMENT[$start, "I_BARE_STATEMENT"] BARE_INSTRUCTION_NAME) -> ^(I_STATEMENT_FORMAT10x[$start, "I_STATEMENT_FORMAT10x"] INSTRUCTION_NAME_FORMAT10x)
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
INVOKE_INSTRUCTION_NAME '{' register_list '}' full_method_name_and_prototype
-> ^(I_INVOKE_STATEMENT[$start, "I_INVOKE_STATEMENT"] INVOKE_INSTRUCTION_NAME register_list full_method_name_and_prototype)
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKE_RANGE_INSTRUCTION_NAME '{' register_range '}' full_method_name_and_prototype
-> ^(I_INVOKE_RANGE_STATEMENT[$start, "I_INVOKE_RANGE_STATEMENT"] INVOKE_RANGE_INSTRUCTION_NAME register_range full_method_name_and_prototype)
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
STATIC_FIELD_INSTRUCTION_NAME REGISTER full_field_name_and_type
-> ^(I_STATIC_FIELD_STATEMENT[$start, "I_STATIC_FIELD_STATEMENT"] STATIC_FIELD_INSTRUCTION_NAME REGISTER full_field_name_and_type)
| //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
INSTANCE_FIELD_INSTRUCTION_NAME REGISTER REGISTER full_field_name_and_type
-> ^(I_INSTANCE_FIELD_STATEMENT[$start, "I_INSTANCE_FIELD_STATEMENT"] INSTANCE_FIELD_INSTRUCTION_NAME REGISTER REGISTER full_field_name_and_type)
| //e.g. const-string v1 "Hello World!"
CONST_STRING_INSTRUCTION_NAME REGISTER STRING_LITERAL
-> ^(I_CONST_STRING_STATEMENT[$start, "I_CONST_STRING_STATMENT"] CONST_STRING_INSTRUCTION_NAME REGISTER STRING_LITERAL)
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
CONST_CLASS_INSTRUCTION_NAME REGISTER class_or_array_type_descriptor
-> ^(I_CONST_CLASS_STATEMENT[$start, "I_CONST_CLASS_STATEMENT"] CONST_CLASS_INSTRUCTION_NAME REGISTER class_or_array_type_descriptor)
| //e.g. check-cast v4 Landroid/app/Activity;
CHECK_CAST_INSTRUCTION_NAME REGISTER class_or_array_type_descriptor
-> ^(I_CHECK_CAST_STATEMENT[$start, "I_CHECK_CAST_STATEMENT"] CHECK_CAST_INSTRUCTION_NAME REGISTER class_or_array_type_descriptor)
| //e.g. new-instance v1 android/widget/TextView
NEW_INSTANCE_INSTRUCTION_NAME REGISTER CLASS_DESCRIPTOR
-> ^(I_NEW_INSTANCE_STATEMENT[$start, "I_NEW_INSTANCE_STATEMENT"] NEW_INSTANCE_INSTRUCTION_NAME REGISTER CLASS_DESCRIPTOR)
| //e.g. move-result-object v1 | //e.g. move-result-object v1
SINGLE_REGISTER_INSTRUCTION_NAME REGISTER INSTRUCTION_NAME_FORMAT11x REGISTER
-> ^(I_SINGLE_REGISTER_STATEMENT[$start, "I_SINGLE_REGISTER_STATEMENT"] SINGLE_REGISTER_INSTRUCTION_NAME REGISTER) -> ^(I_STATEMENT_FORMAT11x[$start, "I_STATEMENT_FORMAT11x"] INSTRUCTION_NAME_FORMAT11x REGISTER)
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
INSTRUCTION_NAME_FORMAT21c_FIELD REGISTER full_field_name_and_type
-> ^(I_STATEMENT_FORMAT21c_FIELD[$start, "I_STATEMENT_FORMAT21c_FIELD"] INSTRUCTION_NAME_FORMAT21c_FIELD REGISTER full_field_name_and_type)
| //e.g. const-string v1 "Hello World!"
INSTRUCTION_NAME_FORMAT21c_STRING REGISTER STRING_LITERAL
-> ^(I_STATEMENT_FORMAT21c_STRING[$start, "I_STATEMENT_FORMAT21c_STRING"] INSTRUCTION_NAME_FORMAT21c_STRING REGISTER STRING_LITERAL)
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
INSTRUCTION_NAME_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor
-> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_NAME_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor)
| //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
INSTRUCTION_NAME_FORMAT22c_FIELD REGISTER REGISTER full_field_name_and_type
-> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_INSTANCE_FIELD_STATEMENT"] INSTRUCTION_NAME_FORMAT22c_FIELD REGISTER REGISTER full_field_name_and_type)
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
INSTRUCTION_NAME_FORMAT35c_METHOD '{' register_list '}' full_method_name_and_prototype
-> ^(I_STATEMENT_FORMAT35c_METHOD[$start, "I_STATEMENT_FORMAT35c_METHOD"] INSTRUCTION_NAME_FORMAT35c_METHOD register_list full_method_name_and_prototype)
| //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INSTRUCTION_NAME_FORMAT3rc_METHOD '{' register_range '}' full_method_name_and_prototype
-> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_NAME_FORMAT3rc_METHOD register_range full_method_name_and_prototype)
; ;
@ -286,16 +278,14 @@ simple_name
; ;
instruction_name instruction_name
: INVOKE_INSTRUCTION_NAME : INSTRUCTION_NAME_FORMAT10x
| INVOKE_RANGE_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT11x
| STATIC_FIELD_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT21c_FIELD
| INSTANCE_FIELD_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT21c_STRING
| BARE_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT21c_TYPE
| CONST_STRING_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT22c_FIELD
| CONST_CLASS_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT35c_METHOD
| CHECK_CAST_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT3rc_METHOD
| NEW_INSTANCE_INSTRUCTION_NAME
| SINGLE_REGISTER_INSTRUCTION_NAME
; ;
member_name member_name
@ -340,7 +330,7 @@ double_literal
ACCESS_SPEC ACCESS_SPEC
: 'public' | 'private' | 'static' | 'constructor' | 'final'; : 'public' | 'private' | 'static' | 'constructor' | 'final';
INVOKE_INSTRUCTION_NAME INSTRUCTION_NAME_FORMAT35c_METHOD
: 'invoke-virtual' : 'invoke-virtual'
| 'invoke-super' | 'invoke-super'
| 'invoke-direct' | 'invoke-direct'
@ -348,7 +338,7 @@ INVOKE_INSTRUCTION_NAME
| 'invoke-interface' | 'invoke-interface'
; ;
INVOKE_RANGE_INSTRUCTION_NAME INSTRUCTION_NAME_FORMAT3rc_METHOD
: 'invoke-virtual/range' : 'invoke-virtual/range'
| 'invoke-super/range' | 'invoke-super/range'
| 'invoke-direct/range' | 'invoke-direct/range'
@ -356,24 +346,7 @@ INVOKE_RANGE_INSTRUCTION_NAME
| 'invoke-interface/range' | 'invoke-interface/range'
; ;
STATIC_FIELD_INSTRUCTION_NAME INSTRUCTION_NAME_FORMAT22c_FIELD
: 'sget'
| 'sget-wide'
| 'sget-object'
| 'sget-boolean'
| 'sget-byte'
| 'sget-char'
| 'sget-short'
| 'sput'
| 'sput-wide'
| 'sput-object'
| 'sput-boolean'
| 'sput-byte'
| 'sput-char'
| 'sput-short'
;
INSTANCE_FIELD_INSTRUCTION_NAME
: 'iget' : 'iget'
| 'iget-wide' | 'iget-wide'
| 'iget-object' | 'iget-object'
@ -390,24 +363,11 @@ INSTANCE_FIELD_INSTRUCTION_NAME
| 'iput-short' | 'iput-short'
; ;
BARE_INSTRUCTION_NAME INSTRUCTION_NAME_FORMAT10x
: 'return-void' : 'return-void'
| 'nop'; | 'nop';
CONST_STRING_INSTRUCTION_NAME
: 'const-string';
CONST_CLASS_INSTRUCTION_NAME INSTRUCTION_NAME_FORMAT11x
: 'const-class';
CHECK_CAST_INSTRUCTION_NAME
: 'check-cast';
NEW_INSTANCE_INSTRUCTION_NAME
: 'new-instance';
SINGLE_REGISTER_INSTRUCTION_NAME
: 'move-result' : 'move-result'
| 'move-result-wide' | 'move-result-wide'
| 'move-result-object' | 'move-result-object'
@ -418,7 +378,31 @@ SINGLE_REGISTER_INSTRUCTION_NAME
| 'monitor-enter' | 'monitor-enter'
| 'monitor-exit' | 'monitor-exit'
| 'throw'; | 'throw';
INSTRUCTION_NAME_FORMAT21c_FIELD
: 'sget'
| 'sget-wide'
| 'sget-object'
| 'sget-boolean'
| 'sget-byte'
| 'sget-char'
| 'sget-short'
| 'sput'
| 'sput-wide'
| 'sput-object'
| 'sput-boolean'
| 'sput-byte'
| 'sput-char'
| 'sput-short'
;
INSTRUCTION_NAME_FORMAT21c_STRING
: 'const-string';
INSTRUCTION_NAME_FORMAT21c_TYPE
: 'check-cast'
| 'new-instance'
| 'const-class';
/*since SIMPLE_NAME is so all-encompassing, it includes all integer literals /*since SIMPLE_NAME is so all-encompassing, it includes all integer literals
and a subset of the possible floating point literals. For floating point and a subset of the possible floating point literals. For floating point

View File

@ -249,15 +249,53 @@ statements returns[ArrayList<Instruction> instructions]
instruction returns[Instruction instruction] instruction returns[Instruction instruction]
//e.g. return //e.g. return
: ^(I_BARE_STATEMENT BARE_INSTRUCTION_NAME) : ^(I_STATEMENT_FORMAT10x INSTRUCTION_NAME_FORMAT10x)
{ {
Opcode opcode = Opcode.getOpcodeByName($BARE_INSTRUCTION_NAME.text); Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT10x.text);
$instruction = Format10x.Format.make(dexFile, opcode.value); $instruction = Format10x.Format.make(dexFile, opcode.value);
} }
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V | //e.g. move-result-object v1
^(I_INVOKE_STATEMENT INVOKE_INSTRUCTION_NAME register_list full_method_name_and_prototype) ^(I_STATEMENT_FORMAT11x INSTRUCTION_NAME_FORMAT11x REGISTER)
{ {
Opcode opcode = Opcode.getOpcodeByName($INVOKE_INSTRUCTION_NAME.text); Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT11x.text);
short regA = parseRegister_byte($REGISTER.text);
$instruction = Format11x.Format.make(dexFile, opcode.value, regA);
}
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
^(I_STATEMENT_FORMAT21c_FIELD INSTRUCTION_NAME_FORMAT21c_FIELD REGISTER full_field_name_and_type)
{
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT21c_FIELD.text);
short regA = parseRegister_byte($REGISTER.text);
FieldIdItem fieldIdItem = $full_field_name_and_type.fieldIdItem;
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, fieldIdItem);
}
| //e.g. const-string v1 "Hello World!"
^(I_STATEMENT_FORMAT21c_STRING INSTRUCTION_NAME_FORMAT21c_STRING REGISTER string_literal)
{
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT21c_STRING.text);
short regA = parseRegister_byte($REGISTER.text);
StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value);
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, stringIdItem);
}
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
^(I_STATEMENT_FORMAT21c_TYPE INSTRUCTION_NAME_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor)
{
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT21c_TYPE.text);
short regA = parseRegister_byte($REGISTER.text);
TypeIdItem typeIdItem = $class_or_array_type_descriptor.type;
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
}
| //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
^(I_STATEMENT_FORMAT35c_METHOD INSTRUCTION_NAME_FORMAT35c_METHOD register_list full_method_name_and_prototype)
{
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT35c_METHOD.text);
//this depends on the fact that register_list returns a byte[5] //this depends on the fact that register_list returns a byte[5]
byte[] registers = $register_list.registers; byte[] registers = $register_list.registers;
@ -268,9 +306,9 @@ instruction returns[Instruction instruction]
$instruction = Format35c.Format.make(dexFile, opcode.value, registerCount, registers[0], registers[1], registers[2], registers[3], registers[4], methodIdItem); $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; | //e.g. invoke-virtual/range {v25..v26} java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
^(I_INVOKE_RANGE_STATEMENT INVOKE_RANGE_INSTRUCTION_NAME register_range full_method_name_and_prototype) ^(I_STATEMENT_FORMAT3rc_METHOD INSTRUCTION_NAME_FORMAT3rc_METHOD register_range full_method_name_and_prototype)
{ {
Opcode opcode = Opcode.getOpcodeByName($INVOKE_RANGE_INSTRUCTION_NAME.text); Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT3rc_METHOD.text);
int startRegister = $register_range.startRegister; int startRegister = $register_range.startRegister;
int endRegister = $register_range.endRegister; int endRegister = $register_range.endRegister;
@ -289,20 +327,10 @@ instruction returns[Instruction instruction]
//not supported yet //not supported yet
$instruction = Format3rc.Format.make(dexFile, opcode.value, (short)registerCount, startRegister, methodIdItem); $instruction = Format3rc.Format.make(dexFile, opcode.value, (short)registerCount, startRegister, methodIdItem);
} }
| //e.g. sget_object v0 java/lang/System/out LJava/io/PrintStream;
^(I_STATIC_FIELD_STATEMENT STATIC_FIELD_INSTRUCTION_NAME REGISTER full_field_name_and_type)
{
Opcode opcode = Opcode.getOpcodeByName($STATIC_FIELD_INSTRUCTION_NAME.text);
short regA = parseRegister_byte($REGISTER.text);
FieldIdItem fieldIdItem = $full_field_name_and_type.fieldIdItem;
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, fieldIdItem);
}
| //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; | //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
^(I_INSTANCE_FIELD_STATEMENT INSTANCE_FIELD_INSTRUCTION_NAME registerA=REGISTER registerB=REGISTER full_field_name_and_type) ^(I_STATEMENT_FORMAT22c_FIELD INSTRUCTION_NAME_FORMAT22c_FIELD registerA=REGISTER registerB=REGISTER full_field_name_and_type)
{ {
Opcode opcode = Opcode.getOpcodeByName($INSTANCE_FIELD_INSTRUCTION_NAME.text); Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_NAME_FORMAT22c_FIELD.text);
byte regA = parseRegister_nibble($registerA.text); byte regA = parseRegister_nibble($registerA.text);
byte regB = parseRegister_nibble($registerB.text); byte regB = parseRegister_nibble($registerB.text);
@ -310,55 +338,6 @@ instruction returns[Instruction instruction]
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, fieldIdItem); $instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, fieldIdItem);
} }
| //e.g. const-string v1 "Hello World!"
^(I_CONST_STRING_STATEMENT CONST_STRING_INSTRUCTION_NAME REGISTER string_literal)
{
Opcode opcode = Opcode.getOpcodeByName($CONST_STRING_INSTRUCTION_NAME.text);
short regA = parseRegister_byte($REGISTER.text);
StringIdItem stringIdItem = new StringIdItem(dexFile, $string_literal.value);
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, stringIdItem);
}
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
^(I_CONST_CLASS_STATEMENT CONST_CLASS_INSTRUCTION_NAME REGISTER class_or_array_type_descriptor)
{
Opcode opcode = Opcode.getOpcodeByName($CONST_CLASS_INSTRUCTION_NAME.text);
short regA = parseRegister_byte($REGISTER.text);
TypeIdItem typeIdItem = $class_or_array_type_descriptor.type;
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
}
| //e.g. check-cast v4 Landroid/app/Activity;
^(I_CHECK_CAST_STATEMENT CHECK_CAST_INSTRUCTION_NAME REGISTER class_or_array_type_descriptor)
{
//TODO: this should be merged with I_CONST_CLASS_STATEMENT
Opcode opcode = Opcode.getOpcodeByName($CHECK_CAST_INSTRUCTION_NAME.text);
short regA = parseRegister_byte($REGISTER.text);
TypeIdItem typeIdItem = $class_or_array_type_descriptor.type;
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
}
| //e.g. new-instance v1 android/widget/TextView
^(I_NEW_INSTANCE_STATEMENT NEW_INSTANCE_INSTRUCTION_NAME REGISTER class_type_descriptor)
{
Opcode opcode = Opcode.getOpcodeByName($NEW_INSTANCE_INSTRUCTION_NAME.text);
short regA = parseRegister_byte($REGISTER.text);
TypeIdItem typeIdItem = $class_type_descriptor.type;
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
}
| //e.g. move-result-object v1
^(I_SINGLE_REGISTER_STATEMENT SINGLE_REGISTER_INSTRUCTION_NAME REGISTER)
{
Opcode opcode = Opcode.getOpcodeByName($SINGLE_REGISTER_INSTRUCTION_NAME.text);
short regA = parseRegister_byte($REGISTER.text);
$instruction = Format11x.Format.make(dexFile, opcode.value, regA);
}
; ;
@ -403,15 +382,14 @@ simple_name
; ;
instruction_name returns[String value] instruction_name returns[String value]
: INVOKE_INSTRUCTION_NAME : INSTRUCTION_NAME_FORMAT10x
| INVOKE_RANGE_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT11x
| STATIC_FIELD_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT21c_FIELD
| INSTANCE_FIELD_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT21c_STRING
| BARE_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT21c_TYPE
| CONST_STRING_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT22c_FIELD
| CONST_CLASS_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT35c_METHOD
| CHECK_CAST_INSTRUCTION_NAME | INSTRUCTION_NAME_FORMAT3rc_METHOD
| NEW_INSTANCE_INSTRUCTION_NAME
; ;
member_name returns[String memberName] member_name returns[String memberName]

View File

@ -32,6 +32,8 @@ import org.JesusFreke.dexlib.code.Instruction;
import org.JesusFreke.dexlib.code.Opcode; import org.JesusFreke.dexlib.code.Opcode;
import org.JesusFreke.dexlib.DexFile; import org.JesusFreke.dexlib.DexFile;
import org.JesusFreke.dexlib.IndexedItem; import org.JesusFreke.dexlib.IndexedItem;
import org.JesusFreke.dexlib.FieldIdItem;
import org.JesusFreke.dexlib.TypeIdItem;
public class Format21c extends Format public class Format21c extends Format
{ {
@ -51,6 +53,10 @@ public class Format21c extends Format
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
if (opcode == Opcode.NEW_INSTANCE.value && ((TypeIdItem)item).toString().charAt(0) != 'L') {
throw new RuntimeException("Only class references can be used with the new-instance opcode");
}
bytes[0] = opcode; bytes[0] = opcode;
bytes[1] = (byte)regA; bytes[1] = (byte)regA;