1 17 package org.apache.bcel.verifier.structurals; 18 19 20 import org.apache.bcel.generic.ReferenceType; 21 import org.apache.bcel.generic.Type; 22 import org.apache.bcel.verifier.exc.AssertionViolatedException; 23 import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; 24 25 32 public class LocalVariables{ 33 34 private Type[] locals; 35 36 39 public LocalVariables(int maxLocals){ 40 locals = new Type[maxLocals]; 41 for (int i=0; i<maxLocals; i++){ 42 locals[i] = Type.UNKNOWN; 43 } 44 } 45 46 51 protected Object clone(){ 52 LocalVariables lvs = new LocalVariables(locals.length); 53 for (int i=0; i<locals.length; i++){ 54 lvs.locals[i] = this.locals[i]; 55 } 56 return lvs; 57 } 58 59 62 public Type get(int i){ 63 return locals[i]; 64 } 65 66 70 public LocalVariables getClone(){ 71 return (LocalVariables) this.clone(); 72 } 73 74 78 public int maxLocals(){ 79 return locals.length; 80 } 81 82 85 public void set(int i, Type type){ 86 if (type == Type.BYTE || type == Type.SHORT || type == Type.BOOLEAN || type == Type.CHAR){ 87 throw new AssertionViolatedException("LocalVariables do not know about '"+type+"'. Use Type.INT instead."); 88 } 89 locals[i] = type; 90 } 91 92 94 public int hashCode() { return locals.length; } 95 96 99 public boolean equals(Object o){ 100 if (!(o instanceof LocalVariables)) { 101 return false; 102 } 103 LocalVariables lv = (LocalVariables) o; 104 if (this.locals.length != lv.locals.length) { 105 return false; 106 } 107 for (int i=0; i<this.locals.length; i++){ 108 if (!this.locals[i].equals(lv.locals[i])){ 109 return false; 111 } 112 } 113 return true; 114 } 115 116 120 public void merge(LocalVariables lv){ 121 122 if (this.locals.length != lv.locals.length){ 123 throw new AssertionViolatedException("Merging LocalVariables of different size?!? From different methods or what?!?"); 124 } 125 126 for (int i=0; i<locals.length; i++){ 127 merge(lv, i); 128 } 129 } 130 131 136 private void merge(LocalVariables lv, int i){ 137 try { 138 139 if ( (!(locals[i] instanceof UninitializedObjectType)) && (lv.locals[i] instanceof UninitializedObjectType) ){ 142 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected."); 143 } 144 if ( (!(locals[i].equals(lv.locals[i]))) && (locals[i] instanceof UninitializedObjectType) && (lv.locals[i] instanceof UninitializedObjectType) ){ 146 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected."); 147 } 148 if (locals[i] instanceof UninitializedObjectType){ 150 if (! (lv.locals[i] instanceof UninitializedObjectType)){ 151 locals[i] = ((UninitializedObjectType) locals[i]).getInitialized(); 152 } 153 } 154 if ((locals[i] instanceof ReferenceType) && (lv.locals[i] instanceof ReferenceType)){ 155 if (! locals[i].equals(lv.locals[i])){ Type sup = ((ReferenceType) locals[i]).getFirstCommonSuperclass((ReferenceType) (lv.locals[i])); 157 158 if (sup != null){ 159 locals[i] = sup; 160 } 161 else{ 162 throw new AssertionViolatedException("Could not load all the super classes of '"+locals[i]+"' and '"+lv.locals[i]+"'."); 164 } 165 } 166 } 167 else{ 168 if (! (locals[i].equals(lv.locals[i])) ){ 169 175 locals[i] = Type.UNKNOWN; 176 } 177 } 178 } catch (ClassNotFoundException e) { 179 throw new AssertionViolatedException("Missing class: " + e.toString()); 181 } 182 } 183 184 187 public String toString(){ 188 StringBuffer sb = new StringBuffer (); 189 for (int i=0; i<locals.length; i++){ 190 sb.append(Integer.toString(i)); 191 sb.append(": "); 192 sb.append(locals[i]); 193 sb.append("\n"); 194 } 195 return sb.toString(); 196 } 197 198 202 public void initializeObject(UninitializedObjectType u){ 203 for (int i=0; i<locals.length; i++){ 204 if (locals[i] == u){ 205 locals[i] = u.getInitialized(); 206 } 207 } 208 } 209 } 210 | Popular Tags |