1 17 package org.apache.bcel.verifier.structurals; 18 19 20 import java.util.ArrayList ; 21 import org.apache.bcel.generic.ObjectType; 22 import org.apache.bcel.generic.ReferenceType; 23 import org.apache.bcel.generic.Type; 24 import org.apache.bcel.verifier.exc.AssertionViolatedException; 25 import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; 26 27 35 public class OperandStack{ 36 37 38 private ArrayList stack = new ArrayList (); 39 40 41 private int maxStack; 42 43 46 public OperandStack(int maxStack){ 47 this.maxStack = maxStack; 48 } 49 50 54 public OperandStack(int maxStack, ObjectType obj){ 55 this.maxStack = maxStack; 56 this.push(obj); 57 } 58 63 protected Object clone(){ 64 OperandStack newstack = new OperandStack(this.maxStack); 65 newstack.stack = (ArrayList ) this.stack.clone(); 66 return newstack; 67 } 68 69 72 public void clear(){ 73 stack = new ArrayList (); 74 } 75 76 78 public int hashCode() { return stack.hashCode(); } 79 80 85 public boolean equals(Object o){ 86 if (!(o instanceof OperandStack)) { 87 return false; 88 } 89 OperandStack s = (OperandStack) o; 90 return this.stack.equals(s.stack); 91 } 92 93 98 public OperandStack getClone(){ 99 return (OperandStack) this.clone(); 100 } 101 102 105 public boolean isEmpty(){ 106 return stack.isEmpty(); 107 } 108 109 112 public int maxStack(){ 113 return this.maxStack; 114 } 115 116 119 public Type peek(){ 120 return peek(0); 121 } 122 123 127 public Type peek(int i){ 128 return (Type) stack.get(size()-i-1); 129 } 130 131 134 public Type pop(){ 135 Type e = (Type) stack.remove(size()-1); 136 return e; 137 } 138 139 142 public Type pop(int i){ 143 for (int j=0; j<i; j++){ 144 pop(); 145 } 146 return null; 147 } 148 149 152 public void push(Type type){ 153 if (type == null) { 154 throw new AssertionViolatedException("Cannot push NULL onto OperandStack."); 155 } 156 if (type == Type.BOOLEAN || type == Type.CHAR || type == Type.BYTE || type == Type.SHORT){ 157 throw new AssertionViolatedException("The OperandStack does not know about '"+type+"'; use Type.INT instead."); 158 } 159 if (slotsUsed() >= maxStack){ 160 throw new AssertionViolatedException("OperandStack too small, should have thrown proper Exception elsewhere. Stack: "+this); 161 } 162 stack.add(type); 163 } 164 165 168 public int size(){ 169 return stack.size(); 170 } 171 172 176 public int slotsUsed(){ 177 181 int slots = 0; 182 for (int i=0; i<stack.size(); i++){ 183 slots += peek(i).getSize(); 184 } 185 return slots; 186 } 187 188 191 public String toString(){ 192 StringBuffer sb = new StringBuffer (); 193 sb.append("Slots used: "); 194 sb.append(slotsUsed()); 195 sb.append(" MaxStack: "); 196 sb.append(maxStack); 197 sb.append(".\n"); 198 for (int i=0; i<size(); i++){ 199 sb.append(peek(i)); 200 sb.append(" (Size: "); 201 sb.append(String.valueOf(peek(i).getSize())); 202 sb.append(")\n"); 203 } 204 return sb.toString(); 205 } 206 207 212 public void merge(OperandStack s){ 213 try { 214 if ( (slotsUsed() != s.slotsUsed()) || (size() != s.size()) ) { 215 throw new StructuralCodeConstraintException("Cannot merge stacks of different size:\nOperandStack A:\n"+this+"\nOperandStack B:\n"+s); 216 } 217 218 for (int i=0; i<size(); i++){ 219 if ( (! (stack.get(i) instanceof UninitializedObjectType)) && (s.stack.get(i) instanceof UninitializedObjectType) ){ 222 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object on the stack detected."); 223 } 224 if ( (!(stack.get(i).equals(s.stack.get(i)))) && (stack.get(i) instanceof UninitializedObjectType) && (!(s.stack.get(i) instanceof UninitializedObjectType))){ 227 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object on the stack detected."); 228 } 229 if (stack.get(i) instanceof UninitializedObjectType){ if (! (s.stack.get(i) instanceof UninitializedObjectType)){ stack.set(i, ((UninitializedObjectType) (stack.get(i))).getInitialized() ); } 234 } 235 if (! stack.get(i).equals(s.stack.get(i))){ 236 if ( (stack.get(i) instanceof ReferenceType) && 237 (s.stack.get(i) instanceof ReferenceType) ){ 238 stack.set(i, ((ReferenceType) stack.get(i)).getFirstCommonSuperclass((ReferenceType) (s.stack.get(i)))); 239 } 240 else{ 241 throw new StructuralCodeConstraintException("Cannot merge stacks of different types:\nStack A:\n"+this+"\nStack B:\n"+s); 242 } 243 } 244 } 245 } catch (ClassNotFoundException e) { 246 throw new AssertionViolatedException("Missing class: " + e.toString()); 248 } 249 } 250 251 255 public void initializeObject(UninitializedObjectType u){ 256 for (int i=0; i<stack.size(); i++){ 257 if (stack.get(i) == u){ 258 stack.set(i, u.getInitialized()); 259 } 260 } 261 } 262 263 } 264 | Popular Tags |