2 using System.Collections.Generic;
5 namespace Mono.Debugger.Soft
7 public class StackFrame : Mirror
13 StackFrameFlags flags;
16 * FIXME: Decide on the way to request/handle debugging information:
17 * - request the info in bulk for all frames/on demand for individual frames
18 * - request the info from the runtime/request only the il offset, and compute
19 * everything else based on this info using the method debug info.
22 internal StackFrame (VirtualMachine vm, long id, ThreadMirror thread, MethodMirror method, int il_offset, StackFrameFlags flags) : base (vm, id) {
25 this.il_offset = il_offset;
29 public ThreadMirror Thread {
35 public MethodMirror Method {
41 public Location Location {
43 if (location == null) {
45 string src_file = null;
47 int column_number = 0;
52 line_number = method.il_offset_to_line_number (il_offset, out src_file, out hash, out column_number);
54 location = new Location (vm, Method, 0, il_offset, src_file != null ? src_file : method.SourceFile, line_number, column_number, hash);
60 public string FileName {
62 return Location.SourceFile;
68 return Location.ILOffset;
72 public int LineNumber {
74 return Location.LineNumber;
78 public bool IsDebuggerInvoke {
80 return (flags & StackFrameFlags.DEBUGGER_INVOKE) != 0;
85 * Whenever this frame transitions to native code. The method associated
86 * with the frame is either an InternalCall or a pinvoke method.
88 public bool IsNativeTransition {
90 return (flags & StackFrameFlags.NATIVE_TRANSITION) != 0;
94 public Value GetValue (ParameterInfoMirror param) {
96 throw new ArgumentNullException ("param");
97 if (param.Method != Method)
98 throw new ArgumentException ("Parameter doesn't belong to this frame's method.");
100 throw new ArgumentException ("Parameter represents the method return value.");
103 // FIXME: Allow returning the frame return value if possible
104 return vm.DecodeValue (vm.conn.StackFrame_GetValues (thread.Id, Id, new int [] { (- param.Position) - 1 })[0]);
107 public Value GetValue (LocalVariable var) {
109 throw new ArgumentNullException ("var");
110 if (var.Method != Method)
111 throw new ArgumentException ("Local variable doesn't belong to this frame's method.");
114 // FIXME: Check for return value
115 // FIXME: Allow returning the frame return value if possible
116 return vm.DecodeValue (vm.conn.StackFrame_GetValues (thread.Id, Id, new int [] { var.GetValueIndex } )[0]);
119 public Value[] GetValues (LocalVariable[] vars) {
121 throw new ArgumentNullException ("vars");
122 for (int i = 0; i < vars.Length; ++i) {
123 if (vars [i] == null)
124 throw new ArgumentNullException ("vars");
125 if (vars [i].Method != Method)
126 throw new ArgumentException ("Local variable doesn't belong to this frame's method.");
128 int[] pos = new int [vars.Length];
129 for (int i = 0; i < vars.Length; ++i)
130 pos [i] = vars [i].GetValueIndex;
131 return vm.DecodeValues (vm.conn.StackFrame_GetValues (thread.Id, Id, pos));
134 public Value GetArgument (int pos) {
135 return GetValue (Method.GetParameters () [pos]);
138 public Value GetThis () {
139 return vm.DecodeValue (vm.conn.StackFrame_GetThis (thread.Id, Id));
142 public void SetValue (LocalVariable var, Value value) {
144 throw new ArgumentNullException ("var");
145 if (var.Method != Method)
146 throw new ArgumentException ("Local variable doesn't belong to this frame's method.");
148 throw new ArgumentNullException ("value");
151 // FIXME: Check for return value
153 vm.conn.StackFrame_SetValues (thread.Id, Id, new int [] { var.GetValueIndex }, new ValueImpl [] { vm.EncodeValue (value) });
154 } catch (CommandException ex) {
155 if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
156 throw new ArgumentException ("Value does not match the type of the local variable.");
162 public void SetValue (ParameterInfoMirror param, Value value) {
164 throw new ArgumentNullException ("param");
165 if (param.Method != Method)
166 throw new ArgumentException ("Parameter doesn't belong to this frame's method.");
168 throw new ArgumentException ("Parameter represents the method return value.");
170 throw new ArgumentNullException ("value");
174 // FIXME: Allow setting the frame return value if possible
176 vm.conn.StackFrame_SetValues (thread.Id, Id, new int [] { (- param.Position) - 1 }, new ValueImpl [] { vm.EncodeValue (value) });
177 } catch (CommandException ex) {
178 if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
179 throw new ArgumentException ("Value does not match the type of the variable.");
185 public IList<LocalVariable> GetVisibleVariables () {
186 if (Location.ILOffset == -1)
187 throw new AbsentInformationException ();
189 return Method.GetLocals ().Where (l => l.LiveRangeStart <= location.ILOffset && l.LiveRangeEnd >= location.ILOffset).ToList ();
192 public LocalVariable GetVisibleVariableByName (string name) {
194 throw new ArgumentNullException ("name");
196 if (Location.ILOffset == -1)
197 throw new AbsentInformationException ();
199 return Method.GetLocals ().Where (l => l.LiveRangeStart <= location.ILOffset && l.LiveRangeEnd >= location.ILOffset && l.Name == name).FirstOrDefault ();