Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: netscape/jsdebug/ThreadStateBase.java


1   /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2    *
3    * The contents of this file are subject to the Netscape Public
4    * License Version 1.1 (the "License"); you may not use this file
5    * except in compliance with the License. You may obtain a copy of
6    * the License at http://www.mozilla.org/NPL/
7    *
8    * Software distributed under the License is distributed on an "AS
9    * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10   * implied. See the License for the specific language governing
11   * rights and limitations under the License.
12   *
13   * The Original Code is mozilla.org code.
14   *
15   * The Initial Developer of the Original Code is Netscape
16   * Communications Corporation.  Portions created by Netscape are
17   * Copyright (C) 1998 Netscape Communications Corporation. All
18   * Rights Reserved.
19   *
20   * Contributor(s): 
21   */
22  
23  package netscape.jsdebug;
24  
25  /*  
26  *  jband - 03/19/97
27  *
28  *  This is an 'abstracted version of netscape.debug.ThreadState 
29  *
30  *  The methods that were 'native' there are 'abstract' here.
31  *  Changed 'private' data to 'protected' (though native access is immune)
32  *  Changed 'private' resume0() to 'protected'
33  *  Removed ThreadHook referneces
34  *
35  */
36  
37  /**
38  * When a hook is hit, the debugger records the state of the
39  * thread before the hook in a ThreadState object.  This object
40  * is then passed to any hook methods that are called, and can
41  * be used to change the state of the thread when it resumes from the
42  * hook.
43  *
44  * @author  John Bandhauer
45  * @author  Nick Thompson
46  * @version 1.0
47  * @since   1.0
48  */
49  public abstract class ThreadStateBase {
50      protected Thread thread;
51      protected boolean valid;
52      protected boolean runningHook;
53      protected boolean resumeWhenDone;
54      protected int status;
55      protected int continueState;
56      protected StackFrameInfo[] stack; /* jband - 03/19/97 - had no access modifier */
57      protected Object returnValue;
58      protected Throwable currentException;
59      protected int currentFramePtr;  /* used internally */
60      protected ThreadStateBase previous;
61  
62      /**
63       * <B><font color="red">Not Implemented.</font></B> 
64       * Always throws <code>InternalError("unimplemented")</code>
65       */
66      public static ThreadStateBase getThreadState(Thread t)
67          throws InvalidInfoException
68      {
69          throw new InternalError("unimplemented");
70      }
71  
72      /**
73       * Get the Thread that this ThreadState came from.
74       */
75      public Thread getThread() {
76          return thread;
77      }
78  
79      /**
80       * Return true if the Thread hasn't been resumed since this ThreadState
81       * was made.
82       */
83      public boolean isValid() {
84          return valid;
85      }
86  
87      /**
88       * Return true if the thread is currently running a hook
89       * for this ThreadState
90       */
91      public boolean isRunningHook() {
92          return runningHook;
93      }
94  
95      /**
96       * partial list of thread states from sun.debug.ThreadInfo.
97       * XXX some of these don't apply.
98       */
99      public final static int THR_STATUS_UNKNOWN    = 0x01;
100     public final static int THR_STATUS_ZOMBIE    = 0x02;
101     public final static int THR_STATUS_RUNNING    = 0x03;
102     public final static int THR_STATUS_SLEEPING    = 0x04;
103     public final static int THR_STATUS_MONWAIT    = 0x05;
104     public final static int THR_STATUS_CONDWAIT    = 0x06;
105     public final static int THR_STATUS_SUSPENDED  = 0x07;
106     public final static int THR_STATUS_BREAK    = 0x08;
107 
108     /** 
109      * Get the state of the thread at the time it entered debug mode.
110      * This can't be modified directly.
111      */
112     public int getStatus() {
113         return status;
114     }
115 
116     /** 
117      * Get the count of the stackframes
118      */
119     public abstract int countStackFrames()
120         throws InvalidInfoException;
121     /** 
122      * Get the 'top' stackframe; i.e. the one with the current instruction
123      */
124     public abstract StackFrameInfo getCurrentFrame()
125         throws InvalidInfoException;
126 
127     /**
128      * Get the thread's stack as an array.  stack[stack.length-1] is the
129      * current frame, and stack[0] is the beginning of the stack.
130      */
131     public synchronized StackFrameInfo[] getStack()
132         throws InvalidInfoException {
133         // XXX check valid?
134         if (stack == null) {
135             stack = new StackFrameInfo[countStackFrames()];
136         }
137 
138         if (stack.length == 0)
139             return stack;
140 
141         StackFrameInfo frame = getCurrentFrame();
142         stack[stack.length - 1] = frame;
143         for (int i = stack.length - 2; i >= 0; i--) {
144             frame = frame.getCaller();
145             stack[i] = frame;
146         }
147 
148         // should really be read-only for safety
149         return stack;
150     }
151 
152     /**
153      * Leave the thread in a suspended state when the hook method(s)
154      * finish.  This can be undone by calling resume().  This is the
155      * default only if the break was the result of
156      * DebugController.sendInterrupt().
157      */
158     public void leaveSuspended() {
159         resumeWhenDone = false;
160     }
161 
162     /**
163      * Resume the thread.  This is the default unless the break was the result
164      * of DebugController.sendInterrupt(). This method may be called from a
165      * hook method, in which case the thread will resume when the
166      * method returns.
167      * Alternatively, if there is no active hook method and
168      * the thread is suspended around in the DebugFrame, this resumes it
169      * immediately.
170      */
171     public synchronized void resume() {
172         if (runningHook)
173             resumeWhenDone = true;
174         else
175             resume0();
176     }
177 
178     protected abstract void resume0();
179 
180     /**
181      * if the continueState is DEAD, the thread cannot
182      * be restarted.
183      */
184     public final static int DEBUG_STATE_DEAD    = 0x01;
185 
186     /**
187      * if the continueState is RUN, the thread will
188      * proceed to the next program counter value when it resumes.
189      */
190     public final static int DEBUG_STATE_RUN    = 0x02;
191 
192     /**
193      * if the continueState is RETURN, the thread will
194      * return from the current method with the value in getReturnValue()
195      * when it resumes.
196      */
197     public final static int DEBUG_STATE_RETURN    = 0x03;
198 
199     /**
200      * if the continueState is THROW, the thread will
201      * throw an exception (accessible with getException()) when it
202      * resumes.
203      */
204     public final static int DEBUG_STATE_THROW    = 0x04;
205 
206     /**
207      * This gets the current continue state of the debug frame, which
208      * will be one of the DEBUG_STATE_* values above.
209      */
210     public int getContinueState() {
211         return continueState;
212     }
213 
214     public int setContinueState(int state) {
215         int old = continueState;
216         continueState = state;
217         return old;
218     }
219 
220     /**
221      * If the thread was stopped while in the process of returning
222      * a value, this call returns an object representing that value.
223      * non-Object values are wrapped as in the java.lang.reflect api.
224      * This is only relevant if the continue state is RETURN, and the
225      * method throws an IllegalStateException otherwise.
226      */
227     public Object getReturnValue() throws IllegalStateException {
228         if (continueState != DEBUG_STATE_RETURN)
229             throw new IllegalStateException("no value being returned");
230         return returnValue;
231     }
232 
233     /** 
234      * If the thread was stopped while in the process of throwing an
235      * exception, this call returns that exception.  
236      * This is only relevant if the continue state is THROW, and it
237      * throws an IllegalStateException otherwise.
238      */
239     public Throwable getException() throws IllegalStateException {
240         if (continueState != DEBUG_STATE_THROW)
241             throw new IllegalStateException("no exception throw in progress");
242         return currentException;
243     }
244 }
245