1 30 package org.objectweb.asm.tree.analysis; 31 32 import org.objectweb.asm.Type; 33 34 42 public class SimpleVerifier extends BasicVerifier { 43 44 47 private final Type currentClass; 48 49 52 private final Type currentSuperClass; 53 54 57 private final boolean isInterface; 58 59 62 public SimpleVerifier() { 63 this(null, null, false); 64 } 65 66 74 public SimpleVerifier( 75 final Type currentClass, 76 final Type currentSuperClass, 77 final boolean isInterface) 78 { 79 this.currentClass = currentClass; 80 this.currentSuperClass = currentSuperClass; 81 this.isInterface = isInterface; 82 } 83 84 public Value newValue(final Type type) { 85 Value v = super.newValue(type); 86 if (v == BasicValue.REFERENCE_VALUE) { 87 if (type.getSort() == Type.ARRAY) { 88 v = newValue(type.getElementType()); 89 String desc = ((BasicValue) v).getType().getDescriptor(); 90 for (int i = 0; i < type.getDimensions(); ++i) { 91 desc = "[" + desc; 92 } 93 v = new BasicValue(Type.getType(desc)); 94 } else { 95 v = new BasicValue(type); 96 } 97 } 98 return v; 99 } 100 101 protected boolean isArrayValue(final Value value) { 102 Type t = ((BasicValue) value).getType(); 103 if (t != null) { 104 return t.getDescriptor().equals("Lnull;") 105 || t.getSort() == Type.ARRAY; 106 } 107 return false; 108 } 109 110 protected Value getElementValue(final Value objectArrayValue) 111 throws AnalyzerException 112 { 113 Type arrayType = ((BasicValue) objectArrayValue).getType(); 114 if (arrayType != null) { 115 if (arrayType.getSort() == Type.ARRAY) { 116 return newValue(Type.getType(arrayType.getDescriptor() 117 .substring(1))); 118 } else if (arrayType.getDescriptor().equals("Lnull;")) { 119 return objectArrayValue; 120 } 121 } 122 throw new AnalyzerException("Not an array type"); 123 } 124 125 protected boolean isSubTypeOf(final Value value, final Value expected) { 126 Type expectedType = ((BasicValue) expected).getType(); 127 Type type = ((BasicValue) value).getType(); 128 if (expectedType == null) { 129 return type == null; 130 } 131 switch (expectedType.getSort()) { 132 case Type.INT: 133 case Type.FLOAT: 134 case Type.LONG: 135 case Type.DOUBLE: 136 return type == expectedType; 137 case Type.ARRAY: 138 case Type.OBJECT: 139 if (expectedType.getDescriptor().equals("Lnull;")) { 140 return type.getSort() == Type.OBJECT 141 || type.getSort() == Type.ARRAY; 142 } 143 if (type.getDescriptor().equals("Lnull;")) { 144 return true; 145 } else if (type.getSort() == Type.OBJECT 146 || type.getSort() == Type.ARRAY) 147 { 148 return isAssignableFrom(expectedType, type); 149 } else { 150 return false; 151 } 152 default: 153 throw new RuntimeException ("Internal error"); 154 } 155 } 156 157 public Value merge(final Value v, final Value w) { 158 if (!v.equals(w)) { 159 Type t = ((BasicValue) v).getType(); 160 Type u = ((BasicValue) w).getType(); 161 if (t != null 162 && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) 163 { 164 if (u != null 165 && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) 166 { 167 if (t.getDescriptor().equals("Lnull;")) { 168 return w; 169 } 170 if (u.getDescriptor().equals("Lnull;")) { 171 return v; 172 } 173 if (isAssignableFrom(t, u)) { 174 return v; 175 } 176 if (isAssignableFrom(u, t)) { 177 return w; 178 } 179 do { 184 if (t == null || isInterface(t)) { 185 return BasicValue.REFERENCE_VALUE; 186 } 187 t = getSuperClass(t); 188 if (isAssignableFrom(t, u)) { 189 return newValue(t); 190 } 191 } while (true); 192 } 193 } 194 return BasicValue.UNINITIALIZED_VALUE; 195 } 196 return v; 197 } 198 199 private boolean isInterface(final Type t) { 200 if (currentClass != null && t.equals(currentClass)) { 201 return isInterface; 202 } 203 return getClass(t).isInterface(); 204 } 205 206 private Type getSuperClass(final Type t) { 207 if (currentClass != null && t.equals(currentClass)) { 208 return currentSuperClass; 209 } 210 Class c = getClass(t).getSuperclass(); 211 return c == null ? null : Type.getType(c); 212 } 213 214 private boolean isAssignableFrom(final Type t, final Type u) { 215 if (t.equals(u)) { 216 return true; 217 } 218 if (currentClass != null && t.equals(currentClass)) { 219 return isAssignableFrom(t, getSuperClass(u)); 220 } 221 if (currentClass != null && u.equals(currentClass)) { 222 return isAssignableFrom(t, currentSuperClass); 223 } 224 return getClass(t).isAssignableFrom(getClass(u)); 225 } 226 227 protected Class getClass(final Type t) { 228 try { 229 if (t.getSort() == Type.ARRAY) { 230 return Class.forName(t.getDescriptor().replace('/', '.')); 231 } 232 return Class.forName(t.getClassName()); 233 } catch (ClassNotFoundException e) { 234 throw new RuntimeException (e.toString()); 235 } 236 } 237 } 238 | Popular Tags |