KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > StackFrameImpl


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdi.internal;
12
13
14 import java.io.ByteArrayOutputStream JavaDoc;
15 import java.io.DataInputStream JavaDoc;
16 import java.io.DataOutputStream JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
25 import org.eclipse.jdi.internal.jdwp.JdwpFrameID;
26 import org.eclipse.jdi.internal.jdwp.JdwpID;
27 import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
28 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
29
30 import com.sun.jdi.AbsentInformationException;
31 import com.sun.jdi.ClassNotLoadedException;
32 import com.sun.jdi.InvalidStackFrameException;
33 import com.sun.jdi.InvalidTypeException;
34 import com.sun.jdi.LocalVariable;
35 import com.sun.jdi.Locatable;
36 import com.sun.jdi.Location;
37 import com.sun.jdi.ObjectReference;
38 import com.sun.jdi.StackFrame;
39 import com.sun.jdi.ThreadReference;
40 import com.sun.jdi.VMMismatchException;
41 import com.sun.jdi.Value;
42
43 /**
44  * this class implements the corresponding interfaces
45  * declared by the JDI specification. See the com.sun.jdi package
46  * for more information.
47  *
48  */

49 public class StackFrameImpl extends MirrorImpl implements StackFrame, Locatable {
50     /** FrameID that corresponds to this reference. */
51     private JdwpFrameID fFrameID;
52     /** Thread under which this frame's method is running. */
53     private ThreadReferenceImpl fThread;
54     /** Location of the current instruction in the frame. */
55     private LocationImpl fLocation;
56     
57     /**
58      * Creates new StackFrameImpl.
59      */

60     public StackFrameImpl(VirtualMachineImpl vmImpl, JdwpFrameID ID, ThreadReferenceImpl thread, LocationImpl location) {
61         super("StackFrame", vmImpl); //$NON-NLS-1$
62
fFrameID = ID;
63         fThread = thread;
64         fLocation = location;
65     }
66
67     /**
68      * @return Returns the Value of a LocalVariable in this frame.
69      */

70     public Value getValue(LocalVariable variable) throws IllegalArgumentException JavaDoc, InvalidStackFrameException, VMMismatchException {
71         ArrayList JavaDoc list = new ArrayList JavaDoc(1);
72         list.add(variable);
73         return (ValueImpl)getValues(list).get(variable);
74     }
75     
76     /**
77      * @return Returns the values of multiple local variables in this frame.
78      */

79     public Map JavaDoc getValues(List JavaDoc variables) throws IllegalArgumentException JavaDoc, InvalidStackFrameException, VMMismatchException {
80         // Note that this information should not be cached.
81
Map JavaDoc map = new HashMap JavaDoc(variables.size());
82         // if the variable list is empty, nothing to do
83
if (variables.isEmpty()) {
84             return map;
85         }
86         /*
87          * If 'this' is requested, we have to use a special JDWP request.
88          * Therefore, we remember the positions in the list of requests for 'this'.
89          */

90         int sizeAll = variables.size();
91         int sizeThis = 0;
92         boolean[] isThisValue = new boolean[sizeAll];
93         for (int i = 0; i < sizeAll; i++) {
94             LocalVariableImpl var = (LocalVariableImpl)variables.get(i);
95             isThisValue[i] = var.isThis();
96             if (isThisValue[i]) {
97                 sizeThis++;
98             }
99         }
100         int sizeNotThis = sizeAll - sizeThis;
101         
102         if (sizeThis > 0) {
103             Value thisValue = thisObject();
104             for (int i = 0; i < sizeAll; i++) {
105                 if (isThisValue[i]) {
106                     map.put(variables.get(i), thisValue);
107                 }
108             }
109         }
110         
111         // If only 'this' was requested, we're finished.
112
if (sizeNotThis == 0) {
113             return map;
114         }
115             
116         // Request values for local variables other than 'this'.
117
initJdwpRequest();
118         try {
119             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
120             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
121             writeWithThread(this, outData);
122             writeInt(sizeNotThis, "size", outData); //$NON-NLS-1$
123
for (int i = 0; i < sizeAll; i++) {
124                 if (!isThisValue[i]) {
125                     LocalVariableImpl var = (LocalVariableImpl)variables.get(i);
126                     checkVM(var);
127                     writeInt(var.slot(), "slot", outData); //$NON-NLS-1$
128
writeByte(var.tag(), "tag", JdwpID.tagMap(), outData); //$NON-NLS-1$
129
}
130             }
131             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.SF_GET_VALUES, outBytes);
132             defaultReplyErrorHandler(replyPacket.errorCode());
133         
134             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
135             int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
136
if (nrOfElements != sizeNotThis)
137                 throw new InternalError JavaDoc(JDIMessages.StackFrameImpl_Retrieved_a_different_number_of_values_from_the_VM_than_requested_1);
138             
139             for (int i = 0, j = 0; i < sizeAll; i++) {
140                 if (!isThisValue[i])
141                     map.put(variables.get(j++), ValueImpl.readWithTag(this, replyData));
142             }
143             return map;
144         } catch (IOException JavaDoc e) {
145             defaultIOExceptionHandler(e);
146             return null;
147         } finally {
148             handledJdwpRequest();
149         }
150     }
151
152     /**
153      * @see com.sun.jdi.StackFrame#getArgumentValues()
154      * @since 3.3
155      */

