1e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver/*
2e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * Copyright 2013, Google Inc.
3e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * All rights reserved.
4e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver *
5e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * Redistribution and use in source and binary forms, with or without
6e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * modification, are permitted provided that the following conditions are
7e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * met:
8e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver *
9e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver *     * Redistributions of source code must retain the above copyright
10e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * notice, this list of conditions and the following disclaimer.
11e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver *     * Redistributions in binary form must reproduce the above
12e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * copyright notice, this list of conditions and the following disclaimer
13e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * in the documentation and/or other materials provided with the
14e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * distribution.
15e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver *     * Neither the name of Google Inc. nor the names of its
16e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * contributors may be used to endorse or promote products derived from
17e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * this software without specific prior written permission.
18e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver *
19e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver */
31e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
32e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruverpackage org.jf.dexlib2.analysis;
33e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
34e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
35e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruverimport org.jf.util.ExceptionWithContext;
36e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
37e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruverimport javax.annotation.Nonnull;
38e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruverimport javax.annotation.Nullable;
39e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruverimport java.io.IOException;
40e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruverimport java.io.Writer;
41e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
42e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruverpublic class RegisterType {
43e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public final byte category;
4439e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver    @Nullable public final TypeProto type;
45e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
4639e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver    private RegisterType(byte category, @Nullable TypeProto type) {
47e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        assert ((category == REFERENCE || category == UNINIT_REF || category == UNINIT_THIS) && type != null) ||
48e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver               ((category != REFERENCE && category != UNINIT_REF && category != UNINIT_THIS) && type == null);
49e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
50e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        this.category = category;
51e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        this.type = type;
52e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
53e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
54e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    @Override
55e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public String toString() {
56e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        return "(" + CATEGORY_NAMES[category] + (type==null?"":("," + type)) + ")";
57e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
58e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
59e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public void writeTo(Writer writer) throws IOException {
60e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        writer.write('(');
61e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        writer.write(CATEGORY_NAMES[category]);
62e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (type != null) {
63e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            writer.write(',');
6439e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver            writer.write(type.getType());
65e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
66e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        writer.write(')');
67e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
68e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
69e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    @Override
70e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public boolean equals(Object o) {
71e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (this == o) return true;
72e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (o == null || getClass() != o.getClass()) return false;
73e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
74e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        RegisterType that = (RegisterType) o;
75e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
76e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (category != that.category) {
77e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            return false;
78e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
798c2d92d9546163d274feb0b535ad615942123cfdBen Gruver
808c2d92d9546163d274feb0b535ad615942123cfdBen Gruver        // These require strict reference equality. Every instance represents a unique
818c2d92d9546163d274feb0b535ad615942123cfdBen Gruver        // reference that can't be merged with a different one, even if they have the same type.
828c2d92d9546163d274feb0b535ad615942123cfdBen Gruver        if (category == UNINIT_REF || category == UNINIT_THIS) {
838c2d92d9546163d274feb0b535ad615942123cfdBen Gruver            return false;
848c2d92d9546163d274feb0b535ad615942123cfdBen Gruver        }
85e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        return (type != null ? type.equals(that.type) : that.type == null);
86e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
87e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
88e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    @Override
89e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public int hashCode() {
90e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        int result = category;
91e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        result = 31 * result + (type != null ? type.hashCode() : 0);
92e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        return result;
93e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
94e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
95b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // The Unknown category denotes a register type that hasn't been determined yet
96e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte UNKNOWN = 0;
97b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // The Uninit category is for registers that haven't been set yet. e.g. the non-parameter registers in a method
98b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // start out as unint
99e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte UNINIT = 1;
100e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte NULL = 2;
101e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte ONE = 3;
102e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte BOOLEAN = 4;
103e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte BYTE = 5;
104e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte POS_BYTE = 6;
105e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte SHORT = 7;
106e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte POS_SHORT = 8;
107e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte CHAR = 9;
108e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte INTEGER = 10;
109e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte FLOAT = 11;
110e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte LONG_LO = 12;
111e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte LONG_HI = 13;
112e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte DOUBLE_LO = 14;
113e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte DOUBLE_HI = 15;
114b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // The UninitRef category is used after a new-instance operation, and before the corresponding <init> is called
115e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte UNINIT_REF = 16;
116b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // The UninitThis category is used the "this" register inside an <init> method, before the superclass' <init>
117b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // method is called
118e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte UNINIT_THIS = 17;
119e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte REFERENCE = 18;
120b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // This is used when there are multiple incoming execution paths that have incompatible register types. For
121b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // example if the register's type is an Integer on one incoming code path, but is a Reference type on another
122b6c52bc254b4c5b4fbfd9eabe7b6e4218b4f6183Ben Gruver    // incomming code path. There is no register type that can hold either an Integer or a Reference.
123e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final byte CONFLICTED = 19;
124e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
125e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final String[] CATEGORY_NAMES = new String[] {
126e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Unknown",
127e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Uninit",
128e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Null",
129e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "One",
130e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Boolean",
131e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Byte",
132e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "PosByte",
133e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Short",
134e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "PosShort",
135e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Char",
136e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Integer",
137e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Float",
138e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "LongLo",
139e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "LongHi",
140e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "DoubleLo",
141e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "DoubleHi",
142e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "UninitRef",
143e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "UninitThis",
144e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Reference",
145e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            "Conflicted"
146e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    };
147e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
148e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    //this table is used when merging register types. For example, if a particular register can be either a BYTE
149e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    //or a Char, then the "merged" type of that register would be Integer, because it is the "smallest" type can
150e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    //could hold either type of value.
151e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    protected static byte[][] mergeTable  =
152e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    {
153dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*              UNKNOWN      UNINIT      NULL        ONE,        BOOLEAN     BYTE        POS_BYTE    SHORT       POS_SHORT   CHAR        INTEGER,    FLOAT,      LONG_LO     LONG_HI     DOUBLE_LO   DOUBLE_HI   UNINIT_REF  UNINIT_THIS REFERENCE   CONFLICTED*/
154dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*UNKNOWN*/    {UNKNOWN,     UNINIT,     NULL,       ONE,        BOOLEAN,    BYTE,       POS_BYTE,   SHORT,      POS_SHORT,  CHAR,       INTEGER,    FLOAT,      LONG_LO,    LONG_HI,    DOUBLE_LO,  DOUBLE_HI,  UNINIT_REF, UNINIT_THIS,REFERENCE,  CONFLICTED},
155dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*UNINIT*/     {UNINIT,      UNINIT,     CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
156dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*NULL*/       {NULL,        CONFLICTED, NULL,       BOOLEAN,    BOOLEAN,    BYTE,       POS_BYTE,   SHORT,      POS_SHORT,  CHAR,       INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, REFERENCE,  CONFLICTED},
157dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*ONE*/        {ONE,         CONFLICTED, BOOLEAN,    ONE,        BOOLEAN,    BYTE,       POS_BYTE,   SHORT,      POS_SHORT,  CHAR,       INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
158dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*BOOLEAN*/    {BOOLEAN,     CONFLICTED, BOOLEAN,    BOOLEAN,    BOOLEAN,    BYTE,       POS_BYTE,   SHORT,      POS_SHORT,  CHAR,       INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
159dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*BYTE*/       {BYTE,        CONFLICTED, BYTE,       BYTE,       BYTE,       BYTE,       BYTE,       SHORT,      SHORT,      INTEGER,    INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
160dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*POS_BYTE*/   {POS_BYTE,    CONFLICTED, POS_BYTE,   POS_BYTE,   POS_BYTE,   BYTE,       POS_BYTE,   SHORT,      POS_SHORT,  CHAR,       INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
161dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*SHORT*/      {SHORT,       CONFLICTED, SHORT,      SHORT,      SHORT,      SHORT,      SHORT,      SHORT,      SHORT,      INTEGER,    INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
162dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*POS_SHORT*/  {POS_SHORT,   CONFLICTED, POS_SHORT,  POS_SHORT,  POS_SHORT,  SHORT,      POS_SHORT,  SHORT,      POS_SHORT,  CHAR,       INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
163dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*CHAR*/       {CHAR,        CONFLICTED, CHAR,       CHAR,       CHAR,       INTEGER,    CHAR,       INTEGER,    CHAR,       CHAR,       INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
164dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*INTEGER*/    {INTEGER,     CONFLICTED, INTEGER,    INTEGER,    INTEGER,    INTEGER,    INTEGER,    INTEGER,    INTEGER,    INTEGER,    INTEGER,    INTEGER,    CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
165dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*FLOAT*/      {FLOAT,       CONFLICTED, FLOAT,      FLOAT,      FLOAT,      FLOAT,      FLOAT,      FLOAT,      FLOAT,      FLOAT,      INTEGER,    FLOAT,      CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
166dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*LONG_LO*/    {LONG_LO,     CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_LO,    CONFLICTED, LONG_LO,    CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
167dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*LONG_HI*/    {LONG_HI,     CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_HI,    CONFLICTED, LONG_HI,    CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
168dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*DOUBLE_LO*/  {DOUBLE_LO,   CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_LO,    CONFLICTED, DOUBLE_LO,  CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
169dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*DOUBLE_HI*/  {DOUBLE_HI,   CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_HI,    CONFLICTED, DOUBLE_HI,  CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
170dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*UNINIT_REF*/ {UNINIT_REF,  CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
171dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*UNINIT_THIS*/{UNINIT_THIS, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, UNINIT_THIS,CONFLICTED, CONFLICTED},
172dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*REFERENCE*/  {REFERENCE,   CONFLICTED, REFERENCE,  CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, REFERENCE,  CONFLICTED},
173dd714d9196f863919b5cf41f34a41d6003796d72Ben Gruver            /*CONFLICTED*/ {CONFLICTED,  CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED}
174e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    };
175e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
176e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
177e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType UNKNOWN_TYPE = new RegisterType(UNKNOWN, null);
178e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType UNINIT_TYPE = new RegisterType(UNINIT, null);
179e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType NULL_TYPE = new RegisterType(NULL, null);
180e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType ONE_TYPE = new RegisterType(ONE, null);
181e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType BOOLEAN_TYPE = new RegisterType(BOOLEAN, null);
182e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType BYTE_TYPE = new RegisterType(BYTE, null);
183e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType POS_BYTE_TYPE = new RegisterType(POS_BYTE, null);
184e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType SHORT_TYPE = new RegisterType(SHORT, null);
185e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType POS_SHORT_TYPE = new RegisterType(POS_SHORT, null);
186e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType CHAR_TYPE = new RegisterType(CHAR, null);
187e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType INTEGER_TYPE = new RegisterType(INTEGER, null);
188e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType FLOAT_TYPE = new RegisterType(FLOAT, null);
189e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType LONG_LO_TYPE = new RegisterType(LONG_LO, null);
190e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType LONG_HI_TYPE = new RegisterType(LONG_HI, null);
191e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType DOUBLE_LO_TYPE = new RegisterType(DOUBLE_LO, null);
192e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType DOUBLE_HI_TYPE = new RegisterType(DOUBLE_HI, null);
193e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    public static final RegisterType CONFLICTED_TYPE = new RegisterType(CONFLICTED, null);
194e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
195e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    @Nonnull
1969531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    public static RegisterType getWideRegisterType(@Nonnull CharSequence type, boolean firstRegister) {
197e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        switch (type.charAt(0)) {
198e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case 'J':
199e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                if (firstRegister) {
200e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                    return getRegisterType(LONG_LO, null);
201e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                } else {
202e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                    return getRegisterType(LONG_HI, null);
203e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                }
204e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case 'D':
205e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                if (firstRegister) {
206e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                    return getRegisterType(DOUBLE_LO, null);
207e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                } else {
208e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                    return getRegisterType(DOUBLE_HI, null);
209e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                }
210e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            default:
211e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                throw new ExceptionWithContext("Cannot use this method for narrow register type: %s", type);
212e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
213e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
214e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
2159531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    @Nonnull
2169531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    public static RegisterType getRegisterType(@Nonnull ClassPath classPath, @Nonnull CharSequence type) {
2179531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver        switch (type.charAt(0)) {
2189531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'Z':
2199531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return BOOLEAN_TYPE;
2209531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'B':
2219531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return BYTE_TYPE;
2229531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'S':
2239531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return SHORT_TYPE;
2249531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'C':
2259531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return CHAR_TYPE;
2269531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'I':
2279531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return INTEGER_TYPE;
2289531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'F':
2299531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return FLOAT_TYPE;
2309531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'J':
2319531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return LONG_LO_TYPE;
2329531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'D':
2339531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return DOUBLE_LO_TYPE;
2349531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case 'L':
2359531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            case '[':
2369531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                return getRegisterType(REFERENCE, classPath.getClass(type));
2379531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            default:
2389531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver                throw new ExceptionWithContext("Invalid type: " + type);
2399531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver        }
2409531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    }
2419531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver
2429531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    @Nonnull
2439531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    public static RegisterType getRegisterTypeForLiteral(int literalValue) {
244e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue < -32768) {
2459531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return INTEGER_TYPE;
246e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
247e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue < -128) {
2489531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return SHORT_TYPE;
249e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
250e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue < 0) {
2519531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return BYTE_TYPE;
252e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
253e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue == 0) {
2549531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return NULL_TYPE;
255e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
256e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue == 1) {
2579531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return ONE_TYPE;
258e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
259e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue < 128) {
2609531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return POS_BYTE_TYPE;
261e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
262e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue < 32768) {
2639531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return POS_SHORT_TYPE;
264e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
265e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (literalValue < 65536) {
2669531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver            return CHAR_TYPE;
267e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
2689531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver        return INTEGER_TYPE;
269e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
270e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
2719531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    @Nonnull
27239e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver    public RegisterType merge(@Nonnull RegisterType other) {
2733f05570b6bb8249f545ced73a1beb7f996c5227dBen Gruver        if (other.equals(this)) {
274e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            return this;
275e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
276e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
277e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        byte mergedCategory = mergeTable[this.category][other.category];
278e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
27939e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver        TypeProto mergedType = null;
280e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        if (mergedCategory == REFERENCE) {
28164fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver            TypeProto type = this.type;
28264fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver            if (type != null) {
28364fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver                if (other.type != null) {
28464fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver                    mergedType = type.getCommonSuperclass(other.type);
28564fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver                } else {
28664fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver                    mergedType = type;
28764fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver                }
28864fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver            } else {
28964fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver                mergedType = other.type;
29064fb5097e07d093b3a264157d75eee2cdf811424Ben Gruver            }
291e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        } else if (mergedCategory == UNINIT_REF || mergedCategory == UNINIT_THIS) {
292e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            if (this.category == UNKNOWN) {
293e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return other;
294e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            }
295e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            assert other.category == UNKNOWN;
296e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            return this;
297e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
298a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver
299a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver        if (mergedType != null) {
300a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver            if (mergedType.equals(this.type)) {
301a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver                return this;
302a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver            }
303a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver            if (mergedType.equals(other.type)) {
304a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver                return other;
305a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver            }
306a555aa0c0177f26fdd99b1a8b31d80ba104dbe6eBen Gruver        }
307e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        return RegisterType.getRegisterType(mergedCategory, mergedType);
308e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
309e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
3109531284b1b6a29371ae8d8e6cfe3e1f1bfe23296Ben Gruver    @Nonnull
31139e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver    public static RegisterType getRegisterType(byte category, @Nullable TypeProto typeProto) {
312e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        switch (category) {
313e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case UNKNOWN:
314e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return UNKNOWN_TYPE;
315e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case UNINIT:
316e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return UNINIT_TYPE;
317e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case NULL:
318e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return NULL_TYPE;
319e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case ONE:
320e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return ONE_TYPE;
321e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case BOOLEAN:
322e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return BOOLEAN_TYPE;
323e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case BYTE:
324e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return BYTE_TYPE;
325e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case POS_BYTE:
326e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return POS_BYTE_TYPE;
327e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case SHORT:
328e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return SHORT_TYPE;
329e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case POS_SHORT:
33039e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver                return POS_SHORT_TYPE;
331e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case CHAR:
332e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return CHAR_TYPE;
333e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case INTEGER:
334e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return INTEGER_TYPE;
335e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case FLOAT:
336e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return FLOAT_TYPE;
337e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case LONG_LO:
338e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return LONG_LO_TYPE;
339e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case LONG_HI:
340e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return LONG_HI_TYPE;
341e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case DOUBLE_LO:
342e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return DOUBLE_LO_TYPE;
343e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case DOUBLE_HI:
344e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return DOUBLE_HI_TYPE;
345e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver            case CONFLICTED:
346e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver                return CONFLICTED_TYPE;
347e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver        }
348e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver
34939e4d4487e20041700f036a58a4dd7fb50e954bfBen Gruver        return new RegisterType(category, typeProto);
350e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver    }
351e1e9510f41b7a9066e3aa01a77806b039a5b8610Ben Gruver}
352