KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gov > nasa > jpf > jvm > StackFrame


1 //
2
// Copyright (C) 2005 United States Government as represented by the
3
// Administrator of the National Aeronautics and Space Administration
4
// (NASA). All Rights Reserved.
5
//
6
// This software is distributed under the NASA Open Source Agreement
7
// (NOSA), version 1.3. The NOSA has been approved by the Open Source
8
// Initiative. See the file NOSA-1.3-JPF at the top of the distribution
9
// directory tree for the complete NOSA document.
10
//
11
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
12
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
13
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
14
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
15
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
16
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
17
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
18
//
19
package gov.nasa.jpf.jvm;
20
21 import gov.nasa.jpf.JPFException;
22 import gov.nasa.jpf.jvm.bytecode.Instruction;
23 import gov.nasa.jpf.util.Debug;
24 import gov.nasa.jpf.util.HashData;
25
26 import java.util.Random JavaDoc;
27
28 import org.apache.bcel.Constants;
29
30
31 /**
32  * Describes a stack frame.
33  *
34  * implementation is based on the fact that each Java method has a fixed size
35  * operand stack (overrun actually checked by a real VM), and the heuristics that
36  * (a) stack / local operations are frequent
37  * (b) stack / local sizes are typically small (both < 10)
38  * hence a BitSet is not too useful
39  */

