2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Mono.Debugger.Soft / Mono.Debugger.Soft / ObjectMirror.cs
blob8b0db9998248d822d70bd1dfefb25834bf40c2d8
1 using System;
2 using System.Collections.Generic;
3 using System.Runtime.Remoting.Messaging;
4 using System.Threading;
6 namespace Mono.Debugger.Soft
8 public class ObjectMirror : Value {
10 internal ObjectMirror (VirtualMachine vm, long id) : base (vm, id) {
13 public TypeMirror Type {
14 get {
15 return vm.GetType (vm.conn.Object_GetType (id));
19 public AppDomainMirror Domain {
20 get {
21 return vm.GetDomain (vm.conn.Object_GetDomain (id));
25 public bool IsCollected {
26 get {
27 return vm.conn.Object_IsCollected (id);
31 public Value GetValue (FieldInfoMirror field) {
32 return GetValues (new FieldInfoMirror [] { field }) [0];
35 public Value[] GetValues (IList<FieldInfoMirror> fields) {
36 if (fields == null)
37 throw new ArgumentNullException ("fields");
38 foreach (FieldInfoMirror f in fields) {
39 if (f == null)
40 throw new ArgumentNullException ("field");
41 CheckMirror (f);
43 long[] ids = new long [fields.Count];
44 for (int i = 0; i < fields.Count; ++i)
45 ids [i] = fields [i].Id;
46 try {
47 return vm.DecodeValues (vm.conn.Object_GetValues (id, ids));
48 } catch (CommandException ex) {
49 if (ex.ErrorCode == ErrorCode.INVALID_FIELDID)
50 throw new ArgumentException ("One of the fields is not valid for this type.", "fields");
51 else
52 throw;
56 public void SetValues (IList<FieldInfoMirror> fields, Value[] values) {
57 if (fields == null)
58 throw new ArgumentNullException ("fields");
59 if (values == null)
60 throw new ArgumentNullException ("values");
61 foreach (FieldInfoMirror f in fields) {
62 if (f == null)
63 throw new ArgumentNullException ("field");
64 CheckMirror (f);
66 foreach (Value v in values) {
67 if (v == null)
68 throw new ArgumentNullException ("values");
69 CheckMirror (v);
71 long[] ids = new long [fields.Count];
72 for (int i = 0; i < fields.Count; ++i)
73 ids [i] = fields [i].Id;
74 try {
75 vm.conn.Object_SetValues (id, ids, vm.EncodeValues (values));
76 } catch (CommandException ex) {
77 if (ex.ErrorCode == ErrorCode.INVALID_FIELDID)
78 throw new ArgumentException ("One of the fields is not valid for this type.", "fields");
79 else if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
80 throw new ArgumentException ("One of the values is not valid for its field.", "values");
81 else
82 throw;
86 public void SetValue (FieldInfoMirror field, Value value) {
87 SetValues (new FieldInfoMirror [] { field }, new Value [] { value });
91 * The current address of the object. It can change during garbage
92 * collections. Use a long since the debuggee might have a different
93 * pointer size.
95 public long Address {
96 get {
97 return vm.conn.Object_GetAddress (id);
101 public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
102 return InvokeMethod (vm, thread, method, this, arguments, InvokeOptions.None);
105 public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
106 return InvokeMethod (vm, thread, method, this, arguments, options);
109 [Obsolete ("Use the overload without the 'vm' argument")]
110 public IAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
111 return BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
114 public IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
115 return BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
118 public Value EndInvokeMethod (IAsyncResult asyncResult) {
119 return EndInvokeMethodInternal (asyncResult);
123 * Common implementation for invokes
126 class InvokeAsyncResult : IInvokeAsyncResult {
128 public object AsyncState {
129 get; set;
132 public WaitHandle AsyncWaitHandle {
133 get; set;
136 public bool CompletedSynchronously {
137 get {
138 return false;
142 public bool IsCompleted {
143 get; set;
146 public AsyncCallback Callback {
147 get; set;
150 public ErrorCode ErrorCode {
151 get; set;
154 public VirtualMachine VM {
155 get; set;
158 public ThreadMirror Thread {
159 get; set;
162 public ValueImpl Value {
163 get; set;
166 public ValueImpl Exception {
167 get; set;
170 public int ID {
171 get; set;
174 public void Abort ()
176 if (ID == 0) // Ooops
177 return;
179 ObjectMirror.AbortInvoke (VM, Thread, ID);
183 internal static IInvokeAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
184 if (thread == null)
185 throw new ArgumentNullException ("thread");
186 if (method == null)
187 throw new ArgumentNullException ("method");
188 if (arguments == null)
189 arguments = new Value [0];
191 InvokeFlags f = InvokeFlags.NONE;
193 if ((options & InvokeOptions.DisableBreakpoints) != 0)
194 f |= InvokeFlags.DISABLE_BREAKPOINTS;
195 if ((options & InvokeOptions.SingleThreaded) != 0)
196 f |= InvokeFlags.SINGLE_THREADED;
198 InvokeAsyncResult r = new InvokeAsyncResult { AsyncState = state, AsyncWaitHandle = new ManualResetEvent (false), VM = vm, Thread = thread, Callback = callback };
200 r.ID = vm.conn.VM_BeginInvokeMethod (thread.Id, method.Id, this_obj != null ? vm.EncodeValue (this_obj) : vm.EncodeValue (vm.CreateValue (null)), vm.EncodeValues (arguments), f, InvokeCB, r);
202 return r;
205 // This is called when the result of an invoke is received
206 static void InvokeCB (ValueImpl v, ValueImpl exc, ErrorCode error, object state) {
207 InvokeAsyncResult r = (InvokeAsyncResult)state;
209 if (error != 0) {
210 r.ErrorCode = error;
211 } else {
212 r.Value = v;
213 r.Exception = exc;
216 r.IsCompleted = true;
217 ((ManualResetEvent)r.AsyncWaitHandle).Set ();
219 if (r.Callback != null)
220 r.Callback.BeginInvoke (r, null, null);
223 internal static Value EndInvokeMethodInternal (IAsyncResult asyncResult) {
224 if (asyncResult == null)
225 throw new ArgumentNullException ("asyncResult");
227 InvokeAsyncResult r = (InvokeAsyncResult)asyncResult;
229 if (!r.IsCompleted)
230 r.AsyncWaitHandle.WaitOne ();
232 if (r.ErrorCode != 0) {
233 try {
234 r.VM.ErrorHandler (null, new ErrorHandlerEventArgs () { ErrorCode = r.ErrorCode });
235 } catch (CommandException ex) {
236 if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
237 throw new ArgumentException ("Incorrect number or types of arguments", "arguments");
238 else
239 throw;
241 throw new NotImplementedException ();
242 } else {
243 if (r.Exception != null)
244 throw new InvocationException ((ObjectMirror)r.VM.DecodeValue (r.Exception));
245 else
246 return r.VM.DecodeValue (r.Value);
250 internal static Value InvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) {
251 return EndInvokeMethodInternal (BeginInvokeMethod (vm, thread, method, this_obj, arguments, options, null, null));
254 internal static void AbortInvoke (VirtualMachine vm, ThreadMirror thread, int id)
256 vm.conn.VM_AbortInvoke (thread.Id, id);