Add support for Format52c (type references)
diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java
index a39ded3..a352882 100644
--- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java
+++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java
@@ -136,6 +136,7 @@
                 writeLiteral(writer);
                 return true;
             case Format22c:
+            case Format52c:
                 writeOpcode(writer);
                 writer.write(' ');
                 writeFirstRegister(writer);
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java
index 198dc26..60a88eb 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Format.java
@@ -63,6 +63,7 @@
     Format3rms(Instruction3rms.Factory, 6),
     Format41c(Instruction41c.Factory, 8),
     Format51l(Instruction51l.Factory, 10),
+    Format52c(Instruction52c.Factory, 10),
     ArrayData(null, -1, true),
     PackedSwitchData(null, -1, true),
     SparseSwitchData(null, -1, true),
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java
index 46b2c5a..3ffb71c 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction22c.java
@@ -62,6 +62,10 @@
     }
 
     protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
+        if(getReferencedItem().getIndex() > 0xFFFF) {
+            throw new RuntimeException(String.format("%s index is too large. Use the %s/jumbo instruction instead.", opcode.referenceType.name(), opcode.name));
+        }
+
         out.writeByte(opcode.value);
         out.writeByte((regB << 4) | regA);
         out.writeShort(getReferencedItem().getIndex());
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction52c.java b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction52c.java
new file mode 100644
index 0000000..0d7f3f5
--- /dev/null
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Format/Instruction52c.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.jf.dexlib.Code.Format;
+
+import org.jf.dexlib.Code.Instruction;
+import org.jf.dexlib.Code.Opcode;
+import org.jf.dexlib.Code.TwoRegisterInstruction;
+import org.jf.dexlib.DexFile;
+import org.jf.dexlib.Item;
+import org.jf.dexlib.Util.AnnotatedOutput;
+import org.jf.dexlib.Util.NumberUtils;
+
+public class Instruction52c extends InstructionWithJumboReference implements TwoRegisterInstruction {
+    public static final InstructionFactory Factory = new Factory();
+    private short regA;
+    private short regB;
+
+    public Instruction52c(Opcode opcode, int regA, int regB, Item referencedItem) {
+        super(opcode, referencedItem);
+
+        if (regA >= 1 << 16) {
+            throw new RuntimeException("The register number must be less than v65536");
+        }
+
+        if (regB >= 1 << 16) {
+            throw new RuntimeException("The register number must be less than v65536");
+        }
+
+        this.regA = (short)regA;
+        this.regB = (short)regB;
+    }
+
+    private Instruction52c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
+        super(dexFile, opcode, buffer, bufferIndex);
+
+        this.regA = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 6);
+        this.regB = (short)NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 8);
+    }
+
+    protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
+        out.writeByte(0xFF);
+        out.writeByte(opcode.value);
+        out.writeInt(getReferencedItem().getIndex());
+        out.writeShort(getRegisterA());
+        out.writeShort(getRegisterB());
+    }
+
+    public Format getFormat() {
+        return Format.Format52c;
+    }
+
+    public int getRegisterA() {
+        return regA & 0xFFFF;
+    }
+
+    public int getRegisterB() {
+        return regB & 0xFFFF;
+    }
+
+    private static class Factory implements InstructionFactory {
+        public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
+            return new Instruction52c(dexFile, opcode, buffer, bufferIndex);
+        }
+    }
+}
diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java b/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java
index 1a884a1..5679feb 100644
--- a/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java
+++ b/dexlib/src/main/java/org/jf/dexlib/Code/Opcode.java
@@ -284,7 +284,9 @@
 
     CONST_CLASS_JUMBO((short)0xff00, "const-class/jumbo", ReferenceType.type, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
     CHECK_CAST_JUMBO((short)0xff01, "check-cast/jumbo", ReferenceType.type, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
+    INSTANCE_OF_JUMBO((short)0xff02, "instance-of/jumbo", ReferenceType.type, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
     NEW_INSTANCE_JUMBO((short)0xff03, "new-instance/jumbo", ReferenceType.type, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
+    NEW_ARRAY_JUMBO((short)0xff04, "new-array/jumbo", ReferenceType.type, Format.Format52c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
 
     SGET_JUMBO((short)0xff14, "sget/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
     SGET_WIDE_JUMBO((short)0xff15, "sget-wide/jumbo", ReferenceType.field, Format.Format41c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
diff --git a/smali-integration-tests/src/test/smali/jumbo-type-tests/Assert.smali b/smali-integration-tests/src/test/smali/jumbo-type-tests/Assert.smali
new file mode 100644
index 0000000..9d2ae5e
--- /dev/null
+++ b/smali-integration-tests/src/test/smali/jumbo-type-tests/Assert.smali
@@ -0,0 +1,41 @@
+.class public LAssert;
+.super Ljava/lang/Object;
+.source "Assert.smali"
+
+#junit's Assert doesn't have an AssertEquals method for ints, only longs
+.method public static assertEquals(II)V
+    .registers 4
+
+    int-to-long v0, p1
+    int-to-long p0, p0
+
+    invoke-static {v0, v1, p0, p1}, Lorg/junit/Assert;->assertEquals(JJ)V
+    return-void
+.end method
+
+#junit's Assert doesn't have an AssertEquals method for floats, only doubles
+.method public static assertEquals(FF)V
+    .registers 6
+
+    float-to-double v0, p0
+    float-to-double v2, p1
+
+    const-wide v4, .00001
+
+    invoke-static/range {v0..v5}, Lorg/junit/Assert;->assertEquals(DDD)V
+    return-void
+.end method
+
+#convenience method that supplies a default "Delta" argument
+.method public static assertEquals(DD)V
+    .registers 6
+
+    move-wide v0, p0
+    move-wide v2, p2
+
+    const-wide v4, .00001
+
+    invoke-static/range {v0..v5}, Lorg/junit/Assert;->assertEquals(DDD)V
+
+    return-void
+.end method
\ No newline at end of file
diff --git a/smali-integration-tests/src/test/smali/jumbo-type-tests/Format52c.smali b/smali-integration-tests/src/test/smali/jumbo-type-tests/Format52c.smali
new file mode 100644
index 0000000..b407cd3
--- /dev/null
+++ b/smali-integration-tests/src/test/smali/jumbo-type-tests/Format52c.smali
@@ -0,0 +1,98 @@
+#Copyright 2011, Google Inc.
+#All rights reserved.
+#
+#Redistribution and use in source and binary forms, with or without
+#modification, are permitted provided that the following conditions are
+#met:
+#
+#    * Redistributions of source code must retain the above copyright
+#notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above
+#copyright notice, this list of conditions and the following disclaimer
+#in the documentation and/or other materials provided with the
+#distribution.
+#    * Neither the name of Google Inc. nor the names of its
+#contributors may be used to endorse or promote products derived from
+#this software without specific prior written permission.
+#
+#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+
+.class public LFormat52c;
+.super Ljava/lang/Object;
+.source "Format52c.smali"
+
+.method public constructor <init>()V
+    .registers 1
+    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+    return-void
+.end method
+
+.method public test-instance-of-jumbo-success()V
+    .registers 258
+    .annotation runtime Lorg/junit/Test;
+    .end annotation
+
+    const-string v0, "test"
+
+    new-instance v1, LStringWrapper;
+    invoke-direct {v1, v0}, LStringWrapper;-><init>(Ljava/lang/String;)V
+
+    move-object/16 v256, v1
+
+    instance-of/jumbo v257, v256, Ljava/lang/Object;
+
+    const v0, 1
+    move/16 v256, v0
+
+    invoke-static/range {v256 .. v257}, LAssert;->assertEquals(II)V
+    return-void
+.end method
+
+.method public test-instance-of-jumbo-failure()V
+    .registers 258
+    .annotation runtime Lorg/junit/Test;
+    .end annotation
+
+    const-string v0, "test"
+
+    new-instance v1, LStringWrapper;
+    invoke-direct {v1, v0}, LStringWrapper;-><init>(Ljava/lang/String;)V
+
+    move-object/16 v256, v1
+
+    instance-of/jumbo v257, v256, Lzzz99999;
+
+    const v0, 0
+    move/16 v256, v0
+
+    invoke-static/range {v256 .. v257}, LAssert;->assertEquals(II)V
+    return-void
+.end method
+
+.method public test-new-array-jumbo()V
+    .registers 258
+    .annotation runtime Lorg/junit/Test;
+    .end annotation
+
+    const v0, 1
+    move/16 v256, v0
+
+    new-array/jumbo v257, v256, [Lzzz99999;
+
+    move-object/16 v1, v257
+
+    array-length v2, v1
+
+    invoke-static {v0, v2}, LAssert;->assertEquals(II)V
+    return-void
+.end method
\ No newline at end of file
diff --git a/smali-integration-tests/src/test/smali/jumbo-type-tests/TestSuite.smali b/smali-integration-tests/src/test/smali/jumbo-type-tests/TestSuite.smali
index c6e5350..001e18f 100644
--- a/smali-integration-tests/src/test/smali/jumbo-type-tests/TestSuite.smali
+++ b/smali-integration-tests/src/test/smali/jumbo-type-tests/TestSuite.smali
@@ -35,5 +35,7 @@
 .end annotation
 
 .annotation runtime Lorg/junit/runners/Suite$SuiteClasses;
-    value = {   LFormat41c; }
+    value = {   LFormat41c;,
+                LFormat52c;
+            }
 .end annotation
\ No newline at end of file
diff --git a/smali/src/main/antlr3/org/jf/smali/smaliLexer.g b/smali/src/main/antlr3/org/jf/smali/smaliLexer.g
index d448462..ce1a623 100644
--- a/smali/src/main/antlr3/org/jf/smali/smaliLexer.g
+++ b/smali/src/main/antlr3/org/jf/smali/smaliLexer.g
@@ -714,6 +714,10 @@
 INSTRUCTION_FORMAT51l
 	:	'const-wide';
 
+INSTRUCTION_FORMAT52c_TYPE
+	:	'instance-of/jumbo'
+	|	'new-array/jumbo';
+
 
 /**********************************************************
 * Types
diff --git a/smali/src/main/antlr3/org/jf/smali/smaliParser.g b/smali/src/main/antlr3/org/jf/smali/smaliParser.g
index 318ac14..8b22556 100644
--- a/smali/src/main/antlr3/org/jf/smali/smaliParser.g
+++ b/smali/src/main/antlr3/org/jf/smali/smaliParser.g
@@ -120,6 +120,7 @@
 	I_STATEMENT_FORMAT41c_TYPE;
 	I_STATEMENT_FORMAT41c_FIELD;
 	I_STATEMENT_FORMAT51l;
+	I_STATEMENT_FORMAT52c_TYPE;
 	I_STATEMENT_ARRAY_DATA;
 	I_STATEMENT_PACKED_SWITCH;
 	I_STATEMENT_SPARSE_SWITCH;
@@ -845,6 +846,9 @@
 	|	//e.g. const-wide v0, 5000000000L
 		INSTRUCTION_FORMAT51l REGISTER COMMA fixed_literal {$size = Format.Format51l.size;}
 		-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal)
+	|	//e.g. instance-of/jumbo v0, v1, Ljava/lang/String;
+		INSTRUCTION_FORMAT52c_TYPE REGISTER COMMA REGISTER COMMA nonvoid_type_descriptor {$size = Format.Format52c.size;}
+		-> ^(I_STATEMENT_FORMAT52c_TYPE[$start, "I_STATEMENT_FORMAT52c_TYPE"] INSTRUCTION_FORMAT52c_TYPE REGISTER REGISTER nonvoid_type_descriptor)
 	|
 		ARRAY_DATA_DIRECTIVE
 		{
diff --git a/smali/src/main/antlr3/org/jf/smali/smaliTreeWalker.g b/smali/src/main/antlr3/org/jf/smali/smaliTreeWalker.g
index 8055c49..f4ffefa 100644
--- a/smali/src/main/antlr3/org/jf/smali/smaliTreeWalker.g
+++ b/smali/src/main/antlr3/org/jf/smali/smaliTreeWalker.g
@@ -1279,6 +1279,17 @@
 
 			$instructions.add(new Instruction51l(opcode, regA, litB));
 		}
+	|	//e.g. instance-of/jumbo v0, v1, Ljava/lang/String;
+		^(I_STATEMENT_FORMAT52c_TYPE INSTRUCTION_FORMAT52c_TYPE registerA=REGISTER registerB=REGISTER nonvoid_type_descriptor)
+		{
+			Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT52c_TYPE.text);
+			int regA = parseRegister_short($registerA.text, $totalMethodRegisters, $methodParameterRegisters);
+			int regB = parseRegister_short($registerB.text, $totalMethodRegisters, $methodParameterRegisters);
+
+			TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
+
+			$instructions.add(new Instruction52c(opcode, regA, regB, typeIdItem));
+		}
 	|	//e.g. .array-data 4 1000000 .end array-data
 		^(I_STATEMENT_ARRAY_DATA ^(I_ARRAY_ELEMENT_SIZE short_integral_literal) array_elements)
 		{
diff --git a/smali/src/main/jflex/smaliLexer.flex b/smali/src/main/jflex/smaliLexer.flex
index 97da209..5bd13d3 100644
--- a/smali/src/main/jflex/smaliLexer.flex
+++ b/smali/src/main/jflex/smaliLexer.flex
@@ -575,6 +575,10 @@
     "const-wide" {
         return newToken(INSTRUCTION_FORMAT51l);
     }
+
+    "instance-of/jumbo" | "new-array/jumbo" {
+        return newToken(INSTRUCTION_FORMAT52c_TYPE);
+    }
 }
 
 /*Types*/
diff --git a/smali/src/test/resources/LexerTest/InstructionTest.smali b/smali/src/test/resources/LexerTest/InstructionTest.smali
index c80dc8e..c747c60 100644
--- a/smali/src/test/resources/LexerTest/InstructionTest.smali
+++ b/smali/src/test/resources/LexerTest/InstructionTest.smali
@@ -239,4 +239,6 @@
 sput-byte/jumbo
 sput-char/jumbo
 sput-short/jumbo
-const-wide
\ No newline at end of file
+const-wide
+instance-of/jumbo
+new-array/jumbo
\ No newline at end of file
diff --git a/smali/src/test/resources/LexerTest/InstructionTest.tokens b/smali/src/test/resources/LexerTest/InstructionTest.tokens
index 871c5a0..86d2981 100644
--- a/smali/src/test/resources/LexerTest/InstructionTest.tokens
+++ b/smali/src/test/resources/LexerTest/InstructionTest.tokens
@@ -239,4 +239,6 @@
 INSTRUCTION_FORMAT41c_FIELD("sput-byte/jumbo")
 INSTRUCTION_FORMAT41c_FIELD("sput-char/jumbo")
 INSTRUCTION_FORMAT41c_FIELD("sput-short/jumbo")
-INSTRUCTION_FORMAT51l("const-wide")
\ No newline at end of file
+INSTRUCTION_FORMAT51l("const-wide")
+INSTRUCTION_FORMAT52c_TYPE("instance-of/jumbo")
+INSTRUCTION_FORMAT52c_TYPE("new-array/jumbo")
\ No newline at end of file