156     public List JavaDoc getArgumentValues() throws InvalidStackFrameException {
157         if(!thread().isSuspended()) {
158             throw new InvalidStackFrameException(JDIMessages.StackFrameImpl_no_argument_values_available);
159         }
160         try {
161             List JavaDoc list = location().method().variables();
162             ArrayList JavaDoc ret = new ArrayList JavaDoc();
163             LocalVariable var = null;
164             for(Iterator JavaDoc iter = list.iterator(); iter.hasNext();){
165                 var = (LocalVariable) iter.next();
166                 if(var.isArgument()) {
167                     ret.add(getValue(var));
168                 }
169             }
170             return ret;
171         }
172         catch (AbsentInformationException e) {
173             JDIDebugPlugin.log(e);
174             return null;
175         }
176     }
177     
178     /**
179      * @return Returns the Location of the current instruction in the frame.
180      */

181     public Location location() {
182         return fLocation;
183     }
184     
185     /**
186      * Sets the Value of a LocalVariable in this frame.
187      */

188     public void setValue(LocalVariable var, Value value) throws InvalidTypeException, ClassNotLoadedException {
189         // Note that this information should not be cached.
190
initJdwpRequest();
191         try {
192             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
193             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
194             ((ThreadReferenceImpl)thread()).write(this, outData);
195             write(this, outData);
196             writeInt(1, "size", outData); // We only set one field //$NON-NLS-1$
197
checkVM(var);
198             writeInt(((LocalVariableImpl)var).slot(), "slot", outData); //$NON-NLS-1$
199

200             // check the type and the vm of the value, convert the value if needed.
201
ValueImpl checkedValue= ValueImpl.checkValue(value, var.type(), virtualMachineImpl());
202             
203             if (checkedValue != null) {
204                 checkedValue.writeWithTag(this, outData);
205             } else {
206                 ValueImpl.writeNullWithTag(this, outData);
207             }
208     
209             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.SF_SET_VALUES, outBytes);
210             switch (replyPacket.errorCode()) {
211                 case JdwpReplyPacket.INVALID_CLASS:
212                     throw new ClassNotLoadedException(var.typeName());
213             }
214             defaultReplyErrorHandler(replyPacket.errorCode());
215         } catch (IOException JavaDoc e) {
216             defaultIOExceptionHandler(e);
217         } finally {
218             handledJdwpRequest();
219         }
220     }
221
222     /**
223      * @return Returns the value of 'this' for the current frame.
224      */

