1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.code; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Utility methods to merge various frame information. 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Merger { 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class is uninstantiable. 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Merger() { 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This space intentionally left blank. 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merges two locals arrays. If the merged result is the same as the first 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * argument, then return the first argument (not a copy). 37de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 3899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param locals1 {@code non-null;} a locals array 3999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param locals2 {@code non-null;} another locals array 4099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the result of merging the two locals arrays 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static OneLocalsArray mergeLocals(OneLocalsArray locals1, 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OneLocalsArray locals2) { 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (locals1 == locals2) { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Easy out. 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return locals1; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = locals1.getMaxLocals(); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OneLocalsArray result = null; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (locals2.getMaxLocals() != sz) { 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("mismatched maxLocals values"); 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer tb1 = locals1.getOrNull(i); 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer tb2 = locals2.getOrNull(i); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer resultType = mergeType(tb1, tb2); 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultType != tb1) { 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We only need to do anything when the result differs 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from what is in the first array, since that's what the 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result gets initialized to. 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = locals1.copy(); 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultType == null) { 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.invalidate(i); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(i, resultType); 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return locals1; 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setImmutable(); 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merges two stacks. If the merged result is the same as the first 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * argument, then return the first argument (not a copy). 89de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 9099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param stack1 {@code non-null;} a stack 9199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param stack2 {@code non-null;} another stack 9299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the result of merging the two stacks 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static ExecutionStack mergeStack(ExecutionStack stack1, 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExecutionStack stack2) { 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (stack1 == stack2) { 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Easy out. 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return stack1; 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = stack1.size(); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExecutionStack result = null; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (stack2.size() != sz) { 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("mismatched stack depths"); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer tb1 = stack1.peek(i); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer tb2 = stack2.peek(i); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer resultType = mergeType(tb1, tb2); 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultType != tb1) { 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We only need to do anything when the result differs 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from what is in the first stack, since that's what the 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result gets initialized to. 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = stack1.copy(); 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultType == null) { 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("incompatible: " + tb1 + ", " + 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tb2); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.change(i, resultType); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (SimException ex) { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ex.addContext("...while merging stack[" + Hex.u2(i) + "]"); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw ex; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return stack1; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.setImmutable(); 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merges two frame types. 146de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 14799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ft1 {@code non-null;} a frame type 14899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ft2 {@code non-null;} another frame type 14999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the result of merging the two types 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static TypeBearer mergeType(TypeBearer ft1, TypeBearer ft2) { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((ft1 == null) || ft1.equals(ft2)) { 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ft1; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (ft2 == null) { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type type1 = ft1.getType(); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type type2 = ft2.getType(); 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 == type2) { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type1; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (type1.isReference() && type2.isReference()) { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type1 == Type.KNOWN_NULL) { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A known-null merges with any other reference type to 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be that reference type. 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type2; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (type2 == Type.KNOWN_NULL) { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The same as above, but this time it's type2 that's 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the known-null. 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type1; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (type1.isArray() && type2.isArray()) { 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer componentUnion = 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mergeType(type1.getComponentType(), 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type2.getComponentType()); 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (componentUnion == null) { 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * At least one of the types is a primitive type, 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so the merged result is just Object. 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Type.OBJECT; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((Type) componentUnion).getArrayType(); 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * All other unequal reference types get merged to be 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Object in this phase. This is fine here, but it 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * won't be the right thing to do in the verifier. 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Type.OBJECT; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (type1.isIntlike() && type2.isIntlike()) { 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merging two non-identical int-like types results in 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the type int. 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Type.INT; 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether the given supertype is possibly assignable from 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the given subtype. This takes into account primitiveness, 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * int-likeness, known-nullness, and array dimensions, but does 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not assume anything about class hierarchy other than that the 21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * type {@code Object} is the supertype of all reference 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * types and all arrays are assignable to 21499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code Serializable} and {@code Cloneable}. 215de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 21699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param supertypeBearer {@code non-null;} the supertype 21799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param subtypeBearer {@code non-null;} the subtype 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static boolean isPossiblyAssignableFrom(TypeBearer supertypeBearer, 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer subtypeBearer) { 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type supertype = supertypeBearer.getType(); 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type subtype = subtypeBearer.getType(); 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (supertype.equals(subtype)) { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Easy out. 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int superBt = supertype.getBasicType(); 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int subBt = subtype.getBasicType(); 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Treat return types as Object for the purposes of this method. 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (superBt == Type.BT_ADDR) { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project supertype = Type.OBJECT; 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project superBt = Type.BT_OBJECT; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (subBt == Type.BT_ADDR) { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subtype = Type.OBJECT; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subBt = Type.BT_OBJECT; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((superBt != Type.BT_OBJECT) || (subBt != Type.BT_OBJECT)) { 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * No two distinct primitive types are assignable in this sense, 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unless they are both int-like. 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return supertype.isIntlike() && subtype.isIntlike(); 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // At this point, we know both types are reference types. 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (supertype == Type.KNOWN_NULL) { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A known-null supertype is only assignable from another 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * known-null (handled in the easy out at the top of the 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method). 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (subtype == Type.KNOWN_NULL) { 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A known-null subtype is in fact assignable to any 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reference type. 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (supertype == Type.OBJECT) { 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Object is assignable from any reference type. 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (supertype.isArray()) { 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The supertype is an array type. 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! subtype.isArray()) { 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The subtype isn't an array, and so can't be assignable. 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Strip off as many matched component types from both 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * types as possible, and check the assignability of the 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * results. 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project supertype = supertype.getComponentType(); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subtype = subtype.getComponentType(); 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (supertype.isArray() && subtype.isArray()); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return isPossiblyAssignableFrom(supertype, subtype); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (subtype.isArray()) { 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Other than Object (handled above), array types are 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * assignable only to Serializable and Cloneable. 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (supertype == Type.SERIALIZABLE) || 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (supertype == Type.CLONEABLE); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * All other unequal reference types are considered at 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * least possibly assignable. 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 306