1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser;
18
19 import org.apache.bcel.generic.*;
20 import org.apache.bcel.verifier.exc.*;
21 import java.util.*;
22
23
24
25
26
27
28
29
30
31
32
33 public class OperandStack{
34
35
36 private ArrayList stack = new ArrayList();
37
38
39 private int maxStack;
40
41
42
43
44 public OperandStack(int maxStack){
45 this.maxStack = maxStack;
46 }
47
48
49
50
51
52 public OperandStack(int maxStack, ObjectType obj){
53 this.maxStack = maxStack;
54 this.push(obj);
55 }
56
57
58
59
60
61 protected Object clone(){
62 OperandStack newstack = new OperandStack(this.maxStack);
63 newstack.stack = (ArrayList) this.stack.clone();
64 return newstack;
65 }
66
67
68
69
70 public void clear(){
71 stack = new ArrayList();
72 }
73
74
75
76
77
78
79 public boolean equals(Object o){
80 if (!(o instanceof OperandStack)) return false;
81 OperandStack s = (OperandStack) o;
82 return this.stack.equals(s.stack);
83 }
84
85
86
87
88
89
90 public OperandStack getClone(){
91 return (OperandStack) this.clone();
92 }
93
94
95
96
97 public boolean isEmpty(){
98 return stack.isEmpty();
99 }
100
101
102
103
104 public int maxStack(){
105 return this.maxStack;
106 }
107
108
109
110
111 public Type peek(){
112 return peek(0);
113 }
114
115
116
117
118
119 public Type peek(int i){
120 return (Type) stack.get(size()-i-1);
121 }
122
123
124
125
126 public Type pop(){
127 Type e = (Type) stack.remove(size()-1);
128 return e;
129 }
130
131
132
133
134 public Type pop(int i){
135 for (int j=0; j<i; j++){
136 pop();
137 }
138 return null;
139 }
140
141
142
143
144 public void push(Type type){
145 if (type == null) throw new AssertionViolatedException("Cannot push NULL onto OperandStack.");
146 if (type == Type.BOOLEAN || type == Type.CHAR || type == Type.BYTE || type == Type.SHORT){
147 throw new AssertionViolatedException("The OperandStack does not know about '"+type+"'; use Type.INT instead.");
148 }
149 if (slotsUsed() >= maxStack){
150 throw new AssertionViolatedException("OperandStack too small, should have thrown proper Exception elsewhere. Stack: "+this);
151 }
152 stack.add(type);
153 }
154
155
156
157
158 public int size(){
159 return stack.size();
160 }
161
162
163
164
165
166 public int slotsUsed(){
167
168
169
170
171 int slots = 0;
172 for (int i=0; i<stack.size(); i++){
173 slots += peek(i).getSize();
174 }
175 return slots;
176 }
177
178
179
180
181 public String toString(){
182 String s = "Slots used: "+slotsUsed()+" MaxStack: "+maxStack+".\n";
183 for (int i=0; i<size(); i++){
184 s+=peek(i)+" (Size: "+peek(i).getSize()+")\n";
185 }
186 return s;
187 }
188
189
190
191
192
193
194 public void merge(OperandStack s){
195 if ( (slotsUsed() != s.slotsUsed()) || (size() != s.size()) )
196 throw new StructuralCodeConstraintException("Cannot merge stacks of different size:\nOperandStack A:\n"+this+"\nOperandStack B:\n"+s);
197
198 for (int i=0; i<size(); i++){
199 this.stack.set(i, Frame.merge((Type)this.stack.get(i), (Type)s.stack.get(i), true));
200 }
201 }
202
203
204
205
206
207 public void initializeObject(UninitializedObjectType u){
208 for (int i=0; i<stack.size(); i++){
209 if (stack.get(i) == u){
210 stack.set(i, u.getInitialized());
211 }
212 }
213 }
214
215 }