225     public ObjectReference thisObject() throws InvalidStackFrameException {
226         // Note that this information should not be cached.
227
initJdwpRequest();
228         try {
229             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
230             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
231             writeWithThread(this, outData);
232     
233             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.SF_THIS_OBJECT, outBytes);
234             defaultReplyErrorHandler(replyPacket.errorCode());
235             
236             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
237             ObjectReference result = ObjectReferenceImpl.readObjectRefWithTag(this, replyData);
238             return result;
239         } catch (IOException JavaDoc e) {
240             defaultIOExceptionHandler(e);
241             return null;
242         } finally {
243             handledJdwpRequest();
244         }
245     }
246
247     /**
248      * @return Returns the thread under which this frame's method is running.
249      */

250     public ThreadReference thread() {
251         return fThread;
252     }
253     
254     /**
255      * @return Returns a LocalVariable that matches the given name and is visible at the current frame location.
256      */

257     public LocalVariable visibleVariableByName(String JavaDoc name) throws AbsentInformationException {
258         Iterator JavaDoc iter = visibleVariables().iterator();
259         while (iter.hasNext()) {
260             LocalVariableImpl var = (LocalVariableImpl)iter.next();
261             if (var.name().equals(name)) {
262                 return var;
263             }
264         }
265         
266         return null;
267     }
268     
269     /**
270      * @return Returns the values of multiple local variables in this frame.
271      */

272     public List JavaDoc visibleVariables() throws AbsentInformationException {
273         List JavaDoc variables= fLocation.method().variables();
274         Iterator JavaDoc iter = variables.iterator();
275         List JavaDoc visibleVars = new ArrayList JavaDoc(variables.size());
276         while (iter.hasNext()) {
277             LocalVariableImpl var = (LocalVariableImpl)iter.next();
278             // Only return local variables other than the this pointer.
279
if (var.isVisible(this) && !var.isThis()) {
280                 visibleVars.add(var);
281             }
282         }
283         return visibleVars;
284     }
285     
286     /**
287      * @return Returns the hash code value.
288      */

289     public int hashCode() {
290         return fThread.hashCode() + fFrameID.hashCode();
291     }
292     
293     /**
294      * @return Returns true if two mirrors refer to the same entity in the target VM.
295      * @see java.lang.Object#equals(Object)
296      */

297     public boolean equals(Object JavaDoc object) {
298         return object != null && object.getClass().equals(this.getClass()) && fThread.equals(((StackFrameImpl)object).fThread) && fFrameID.equals(((StackFrameImpl)object).fFrameID);
299     }
300     
301     /**
302      * Writes JDWP representation.
303      */

304     public void write(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
305         fFrameID.write(out);
306         if (target.fVerboseWriter != null) {
307             target.fVerboseWriter.println("stackFrame", fFrameID.value()); //$NON-NLS-1$
308
}
309     }
310     
311     /**
312      * Writes JDWP representation.
313      */

314     public void writeWithThread(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
315         fThread.write(target, out);
316         write(target, out);
317     }
318     
319     /**
320      * @return Reads JDWP representation and returns new instance.
321      */

322     public static StackFrameImpl readWithLocation(MirrorImpl target, ThreadReferenceImpl thread, DataInputStream JavaDoc in) throws IOException JavaDoc {
323         VirtualMachineImpl vmImpl = target.virtualMachineImpl();
324         JdwpFrameID ID = new JdwpFrameID(vmImpl);
325         ID.read(in);
326         if (target.fVerboseWriter != null) {
327             target.fVerboseWriter.println("stackFrame", ID.value()); //$NON-NLS-1$
328
}
329
330         if (ID.isNull()) {
331             return null;
332         }
333         LocationImpl location = LocationImpl.read(target, in);
334         if (location == null) {
335             return null;
336         }
337
338         return new StackFrameImpl(vmImpl, ID, thread, location);
339     }
340 }
341
Popular Tags