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