40 public class StackFrame implements Constants {
41   /**
42    * Used for random choices.
43    */

44   private static Random JavaDoc random = new Random JavaDoc();
45
46   /** top index of the operand stack (NOT size) */
47   int top;
48
49   /** since the 'this' local slot apparently can change during execution, we need to keep
50    * track of it elsewhere
51    */

52   int thisRef = -1;
53   
54   /** the operand stack (untyped, except of ref/no-ref) */
55   int[] operands;
56   boolean[] isOperandRef;
57   
58   /** This array can be used to store attributes (e.g. variable names) for
59    * operands. We don't do anything with this except of preserving it (across
60    * dups etc.), so it's pretty much up to the VM listeners what's stored
61    */

62   Object JavaDoc[] operandAttr;
63   
64   /**
65    * Local variables.
66    */

67   int[] locals;
68   boolean[] isLocalRef;
69   
70
71   /**
72    * Program counter.
73    */

74   private Instruction pc;
75
76   /**
77    * Method being executed.
78    */

79   private MethodInfo mi;
80
81   /**
82    * this is set to true if this method was directly called by the VM, i.e. there is
83    * no corresponding INVOKE instruction
84    */

85   private boolean isDirectCall;
86   
87   /**
88    * Creates a new stack frame for a given method.
89    * 'isDirect' specifies if this method was called directly by the VM, i.e. there is
90    * no corresponding INVOKE insn in the underlying stack frame (for instance, that's
91    * important to know for handling return values and computing the next pc)
92    * 'caller' is the calling stack frame (if any)
93    */

94   public StackFrame (MethodInfo m, boolean isDirect, StackFrame caller) {
95     mi = m;
96     pc = mi.getInstruction(0);
97     
98     int nOperands = mi.getMaxStack();
99     operands = new int[nOperands];
100     isOperandRef = new boolean[nOperands];
101     operandAttr = new Object JavaDoc[nOperands];
102     top = -1; // index, not size!
103

104     int nargs = mi.getArgumentsSize();
105     int nlocals = (pc == null) ? nargs : mi.getMaxLocals();
106     locals = new int[nlocals];
107     isLocalRef = new boolean[nlocals];
108
109     isDirectCall = isDirect;
110     
111     // copy the args, if any
112
if (nargs > 0 && (caller != null)) {
113       int[] a = caller.operands;
114       boolean[] r = caller.isOperandRef;
115       
116       for (int i=0, j=caller.top-nargs+1; i<nargs; i++, j++) {
117         locals[i] = a[j];
118         isLocalRef[i] = r[j];
119       }
120       
121       if (!mi.isStatic()) { // according to the spec, this is guaranteed upon entry
122
thisRef = locals[0];
123       }
124     }
125   }
126
127   public StackFrame (MethodInfo m, boolean isDirect, int objRef) {
128     this(m, isDirect, null);
129     
130     // maybe we should check here if this is an instance method
131

132     thisRef = objRef;
133     
134     locals[0] = thisRef;
135     isLocalRef[0] = true;
136   }
137   
138   /**
139    * Creates an empty stack frame. Used by clone.
140    */

141   private StackFrame () {
142   }
143   
144   public boolean isDirectCall () {
145     return isDirectCall;
146   }
147   
148   /**
149    * return the object reference for an instance method to be called (we are still in the
150    * caller's frame). This only makes sense after all params have been pushed, before the
151    * INVOKEx insn is executed
152    */

153   public int getCalleeThis (MethodInfo mi) {
154     return getCalleeThis(mi.getArgumentsSize());
155   }
156
157   /**
158    * return reference of called object in the context of the caller
159    * (i.e. we are in the caller frame)
160    */

161   public int getCalleeThis (int size) {
162     // top is the topmost index
163
int i = size-1;
164     if (top < i) {
165       return -1;
166     }
167
168     return operands[top-i];
169   }
170
171   public ClassInfo getClassInfo () {
172     return mi.getClassInfo();
173   }
174
175   // gets and sets some derived information
176
public int getLine () {
177     return mi.getLineNumber(pc);
178   }
179
180   public void setOperandAttr (Object JavaDoc o) {
181     operandAttr[top] = o;
182   }
183   
184   public Object JavaDoc getOperandAttr () {
185     if (top >=0 ){
186       return operandAttr[top];
187     } else {
188       return null;
189     }
190   }
191
192   public Object JavaDoc getOperandAttr (int offset) {
193     if (top >= offset) {
194       return operandAttr[top-offset];
195     } else {
196       return null;
197     }
198   }
199   
200   public void setLocalVariable (int index, int v, boolean ref) {
201     boolean activateGc = (isLocalRef[index] && (locals[index] != -1));
202
203     locals[index] = v;
204     isLocalRef[index] = ref;
205
206     if (ref) {
207       if (v != -1) activateGc = true;
208     }
209
210     if (activateGc) {
211         JVM.getVM().getSystemState().activateGC();
212     }
213   }
214
215   public int getLocalVariable (int i) {
216     return locals[i];
217   }
218
219   public int getLocalVariable (String JavaDoc name) {
220     return getLocalVariable(getLocalVariableOffset(name));
221   }
222
223   public String JavaDoc[] getLocalVariableNames () {
224     return mi.getLocalVariableNames();
225   }
226
227   public boolean isLocalVariableRef (int idx) {
228     return isLocalRef[idx];
229   }
230
231   public String JavaDoc getLocalVariableType (String JavaDoc name) {
232     String JavaDoc[] lNames = mi.getLocalVariableNames();
233     String JavaDoc[] lTypes = mi.getLocalVariableTypes();
234
235     if ((lNames != null) && (lTypes != null)) {
236       for (int i = 0, l = lNames.length; i < l; i++) {
237         if (name.equals(lNames[i])) {
238           return lTypes[i];
239         }
240       }
241     }
242
243     throw new JPFException("Local variable " + name + " not found");
244   }
245
246   public int[] getLocalVariables () {
247     return locals;
248   }
249
250   public void setLongLocalVariable (int index, long v) {
251
252     // local slots shouldn't change type, and 'long' can't be a reference,
253
// hence no isLocalRef update or gc request
254

255     locals[index + 1] = Types.loLong(v);
256     locals[index] = Types.hiLong(v);
257   }
258
259   public long getLongLocalVariable (int i) {
260     return Types.intsToLong(locals[i + 1], locals[i]);
261   }
262
263   public long getLongLocalVariable (String JavaDoc name) {
264     return getLongLocalVariable(getLocalVariableOffset(name));
265   }
266
267   public MethodInfo getMethodInfo () {
268     return mi;
269   }
270
271   public String JavaDoc getMethodName () {
272     return mi.getName();
273   }
274
275   public boolean isOperandRef (int idx) {
276     return isOperandRef[top-idx];
277   }
278
279   public boolean isOperandRef () {
280     return isOperandRef[top];
281   }
282
283   public void setPC (Instruction newpc) {
284     pc = newpc;
285   }
286
287   public Instruction getPC () {
288     return pc;
289   }
290
291   public String JavaDoc getStackTrace () {
292     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(128);
293     sb.append("\tat ");
294     sb.append(mi.getClassInfo().getName());
295     sb.append(".");
296     sb.append(mi.getName());
297
298     if (pc != null) {
299       sb.append("(");
300       sb.append(mi.getClassInfo().getSourceFileName());
301       sb.append(":");
302       sb.append(getLine());
303       sb.append(")");
304     } else {
305       sb.append("(Native Method)");
306     }
307     //sb.append('\n');
308

309     return sb.toString();
310   }
311
312   /**
313    * if this is an instance method, return the reference of the corresponding object
314    * (note this only has to be in slot 0 upon entry)
315    */

316   public int getThis () {
317     return thisRef;
318   }
319
320   // stack operations
321
public void clearOperandStack () {
322     top = -1;
323   }
324
325   // functions to handle exceptions
326
// creates a clone of the stack frame
327
public Object JavaDoc clone () {
328     StackFrame sf = new StackFrame();
329
330     sf.operands = new int[operands.length];
331     System.arraycopy(operands,0,sf.operands,0,top+1);
332
333     sf.isOperandRef = new boolean[operands.length];
334     System.arraycopy( isOperandRef, 0, sf.isOperandRef, 0, top+1);
335
336     sf.operandAttr = new Object JavaDoc[operands.length];
337     System.arraycopy(operandAttr, 0, sf.operandAttr, 0, top+1);
338     
339     sf.top = top;
340
341     sf.locals = new int[locals.length];
342     System.arraycopy(locals, 0, sf.locals, 0, locals.length);
343
344     sf.isLocalRef = new boolean[locals.length];
345     System.arraycopy(isLocalRef, 0, sf.isLocalRef, 0, locals.length);
346         
347     sf.pc = pc;
348     sf.mi = mi;
349
350     sf.isDirectCall = isDirectCall;
351     sf.thisRef = thisRef;
352     
353     return sf;
354   }
355
356   // all the dupses don't have any GC side effect (everything is already
357
// on the stack), so skip the GC requests associated with push()/pop()
358

359   public void dup () {
360     // .. A => .. A.A
361
int t= top;
362     top++;
363     
364     operands[top] = operands[t];
365     isOperandRef[top] = isOperandRef[t];
366     operandAttr[top] = operandAttr[t];
367   }
368
369   public void dup2 () {
370     // .. A B => .. A B.A B
371
int td = top+1;
372     int ts = top-1;
373     operands[td] = operands[ts];
374     isOperandRef[td] = isOperandRef[ts];
375     operandAttr[td] = operandAttr[ts];
376     
377     td++; ts++;
378     operands[td] = operands[ts];
379     isOperandRef[td] = isOperandRef[ts];
380     operandAttr[td] = operandAttr[ts];
381     
382     top = td;
383   }
384
385   public void dup2_x1 () {
386     // .. A B C => .. B C A.B C
387

388     int b, c;
389     boolean bRef, cRef;
390     Object JavaDoc bAnn, cAnn;
391     int ts, td;
392     
393     // duplicate B
394
ts = top-1; td = top+1;
395     operands[td] = b = operands[ts];
396     isOperandRef[td] = bRef = isOperandRef[ts];
397     operandAttr[td] = bAnn = operandAttr[ts];
398     
399     // duplicate C
400
ts=top; td++;
401     operands[td] = c = operands[ts];
402     isOperandRef[td] = cRef = isOperandRef[ts];
403     operandAttr[td] = cAnn = operandAttr[ts];
404
405     // shuffle A
406
ts=top-2; td=top;
407     operands[td] = operands[ts];
408     isOperandRef[td] = isOperandRef[ts];
409     operandAttr[td] = operandAttr[ts];
410     
411     // shuffle B
412
td = ts;
413     operands[td] = b;
414     isOperandRef[td] = bRef;
415     operandAttr[td] = bAnn;
416     
417     // shuffle C
418
td++;
419     operands[td] = c;
420     isOperandRef[td] = cRef;
421     operandAttr[td] = cAnn;
422     
423     top += 2;
424   }
425
426   public void dup2_x2 () {
427     // .. A B C D => .. C D A B.C D
428

429     int c, d;
430     boolean cRef, dRef;
431     Object JavaDoc cAnn, dAnn;
432     int ts, td;
433     
434     // duplicate C
435
ts = top-1; td = top+1;
436     operands[td] = c = operands[ts];
437     isOperandRef[td] = cRef = isOperandRef[ts];
438     operandAttr[td] = cAnn = operandAttr[ts];
439     
440     // duplicate D
441
ts=top; td++;
442     operands[td] = d = operands[ts];
443     isOperandRef[td] = dRef = isOperandRef[ts];
444     operandAttr[td] = dAnn = operandAttr[ts];
445
446     // shuffle A
447
ts = top-3; td = top-1;
448     operands[td] = operands[ts];
449     isOperandRef[td] = isOperandRef[ts];
450     operandAttr[td] = operandAttr[ts];
451     
452     // shuffle B
453
ts++; td = top;
454     operands[td] = operands[ts];
455     isOperandRef[td] = isOperandRef[ts];
456     operandAttr[td] = operandAttr[ts];
457     
458     // shuffle C
459
td=ts;
460     operands[td] = c;
461     isOperandRef[td] = cRef;
462     operandAttr[td] = cAnn;
463     
464     // shuffle C
465
td++;
466     operands[td] = d;
467     isOperandRef[td] = dRef;
468     operandAttr[td] = dAnn;
469     
470     top += 2;
471   }
472
473   public void dup_x1 () {
474     // .. A B => .. B A.B
475

476     int b;
477     boolean bRef;
478     Object JavaDoc bAnn;
479     int ts, td;
480     
481     // duplicate B
482
ts = top; td = top+1;
483     operands[td] = b = operands[ts];
484     isOperandRef[td] = bRef = isOperandRef[ts];
485     operandAttr[td] = bAnn = operandAttr[ts];
486     
487     // shuffle A
488
ts = top-1; td = top;
489     operands[td] = operands[ts];
490     isOperandRef[td] = isOperandRef[ts];
491     operandAttr[td] = operandAttr[ts];
492     
493     // shuffle B
494
td = ts;
495     operands[td] = b;
496     isOperandRef[td] = bRef;
497     operandAttr[td] = bAnn;
498     
499     top++;
500   }
501
502   public void dup_x2 () {
503     // .. A B C => .. C A B.C
504

505     int c;
506     boolean cRef;
507     Object JavaDoc cAnn;
508     int ts, td;
509     
510     // duplicate C
511
ts = top; td = top+1;
512     operands[td] = c = operands[ts];
513     isOperandRef[td] = cRef = isOperandRef[ts];
514     operandAttr[td] = cAnn = operandAttr[ts];
515     
516     // shuffle B
517
ts=top-1; td=top;
518     operands[td] = operands[ts];
519     isOperandRef[td] = isOperandRef[ts];
520     operandAttr[td] = operandAttr[ts];
521     
522     // shuffle A
523
td=ts; ts--;
524     operands[td] = operands[ts];
525     isOperandRef[td] = isOperandRef[ts];
526     operandAttr[td] = operandAttr[ts];
527
528     // shuffle C
529
td = ts;
530     operands[td] = c;
531     isOperandRef[td] = cRef;
532     operandAttr[td] = cAnn;
533     
534     top++;
535   }
536
537   
538   // <2do> pcm - I assume this compares snapshots, not types. Otherwise it
539
// would be pointless to compare stack/local values
540
public boolean equals (Object JavaDoc object) {
541     // casts to stack frame
542
StackFrame sf = (StackFrame) object;
543
544     // compares the program counter REFERENCES
545
// the code is statically read into the vm so the same
546
// chunk of code means the same reference
547
if (pc != sf.pc) {
548       return false;
549     }
550
551     if (mi != sf.mi) {
552       return false;
553     }
554
555     // compare the locals
556
int[] l = sf.locals;
557     boolean[] lr = sf.isLocalRef;
558     int nlocals = locals.length;
559
560     if (nlocals != l.length) {
561       return false;
562     }
563     for (int idx = 0; idx < nlocals; idx++) {
564       if ((locals[idx] != l[idx]) || (isLocalRef[idx] != lr[idx])) {
565         return false;
566       }
567     }
568
569     // compare the operand stacks
570
int[] o = sf.operands;
571     boolean[] or = sf.isOperandRef;
572
573     if (top != sf.top) {
574       return false;
575     }
576     for (int idx = 0; idx <= top; idx++) {
577       if ((operands[idx] != o[idx]) || (isOperandRef[idx] != or[idx]) ) {
578         return false;
579       }
580     }
581
582     return true;
583   }
584
585   public boolean hasAnyRef () {
586     for (int i=0; i<=top; i++) {
587       if (isOperandRef[i]) {
588         return true;
589       }
590     }
591     
592     for (int i = 0, l = locals.length; i < l; i++) {
593       if (isLocalRef[i]) {
594         return true;
595       }
596     }
597
598     return false;
599   }
600
601   public void hash (HashData hd) {
602     for (int i = 0, l = locals.length; i < l; i++) {
603       hd.add(locals[i]);
604     }
605
606     for (int i=0; i<=top; i++) {
607       hd.add(operands[i]);
608     }
609   }
610
611   // computes an hash code for the hash table
612
// the default hash code is different for each object
613
// we need to redifine it to make the hash table work
614
public int hashCode () {
615     HashData hd = new HashData();
616
617     hash(hd);
618
619     return hd.getValue();
620   }
621
622   public void log (int id) {
623     Debug.print(Debug.MESSAGE, " SF#" + id + " S(");
624
625     for (int i = 0; i <=top; i++) {
626       Debug.print(Debug.MESSAGE, " ");
627
628       if (isOperandRef[i]) {
629         Debug.print(Debug.MESSAGE, "#");
630       }
631
632       Debug.print(Debug.MESSAGE, operands[i] + "");
633     }
634
635     Debug.print(Debug.MESSAGE, " ) L(");
636
637     for (int i = 0; i < locals.length; i++) {
638       int j = locals[i];
639       Debug.print(Debug.MESSAGE, " ");
640
641       if (isLocalRef[i]) {
642         Debug.print(Debug.MESSAGE, "#");
643       }
644
645       Debug.print(Debug.MESSAGE, j + "");
646     }
647
648     Debug.print(Debug.MESSAGE, " ) ");
649
650     if (mi == null) {
651       Debug.print(Debug.MESSAGE, "null");
652     } else {
653       Debug.print(Debug.MESSAGE, mi.getCompleteName());
654     }
655
656     Debug.print(Debug.MESSAGE, ":");
657
658     if (pc == null) {
659       Debug.println(Debug.MESSAGE, "null");
660     } else {
661       Debug.println(Debug.MESSAGE, pc.getPosition() + " " + pc);
662     }
663   }
664
665   /**
666    * mark all objects reachable from local or operand stack positions containing
667    * references. Done during phase1 marking of threads (the stack is one of the
668    * Thread gc roots)
669    * @aspects: gc
670    */

671   public void markThreadRoots (int tid) {
672     DynamicArea heap = DynamicArea.getHeap();
673     int objRef;
674
675     for (int i=0; i<= top; i++) {
676       if (isOperandRef[i]) {
677         heap.markThreadRoot(operands[i], tid);
678       }
679     }
680
681     for (int i = 0, l = locals.length; i < l; i++) {
682       if (isLocalRef[i]) {
683         heap.markThreadRoot(locals[i], tid);
684       }
685     }
686   }
687   
688   
689   public void printStackContent () {
690     Debug.print(Debug.ERROR, "\tat ");
691     Debug.print(Debug.ERROR, mi.getCompleteName());
692
693     if (pc != null) {
694       Debug.println(Debug.ERROR, ":" + pc.getPosition());
695     } else {
696       Debug.println(Debug.ERROR);
697     }
698
699     Debug.println(Debug.ERROR, "\t Operand stack is:");
700
701     for (int i = 0; i <=top; i++) {
702       Debug.print(Debug.ERROR, "\t ");
703
704       if (isOperandRef[i]) {
705         Debug.print(Debug.ERROR, "#");
706       }
707
708       Debug.println(Debug.ERROR, operands[i]);
709     }
710
711     Debug.println(Debug.ERROR, "\t Local variables are:");
712
713     for (int i = 0, l = locals.length; i < l; i++) {
714       Debug.print(Debug.ERROR, "\t ");
715
716       if (isLocalRef[i]) {
717         Debug.print(Debug.ERROR, "#");
718       }
719
720       Debug.println(Debug.ERROR, "" + locals[i]);
721     }
722   }
723
724   public void printStackTrace () {
725     Debug.println(Debug.ERROR, getStackTrace());
726   }
727
728   public void swap () {
729     int t = top-1;
730     int v = operands[top];
731     boolean isRef = isOperandRef[top];
732     Object JavaDoc a = operandAttr[top];
733     
734     operands[top] = operands[t];
735     isOperandRef[top] = isOperandRef[t];
736     operandAttr[top] = operandAttr[t];
737     
738     operands[t] = v;
739     isOperandRef[t] = isRef;
740     operandAttr[t] = a;
741   }
742
743   public String JavaDoc toString () {
744     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
745
746     sb.append("StackFrame(");
747     sb.append("top="); sb.append(top);
748     sb.append("operands=");
749     sb.append('[');
750
751     for (int i = 0; i <= top; i++) {
752       if (i != 0) {
753         sb.append(',');
754       }
755
756       sb.append(operands[i]);
757       if (operandAttr[i] != null) {
758         sb.append('(');
759         sb.append(operandAttr[i]);
760         sb.append(')');
761       }
762     }
763
764     sb.append(']');
765     sb.append(',');
766     sb.append("locals=");
767     sb.append('[');
768
769     for (int i = 0; i < locals.length; i++) {
770       if (i != 0) {
771         sb.append(',');
772       }
773
774       sb.append(locals[i]);
775     }
776
777     sb.append(']');
778     sb.append(',');
779     sb.append("pc=");
780     sb.append(pc.getPosition());
781     sb.append(',');
782     sb.append("oRefs=");
783
784     for (int i = 0; i <= top; i++) {
785       sb.append(isOperandRef[i] ? 'R' : '-');
786     }
787
788     sb.append(',');
789     sb.append("lRefs=");
790
791     for (int i = 0; i < locals.length; i++) {
792       sb.append(isLocalRef[i] ? 'R' : '-');
793     }
794
795     sb.append(')');
796
797     return sb.toString();
798   }
799
800   long longPeek () {
801     return Types.intsToLong( operands[top], operands[top-1]);
802   }
803
804   long longPeek (int n) {
805     int i = top - n;
806     return Types.intsToLong( operands[i], operands[i-1]);
807   }
808
809   long longPop () {
810     int lo = pop();
811     int hi = pop();
812
813     return Types.intsToLong(lo, hi);
814   }
815
816   void longPush (long v) {
817     push(Types.hiLong(v), false);
818     push(Types.loLong(v), false);
819   }
820
821   int peek () {
822     return operands[top];
823   }
824
825   int peek (int n) {
826     return operands[top-n];
827   }
828
829   void pop (int n) {
830     int t = top - n;
831     for (int i=top; i>t; i--) {
832       if (isOperandRef[i] && (operands[i] != -1)) {
833         JVM.getVM().getSystemState().activateGC();
834         break;
835       }
836     }
837     
838     top = t;
839   }
840
841   int pop () {
842     int v = operands[top];
843
844     if (isOperandRef[top]) {
845       if (v != -1) {
846         JVM.getVM().getSystemState().activateGC();
847       }
848     }
849     top--;
850
851     // note that we don't reset the operands or oRefs values, so that
852
// we can still access them after the insn doing the pop got executed
853
// (e.g. useful for listeners)
854

855     return v;
856   }
857
858   void push (int v, boolean ref) {
859     top++;
860     operands[top] = v;
861     isOperandRef[top] = ref;
862     operandAttr[top] = null;
863     
864     if (ref && (v != -1)) {
865       JVM.getVM().getSystemState().activateGC();
866     }
867   }
868
869   // return the value of a variable given the name
870
private int getLocalVariableOffset (String JavaDoc name) {
871     String JavaDoc[] lNames = mi.getLocalVariableNames();
872     String JavaDoc[] lTypes = mi.getLocalVariableTypes();
873
874     int offset = 0;
875
876     for (int i = 0, l = lNames.length; i < l; i++) {
877       if (name.equals(lNames[i])) {
878         return offset;
879       } else {
880         offset += Types.getTypeSize(lTypes[i]);
881       }
882     }
883
884     throw new JPFException("Local variable " + name + " not found");
885   }
886
887 }
888
889
Popular Tags