| 1 30 package com.tc.asm.tree.analysis; 31 32 import java.util.List ; 33 34 import com.tc.asm.Type; 35 36 44 public class SimpleVerifier extends BasicVerifier { 45 46 49 private final Type currentClass; 50 51 54 private final Type currentSuperClass; 55 56 59 private final List currentClassInterfaces; 60 61 64 private final boolean isInterface; 65 66 69 public SimpleVerifier() { 70 this(null, null, false); 71 } 72 73 81 public SimpleVerifier( 82 final Type currentClass, 83 final Type currentSuperClass, 84 final boolean isInterface) 85 { 86 this(currentClass, currentSuperClass, null, isInterface); 87 } 88 89 99 public SimpleVerifier( 100 final Type currentClass, 101 final Type currentSuperClass, 102 final List currentClassInterfaces, 103 final boolean isInterface) 104 { 105 this.currentClass = currentClass; 106 this.currentSuperClass = currentSuperClass; 107 this.currentClassInterfaces = currentClassInterfaces; 108 this.isInterface = isInterface; 109 } 110 111 public Value newValue(final Type type) { 112 Value v = super.newValue(type); 113 if (v == BasicValue.REFERENCE_VALUE) { 114 v = new BasicValue(type); 115 } 116 return v; 117 } 118 119 protected boolean isArrayValue(final Value value) { 120 Type t = ((BasicValue) value).getType(); 121 if (t != null) { 122 return t.getDescriptor().equals("Lnull;") 123 || t.getSort() == Type.ARRAY; 124 } 125 return false; 126 } 127 128 protected Value getElementValue(final Value objectArrayValue) 129 throws AnalyzerException 130 { 131 Type arrayType = ((BasicValue) objectArrayValue).getType(); 132 if (arrayType != null) { 133 if (arrayType.getSort() == Type.ARRAY) { 134 return newValue(Type.getType(arrayType.getDescriptor() 135 .substring(1))); 136 } else if (arrayType.getDescriptor().equals("Lnull;")) { 137 return objectArrayValue; 138 } 139 } 140 throw new AnalyzerException("Not an array type"); 141 } 142 143 protected boolean isSubTypeOf(final Value value, final Value expected) { 144 Type expectedType = ((BasicValue) expected).getType(); 145 Type type = ((BasicValue) value).getType(); 146 if (expectedType == null) { 147 return type == null; 148 } 149 switch (expectedType.getSort()) { 150 case Type.INT: 151 case Type.FLOAT: 152 case Type.LONG: 153 case Type.DOUBLE: 154 return type == expectedType; 155 case Type.ARRAY: 156 case Type.OBJECT: 157 if (expectedType.getDescriptor().equals("Lnull;")) { 158 return type.getSort() == Type.OBJECT 159 || type.getSort() == Type.ARRAY; 160 } 161 if (type.getDescriptor().equals("Lnull;")) { 162 return true; 163 } else if (type.getSort() == Type.OBJECT 164 || type.getSort() == Type.ARRAY) 165 { 166 return isAssignableFrom(expectedType, type); 167 } else { 168 return false; 169 } 170 default: 171 throw new RuntimeException ("Internal error"); 172 } 173 } 174 175 public Value merge(final Value v, final Value w) { 176 if (!v.equals(w)) { 177 Type t = ((BasicValue) v).getType(); 178 Type u = ((BasicValue) w).getType(); 179 if (t != null 180 && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) 181 { 182 if (u != null 183 && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) 184 { 185 if (t.getDescriptor().equals("Lnull;")) { 186 return w; 187 } 188 if (u.getDescriptor().equals("Lnull;")) { 189 return v; 190 } 191 if (isAssignableFrom(t, u)) { 192 return v; 193 } 194 if (isAssignableFrom(u, t)) { 195 return w; 196 } 197 do { 202 if (t == null || isInterface(t)) { 203 return BasicValue.REFERENCE_VALUE; 204 } 205 t = getSuperClass(t); 206 if (isAssignableFrom(t, u)) { 207 return newValue(t); 208 } 209 } while (true); 210 } 211 } 212 return BasicValue.UNINITIALIZED_VALUE; 213 } 214 return v; 215 } 216 217 private boolean isInterface(final Type t) { 218 if (currentClass != null && t.equals(currentClass)) { 219 return isInterface; 220 } 221 return getClass(t).isInterface(); 222 } 223 224 private Type getSuperClass(final Type t) { 225 if (currentClass != null && t.equals(currentClass)) { 226 return currentSuperClass; 227 } 228 Class c = getClass(t).getSuperclass(); 229 return c == null ? null : Type.getType(c); 230 } 231 232 private boolean isAssignableFrom(final Type t, final Type u) { 233 if (t.equals(u)) { 234 return true; 235 } 236 if (currentClass != null && t.equals(currentClass)) { 237 return isAssignableFrom(t, getSuperClass(u)); 238 } 239 if (currentClass != null && u.equals(currentClass)) { 240 if (isAssignableFrom(t, currentSuperClass)) { 241 return true; 242 } 243 if (currentClassInterfaces != null) { 244 for (int i = 0; i < currentClassInterfaces.size(); ++i) { 245 Type v = (Type) currentClassInterfaces.get(i); 246 if (isAssignableFrom(t, v)) { 247 return true; 248 } 249 } 250 } 251 return false; 252 } 253 return getClass(t).isAssignableFrom(getClass(u)); 254 } 255 256 protected Class getClass(final Type t) { 257 try { 258 if (t.getSort() == Type.ARRAY) { 259 return Class.forName(t.getDescriptor().replace('/', '.')); 260 } 261 return Class.forName(t.getClassName()); 262 } catch (ClassNotFoundException e) { 263 throw new RuntimeException (e.toString()); 264 } 265 } 266 } 267 | Popular Tags |