1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.javaflow.bytecode;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.io.Serializable;
23 import org.apache.commons.javaflow.utils.ReflectionUtils;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27
28
29
30
31
32
33
34 public class Stack implements Serializable {
35
36 private static final Log log = LogFactory.getLog(Stack.class);
37 private static final long serialVersionUID = 2L;
38
39 private int[] istack;
40 private float[] fstack;
41 private double[] dstack;
42 private long[] lstack;
43 private Object[] ostack;
44 private Object[] rstack;
45 private int iTop, fTop, dTop, lTop, oTop, rTop;
46 protected Runnable runnable;
47
48 public Stack(Runnable pRunnable) {
49 istack = new int[10];
50 lstack = new long[5];
51 dstack = new double[5];
52 fstack = new float[5];
53 ostack = new Object[10];
54 rstack = new Object[5];
55 runnable = pRunnable;
56 }
57
58 public Stack(final Stack pParent) {
59 istack = new int[pParent.istack.length];
60 lstack = new long[pParent.lstack.length];
61 dstack = new double[pParent.dstack.length];
62 fstack = new float[pParent.fstack.length];
63 ostack = new Object[pParent.ostack.length];
64 rstack = new Object[pParent.rstack.length];
65 iTop = pParent.iTop;
66 fTop = pParent.fTop;
67 dTop = pParent.dTop;
68 lTop = pParent.lTop;
69 oTop = pParent.oTop;
70 rTop = pParent.rTop;
71 System.arraycopy(pParent.istack, 0, istack, 0, iTop);
72 System.arraycopy(pParent.fstack, 0, fstack, 0, fTop);
73 System.arraycopy(pParent.dstack, 0, dstack, 0, dTop);
74 System.arraycopy(pParent.lstack, 0, lstack, 0, lTop);
75 System.arraycopy(pParent.ostack, 0, ostack, 0, oTop);
76 System.arraycopy(pParent.rstack, 0, rstack, 0, rTop);
77 runnable = pParent.runnable;
78 }
79
80 public boolean hasDouble() {
81 return dTop > 0;
82 }
83
84 public double popDouble() {
85 if (dTop == 0) {
86 throw new EmptyStackException("pop double");
87 }
88
89 final double d = dstack[--dTop];
90 log.debug("pop double " + d + " " + getStats());
91 return d;
92 }
93
94 public boolean hasFloat() {
95 return fTop > 0;
96 }
97
98 public float popFloat() {
99 if (fTop == 0) {
100 throw new EmptyStackException("pop float");
101 }
102
103 final float f = fstack[--fTop];
104 log.debug("pop float " + f + " " + getStats());
105 return f;
106 }
107
108 public boolean hasInt() {
109 return iTop > 0;
110 }
111
112 public int popInt() {
113 if (iTop == 0) {
114 throw new EmptyStackException("pop int");
115 }
116
117 final int i = istack[--iTop];
118 log.debug("pop int " + i + " " + getStats());
119 return i;
120 }
121
122 public boolean hasLong() {
123 return lTop > 0;
124 }
125
126 public long popLong() {
127 if (lTop == 0) {
128 throw new EmptyStackException("pop long");
129 }
130
131 final long l = lstack[--lTop];
132 log.debug("pop long " + l + " " + getStats());
133 return l;
134 }
135
136 public boolean hasObject() {
137 return oTop > 0;
138 }
139
140 public Object popObject() {
141 if (oTop == 0) {
142 throw new EmptyStackException("pop object");
143 }
144
145 final Object o = ostack[--oTop];
146 ostack[oTop] = null;
147
148 if(log.isDebugEnabled()) {
149 final String clazz = ReflectionUtils.getClassName(o);
150 final String clazzLoader = ReflectionUtils.getClassLoaderName(o);
151
152 log.debug("pop object "+ clazz + "/" + clazzLoader + " [" + o + "] ");
153 }
154
155 return o;
156 }
157
158 public boolean hasReference() {
159 return rTop > 0;
160 }
161
162 public Object popReference() {
163 if (rTop == 0) {
164 throw new EmptyStackException("pop reference");
165 }
166
167 final Object o = rstack[--rTop];
168 rstack[rTop] = null;
169
170 if(log.isDebugEnabled()) {
171 final String clazz = ReflectionUtils.getClassName(o);
172 final String clazzLoader = ReflectionUtils.getClassLoaderName(o);
173
174 log.debug("pop reference "+ clazz + "/" + clazzLoader + " [" + o + "] " + getStats());
175 }
176
177 return o;
178 }
179
180 public void pushDouble(double d) {
181 log.debug("push double " + d + " " + getStats());
182
183 if (dTop == dstack.length) {
184 double[] hlp = new double[Math.max(8,dstack.length*2)];
185 System.arraycopy(dstack, 0, hlp, 0, dstack.length);
186 dstack = hlp;
187 }
188 dstack[dTop++] = d;
189 }
190
191 public void pushFloat(float f) {
192 log.debug("push float " + f + " " + getStats());
193
194 if (fTop == fstack.length) {
195 float[] hlp = new float[Math.max(8,fstack.length*2)];
196 System.arraycopy(fstack, 0, hlp, 0, fstack.length);
197 fstack = hlp;
198 }
199 fstack[fTop++] = f;
200 }
201
202 public void pushInt(int i) {
203 log.debug("push int " + i + " " + getStats());
204
205 if (iTop == istack.length) {
206 int[] hlp = new int[Math.max(8,istack.length*2)];
207 System.arraycopy(istack, 0, hlp, 0, istack.length);
208 istack = hlp;
209 }
210 istack[iTop++] = i;
211 }
212
213 public void pushLong(long l) {
214 log.debug("push long " + l + " " + getStats());
215
216 if (lTop == lstack.length) {
217 long[] hlp = new long[Math.max(8,lstack.length*2)];
218 System.arraycopy(lstack, 0, hlp, 0, lstack.length);
219 lstack = hlp;
220 }
221 lstack[lTop++] = l;
222 }
223
224 public void pushObject(Object o) {
225
226 if (log.isDebugEnabled()) {
227 final String clazz = ReflectionUtils.getClassName(o);
228 final String clazzLoader = ReflectionUtils.getClassLoaderName(o);
229 log.debug("push object " + clazz + "/" + clazzLoader + " [" + o + "] " + getStats());
230 }
231
232 if (oTop == ostack.length) {
233 Object[] hlp = new Object[Math.max(8,ostack.length*2)];
234 System.arraycopy(ostack, 0, hlp, 0, ostack.length);
235 ostack = hlp;
236 }
237 ostack[oTop++] = o;
238 }
239
240 public void pushReference(Object o) {
241
242 if (log.isDebugEnabled()) {
243 final String clazz = ReflectionUtils.getClassName(o);
244 final String clazzLoader = ReflectionUtils.getClassLoaderName(o);
245
246 log.debug("push reference " + clazz + "/" + clazzLoader + " [" + o + "] " + getStats());
247 }
248
249 if (rTop == rstack.length) {
250 Object[] hlp = new Object[Math.max(8,rstack.length*2)];
251 System.arraycopy(rstack, 0, hlp, 0, rstack.length);
252 rstack = hlp;
253 }
254 rstack[rTop++] = o;
255 }
256
257 public boolean isSerializable() {
258 for (int i = 0; i < rTop; i++) {
259 final Object r = rstack[i];
260 if (!(r instanceof Serializable)) {
261 return false;
262 }
263 }
264 for (int i = 0; i < oTop; i++) {
265 final Object o = ostack[i];
266 if (!(o instanceof Serializable)) {
267 return false;
268 }
269 }
270 return true;
271 }
272
273 public boolean isEmpty() {
274 return iTop==0 && lTop==0 && dTop==0 && fTop==0 && oTop==0 && rTop==0;
275 }
276
277 private String getStats() {
278 final StringBuffer sb = new StringBuffer();
279 sb.append("i[").append(iTop).append("],");
280 sb.append("l[").append(lTop).append("],");
281 sb.append("d[").append(dTop).append("],");
282 sb.append("f[").append(fTop).append("],");
283 sb.append("o[").append(oTop).append("],");
284 sb.append("r[").append(rTop).append("]");
285 return sb.toString();
286 }
287
288 private String getContent() {
289 final StringBuffer sb = new StringBuffer();
290 sb.append("i[").append(iTop).append("]\n");
291 sb.append("l[").append(lTop).append("]\n");
292 sb.append("d[").append(dTop).append("]\n");
293 sb.append("f[").append(fTop).append("]\n");
294 sb.append("o[").append(oTop).append("]\n");
295 for(int i=0; i<oTop;i++) {
296 sb.append(' ').append(i).append(": ");
297 sb.append(ReflectionUtils.getClassName(ostack[i])).append('/').append(ReflectionUtils.getClassLoaderName(ostack[i]));
298 sb.append('\n');
299 }
300 sb.append("r[").append(rTop).append("]\n");
301 for(int i=0; i<rTop;i++) {
302 sb.append(' ').append(i).append(": ");
303 sb.append(ReflectionUtils.getClassName(rstack[i])).append('/').append(ReflectionUtils.getClassLoaderName(rstack[i]));
304 sb.append('\n');
305 }
306
307 return sb.toString();
308 }
309
310 public String toString() {
311 return getContent();
312 }
313
314
315 private void writeObject(ObjectOutputStream s) throws IOException {
316 s.writeInt(iTop);
317 for( int i=0; i<iTop; i++ ) {
318 s.writeInt(istack[i]);
319 }
320
321 s.writeInt(lTop);
322 for( int i=0; i<lTop; i++ ) {
323 s.writeLong(lstack[i]);
324 }
325
326 s.writeInt(dTop);
327 for( int i=0; i<dTop; i++ ) {
328 s.writeDouble(dstack[i]);
329 }
330
331 s.writeInt(fTop);
332 for( int i=0; i<fTop; i++ ) {
333 s.writeDouble(fstack[i]);
334 }
335
336 s.writeInt(oTop);
337 for( int i=0; i<oTop; i++ ) {
338 s.writeObject(ostack[i]);
339 }
340
341 s.writeInt(rTop);
342 for( int i=0; i<rTop; i++ ) {
343 s.writeObject(rstack[i]);
344 }
345
346 s.writeObject(runnable);
347 }
348
349 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
350 iTop = s.readInt();
351 istack = new int[iTop];
352 for( int i=0; i<iTop; i++ ) {
353 istack[i] = s.readInt();
354 }
355
356 lTop = s.readInt();
357 lstack = new long[lTop];
358 for( int i=0; i<lTop; i++ ) {
359 lstack[i] = s.readLong();
360 }
361
362 dTop = s.readInt();
363 dstack = new double[dTop];
364 for( int i=0; i<dTop; i++ ) {
365 dstack[i] = s.readDouble();
366 }
367
368 fTop = s.readInt();
369 fstack = new float[fTop];
370 for( int i=0; i<fTop; i++ ) {
371 fstack[i] = s.readFloat();
372 }
373
374 oTop = s.readInt();
375 ostack = new Object[oTop];
376 for( int i=0; i<oTop; i++ ) {
377 ostack[i] = s.readObject();
378 }
379
380 rTop = s.readInt();
381 rstack = new Object[rTop];
382 for( int i=0; i<rTop; i++ ) {
383 rstack[i] = s.readObject();
384 }
385
386 runnable = (Runnable)s.readObject();
387 }
388
389 }