1 package com.sun.org.apache.bcel.internal.verifier.structurals; 2 3 56 57 import com.sun.org.apache.bcel.internal.generic.*; 58 import com.sun.org.apache.bcel.internal.verifier.exc.*; 59 import java.util.*; 60 61 69 public class OperandStack{ 70 71 72 private ArrayList stack = new ArrayList(); 73 74 75 private int maxStack; 76 77 80 public OperandStack(int maxStack){ 81 this.maxStack = maxStack; 82 } 83 84 88 public OperandStack(int maxStack, ObjectType obj){ 89 this.maxStack = maxStack; 90 this.push(obj); 91 } 92 97 protected Object clone(){ 98 OperandStack newstack = new OperandStack(this.maxStack); 99 newstack.stack = (ArrayList) this.stack.clone(); 100 return newstack; 101 } 102 103 106 public void clear(){ 107 stack = new ArrayList(); 108 } 109 110 115 public boolean equals(Object o){ 116 if (!(o instanceof OperandStack)) return false; 117 OperandStack s = (OperandStack) o; 118 return this.stack.equals(s.stack); 119 } 120 121 126 public OperandStack getClone(){ 127 return (OperandStack) this.clone(); 128 } 129 130 133 public boolean isEmpty(){ 134 return stack.isEmpty(); 135 } 136 137 140 public int maxStack(){ 141 return this.maxStack; 142 } 143 144 147 public Type peek(){ 148 return peek(0); 149 } 150 151 155 public Type peek(int i){ 156 return (Type) stack.get(size()-i-1); 157 } 158 159 162 public Type pop(){ 163 Type e = (Type) stack.remove(size()-1); 164 return e; 165 } 166 167 170 public Type pop(int i){ 171 for (int j=0; j<i; j++){ 172 pop(); 173 } 174 return null; 175 } 176 177 180 public void push(Type type){ 181 if (type == null) throw new AssertionViolatedException("Cannot push NULL onto OperandStack."); 182 if (type == Type.BOOLEAN || type == Type.CHAR || type == Type.BYTE || type == Type.SHORT){ 183 throw new AssertionViolatedException("The OperandStack does not know about '"+type+"'; use Type.INT instead."); 184 } 185 if (slotsUsed() >= maxStack){ 186 throw new AssertionViolatedException("OperandStack too small, should have thrown proper Exception elsewhere. Stack: "+this); 187 } 188 stack.add(type); 189 } 190 191 194 int size(){ 195 return stack.size(); 196 } 197 198 202 public int slotsUsed(){ 203 207 int slots = 0; 208 for (int i=0; i<stack.size(); i++){ 209 slots += peek(i).getSize(); 210 } 211 return slots; 212 } 213 214 217 public String toString(){ 218 String s = "Slots used: "+slotsUsed()+" MaxStack: "+maxStack+".\n"; 219 for (int i=0; i<size(); i++){ 220 s+=peek(i)+" (Size: "+peek(i).getSize()+")\n"; 221 } 222 return s; 223 } 224 225 230 public void merge(OperandStack s){ 231 if ( (slotsUsed() != s.slotsUsed()) || (size() != s.size()) ) 232 throw new StructuralCodeConstraintException("Cannot merge stacks of different size:\nOperandStack A:\n"+this+"\nOperandStack B:\n"+s); 233 234 for (int i=0; i<size(); i++){ 235 if ( (! (stack.get(i) instanceof UninitializedObjectType)) && (s.stack.get(i) instanceof UninitializedObjectType) ){ 238 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object on the stack detected."); 239 } 240 if ( (!(stack.get(i).equals(s.stack.get(i)))) && (stack.get(i) instanceof UninitializedObjectType) && (!(s.stack.get(i) instanceof UninitializedObjectType))){ 243 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object on the stack detected."); 244 } 245 if (stack.get(i) instanceof UninitializedObjectType){ if (! (s.stack.get(i) instanceof UninitializedObjectType)){ stack.set(i, ((UninitializedObjectType) (stack.get(i))).getInitialized() ); } 250 } 251 if (! stack.get(i).equals(s.stack.get(i))){ 252 if ( (stack.get(i) instanceof ReferenceType) && 253 (s.stack.get(i) instanceof ReferenceType) ){ 254 stack.set(i, ((ReferenceType) stack.get(i)).firstCommonSuperclass((ReferenceType) (s.stack.get(i)))); 255 } 256 else{ 257 throw new StructuralCodeConstraintException("Cannot merge stacks of different types:\nStack A:\n"+this+"\nStack B:\n"+s); 258 } 259 } 260 } 261 } 262 263 267 public void initializeObject(UninitializedObjectType u){ 268 for (int i=0; i<stack.size(); i++){ 269 if (stack.get(i) == u){ 270 stack.set(i, u.getInitialized()); 271 } 272 } 273 } 274 275 } 276 | Popular Tags |